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.IO;
using System.Linq;
using System.Text;
namespace IStation.WinFrmUI.Monitor
{
public partial class ModelCorrectionCombinePage1 : DocumentPage
{
public ModelCorrectionCombinePage1()
{
InitializeComponent();
this.PageTitle.Caption = "模型修正组合";
this.gridView1.SetNormalView();
this.gridView2.SetNormalView();
this.repositoryItemDateEdit1.SetOnlyShowYearMonth();
this.repositoryItemDateEdit2.SetOnlyShowYearMonth();
this.barEditDateStart.EditValue = new DateTime(2024, 9, 1);
this.barEditDateEnd.EditValue = new DateTime(2024, 9, 1);
this.stationListCtrl1.FocusedChangedEvent += StationListCtrl1_FocusedChangedEvent;
this.monitorDataSourcesTreeList1.FocusedChangedEvent += MonitorDataSourcesListCtrl1_FocusedChangedEvent;
}
#region ViewModel
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()
{
this.STDP = Math.Round(this.STDP, 5);
this.STDPHead = Math.Round(this.STDPHead, 5);
}
}
///
/// 模型组合偏差
///
public class ModelCombineDiffViewModel
{
[Display(Name = "运行组合")]
public string RunFlags { get; set; }
[Display(Name = "最小流量")]
public double MinFlow { get; set; }
[Display(Name = "最大流量")]
public double MaxFlow { get; set; }
[Display(Name = "模型偏差")]
public string ModelDeviation { get; set; }
[Display(Name = "数量")]
public int Count { get; set; }
}
///
/// 模型组合偏差
///
public class ModelViewModel
{
public string Time { get; set; }
public List RunFlags { get; set; }
public string RunFlagsStr { get; set; }
public int RunCount { get; set; }
public double TotalFlow { get; set; }
public double PumpTotalFlow { get; set; }
public Dictionary ModelDeviation { 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 _model_vm_list = null;
private string _model_file = System.IO.Path.Combine
(Settings.File.RootDirectory, Settings.File.DataFolder, "ch2_v3_20240918(Clear).inp");
///
/// 清空数据
///
public void Clear()
{
_model_diff_vm_list = new List();
this.modelDiffViewModelBindingSource.DataSource = new List();
}
///
/// 初始化数据
///
public override void InitialDataSource()
{
this.stationListCtrl1.SetBindingData();
this.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 (this.barCekLoad.Checked)
{
return;
}
var station_index = station.SortCode;
var dt_start = Convert.ToDateTime(this.barEditDateStart.EditValue);
var dt_end = Convert.ToDateTime(this.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();
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 + "\\" + station.Name + ".json";
if (File.Exists(fileName))
{
var json = File.ReadAllText(fileName);
ana_factor_list = JsonHelper.Json2Object>(json);
}
SetBindingData(_model_file, flag_pump_dict, record_list, ana_factor_list, this.barCekUseAnalysisFactor.Checked);
}
///
/// 绑定数据
///
public void SetBindingData
(
string model_inp,
Dictionary flag_pump_dict,
List record_list,
List ana_factor_list,
bool use_ana_factor
)
{
if (!File.Exists(model_inp))
{
throw new Exception($"model_inp:is null");
}
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 model_id_tuple = AnalysisFactorHelper.GetModelIdList();
var flow_id_list = model_id_tuple.Item1;
var pressure_id_list = model_id_tuple.Item2;
var pump_id_list = model_id_tuple.Item3;
var pump_flag_dict = AnalysisFactorHelper.GetPumpIdFlagDict();
var flag_pump_id_dict = AnalysisFactorHelper.GetFlagPumpIdDict();
var pattern_id_list = AnalysisFactorHelper.GetPatternIdList();
var curve_id_dict = AnalysisFactorHelper.GetCurveIdDict();
var flow_pump_dict = AnalysisFactorHelper.GetFlowPumpDict();
var pressure_pump_dict = AnalysisFactorHelper.GetPressurePumpDict();
var model_flow_mapping_dict = AnalysisFactorHelper.GetModelFlowIdMappingDict();
var model_pressure_mapping_dict = AnalysisFactorHelper.GetModelPressureIdMappingDict();
var flow_id_dict = new Dictionary();
var pressure_id_dict = new Dictionary();
var pump_id_dict = new Dictionary();
var pattern_id_dict = new Dictionary();
var flag_curve_dict = new Dictionary>();
var curve_point_count = 100;
foreach (var id in flow_id_list)
{
if (EpanetMethods.ENgetlinkindex(id, out int index) != ErrorCode.Ok)
continue;
flow_id_dict.Add(id, index);
}
foreach (var id in pressure_id_list)
{
if (EpanetMethods.ENgetnodeindex(id, out int index) != ErrorCode.Ok)
continue;
pressure_id_dict.Add(id, index);
}
foreach (var id in pump_id_list)
{
if (EpanetMethods.ENgetlinkindex(id, out int index) != ErrorCode.Ok)
continue;
pump_id_dict.Add(id, index);
}
foreach (var id in pattern_id_list)
{
if (EpanetMethods.ENgetpatternindex(id, out int index) != ErrorCode.Ok)
continue;
pattern_id_dict.Add(id, index);
}
var pump_curve_dict = GetPumpCurveDict();
foreach (var item in curve_id_dict)
{
var curve_id = item.Key;
var flag = item.Value;
var pump_id = flag_pump_id_dict[flag];
var qh = pump_curve_dict[flag];
qh = Model.FitCurveHelper.BuildCurveExpress(qh.DefinePoints, eCurveFitType.CubicCurve);
if (EpanetMethods.ENgetcurveindex(curve_id, out int index) != ErrorCode.Ok)
continue;
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 bol = CheckFitPointList(fit_point_list, curve_point_count);
if (!bol)
{
throw new Exception($"CheckFitPointList: false");
}
err = EpanetMethods.ENsetcurve(index, flow_list, head_list, curve_point_count);
if (err != 0)
{
throw new Exception($"ENsetcurve:{err}");
}
flag_curve_dict.Add(pump_id, new Tuple(curve_id, index));
}
var vm_list = new List();
foreach (var record in record_list)
{
var time = record.Time.ToString("G");
var model_record_dict = record.ModelRecordDict;
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 item in pump_id_dict)
{
var pump_id = item.Key;
if (!model_record_dict.ContainsKey(pump_id))
continue;
var flag = pump_flag_dict[pump_id];
var pump_ratio = model_record_dict[pump_id];
if (pump_ratio <= 0.3)
continue;
var hz = Math.Round(pump_ratio * 50);
var ana_factor = ana_factor_list.Find(x => x.Hz == hz && x.Flag == flag);
if (ana_factor == null)
{
throw new Exception($"ana_factor:is null");
}
var qh = pump_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();
//待判断
var curve_index = flag_curve_dict[pump_id].Item2;
err = EpanetMethods.ENsetcurve(curve_index, 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}");
}
var vm = new ModelViewModel();
vm.Time = time;
vm.ModelDeviation = new Dictionary();
vm.RunCount = record.PumpRunCount;
vm.RunFlags = record.PumpSignalRecords.Select(x => x.Flag).OrderBy(x => x).ToList();
vm.RunFlagsStr = IntListHelper.ToString(vm.RunFlags);
foreach (var item in pump_id_dict)
{
var pump_id = item.Key;
if (!model_record_dict.ContainsKey(pump_id))
continue;
var flag = pump_flag_dict[pump_id];
var index = item.Value;
err = EpanetMethods.ENgetlinkvalue(index, LinkValue.Flow, out float model_value);
if ((int)err > 6)
{
throw new Exception($"ENgetnodevalue:{err}");
}
vm.PumpTotalFlow += model_value;
}
foreach (var item in flow_id_dict)
{
var flow_id = item.Key;
var scada_id = model_flow_mapping_dict[flow_id];
if (!model_record_dict.ContainsKey(scada_id))
continue;
var scada_value = model_record_dict[scada_id];
if (flow_pump_dict.ContainsKey(flow_id))
continue;
var index = item.Value;
err = EpanetMethods.ENgetlinkvalue(index, LinkValue.Flow, out float model_value);
if ((int)err > 6)
{
throw new Exception($"ENgetnodevalue:{err}");
}
model_value = Math.Abs(model_value);
vm.TotalFlow += model_value;
}
foreach (var item in pressure_id_dict)
{
var pressure_id = item.Key;
var scada_id = model_pressure_mapping_dict[pressure_id];
if (!model_record_dict.ContainsKey(scada_id))
continue;
var scada_value = model_record_dict[scada_id];
if (!pressure_pump_dict.ContainsKey(pressure_id))
continue;
var pump = pressure_pump_dict[pressure_id];
var pump_ratio = model_record_dict[pump.Item1];
if (pump_ratio <= 0.3)
continue;
var flag = pump.Item2;
var index = item.Value;
err = EpanetMethods.ENgetnodevalue(index, NodeValue.Head, out float model_value);
if ((int)err > 6)
{
throw new Exception($"ENgetnodevalue:{err}");
}
var diff_vlaue = scada_value - model_value;
if (Math.Abs(diff_vlaue)>10)
{
}
vm.ModelDeviation.Add(flag, diff_vlaue);
}
vm_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())
{
_model_diff_vm_list = new List();
var minQ = 20000;
var maxQ = 140000;
var spaceQ = 1000;
for (int currentMinQ = minQ; currentMinQ <= maxQ; currentMinQ += spaceQ)
{
var currentMaxQ = currentMinQ + spaceQ;
var list = vm_list
.Where(x => x.TotalFlow >= currentMinQ && x.TotalFlow <= currentMaxQ)
.ToList();
if (list == null || !list.Any())
continue;
var group = list.GroupBy(x => x.RunFlagsStr);
foreach (var item in group)
{
if (item.Count() < 5)
continue;
var run_flags = item.Key;
var model_diff_vm = new ModelCombineDiffViewModel();
model_diff_vm.RunFlags = run_flags;
model_diff_vm.Count = item.Count();
model_diff_vm.MinFlow = currentMinQ;
model_diff_vm.MaxFlow = currentMaxQ;
var model_deviation_dict = new Dictionary();
List> tuple_list = item.SelectMany(x => x.ModelDeviation.Select(d => new Tuple(d.Key, d.Value))).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.Item2).ToArray();
var filter_std_dev_pop_tuple = AnalysisFactorHelper.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);
model_deviation_dict.Add(flag, head_diff_avg);
}
model_diff_vm.ModelDeviation = JsonHelper.Object2Json(model_deviation_dict);
var error = false;
foreach (var item_v in model_deviation_dict)
{
if (Math.Abs(item_v.Value) > 5)
{
error = true;
break;
}
}
if (error) { continue; }
_model_diff_vm_list.Add(model_diff_vm);
}
}
}
this.modelDiffViewModelBindingSource.DataSource = _model_diff_vm_list;
this.gridView1.BestFitColumns();
//this.pumpFactorViewModelBindingSource.DataSource = vm_pump_facotr_list;
//this.pumpFactorViewModelBindingSource.ResetBindings(false);
//this.gridView2.BestFitColumns();
}
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;
}
bool CheckYValues(float[] xValues, int nPoints)
{
for (int j = 1; j < nPoints; j++)
{
if (xValues[j - 1] <= xValues[j])
{
return false;
}
}
return true;
}
private Dictionary GetPumpCurveDict()
{
var dict = new Dictionary();
var bll_curve = new BLL.PumpCurve();
var station_list = new BLL.Station().GetAll();
foreach (var station in station_list)
{
var pumps = new BLL.Equipment().GetPumpListByBelongTypeAndBelongID(IStation.ObjectType.Station, station.ID);
if (pumps == null || !pumps.Any())
{
return default;
}
foreach (var pump in pumps)
{
Model.CurveExpress qh = null;
var curve_info = bll_curve.GetDefaultWorkingByPumpID(pump.ID)?.CurveInfo;
if (curve_info != null)
{
qh = curve_info.CurveQH;
}
dict.Add(pump.SortCode, qh);
}
}
return dict;
}
//加载
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 (_model_diff_vm_list == null || !_model_diff_vm_list.Any())
{
return;
}
WaitFrmHelper.ShowWaitForm("正在导出");
//var flag_hz_head_diff_list = _model_diff_vm_list.Where(x => x.Type == "压力" && x.Flag.HasValue).Select(x =>
//{
// var flag = x.Flag.Value;
// var hz0 = x.HzRound.Value;
// var head_dev = x.DiffVlaue;
// if (head_dev > 0)
// {
// head_dev = -head_dev;
// }
// else
// {
// head_dev = Math.Abs(head_dev);
// }
// return new Tuple(flag, hz0, head_dev);
//}).ToList();
//var bol = AnalysisFactorHelper.SaveAnalysisFactorDtoListAdd(_station.Name, _pump_list, flag_hz_head_diff_list);
//if (!bol)
//{
// XtraMessageBox.Show("导出失败!");
// return;
//}
WaitFrmHelper.HideWaitForm();
AlertTool.ShowInfo(System.Windows.Forms.Application.OpenForms[0], "提示", "导出完成!");
}
}
}