using DevExpress.XtraCharts; using DevExpress.XtraEditors; using IStation.Epanet; using IStation.Epanet.Enums; using IStation.Model; using IStation.Untity; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Drawing; using System.IO; using System.Linq; using System.Runtime; using System.Text; using static IStation.WinFrmUI.AnalysisHelper; namespace IStation.WinFrmUI.Monitor { public partial class ModelCorrectionPage : DocumentPage { public ModelCorrectionPage() { InitializeComponent(); PageTitle.Caption = "模型修正"; gridView1.SetNormalView(); gridView2.SetNormalView(); gridView3.SetNormalView(); colHz.Visible = false; colRpm.Visible = false; colWaterLevel.Visible = false; repositoryItemDateEdit1.SetOnlyShowYearMonth(); repositoryItemDateEdit2.SetOnlyShowYearMonth(); barEditDateStart.EditValue = new DateTime(2024, 1, 1); barEditDateEnd.EditValue = new DateTime(2024, 9, 1); cmbFlag.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor; // this.barCekUseFlow.Visibility = DevExpress.XtraBars.BarItemVisibility.Never; barCekUseFlow.Checked = true; stationListCtrl1.FocusedChangedEvent += StationListCtrl1_FocusedChangedEvent; monitorDataSourcesTreeList1.FocusedChangedEvent += MonitorDataSourcesListCtrl1_FocusedChangedEvent; timeValueSwiftPlotChartView1.SetTimeAxisX(DevExpress.XtraCharts.DateTimeMeasureUnit.Minute); InitialDiagarm(); } private Series _series_default_head; // private Series _series_curve_head; // private Series _series_correct_curve_head; // private void InitialDiagarm() { chartControl1.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False;//是否在图表上显示图例 var diagram = (SwiftPlotDiagram)chartControl1.Diagram; diagram.EnableAxisXScrolling = true;//X轴是否允许滚动 diagram.EnableAxisXZooming = true;//X轴是否允许缩放 diagram.PaneLayout.Direction = PaneLayoutDirection.Vertical;//窗格的对齐方式 diagram.AxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Minute; _series_default_head = chartControl1.GetSeriesByName("SeriesDefaultHead"); _series_curve_head = chartControl1.GetSeriesByName("SeriesCurveHead"); _series_correct_curve_head = chartControl1.GetSeriesByName("SeriesCorrectCurveHead"); _series_default_head.CrosshairLabelPattern = "监测压力:{V}"; _series_curve_head.CrosshairLabelPattern = "模型压力:{V}"; _series_correct_curve_head.CrosshairLabelPattern = "压力偏差:{V}"; } #region ViewModel public class PumpViewModel { [Display(Name = "时间")] public string Time { get; set; } [Display(Name = "泵")] public int Flag { get; set; } [Display(Name = "转速")] public double Rpm { get; set; } [Display(Name = "频率")] public double Hz { get; set; } [Display(Name = "频率")] public double Hz0 { get; set; } [Display(Name = "水位")] public double WaterLevel { get; set; } [Display(Name = "进口压力")] public double InletPressure { get; set; } [Display(Name = "出口压力")] public double OutletPressure { get; set; } [Display(Name = "模型出口压力")] public double ModelOutletPressure { get; set; } [Display(Name = "瞬时流量")] public double Flow { get; set; } [Display(Name = "模型流量")] public double ModelFlow { get; set; } [Display(Name = "流量差值")] public double FlowDiff { get; set; } [Display(Name = "压差")] public double PressureDiff { get; set; } [Display(Name = "曲线压差")] public double CurvePressureDiff { get; set; } [Display(Name = "压差差值")] public double PressureDiffDev { get; set; } } public class ModelDiffViewModel { [Display(Name = "时间")] public DateTime Date { get; set; } [Display(Name = "时间")] public string Time { get; set; } [Display(Name = "名称")] public string Name { get; set; } [Display(Name = "监测压力")] public double ScadaPressure { get; set; } [Display(Name = "监测流量")] public double ScadaFlow { get; set; } [Display(Name = "模型压力")] public double MonitorPressure { get; set; } [Display(Name = "模型流量")] public double MonitorFlow { get; set; } [Display(Name = "压力偏差")] public double PressureDiff { get; set; } [Display(Name = "流量偏差")] public double FlowDiff { get; set; } } public class PumpFactorViewModel { [Display(Name = "泵")] public int Flag { get; set; } [Display(Name = "频率")] public double Hz { get; set; } [Display(Name = "总体标准差")] public double? STDP { get; set; } [Display(Name = "扬程(STDP)")] public double? STDPHead { get; set; } [Display(Name = "备注")] public string Note { get; set; } public void Round() { if (STDP.HasValue) { STDP = Math.Round(STDP.Value, 5); } if (STDPHead.HasValue) { STDPHead = Math.Round(STDPHead.Value, 5); } } } public class CurveQhdPoint { public CurveQhdPoint(double q, double h, double pd) { Q = q; H = h; Pd = pd; } public CurveQhdPoint() { } public double Q { get; set; } public double H { get; set; } public double Pd { get; set; } } #endregion private BLL.StationSignalRecordPacket _bll = new BLL.StationSignalRecordPacket(); private Model.Station _station = null; private Model.MonitorDataSources _monitorDataSources = null; private List> _pump_list = null; private List _model_diff_vm_list = null; private List _pump_vm_list = null; private string _model_file = System.IO.Path.Combine (SettingsD.File.RootDirectory, SettingsD.File.DataFolder, "ch2_v3_20240801(Clear).inp"); /// /// 清空数据 /// public void Clear() { _pump_vm_list = new List(); _model_diff_vm_list = new List(); cmbFlag.SelectedItem = null; cmbFlag.Properties.Items.Clear(); modelTimeViewModelBindingSource.DataSource = new List(); pumpFactorViewModelBindingSource.DataSource = new List(); pumpViewModelBindingSource.DataSource = new List(); ClearChart(); } private void ClearChart() { chartControl1.BeginInit(); _series_default_head.Points.Clear(); _series_curve_head.Points.Clear(); _series_correct_curve_head.Points.Clear(); chartControl1.EndInit(); } /// /// 初始化数据 /// public override void InitialDataSource() { stationListCtrl1.SetBindingData(); monitorDataSourcesTreeList1.SetBindingData(); } //泵站变换 private void StationListCtrl1_FocusedChangedEvent(Model.Station obj) { _station = obj; WaitFrmHelper.ShowWaitForm(); SetBindingData(_monitorDataSources, _station); WaitFrmHelper.HideWaitForm(); } //来源变换 private void MonitorDataSourcesListCtrl1_FocusedChangedEvent(Model.MonitorDataSources obj) { _monitorDataSources = obj; WaitFrmHelper.ShowWaitForm(); SetBindingData(_monitorDataSources, _station); WaitFrmHelper.HideWaitForm(); } /// /// 绑定数据 /// public void SetBindingData(Model.MonitorDataSources monitorDataSources, Model.Station station) { Clear(); if (monitorDataSources == null || station == null) { return; } if (barCekLoad.Checked) { return; } var station_index = station.SortCode; var dt_start = Convert.ToDateTime(barEditDateStart.EditValue); var dt_end = Convert.ToDateTime(barEditDateEnd.EditValue); var packets = _bll.Get(monitorDataSources.ID, station.ID); packets = packets?.Where(x => (x.Year >= dt_start.Year && x.Year <= dt_end.Year) && (x.Month >= dt_start.Month && x.Month <= dt_end.Month)).ToList(); if (packets == null || !packets.Any()) return; _pump_list = new BLL.Equipment().GetPumpListByBelongTypeAndBelongID(IStation.ObjectType.Station, station.ID); if (_pump_list == null || !_pump_list.Any()) { return; } var flag_pump_dict = _pump_list.ToDictionary(x => x.SortCode, x => x.RatedParas); var flag_list = _pump_list.Select(x => x.SortCode).OrderBy(x => x).ToList(); cmbFlag.Properties.Items.AddRange(flag_list); var record_list = packets.SelectMany(x => x.StationSignalRecords).ToList(); var root_folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "分析"); List ana_factor_list = null; var fileName = root_folder + "\\" + "AnalysisFactor.json"; if (File.Exists(fileName)) { var json = File.ReadAllText(fileName); ana_factor_list = JsonHelper.Json2Object>(json); } var pipe_flow_id_list = GlobalHelper.GetPipeFlowIdList(station.SortCode); var pipe_pressure_id_list = GlobalHelper.GetPipePressureIdList(station.SortCode); SetBindingData(_model_file, pipe_flow_id_list, pipe_pressure_id_list, flag_pump_dict, record_list, ana_factor_list, barCekUseAnalysisFactor.Checked); } /// /// 绑定数据 /// public void SetBindingData ( string model_inp, List pipe_flow_id_list, List pipe_pressure_id_list, Dictionary flag_pump_dict, List station_record_list, List ana_factor_list, bool use_ana_factor ) { if (!File.Exists(model_inp)) { throw new Exception($"model_inp:is null"); } var bll_curve = new BLL.PumpCurve(); 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_list = new List(); var vm_diff_list = new List(); foreach (var station_record in station_record_list) { 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 < 0) { continue; } if (total_flow <= 0 && pump_total_flow <= 0) { continue; } if (pump_total_flow > 0 && Math.Abs(diff_flow) > 2000) { continue; } if (pump_record_list.Exists(x => x.Flag != 15 && x.Flag != 16 && x.Rpm < 1)) { continue; } if (pump_record_list.Exists(x => x.OutletPressure > 50)) { 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}"); } } if (ana_factor_list != null && ana_factor_list.Any() && use_ana_factor) { foreach (var pump_record in pump_record_list) { var flag = pump_record.Flag; var pump = flag_pump_dict[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; var hz0 = Math.Round(rpm_ratio * 50, 0); if (hz0 > 50) hz0 = 50; var ana_factor = ana_factor_list.Find(x => x.Hz == hz0 && x.Flag == flag); if (ana_factor == null) { throw new Exception($"ana_factor:is null"); } var qh = flag_qh_curve_dict[flag]; var head_dev = (float)ana_factor.HeadDeviation; var fit_point_list = new List(curve_point_count); if (head_dev == 0) { fit_point_list = qh.GetFitPoints(curve_point_count); } else { var pt_list_ct = qh.DefinePoints.Select(x => new Model.CurvePoint(x.X, x.Y + head_dev)).ToList(); var qh_ct = Model.FitCurveHelper.BuildCurveExpress(pt_list_ct, Model.eCurveFitType.CubicCurve); fit_point_list = qh_ct.GetFitPoints(curve_point_count); } var x_list = fit_point_list.Select(x => (float)x.X).ToList(); var y_list = fit_point_list.Select(x => (float)x.Y).ToList(); //待判断 err = EpanetMethods.ENsetcurve(mapping.CurveIndex, x_list.ToArray(), y_list.ToArray(), curve_point_count); if ((int)err > 6) { throw new Exception($"ENsetcurve:{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}"); } foreach (var pump_record in pump_record_list) { var flag = pump_record.Flag; var pump = flag_pump_dict[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}"); } if (Math.Abs(model_flow) < 1) { break; } err = EpanetMethods.ENgetnodevalue(mapping.PressureIndex, NodeValue.Pressure, out float model_outlet_pressure); if ((int)err > 6) { throw new Exception($"ENgetnodevalue:{err}"); } if (Math.Abs(model_outlet_pressure) > 45) { break; } 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 vm = new PumpViewModel(); vm.Time = time; vm.Rpm = rpm; vm.Flag = flag; vm.Hz = hz; vm.Hz0 = hz0; vm.WaterLevel = wl; vm.InletPressure = Math.Round(inlet_pressure, 2); vm.OutletPressure = Math.Round(outlet_pressure, 2); vm.PressureDiff = Math.Round(pressure_diff, 2); vm.Flow = Math.Round(flow, 1); vm.ModelFlow = Math.Round(model_flow, 1); vm.ModelOutletPressure = Math.Round(model_outlet_pressure, 2); vm.CurvePressureDiff = Math.Round(model_pressure_diff, 2); vm.PressureDiffDev = Math.Round(pressure_diff - model_pressure_diff, 3); vm.FlowDiff = Math.Round(flow_diff, 1); vm_list.Add(vm); } 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_list.Any()) { Clear(); return; } var vm_pump_facotr_list = new List(); if (barCekUseFlow.Checked) { var flag_hz_head_diff_flow_list = vm_list.Select(x => new Tuple(x.Flag, x.Hz0, x.PressureDiffDev, x.ModelFlow)).ToList(); var list_flow = GetAnalysisFactorDtoList(flag_pump_dict, flag_hz_head_diff_flow_list); foreach (var item in list_flow) { var vm_pump_facotr = new PumpFactorViewModel(); vm_pump_facotr.Flag = item.Flag; vm_pump_facotr.Hz = item.Hz; vm_pump_facotr.STDP = item.HeadSTDP; vm_pump_facotr.STDPHead = item.HeadDeviation; vm_pump_facotr.Note = $"{item.Accuracy == -1}"; vm_pump_facotr.Round(); vm_pump_facotr_list.Add(vm_pump_facotr); } } else { var flag_hz_head_diff_list = vm_list.Select(x => new Tuple(x.Flag, x.Hz0, x.PressureDiffDev)).ToList(); var list = AnalysisHelper.GetAnalysisFactorDtoList(flag_pump_dict, flag_hz_head_diff_list); foreach (var item in list) { var vm_pump_facotr = new PumpFactorViewModel(); vm_pump_facotr.Flag = item.Flag; vm_pump_facotr.Hz = item.Hz; vm_pump_facotr.STDP = item.HeadSTDP; vm_pump_facotr.STDPHead = item.HeadDeviation; vm_pump_facotr.Note = $"{item.Accuracy == -1}"; vm_pump_facotr.Round(); vm_pump_facotr_list.Add(vm_pump_facotr); } } SetBindingData(vm_diff_list); _model_diff_vm_list = vm_diff_list; modelTimeViewModelBindingSource.DataSource = _model_diff_vm_list; modelTimeViewModelBindingSource.ResetBindings(false); gridView3.BestFitColumns(); _pump_vm_list = vm_list; pumpViewModelBindingSource.DataSource = vm_list; pumpViewModelBindingSource.ResetBindings(false); gridView1.BestFitColumns(); pumpFactorViewModelBindingSource.DataSource = vm_pump_facotr_list; pumpFactorViewModelBindingSource.ResetBindings(false); gridView2.BestFitColumns(); GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect(2, GCCollectionMode.Forced); GC.WaitForFullGCComplete(); } private void SetBindingData(List vm_list) { timeValueSwiftPlotChartView1.ClearSeries(); if (vm_list == null || !vm_list.Any()) { return; } var flow_dict = new Dictionary>(); var pressure_dict_dict = new Dictionary>(); var group = vm_list.GroupBy(x => x.Name); for (int i = 0; i < group.Count(); i++) { var color = GetRandomColor(i); var item = group.ElementAt(i); var name = item.Key; //var scada_flow_list = item.Select(x => new TimeValue(x.Date, x.ScadaFlow)).ToList(); //var model_flow_list = item.Select(x => new TimeValue(x.Date, x.MonitorFlow)).ToList(); //var flow_diff_list = item.Select(x => new TimeValue(x.Date, x.FlowDiff)).ToList(); //var scada_pressure_list = item.Select(x => new TimeValue(x.Date, x.ScadaPressure)).ToList(); //var model_pressure_list = item.Select(x => new TimeValue(x.Date, x.MonitorPressure)).ToList(); var pressure_diff_list = item.Where(x => !(Math.Abs(x.PressureDiff) > 2)).Select(x => new TimeValue(x.Date, x.PressureDiff)).ToList(); //this.timeValueSwiftPlotChartView1.AddSwiftPlotSeries(name, color, name + "(监测流量)", "流量", scada_flow_list); //this.timeValueSwiftPlotChartView1.AddSwiftPlotSeries(name, color, name + "(模型流量)", "流量", model_flow_list); //this.timeValueSwiftPlotChartView1.AddSwiftPlotSeries(name, color, name + "(偏差流量)", "流量", flow_diff_list); // this.timeValueSwiftPlotChartView1.AddSwiftPlotSeries(name, color, name + "(监测压力)", "压力", scada_pressure_list); //this.timeValueSwiftPlotChartView1.AddSwiftPlotSeries(name, color, name + "(模型压力)", "压力", model_pressure_list); timeValueSwiftPlotChartView1.AddSwiftPlotSeries(name, color, name + "(偏差压力)", "压力", pressure_diff_list); } } #region Color private List ColorArray = new List() { Color.Red, Color.Blue, Color.Green, Color.DodgerBlue, Color.Fuchsia, Color.MidnightBlue, Color.Maroon, Color.Aquamarine, Color.Bisque, Color.BurlyWood }; /// /// 获取随机颜色 /// /// private Color GetRandomColor(int count) { if (count < ColorArray.Count) { return ColorArray[count]; } return ColorHelper.GetRandomColor(); } #endregion 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 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 void cmbFlag_SelectedIndexChanged(object sender, EventArgs e) { ClearChart(); if (_pump_vm_list == null || !_pump_vm_list.Any()) { return; } if (!int.TryParse(cmbFlag.Text, out int flag)) { return; } var vm_list = _pump_vm_list.Where(x => x.Flag == flag).ToList(); if (vm_list == null || !vm_list.Any()) { return; } chartControl1.BeginInit(); foreach (var vm in vm_list) { var time = vm.Time; var diff = vm.ModelOutletPressure - vm.OutletPressure; if (Math.Abs(diff) > 4) { continue; } _series_default_head.Points.Add(new SeriesPoint(time, vm.OutletPressure)); _series_curve_head.Points.Add(new SeriesPoint(time, vm.ModelOutletPressure)); _series_correct_curve_head.Points.Add(new SeriesPoint(time, Math.Round(diff, 2))); } chartControl1.EndInit(); } //加载 private void barCekLoad_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { WaitFrmHelper.ShowWaitForm(); SetBindingData(_monitorDataSources, _station); WaitFrmHelper.HideWaitForm(); } // 刷新数据 private void barBtnRefresh_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { InitialDataSource(); } private void barBtnExportAnalysisFactor_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { if (_monitorDataSources == null || _station == null) { return; } if (_pump_list == null || !_pump_list.Any()) { return; } if (_pump_vm_list == null || !_pump_vm_list.Any()) { return; } WaitFrmHelper.ShowWaitForm("正在导出"); var bol = false; if (barCekUseFlow.Checked) { var flag_hz_head_diff_flow_list = _pump_vm_list.Select(x => new Tuple(x.Flag, x.Hz0, x.PressureDiffDev, x.ModelFlow)).ToList(); bol = SaveAnalysisFactorDtoList(_station.SortCode, _pump_list, flag_hz_head_diff_flow_list); } else { var flag_hz_head_diff_list = _pump_vm_list.Select(x => new Tuple(x.Flag, x.Hz0, x.PressureDiffDev)).ToList(); bol = AnalysisHelper.SaveAnalysisFactorDtoList(_station.SortCode, _pump_list, flag_hz_head_diff_list); } if (!bol) { XtraMessageBox.Show("导出失败!"); return; } WaitFrmHelper.HideWaitForm(); AlertTool.ShowInfo(System.Windows.Forms.Application.OpenForms[0], "提示", "导出完成!"); } private bool SaveAnalysisFactorDtoList(int station_index, List> eq_list, List> flag_hz_head_diff_list) { if (eq_list == null || !eq_list.Any()) { return default; } if (flag_hz_head_diff_list == null || !flag_hz_head_diff_list.Any()) { return default; } var flag_pump_dict = eq_list.ToDictionary(x => x.SortCode, x => x.RatedParas); var all_list = GetAnalysisFactorDtoList(flag_pump_dict, flag_hz_head_diff_list); if (all_list == null || !all_list.Any()) { return default; } all_list.ForEach(x => x.Station = station_index); 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 + "\\" + "AnalysisFactor.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 != station_index).ToList(); File.Delete(fileName); } if (exist_list != null) { all_list.AddRange(exist_list); } all_list = all_list.OrderBy(x => x.Flag).ThenBy(x => x.Hz).ToList(); var json = JsonHelper.Object2Json(all_list); File.WriteAllText(fileName, json); return true; } public static List GetAnalysisFactorDtoList(Dictionary flag_pump_dict, List> flag_hz_head_diff_list) { if (flag_pump_dict == null || !flag_pump_dict.Any()) { return default; } if (flag_hz_head_diff_list == null || !flag_hz_head_diff_list.Any()) { return default; } var exist_data_analysis_factor_list = new List(); var opt_std_dev_pop = 0.3; //分析5hz范围内的系数 var group_by_flag = flag_hz_head_diff_list.GroupBy(x => x.Item1); var flag_range5_hz_factor_dict = new Dictionary>>(); foreach (var flag_item in group_by_flag) { var flag = flag_item.Key; var pump = flag_pump_dict[flag]; if (!pump.IsBp) continue; for (double i = 20; i <= 50; i += 5) { var min_hz = i - 5; double max_hz = i; var list = flag_item.Where(x => x.Item2 >= min_hz && x.Item2 <= max_hz).ToList(); if (list == null || list.Count() < 10) continue; var head_diff_list = list.Select(x => x.Item3).ToList(); var head_filter_tuple = AnalysisHelper.GetFilterBySTDP(head_diff_list.ToArray(), opt_std_dev_pop); var head_filter_array = head_filter_tuple.Item1; var head_std_dev_pop = head_filter_tuple.Item2; var head_std_dev_pop_head_avg = head_filter_array.Average(); var flow_list = list.Select(x => x.Item4).ToList(); var flow_filter_tuple = AnalysisHelper.GetFilterBySTDP(flow_list.ToArray(), 50, 1, 3); var flow_filter_array = flow_filter_tuple.Item1; var flow_std_dev_pop = flow_filter_tuple.Item2; var flow_std_dev_pop_head_avg = flow_filter_array.Average(); var head_diff_avg = head_std_dev_pop_head_avg - Model.CurveCalcuHelper.CalculateOtherPress(flow_std_dev_pop_head_avg, pump.Ic, pump.Oc, null, null); if (!flag_range5_hz_factor_dict.ContainsKey(flag)) { flag_range5_hz_factor_dict.Add(flag, new Dictionary>()); } flag_range5_hz_factor_dict[flag].Add(max_hz, new Tuple(head_std_dev_pop, head_diff_avg, head_filter_array.Count())); } } //分析1hz范围内的系数 var group_by_flag_hz = flag_hz_head_diff_list.GroupBy(x => new { x.Item1, x.Item2 }); foreach (var item in group_by_flag_hz) { var hz = item.Key.Item2; if (hz < 20) continue; if (item.Count() < 5) continue; var flag = item.Key.Item1; var pump = flag_pump_dict[flag]; var head_diff_list = item.Select(x => x.Item3).ToList(); var filter_std_dev_pop_tuple = AnalysisHelper.GetFilterBySTDP(head_diff_list.ToArray(), opt_std_dev_pop); 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(); if (Math.Abs(std_dev_pop_head_avg) > 5) continue; if (Math.Abs(std_dev_pop) > 1) continue; if (Math.Abs(std_dev_pop) > 0.5 && item.Count() < 10) continue; var flow_list = item.Select(x => x.Item4).ToList(); var flow_filter_tuple = AnalysisHelper.GetFilterBySTDP(flow_list.ToArray(), opt_std_dev_pop); var flow_filter_array = flow_filter_tuple.Item1; var flow_std_dev_pop = flow_filter_tuple.Item2; var flow_std_dev_pop_head_avg = flow_filter_array.Average(); var other_press = Model.CurveCalcuHelper.CalculateOtherPress(flow_std_dev_pop_head_avg, pump.Ic, pump.Oc, null, null); if (!pump.IsBp) { other_press = 0; } var head_diff_avg = std_dev_pop_head_avg - other_press; var analysis_facotr = new AnalysisHelper.AnalysisFactorDto(); analysis_facotr.Flag = flag; analysis_facotr.Hz = hz; analysis_facotr.HeadSTDP = std_dev_pop; analysis_facotr.HeadDeviation = head_diff_avg; analysis_facotr.Accuracy = 0; exist_data_analysis_factor_list.Add(analysis_facotr); } exist_data_analysis_factor_list = exist_data_analysis_factor_list.OrderBy(x => x.Flag).ThenBy(x => x.Hz).ToList(); //相似换算修正系数(不存在监测数据的频率) var similar_analysis_factor_list = new List(); foreach (var pump_item in flag_pump_dict) { var flag = pump_item.Key; var pump = pump_item.Value; if (!pump.IsBp) continue; if (!flag_range5_hz_factor_dict.ContainsKey(flag)) continue; var range5_hz_item = flag_range5_hz_factor_dict[flag]; for (int hz = 1; hz <= 50; hz++) { if (exist_data_analysis_factor_list.Exists(x => x.Flag == flag && x.Hz == hz)) continue; var hz_range_num = hz / 5; var hz_key = (hz_range_num + 1) * 5; if (hz_key > 50) hz_key = 50; if (range5_hz_item.ContainsKey(hz_key)) { var item = range5_hz_item[hz_key]; var analysis_facotr = new AnalysisHelper.AnalysisFactorDto(); analysis_facotr.Flag = flag; analysis_facotr.Hz = hz; analysis_facotr.HeadSTDP = item.Item1; analysis_facotr.HeadDeviation = item.Item2; analysis_facotr.Accuracy = 0; similar_analysis_factor_list.Add(analysis_facotr); } else { var hz_list = range5_hz_item.Select(x => x.Key).ToList(); var similar_hz = hz_list.Where(x => x >= hz_key)?.OrderBy(x => x).FirstOrDefault(); if (similar_hz == null || similar_hz.Value == 0) { similar_hz = hz_list.OrderByDescending(x => x).FirstOrDefault(); } if (similar_hz == null) { throw new Exception("similar_hz error"); } var tuple = range5_hz_item[similar_hz.Value]; var similar_ratio = hz / similar_hz.Value; var head_dev = tuple.Item2 * similar_ratio; var head_stdp = tuple.Item1 * similar_ratio; var analysis_facotr = new AnalysisHelper.AnalysisFactorDto(); analysis_facotr.Flag = flag; analysis_facotr.Hz = hz; analysis_facotr.HeadSTDP = head_stdp; analysis_facotr.HeadDeviation = head_dev; analysis_facotr.Accuracy = -1; similar_analysis_factor_list.Add(analysis_facotr); } } } var all_analysis_factor_list = new List(); all_analysis_factor_list.AddRange(exist_data_analysis_factor_list); all_analysis_factor_list.AddRange(similar_analysis_factor_list); all_analysis_factor_list = all_analysis_factor_list.OrderBy(x => x.Flag).ThenBy(x => x.Hz).ToList(); return all_analysis_factor_list; } } }