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
}