using IStation.Model; using System.ComponentModel.DataAnnotations; namespace IStation.Test { public class Station2Helper { /// /// 绑定数据 /// public static void Start() { var projectId = 661070185922629; IStation.SettingsD.Project.ID = projectId; var monitorDataSourcesId = 606203941007429; var stationIndex = 2; var stationId = 462958422204485; var dtStart = new DateTime(2024, 1, 1); var dtEnd = new DateTime(2025, 1, 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 = new Dictionary(); foreach (var pump in pumpList) { Model.CurveExpress qh = null; var curveInfo = bllCurve.GetDefaultWorkingByPumpID(pump.ID)?.CurveInfo; if (curveInfo?.CurveQH != null) { qh = curveInfo.CurveQH; } flagQhCurveDict.Add(pump.SortCode, qh); } var pipe_flow_id_list = GlobalHelperW.GetPipeFlowIdList(stationIndex); var pipe_pressure_id_list = GlobalHelperW.GetPipePressureIdList(stationIndex); var packet_list = bll.Get(monitorDataSourcesId, stationId); //packet_list = packet_list.Where(x => (x.Year >= dtStart.Year && x.Year <= dtEnd.Year) && (x.Month >= dtStart.Month && x.Month <= dtEnd.Month)).ToList(); //if (packet_list == null || !packet_list.Any()) // return; var allStationRecordList = packet_list.SelectMany(x => x.StationSignalRecords).ToList(); Console.WriteLine($"泵站总数:{allStationRecordList.Count}"); var stationRecordList = DynamicThresholdProcessorHelper.Filter(allStationRecordList); Console.WriteLine($"泵站总数:{stationRecordList.Count} 过滤:{allStationRecordList.Count - stationRecordList.Count}"); var stationRecordList2 = stationRecordList.Where(x => { var model_record_dict = x.ModelRecordDict; foreach (var id in pipe_flow_id_list) { if (model_record_dict[id] < 1) { return false; } } foreach (var id in pipe_pressure_id_list) { var value = model_record_dict[id]; if (value < 1 || value > 40) { return false; } } return true; }).ToList(); Console.WriteLine($"泵站总数:{stationRecordList2.Count} 二次过滤:{allStationRecordList.Count - stationRecordList2.Count}"); var allPumpRecordList = stationRecordList2.SelectMany(x => x.PumpSignalRecords).ToList(); Console.WriteLine($"泵总数:{allPumpRecordList.Count}"); var fullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "pumpcsv"); if (Directory.Exists(fullPath)) { Directory.Delete(fullPath, true); } Directory.CreateDirectory(fullPath); var allPumpRecordList2 = allPumpRecordList.Where(x => { if (x.Rpm == IStation.Error.Default || x.Head == IStation.Error.Default) { return false; } if (x.FlowRate < 1 || x.FlowRate > 20000) { return false; } return true; }).ToList(); Console.WriteLine($"泵总数:{allPumpRecordList2.Count} 过滤:{allPumpRecordList.Count - allPumpRecordList2.Count}"); var pumpFlagRecordGroup = allPumpRecordList.OrderBy(x => x.Flag).GroupBy(x => x.Flag); var pumpFlagHzRecordGroup = new Dictionary<(int Flag, int Hz), List>(); foreach (var pumpFlag in pumpFlagRecordGroup) { var flag = pumpFlag.Key; var pump = flagPumpDict[flag]; var pumpQh = flagQhCurveDict[flag]; if (!pump.IsBp) { var allFlagHzRecordList = pumpFlag.ToList(); if (allFlagHzRecordList.Count < 30) { Console.WriteLine($"{flag}泵-{50}hz 总数:{allFlagHzRecordList.Count},<5 跳过"); } var flagHzRecordList = DynamicThresholdProcessorHelper.Filter(allFlagHzRecordList); Console.WriteLine($"{flag}泵-{50}hz 总数:{allFlagHzRecordList.Count},过滤:{allFlagHzRecordList.Count - flagHzRecordList.Count}"); pumpFlagHzRecordGroup.Add((flag, 50), flagHzRecordList); if (flagHzRecordList.Any()) { var curvePtList = pumpQh.GetFitPoints(200).Select(x => new CurvePtViewModel(x)).ToList(); CsvHelper.ExportToCsv(curvePtList, Path.Combine(fullPath, $"{flag}_{50}_old_curve.csv")); CsvHelper.ExportToCsv(flagHzRecordList, Path.Combine(fullPath, $"{flag}_{50}.csv")); } } else { var hzGroup = pumpFlag.OrderBy(x => x.Rpm).GroupBy(x => { return Math.Round(x.Rpm / pump.Nr * 50, 0); }); hzGroup = hzGroup.Where(x => x.Key > 10).ToList(); foreach (var pumpFlagHz in hzGroup) { var hz = pumpFlagHz.Key; var allFlagHzRecordList = pumpFlagHz.ToList(); if (allFlagHzRecordList.Count < 30) { Console.WriteLine($"{flag}泵-{hz}hz 总数:{allFlagHzRecordList.Count},<5 跳过"); } var flagHzRecordList = DynamicThresholdProcessorHelper.Filter(allFlagHzRecordList); Console.WriteLine($"{flag}泵-{hz}hz 总数:{allFlagHzRecordList.Count},过滤:{allFlagHzRecordList.Count - flagHzRecordList.Count}"); pumpFlagHzRecordGroup.Add((flag, (int)hz), flagHzRecordList); if (flagHzRecordList.Any()) { var curvePtList = SimilarCalculateHelper.CalculateQH(pumpQh, 50, hz).GetFitPoints(100); CsvHelper.ExportToCsv(curvePtList.Select(x => new CurvePtViewModel(x)).ToList(), Path.Combine(fullPath, $"{flag}_{hz}_old_curve.csv")); CsvHelper.ExportToCsv(flagHzRecordList, Path.Combine(fullPath, $"{flag}_{hz}.csv")); //var flag_pt = flagHzRecordList.Select(x => new CurvePoint(x.FlowRate, x.Head)).OrderBy(x=>x.X).ToList(); //var optimizer = new PumpCurveOptimizer(curvePtList, flag_pt); //optimizer.PreprocessData(); //optimizer.MergeCurves(); //optimizer.ConstrainedOptimization(); //optimizer.Export(Path.Combine(fullPath, $"{flag}_{hz}_opt.csv")); } } } } /* var vm_list = new List(); foreach (var group in pumpFlagHzRecordGroup) { var flag = group.Key.Flag; var hz = group.Key.Hz; var pump = flagPumpDict[flag]; var curve_qh = flagQhCurveDict[flag]; foreach (var pump_record in group.Value) { var vm_pump = new PumpViewModel(); vm_pump.Flag = flag; vm_pump.Rpm = pump_record.Rpm; vm_pump.Hz = hz; vm_pump.Hz0 = hz; vm_pump.WaterLevel = pump_record.WaterLevel; vm_pump.InletPressure = Math.Round(Model.CurveCalcuHelper.Mpa2M(pump_record.InletPressure), 2); vm_pump.OutletPressure = Math.Round(Model.CurveCalcuHelper.Mpa2M(pump_record.OutletPressure), 2); vm_pump.PressureDiff = Math.Round(vm_pump.OutletPressure - vm_pump.InletPressure, 5); vm_pump.Flow = pump_record.FlowRate; vm_pump.Head = pump_record.Head; vm_pump.Power = pump_record.InstantaneousPower; var curve_head = GetCurveHead(curve_qh, pump.Nr, pump_record.Rpm, pump_record.FlowRate); curve_head = Math.Round(curve_head, 2); var pump_head50hz = Model.CurveCalcuHelper.Calculate50HByHz(vm_pump.Head, hz); var curve_head50hz = Model.CurveCalcuHelper.Calculate50HByHz(curve_head, hz); var head_diff = pump_head50hz - curve_head50hz; head_diff = Math.Round(head_diff, 5); vm_pump.CurveHead = curve_head; vm_pump.HeadDiff = head_diff; vm_list.Add(vm_pump); } } var vm_pump_facotr_list = new List(); foreach (var station_record in stationRecordList2) { var pump_signal_records = station_record.PumpSignalRecords; pump_signal_records = pump_signal_records.OrderBy(x => x.Flag).ToList(); foreach (var pump_record in pump_signal_records) { if (pump_record.Rpm == IStation.Error.Default || pump_record.Head == IStation.Error.Default) { continue; } var flag = pump_record.Flag; var pump = flagPumpDict[flag]; var curve_qh = flagQhCurveDict[flag]; if (!pump.IsBp) { pump_record.Rpm = pump.Nr; } var hz = pump_record.Rpm / pump.Nr * 50; hz = Math.Round(hz, 1); var vm_pump = new PumpViewModel(); vm_pump.Time = station_record.Time.ToString("G"); vm_pump.Flag = flag; vm_pump.Rpm = pump_record.Rpm; vm_pump.Hz = hz; vm_pump.Hz0 = Math.Round(hz, 0); vm_pump.WaterLevel = pump_record.WaterLevel; vm_pump.InletPressure = Math.Round(Model.CurveCalcuHelper.Mpa2M(pump_record.InletPressure), 2); vm_pump.OutletPressure = Math.Round(Model.CurveCalcuHelper.Mpa2M(pump_record.OutletPressure), 2); vm_pump.PressureDiff = Math.Round(vm_pump.OutletPressure - vm_pump.InletPressure, 5); vm_pump.Flow = pump_record.FlowRate; vm_pump.Head = pump_record.Head; vm_pump.Power = pump_record.InstantaneousPower; var curve_head = GetCurveHead(curve_qh, pump.Nr, pump_record.Rpm, pump_record.FlowRate); curve_head = Math.Round(curve_head, 2); var pump_head50hz = Model.CurveCalcuHelper.Calculate50HByHz(vm_pump.Head, hz); var curve_head50hz = Model.CurveCalcuHelper.Calculate50HByHz(curve_head, hz); var head_diff = pump_head50hz - curve_head50hz; head_diff = Math.Round(head_diff, 5); vm_pump.CurveHead = curve_head; vm_pump.HeadDiff = head_diff; vm_list.Add(vm_pump); } } if (!vm_list.Any()) { return; } var flag_hz_head_diff_list = vm_list.Select(x => new Tuple(x.Flag, x.Hz0, x.HeadDiff)).ToList(); var list = AnalysisHelper.GetAnalysisFactorDtoList(flagPumpDict, 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); } var group_by_flag = vm_list.GroupBy(x => new { x.Flag, x.Hz0 }); foreach (var flag_item in group_by_flag) { var flag = flag_item.Key.Flag; var factor = vm_pump_facotr_list?.Find(x => x.Flag == flag && x.Hz == flag_item.Key.Hz0); if (factor == null) { continue; } var pump = flagPumpDict[flag]; var qh = flagQhCurveDict[flag]; var qh_correct_points = qh.DefinePoints.Select(x => new Model.CurvePoint(x.X, x.Y + factor.STDPHead ?? 0)).ToList(); var qh_correct = Model.FitCurveHelper.BuildCurveExpress(qh_correct_points, Model.eCurveFitType.CubicCurve); foreach (var vm in flag_item) { vm.CorrectCurveHead = GetCurveHead(qh_correct, pump.Nr, vm.Rpm, vm.Flow); vm.CorrectHeadDiff = vm.Head - vm.CorrectCurveHead; vm.CorrectCurveHead = Math.Round(vm.CorrectCurveHead, 2); vm.CorrectHeadDiff = Math.Round(vm.CorrectHeadDiff, 5); vm.CorrectPressureDiff = vm.CorrectCurveHead - Model.CurveCalcuHelper.CalculateOtherPress(vm.Flow, pump.Ic, pump.Oc, null, null); vm.CorrectPressureDiffDiff = vm.CorrectPressureDiff - vm.PressureDiff; vm.CorrectPressureDiff = Math.Round(vm.CorrectPressureDiff, 2); vm.CorrectPressureDiffDiff = Math.Round(vm.CorrectPressureDiffDiff, 5); } }*/ //CsvHelper.ExportToCsv(vm_list, "PumpData.csv"); //CsvHelper.ExportToCsv(vm_pump_facotr_list, "PumpFacotrData.csv"); } private static Tuple FilterBySTDP(double[] array, double min_dev, int count) { if (array == null || !array.Any()) { return default; } var array_avg = array.Average(); var array_count = array.Count(); FilterOutliersHelper.STDEV(array, out double std_dev, out double std_dev_pop); if (Math.Abs(std_dev_pop) < min_dev) { return new Tuple(array, std_dev_pop); } if (count > 3) { return new Tuple(array, std_dev_pop); } var filter_array = array.Where(x => !(Math.Abs(x - array_avg) > Math.Abs(std_dev_pop * 2))).ToArray(); if (filter_array == null || !filter_array.Any()) { return default; } count++; return FilterBySTDP(filter_array, min_dev, count); } private static double GetCurveHead(Model.CurveExpress curve_qh, double nr, double rpm, double flow) { if (curve_qh == null) return default; var similar_qh = Model.CurveCalcuHelper.CalculateSimilarQH(curve_qh, nr, rpm); if (similar_qh == null) return default; var head = similar_qh.GetFitPointY(flow); return head; } } #region ViewModel public class CurvePtViewModel { public CurvePtViewModel() { } public CurvePtViewModel(CurvePoint rhs) { X = Math.Round(rhs.X, 6); Y = Math.Round(rhs.Y, 6); } [Display(Name = "X")] public double X { get; set; } [Display(Name = "Y")] public double Y { get; set; } } public class PumpViewModel { [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 PressureDiff { get; set; } [Display(Name = "瞬时流量")] public double Flow { get; set; } [Display(Name = "扬程")] public double Head { get; set; } [Display(Name = "瞬时功率")] public double Power { get; set; } [Display(Name = "曲线扬程")] public double CurveHead { get; set; } [Display(Name = "扬程差值")] public double HeadDiff { get; set; } [Display(Name = "修正曲线扬程")] public double CorrectCurveHead { get; set; } [Display(Name = "修正扬程差值")] public double CorrectHeadDiff { get; set; } [Display(Name = "修正压差")] public double CorrectPressureDiff { get; set; } [Display(Name = "修正压差差值")] public double CorrectPressureDiffDiff { 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); } } } #endregion }