using DevExpress.XtraEditors; using IStation.Epanet; using IStation.Epanet.Enums; using IStation.Model; using IStation.WinFrmUI; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Runtime; using System.Text; using static IStation.WinFrmUI.Monitor.ModelCorrectionCombinePage; namespace IStation.Test { public class Station1CombineHelper { private static string _model_file = System.IO.Path.Combine (SettingsD.File.RootDirectory, SettingsD.File.DataFolder, "ch2_v3_20240801(Clear).inp"); static double _min_flow = 0; static double _max_flow = 100000; static double _space_flow = 500; /// /// 绑定数据 /// public static void Start() { var projectId = 661070185922629; IStation.SettingsD.Project.ID = projectId; var monitorDataSourcesId = 663976941449285;//2024-202504 var stationIndex = 1; var stationId = 462958406303813; var dtStart = new DateTime(2025, 4, 1); var dtEnd = new DateTime(2025, 5, 1); var bll = new BLL.StationSignalRecordPacket(); var bllEquipment = new BLL.Equipment(); var bllCurve = new BLL.PumpCurve(); var pumpList = bllEquipment.GetPumpListByBelongTypeAndBelongID(IStation.ObjectType.Station, stationId); var flagList = pumpList.Select(x => x.SortCode).OrderBy(x => x).ToList(); var flagPumpDict = pumpList.ToDictionary(x => x.SortCode, x => x.RatedParas); var flagQhCurveDict = GetFlagCurveDict(); var flagHzQhCurveDict = GetFlagHzCurveDict(); var pipe_flow_id_list = GlobalHelperW.GetPipeFlowIdList(stationIndex); var pipe_pressure_id_list = GlobalHelperW.GetPipePressureIdList(stationIndex); //var packet_list = bll.Get(monitorDataSourcesId, stationId); //var allStationRecordList = packet_list.SelectMany(x => x.StationSignalRecords).ToList(); var packet_list = bll.Get(monitorDataSourcesId, stationId,2025,2); var allStationRecordList = packet_list.StationSignalRecords.Where(x=>x.Time.Day==11).ToList(); var temp_id_build = new StringBuilder(31); var err = EpanetMethods.ENopen(_model_file, "", ""); if ((int)err > 6) { throw new Exception($"ENopen:{err}"); } err = EpanetMethods.ENopenH(); if ((int)err > 6) { throw new Exception($"ENopenH:{err}"); } var curve_point_count = 100; var flag_qh_curve_dict = GetFlagCurveDict(); var pump_model_mapping_list = AnalysisHelper.GetPumpModelMappingList(); var model_mapping_list = AnalysisHelper.GetStationMappingList(); foreach (var item in pump_model_mapping_list) { var flag = item.Flag; if (EpanetMethods.ENgetlinkindex(item.PumpId, out int pump_index) != ErrorCode.Ok) throw new Exception($"ENgetlinkindex:{err}"); if (!string.IsNullOrEmpty(item.FlowId)) { if (EpanetMethods.ENgetlinkindex(item.FlowId, out int flow_index) != ErrorCode.Ok) throw new Exception($"ENgetlinkindex:{err}"); item.FlowIndex = flow_index; } if (EpanetMethods.ENgetnodeindex(item.PressureId, out int pressure_index) != ErrorCode.Ok) throw new Exception($"ENgetnodeindex:{err}"); if (EpanetMethods.ENgetcurveindex(item.CurveId, out int curve_index) != ErrorCode.Ok) throw new Exception($"ENgetcurveindex:{err}"); item.PumpIndex = pump_index; item.PressureIndex = pressure_index; item.CurveIndex = curve_index; var qh = flag_qh_curve_dict[flag]; var fit_point_list = qh.GetFitPoints(curve_point_count); var flow_list = fit_point_list.Select(x => (float)x.X).ToArray(); var head_list = fit_point_list.Select(x => (float)x.Y).ToArray(); var cek = CheckFitPointList(fit_point_list, curve_point_count); if (!cek) { throw new Exception($"CheckFitPointList: false"); } err = EpanetMethods.ENsetcurve(item.CurveIndex, flow_list, head_list, curve_point_count); if (err != 0) { throw new Exception($"ENsetcurve:{err}"); } } foreach (var item in model_mapping_list) { if (EpanetMethods.ENgetlinkindex(item.FlowId, out int flow_index) != ErrorCode.Ok) throw new Exception($"ENgetlinkindex:{err}"); if (EpanetMethods.ENgetnodeindex(item.PressureId, out int pressure_index) != ErrorCode.Ok) throw new Exception($"ENgetnodeindex:{err}"); item.PressureIndex = pressure_index; item.FlowIndex = flow_index; } var pump_model_mapping_dict = pump_model_mapping_list.ToDictionary(x => x.Flag, y => y); var pattern_id_list = AnalysisHelper.GetPatternIdList(); var pattern_id_dict = new Dictionary(); foreach (var id in pattern_id_list) { if (EpanetMethods.ENgetpatternindex(id, out int index) != ErrorCode.Ok) continue; pattern_id_dict.Add(id, index); } var vm_combine_list = new List(); var vm_diff_list = new List(); foreach (var station_record in allStationRecordList) { var model_record_dict = station_record.ModelRecordDict; var pipe_flow_err = true; var pipe_pressure_err = true; foreach (var id in pipe_flow_id_list) { if (model_record_dict[id] < 1) { pipe_flow_err = false; break; } } foreach (var id in pipe_pressure_id_list) { var value = model_record_dict[id]; if (value < 1 || value > 40) { pipe_pressure_err = false; break; } } if (!pipe_flow_err || !pipe_pressure_err) { continue; } var time = station_record.Time.ToString("G"); var pump_record_list = station_record.PumpSignalRecords; var total_flow = station_record.TotalFlow; var total_pressure = station_record.TotalPressure; var pump_total_flow = pump_record_list.Sum(x => x.FlowRate); var diff_flow = station_record.DiffFlow; //if (total_pressure < 20|| total_pressure>60) //{ // continue; //} if (total_pressure < 0) { continue; } if (total_flow <= 0 && pump_total_flow <= 0) { continue; } if (pump_total_flow > 0 && Math.Abs(diff_flow) > 2000) { continue; } //if (station_record.Time.Month==4&& station_record.Time.Day==17) //{ // continue; //} //if (station_record.Time > new DateTime(2024,4,29)&& station_record.Time < new DateTime(2024, 5, 15)) //{ // continue; //} var pump_run_flags = pump_record_list.Select(x => x.Flag).OrderBy(x => x).ToList(); if (pump_record_list.Exists(x => x.Flag != 15 && x.Flag != 16 && x.Rpm < 1)) { continue; } //if (pump_record_list.Exists(x => x.FlowRate < 1)) //{ // continue; //} if (pump_record_list.Exists(x => x.OutletPressure > 50)) { continue; } if (flagHzQhCurveDict.Any()) { var error = false; foreach (var pump_record in pump_record_list) { var flag = pump_record.Flag; var pump = flagPumpDict[flag]; var mapping = pump_model_mapping_dict[flag]; var rpm_ratio = pump_record.Rpm / pump.Nr; if (!pump.IsBp) rpm_ratio = 1; if (rpm_ratio <= 0.1) continue; int hz0 = (int)Math.Round(rpm_ratio * 50, 0); if (hz0 > 50) hz0 = 50; if (hz0<25) { error = true; break; } var updateCurvePtList = flagHzQhCurveDict[flag][hz0]; if (updateCurvePtList == null) { throw new Exception($"ana_factor:is null"); } var x_list = updateCurvePtList.Select(x => (float)x.X).ToArray(); var y_list = updateCurvePtList.Select(x => (float)x.Y).ToArray(); err = EpanetMethods.ENsetcurve(mapping.CurveIndex, x_list, y_list, curve_point_count); if ((int)err > 6) { throw new Exception($"ENsetcurve:{err}"); } } if (error) { continue; } } foreach (var pattern in pattern_id_dict) { var pattern_id = pattern.Key; var pattern_index = pattern.Value; var pattern_value = 0f; if (model_record_dict.ContainsKey(pattern_id)) { pattern_value = (float)model_record_dict[pattern_id]; } err = EpanetMethods.ENsetpattern(pattern_index, new float[] { pattern_value }, 1); if ((int)err > 6) { throw new Exception($"ENsetpattern:{err}"); } } err = EpanetMethods.ENinitH(0); if ((int)err > 6) { throw new Exception($"ENinitH:{err}"); } err = EpanetMethods.ENrunH(out _); if ((int)err > 6) { throw new Exception($"ENrunH:{err}"); } var flags = pump_record_list.Select(x => x.Flag).OrderBy(x => x).ToList(); var vm_combine = new ModelCombineViewModel(); vm_combine.Time = time; vm_combine.RunFlags = IStation.Untity.IntListHelper.ToString(flags); vm_combine.ModelDeviation = new List>(); vm_combine_list.Add(vm_combine); foreach (var pump_record in pump_record_list) { var flag = pump_record.Flag; var pump = flagPumpDict[flag]; var qh = flag_qh_curve_dict[flag]; var mapping = pump_model_mapping_dict[flag]; var rpm = pump_record.Rpm; if (!pump.IsBp) rpm = pump.Nr; if (rpm == 0) break; var hz = Math.Round(rpm / pump.Nr * 50, 2); if (hz > 50) hz = 50; var hz0 = Math.Round(hz, 0); var wl = pump_record.WaterLevel; var inlet_pressure = Model.CurveCalcuHelper.Mpa2M(pump_record.InletPressure); var outlet_pressure = Model.CurveCalcuHelper.Mpa2M(pump_record.OutletPressure); var pressure_diff = outlet_pressure - inlet_pressure; var flow = pump_record.FlowRate; var curve_head = pump_record.Head; err = EpanetMethods.ENgetlinkvalue(mapping.PumpIndex, LinkValue.Flow, out float model_flow); if ((int)err > 6) { throw new Exception($"ENgetnodevalue:{err}"); } err = EpanetMethods.ENgetnodevalue(mapping.PressureIndex, NodeValue.Pressure, out float model_outlet_pressure); if ((int)err > 6) { throw new Exception($"ENgetnodevalue:{err}"); } model_flow = Math.Abs(model_flow); model_outlet_pressure = Math.Abs(model_outlet_pressure); var model_pressure_diff = model_outlet_pressure - inlet_pressure; var flow_diff = flow - model_flow; var pressure_diff_dev = pressure_diff - model_pressure_diff; var calc_flow = flow > 0 ? flow : model_flow; var dif_flow = flow - model_flow; vm_combine.ScadaTotalFlow += flow < 1 ? model_flow : flow; vm_combine.ModelTotalFlow += model_flow; vm_combine.ModelDeviation.Add(new Tuple(flag, calc_flow, pressure_diff_dev)); } foreach (var mapping in model_mapping_list) { if (!model_record_dict.ContainsKey(mapping.ScadaPressureId)) { continue; } if (!model_record_dict.ContainsKey(mapping.ScadaFlowId)) { continue; } var flow = model_record_dict[mapping.ScadaFlowId]; var outlet_pressure = model_record_dict[mapping.ScadaPressureId]; err = EpanetMethods.ENgetlinkvalue(mapping.FlowIndex, LinkValue.Flow, out float model_flow); if ((int)err > 6) { throw new Exception($"ENgetnodevalue:{err}"); } err = EpanetMethods.ENgetnodevalue(mapping.PressureIndex, NodeValue.Pressure, out float model_outlet_pressure); if ((int)err > 6) { throw new Exception($"ENgetnodevalue:{err}"); } var flow_diff = flow - model_flow; var pressure_diff = outlet_pressure - model_outlet_pressure; var vm = new ModelDiffViewModel(); vm.Date = station_record.Time; vm.Time = time; vm.Name = mapping.Name; vm.ScadaFlow = Math.Round(flow, 1); vm.ScadaPressure = Math.Round(outlet_pressure, 3); vm.MonitorFlow = Math.Round(model_flow, 1); vm.MonitorPressure = Math.Round(model_outlet_pressure, 3); vm.FlowDiff = Math.Round(flow_diff, 1); vm.PressureDiff = Math.Round(pressure_diff, 3); vm_diff_list.Add(vm); } } err = EpanetMethods.ENcloseH(); if ((int)err > 6) { throw new Exception($"ENcloseH:{err}"); } err = EpanetMethods.ENclose(); if ((int)err > 6) { throw new Exception($"ENclose:{err}"); } if (!vm_combine_list.Any()) { return; } var run_flags_flow_pressure_diff_dict = vm_combine_list .Select(x => new Tuple>>(x.RunFlags, x.ScadaTotalFlow, x.ModelDeviation)) .ToList(); var ana_dev_list = GetAnalysisDeviationDtoList(flagPumpDict, run_flags_flow_pressure_diff_dict, _min_flow, _max_flow, _space_flow); SaveAnalysisDeviationDtoList(stationIndex,ana_dev_list); } public static List GetAnalysisDeviationDtoList(Dictionary flag_pump_dict, List>>> run_flags_flow_pressure_diff_dict, double minQ = 0, double maxQ = 100000, double spaceQ = 1000) { // 检查输入参数是否为空 if (flag_pump_dict == null || !flag_pump_dict.Any() || run_flags_flow_pressure_diff_dict == null || !run_flags_flow_pressure_diff_dict.Any()) { return new List(); } var resultList = new List(); // 遍历流量区间 for (double currentMinQ = minQ; currentMinQ <= maxQ; currentMinQ += spaceQ) { double currentMaxQ = currentMinQ + spaceQ; var validItems = run_flags_flow_pressure_diff_dict .Where(x => x.Item2 >= currentMinQ && x.Item2 <= currentMaxQ) .ToList(); // 如果当前区间没有有效数据,跳过本次循环 if (!validItems.Any()) { continue; } // 按运行标志分组 var groupedByRunFlags = validItems.GroupBy(x => x.Item1); foreach (var runFlagsGroup in groupedByRunFlags) { var analysisDeviationDto = CreateAnalysisDeviationDto(runFlagsGroup, currentMinQ, currentMaxQ); if (IsValidDeviation(analysisDeviationDto.PressureDiff)) { resultList.Add(analysisDeviationDto); } } } return resultList; } private static AnalysisHelper.AnalysisDeviationDto CreateAnalysisDeviationDto(IGrouping>>> runFlagsGroup, double currentMinQ, double currentMaxQ) { var vm = new AnalysisHelper.AnalysisDeviationDto { RunFlags = IStation.Untity.IntListHelper.ToList(runFlagsGroup.Key), MinFlow = currentMinQ, MaxFlow = currentMaxQ }; var devDict = new Dictionary(); var allTuples = runFlagsGroup.SelectMany(x => x.Item3).ToList(); var groupedByFlag = allTuples.GroupBy(x => x.Item1); foreach (var flagGroup in groupedByFlag) { var headDiffArray = flagGroup.Select(x => x.Item3).ToArray(); var (filterStdDevPopArray, stdDevPop) = AnalysisHelper.GetFilterBySTDP(headDiffArray); var stdDevPopHeadAvg = filterStdDevPopArray.Average(); var headDiffAvg = Math.Round(stdDevPopHeadAvg, 5); devDict.Add(flagGroup.Key, headDiffAvg); } vm.Count = runFlagsGroup.Count(); vm.PressureDiff = devDict; return vm; } private static bool IsValidDeviation(Dictionary devDict) { foreach (var dev in devDict) { if (Math.Abs(dev.Value) > 5) { return false; } } return true; } //public static List GetAnalysisDeviationDtoList(Dictionary flag_pump_dict, List>>> run_flags_flow_pressure_diff_dict, double minQ = 0, double maxQ = 100000, double spaceQ = 1000) //{ // if (flag_pump_dict == null || !flag_pump_dict.Any()) // { // return default; // } // if (run_flags_flow_pressure_diff_dict == null || !run_flags_flow_pressure_diff_dict.Any()) // { // return default; // } // var list = new List(); // var error_value = false; // for (double current_minQ = minQ; current_minQ <= maxQ; current_minQ += spaceQ) // { // var current_maxQ = current_minQ + spaceQ; // var combine_list = run_flags_flow_pressure_diff_dict.Where(x => x.Item2 >= current_minQ && x.Item2 <= current_maxQ).ToList(); // if (combine_list == null || !combine_list.Any()) // continue; // var group_by_run_flags = combine_list.GroupBy(x => x.Item1); // foreach (var item_run_flags in group_by_run_flags) // { // var flags = item_run_flags.Key; // var vm = new AnalysisHelper.AnalysisDeviationDto // { // RunFlags = IStation.Untity.IntListHelper.ToList(flags), // MinFlow = current_minQ, // MaxFlow = current_maxQ // }; // var dev_dict = new Dictionary(); // List> tuple_list = item_run_flags.SelectMany(x => x.Item3).ToList(); // var group_by_flag = tuple_list.GroupBy(x => x.Item1); // foreach (var flag_item in group_by_flag) // { // var flag = flag_item.Key; // var head_diff_array = flag_item.Select(x => x.Item3).ToArray(); // var filter_std_dev_pop_tuple = AnalysisHelper.GetFilterBySTDP(head_diff_array); // var filter_std_dev_pop_array = filter_std_dev_pop_tuple.Item1; // var std_dev_pop = filter_std_dev_pop_tuple.Item2; // var std_dev_pop_head_avg = filter_std_dev_pop_array.Average(); // var head_diff_avg = std_dev_pop_head_avg; // head_diff_avg = Math.Round(head_diff_avg, 5); // dev_dict.Add(flag, head_diff_avg); // } // vm.Count = item_run_flags.Count(); // vm.PressureDiff = dev_dict; // error_value = false; // foreach (var dev in dev_dict) // { // if (Math.Abs(dev.Value) > 3) // { // error_value = true; // break; // } // } // if (error_value) // { // continue; // } // list.Add(vm); // } // } // return list; //} public static bool SaveAnalysisDeviationDtoList(int stationIndex, List all_list) { var root_folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "分析"); if (!Directory.Exists(root_folder)) { Directory.CreateDirectory(root_folder); } List exist_list = null; var fileName = root_folder + "\\" + "AnalysisDeviation.json"; if (File.Exists(fileName)) { var exist_json = File.ReadAllText(fileName); var all_exist_list = JsonHelper.Json2Object>(exist_json); exist_list = all_exist_list?.Where(x => x.Station != stationIndex).ToList(); File.Delete(fileName); } if (exist_list != null) { all_list.AddRange(exist_list); } all_list = all_list.OrderBy(x => x.Station).ThenBy(x => x.MinFlow).ToList(); var json = JsonHelper.Object2Json(all_list); File.WriteAllText(fileName, json); return true; } static bool CheckFitPointList(List fit_point_list, int nPoints) { var arr = fit_point_list.ToArray(); var max_y = fit_point_list[0].Y; for (int j = 1; j < nPoints; j++) { if (arr[j].Y > max_y) { return false; } else { max_y = fit_point_list.Take(j).Max(x => x.Y); } } return true; } private static Dictionary GetFlagCurveDict() { var dict = new Dictionary(); var bll_curve = new BLL.PumpCurve(); var station_list = new BLL.Station().GetAll(); foreach (var station in station_list) { var eq_list = new BLL.Equipment().GetPumpListByBelongTypeAndBelongID(IStation.ObjectType.Station, station.ID); if (eq_list == null || !eq_list.Any()) { return default; } foreach (var eq in eq_list) { Model.CurveExpress qh = null; var curve_info = bll_curve.GetDefaultWorkingByPumpID(eq.ID)?.CurveInfo; if (curve_info != null) { qh = curve_info.CurveQH; } dict.Add(eq.SortCode, qh); } } return dict; } private static Dictionary>> GetFlagHzCurveDict() { var fullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "pumpcsv"); var fileNameList = Directory.GetFiles(fullPath).Select(x => Path.GetFileNameWithoutExtension(x)).ToList(); if (fileNameList == null || fileNameList.Count() < 1) return default; var dict=new Dictionary>>(); var group = fileNameList.Where(x => x.Contains("_update_curve")).GroupBy(x => x.Substring(0, 2)); foreach (var flagItem in group) { var flag=int.Parse(flagItem.Key); var files = flagItem.OrderBy(x => x).ToList(); var fileInfoList = new List<(int Hz, string FileName)>(); dict[flag] = new Dictionary>(); foreach (var fileName in files) { var hz = (int.Parse(fileName.Substring(3, 2))); if (hz>50) { continue; } fileInfoList.Add((hz, fileName)); } foreach (var item in fileInfoList) { var updateCurvePtList = new List(); var updateCurveFile = Path.Combine(fullPath, $"{item.FileName}.csv"); using (var fs = new FileStream(updateCurveFile, FileMode.Open, FileAccess.Read)) using (var sr = new StreamReader(fs, Encoding.UTF8)) { var strLine = string.Empty; sr.ReadLine(); while (!string.IsNullOrEmpty(strLine = sr.ReadLine())) { var strList = strLine.Split(','); var x = double.Parse(strList[0]); var y = double.Parse(strList[1]); updateCurvePtList.Add(new CurvePoint(x, y)); } } dict[flag][item.Hz]= updateCurvePtList; } } return dict; } } }