using IStation.Epanet; using IStation.Epanet.Enums; namespace IStation.Service { /// /// 模型验证辅助类 /// public partial class ModeVerifyHelper { /// /// 实时验证 /// /// 验证标识 /// 验证时间 /// 验证模型文件 /// ZyScada数据列表 /// 自定义泵模式 /// public static List Verify( long verify_id, DateTime verify_time, string verify_file_path, List monitor_record_list, Dictionary pump_pattern_custom_dict = null) { var log_title = "初始化验证数据"; var log_msg = string.Empty; if (monitor_record_list == null || !monitor_record_list.Any()) { log_msg = "monitor_record_list 数据为空!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } var pump_nr_dict = GlobalHelper.ModelPumpNrDict; var pattern_id_mapping_dict = GlobalHelper.ModelPatternIdMappingDict; var flow_id_mapping_dict = GlobalHelper.ModelFlowIdMappingDict; var pressure_id_mapping_dict = GlobalHelper.ModelPressureIdMappingDict; var pressure_id_kPa_list = GlobalHelper.ModelPressureIdkPaList; var pattern_dict = new Dictionary(); var scada_dict = new Dictionary(); var exist_pump_pattern_custom_dict = pump_pattern_custom_dict != null && pump_pattern_custom_dict.Any(); #region 初始化 pattern_dict scada_dict foreach (var monitor_record in monitor_record_list) { var tag = monitor_record.DataCode; var value = monitor_record.DataValue; #region Pattern foreach (var item in pattern_id_mapping_dict) { if (item.Value != tag) continue; var pattern_id = item.Key; var factor = value ?? 0; if (exist_pump_pattern_custom_dict) { if (pump_pattern_custom_dict.ContainsKey(pattern_id)) { factor = pump_pattern_custom_dict[pattern_id] ?? 0; } } else { if (value.HasValue && pump_nr_dict.ContainsKey(pattern_id)) { factor /= pump_nr_dict[pattern_id]; factor = factor < 0 ? 0 : factor; } } pattern_dict.Add(pattern_id, new float[] { (float)factor }); } #endregion #region Scada foreach (var item in flow_id_mapping_dict) { if (item.Value != tag) continue; scada_dict.Add(tag, value ?? 0); } foreach (var item in pressure_id_mapping_dict) { if (item.Value != tag) continue; var pressure_value = value ?? 0; if (pressure_id_kPa_list.Contains(tag)) { pressure_value /= 1000; } pressure_value = IStation.Curve.PumpCalculateHelper.Mpa2M(pressure_value); scada_dict.Add(tag, pressure_value); } #endregion } #endregion var hydraulic_record_list = Verify(verify_id, verify_time, verify_file_path, flow_id_mapping_dict, pressure_id_mapping_dict, pattern_dict, scada_dict); return hydraulic_record_list; } /// /// 实时验证 /// /// 验证标识 /// 验证时间 /// 验证模型文件 /// 流量Scada标识字典 /// 压力Scada标识字典 /// 模式数据 /// Scada数据 /// public static List Verify( long verify_id, DateTime verify_time, string verify_file_path, Dictionary flow_id_mapping_dict, Dictionary pressure_id_mapping_dict, Dictionary pattern_dict, Dictionary scada_dict) { var log_title = "开始验证"; var log_msg = string.Empty; var hydraulic_record_list = new List(); if (flow_id_mapping_dict == null || !flow_id_mapping_dict.Any()) { log_msg = "流量标签字典为空!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } if (pressure_id_mapping_dict == null || !pressure_id_mapping_dict.Any()) { log_msg = "压力标签字典为空!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } if (pattern_dict == null || !pattern_dict.Any()) { log_msg = "模式数据为空!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } if (scada_dict == null || !scada_dict.Any()) { log_msg = "Scada数据为空!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } var err = EpanetMethods.ENopen(verify_file_path, "", ""); if (err != 0) { log_msg = err.GetMsg(); HydraulicLog.Info(verify_id, log_title, log_msg); return default; } err = EpanetMethods.ENopenH(); if (err != 0) { log_msg = err.GetMsg(); HydraulicLog.Info(verify_id, log_title, log_msg); return default; } log_title = "验证"; var model_id_build = new StringBuilder(31); var pattern_init = true; foreach (var pattern in pattern_dict) { var pattern_id = pattern.Key; var pattern_factor_array = pattern.Value; var pattern_factor_array_count = pattern_factor_array.Length == 0 ? 1 : pattern_factor_array.Length; err = EpanetMethods.ENgetpatternindex(pattern_id, out int pattern_index); if (err != ErrorCode.Ok) { pattern_init = false; log_msg = err.GetMsg(); HydraulicLog.Info(verify_id, log_title, log_msg); continue; } err = EpanetMethods.ENsetpattern(pattern_index, pattern_factor_array, pattern_factor_array_count); if (err != ErrorCode.Ok) { pattern_init = false; log_msg = err.GetMsg(); HydraulicLog.Info(verify_id, log_title, log_msg); continue; } } if (!pattern_init) { log_msg = $"{verify_time:G}:模式初始化失败!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } EpanetMethods.ENinitH(0); EpanetMethods.ENrunH(out _); EpanetMethods.ENgetcount(CountType.Link, out int link_count); EpanetMethods.ENgetcount(CountType.Node, out int node_count); for (int link_index = 1; link_index <= link_count; link_index++) { if (EpanetMethods.ENgetlinkid(link_index, model_id_build) != ErrorCode.Ok) continue; var model_id = model_id_build.ToString(); if (flow_id_mapping_dict.ContainsKey(model_id)) { var scada_id = flow_id_mapping_dict[model_id]; var scada_value = scada_dict[scada_id]; EpanetMethods.ENgetlinkvalue(link_index, LinkValue.Flow, out float model_value); model_value = Math.Abs(model_value); var record = new IStation.Model.HydraulicRecord { VerificationID = verify_id, Time = verify_time, ModelId = model_id, ScadaId = scada_id, ValueType = IStation.eValueType.Flow, ModelValue = (double)model_value, ScadaValue = scada_value }; record.DifferenceValue = record.ScadaValue - record.ModelValue; hydraulic_record_list.Add(record); } EpanetMethods.ENgetlinktype(link_index, out LinkType linkType); if (linkType == LinkType.Pump) { EpanetMethods.ENgetlinkvalue(link_index, LinkValue.InitStatus, out float on_off); } } for (int node_index = 1; node_index <= node_count; node_index++) { if (EpanetMethods.ENgetnodeid(node_index, model_id_build) != ErrorCode.Ok) continue; var model_id = model_id_build.ToString(); if (pressure_id_mapping_dict.ContainsKey(model_id)) { var scada_id = pressure_id_mapping_dict[model_id]; var scada_value = scada_dict[scada_id]; EpanetMethods.ENgetnodevalue(node_index, NodeValue.Head, out float model_value); var record = new IStation.Model.HydraulicRecord { VerificationID = verify_id, Time = verify_time, ModelId = model_id, ScadaId = scada_id, ValueType = IStation.eValueType.Head, ModelValue = (double)model_value, ScadaValue = scada_value }; record.DifferenceValue = record.ScadaValue - record.ModelValue; hydraulic_record_list.Add(record); } } EpanetMethods.ENcloseH(); EpanetMethods.ENclose(); return hydraulic_record_list; } /// /// 历史数据验证 /// /// 验证标识 /// 验证模型文件 /// ZyScada数据列表 /// public static Dictionary> Verify( long verify_id, string verify_file_path, Dictionary>> monitor_record_day_dict) { var log_title = "初始化验证数据"; var log_msg = string.Empty; if (monitor_record_day_dict == null || !monitor_record_day_dict.Any()) { log_msg = "monitor_record_day_dict 数据为空!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } var pump_nr_dict = GlobalHelper.ModelPumpNrDict; var pattern_id_mapping_dict = GlobalHelper.ModelPatternIdMappingDict; var flow_id_mapping_dict = GlobalHelper.ModelFlowIdMappingDict; var pressure_id_mapping_dict = GlobalHelper.ModelPressureIdMappingDict; var pressure_id_kPa_list = GlobalHelper.ModelPressureIdkPaList; var day_value_dict = new Dictionary, Dictionary>>>(); foreach (var day_item in monitor_record_day_dict) { var day = day_item.Key; var monitor_record_list_dict = day_item.Value; var pattern_list_dict = new Dictionary>(); foreach (var item in pattern_id_mapping_dict) { pattern_list_dict.Add(item.Key, new List()); } var scada_dict_dict = new Dictionary>(); #region 初始化 pattern_dict scada_dict for (int i = 0; i < monitor_record_list_dict.Count; i++) { var item = monitor_record_list_dict.ElementAt(i); var time = item.Key; var monitor_record_list = item.Value; var scada_dict = new Dictionary(); foreach (var monitor_record in monitor_record_list) { var tag = monitor_record.DataCode; var value = monitor_record.DataValue; #region Pattern foreach (var mapping in pattern_id_mapping_dict) { if (mapping.Value != tag) continue; var pattern_id = mapping.Key; var factor = value ?? 0; if (value.HasValue && pump_nr_dict.ContainsKey(pattern_id)) { factor /= pump_nr_dict[pattern_id]; factor = factor < 0 ? 0 : factor; } pattern_list_dict[pattern_id].Add((float)factor); } #endregion #region Scada foreach (var mapping in flow_id_mapping_dict) { if (mapping.Value != tag) continue; scada_dict.Add(tag, value ?? 0); } foreach (var mapping in pressure_id_mapping_dict) { if (mapping.Value != tag) continue; var pressure_value = value ?? 0; if (pressure_id_kPa_list.Contains(tag)) { pressure_value /= 1000; } pressure_value = IStation.Curve.PumpCalculateHelper.Mpa2M(pressure_value); scada_dict.Add(tag, pressure_value); } #endregion } scada_dict_dict.Add(time, scada_dict); } #endregion var pattern_array_dict = pattern_list_dict.ToDictionary(x => x.Key, y => y.Value.ToArray()); day_value_dict.Add(day, new(pattern_array_dict, scada_dict_dict)); } var hydraulic_record_list_dict = Verify(verify_id, verify_file_path, flow_id_mapping_dict, pressure_id_mapping_dict, day_value_dict); return hydraulic_record_list_dict; } /// /// 历史数据验证 /// /// 验证标识 /// 验证模型文件 /// 流量Scada标识字典 /// 压力Scada标识字典 /// 日数据列表 /// public static Dictionary> Verify( long verify_id, string verify_file_path, Dictionary flow_id_mapping_dict, Dictionary pressure_id_mapping_dict, Dictionary, Dictionary>>> day_value_dict) { #region 入参验证 var log_title = "开始验证"; var log_msg = string.Empty; var hydraulic_record_list_dict = new Dictionary>(); if (flow_id_mapping_dict == null || !flow_id_mapping_dict.Any()) { log_msg = "流量标签字典为空!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } if (pressure_id_mapping_dict == null || !pressure_id_mapping_dict.Any()) { log_msg = "压力标签字典为空!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } if (day_value_dict == null || !day_value_dict.Any()) { log_msg = "日数据列表为空!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } #endregion #region 加载模型 var err = EpanetMethods.ENopen(verify_file_path, "", ""); if (err != 0) { log_msg = err.GetMsg(); HydraulicLog.Info(verify_id, log_title, log_msg); return default; } //EpanetMethods.ENsettimeparam(TimeParameter.PatternStep, 1); //EpanetMethods.ENsettimeparam(TimeParameter.HydStep, 1); //EpanetMethods.ENsettimeparam(TimeParameter.ReportStep, 1); err = EpanetMethods.ENopenH(); if (err != 0) { log_msg = err.GetMsg(); HydraulicLog.Info(verify_id, log_title, log_msg); return default; } #endregion log_title = "验证"; var model_id_build = new StringBuilder(31); var pattern_init = true; var pattern_time_step = 0; foreach (var day_value in day_value_dict) { var day = day_value.Key; var pattern_dict = day_value.Value.Item1; var time_value_dict = day_value.Value.Item2; if (time_value_dict == null || !time_value_dict.Any()) { continue; } #region 模式初始化 pattern_init = true; pattern_time_step = 0; foreach (var pattern in pattern_dict) { var pattern_id = pattern.Key; var pattern_factor_array = pattern.Value; var pattern_factor_array_count = pattern_factor_array.Length == 0 ? 1 : pattern_factor_array.Length; err = EpanetMethods.ENgetpatternindex(pattern_id, out int pattern_index); if (err != ErrorCode.Ok) { pattern_init = false; log_msg = err.GetMsg(); HydraulicLog.Info(verify_id, log_title, log_msg); continue; } err = EpanetMethods.ENsetpattern(pattern_index, pattern_factor_array, pattern_factor_array_count); if (err != ErrorCode.Ok) { pattern_init = false; log_msg = err.GetMsg(); HydraulicLog.Info(verify_id, log_title, log_msg); continue; } } if (!pattern_init) { log_msg = $"{day:G}:模式初始化失败!"; HydraulicLog.Info(verify_id, log_title, log_msg); return default; } #endregion #region 模型验证 var time_value_dict_dict = time_value_dict.ToDictionary(x => x.Key.TimeOfDay.TotalSeconds, y => y); EpanetMethods.ENinitH(0); do { EpanetMethods.ENrunH(out int current_ts); EpanetMethods.ENgetcount(CountType.Link, out int link_count); EpanetMethods.ENgetcount(CountType.Node, out int node_count); var current_time = TimeSpan.FromSeconds(current_ts); if (time_value_dict_dict.ContainsKey(current_time.TotalSeconds)) { var hydraulic_record_list = new List(); var time_value = time_value_dict_dict[current_ts]; var verify_time = time_value.Key; var scada_dict = time_value.Value; for (int link_index = 1; link_index <= link_count; link_index++) { if (EpanetMethods.ENgetlinkid(link_index, model_id_build) != ErrorCode.Ok) continue; var model_id = model_id_build.ToString(); if (flow_id_mapping_dict.ContainsKey(model_id)) { var scada_id = flow_id_mapping_dict[model_id]; var scada_value = scada_dict[scada_id]; EpanetMethods.ENgetlinkvalue(link_index, LinkValue.Flow, out float model_value); var record = new IStation.Model.HydraulicRecord { VerificationID = verify_id, Time = verify_time, ModelId = model_id, ScadaId = scada_id, ValueType = IStation.eValueType.Flow, ModelValue = (double)Math.Abs(model_value), ScadaValue = scada_value }; record.DifferenceValue = record.ScadaValue - record.ModelValue; hydraulic_record_list.Add(record); } EpanetMethods.ENgetlinktype(link_index, out LinkType linkType); if (linkType == LinkType.Pump) { EpanetMethods.ENgetlinkvalue(link_index, LinkValue.InitStatus, out float on_off); } } for (int node_index = 1; node_index <= node_count; node_index++) { if (EpanetMethods.ENgetnodeid(node_index, model_id_build) != ErrorCode.Ok) continue; var model_id = model_id_build.ToString(); if (pressure_id_mapping_dict.ContainsKey(model_id)) { var scada_id = pressure_id_mapping_dict[model_id]; var scada_value = scada_dict[scada_id]; EpanetMethods.ENgetnodevalue(node_index, NodeValue.Head, out float model_value); var record = new IStation.Model.HydraulicRecord { VerificationID = verify_id, Time = verify_time, ModelId = model_id, ScadaId = scada_id, ValueType = IStation.eValueType.Head, ModelValue = (double)model_value, ScadaValue = scada_value }; record.DifferenceValue = record.ScadaValue - record.ModelValue; hydraulic_record_list.Add(record); } } hydraulic_record_list_dict.Add(verify_time, hydraulic_record_list); } EpanetMethods.ENnextH(out pattern_time_step); } while (pattern_time_step > 0); #endregion } EpanetMethods.ENcloseH(); EpanetMethods.ENclose(); return hydraulic_record_list_dict; } } }