using IStation.Model;
|
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 ScadaDiffPage : DocumentPage
|
{
|
public ScadaDiffPage()
|
{
|
InitializeComponent();
|
PageTitle.Caption = "工况均差验证";
|
|
equipmentExTreeListCtrl1.FocusedChangedEvent += EquipmentExTreeListCtrl1_FocusedChangedEvent; ;
|
monitorDataSourcesTreeList.FocusedChangedEvent += MonitorDataSourcesTreeList1_FocusedChangedEvent;
|
|
gridView1.SetNormalView();
|
InitialChart();
|
}
|
|
|
public class VerifyViewModel : PumpSignalRecord
|
{
|
|
public VerifyViewModel(Model.PumpSignalRecord rhs) : base(rhs) { }
|
public VerifyViewModel(Model.PumpSignalRecord rhs, DateTime dateTime) : base(rhs)
|
{
|
Time = dateTime;
|
}
|
|
[Display(Name = "时间", Order = 0)]
|
public DateTime Time { get; set; }
|
|
[Display(Name = "曲线功率", Order = 11)]
|
public double InterPower { get; set; }
|
|
[Display(Name = "功率差值", Order = 12)]
|
public double PowerDiff { get; set; }
|
|
[Display(Name = "曲线扬程", Order = 9)]
|
public double InterHead { get; set; }
|
|
[Display(Name = "扬程差值", Order = 10)]
|
public double HeadDiff { get; set; }
|
|
[Display(Name = "扬程差值(修正后)", Order = 10)]
|
public double UpdateHeadDiff { get; set; }
|
|
[Display(Name = "效率", Order = 8)]
|
public double Eff { get; set; }
|
}
|
|
|
private List<VerifyViewModel> _verifyViewModelList = null;
|
|
private Model.MonitorDataSources _monitorDataSources = null;
|
private Model.Equipment _equipment = null;
|
private readonly BLL.MonitorDataSet _bll = new BLL.MonitorDataSet();
|
private readonly BLL.EquipmentMonitorMapping _bllEquipmentMonitorMapping = new BLL.EquipmentMonitorMapping();
|
private readonly BLL.MonitorPoint _bllMonitorPoint = new BLL.MonitorPoint();
|
|
|
|
/// <summary>
|
/// 初始化图表
|
/// </summary>
|
public void InitialChart()
|
{
|
|
|
}
|
|
/// <summary>
|
/// 初始化数据
|
/// </summary>
|
public override void InitialDataSource()
|
{
|
equipmentExTreeListCtrl1.SetBindingData();
|
monitorDataSourcesTreeList.SetBindingData();
|
}
|
|
private void MonitorDataSourcesTreeList1_FocusedChangedEvent(Model.MonitorDataSources obj)
|
{
|
_monitorDataSources = obj;
|
}
|
|
private void EquipmentExTreeListCtrl1_FocusedChangedEvent(Model.Equipment obj)
|
{
|
_equipment = obj;
|
}
|
|
//验证
|
private void barBtnVerify_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
memoInfo.Text = string.Empty;
|
if (_monitorDataSources == null || _equipment == null)
|
return;
|
|
_verifyViewModelList = new List<VerifyViewModel>();
|
|
var pump = new BLL.Equipment().GetChildPumpByEnginePumpID(_equipment.ID);
|
|
var packet_list = new BLL.StationSignalRecordPacket().Get(_monitorDataSources.ID, _equipment.BelongID);
|
var record_list = new List<Model.StationSignalRecord>();
|
foreach (var packet in packet_list)
|
{
|
var stationSignalRecords = packet.StationSignalRecords?.ToList();
|
if (stationSignalRecords == null || !stationSignalRecords.Any())
|
{
|
continue;
|
}
|
record_list.AddRange(stationSignalRecords);
|
}
|
|
|
foreach (var stationSignalRecord in record_list)
|
{
|
foreach (var pumpSignalRecord in stationSignalRecord.PumpSignalRecords)
|
{
|
if (pumpSignalRecord.Flag != pump.SortCode)
|
continue;
|
var time = stationSignalRecord.Time;
|
var rpm = pumpSignalRecord.Rpm;
|
var fre = pumpSignalRecord.Frequency;
|
|
var vm = new VerifyViewModel(pumpSignalRecord, time);
|
_verifyViewModelList.Add(vm);
|
}
|
}
|
|
var curveInfo = new BLL.PumpCurve().GetDefaultWorkingByPumpID(pump.ID)?.CurveInfo;
|
if (curveInfo == null)
|
{
|
return;
|
}
|
|
var seriesViewPower = new DevExpress.XtraCharts.LineSeriesView();
|
seriesViewPower.Color = System.Drawing.Color.LightCoral;
|
var seriesPower = new DevExpress.XtraCharts.Series
|
{
|
Name = pump.SortCode + "-功率",
|
View = seriesViewPower,
|
LegendText = pump.SortCode + "-功率"
|
};
|
|
var helper = new FilterOutliersHelper();
|
var verifyViewModelList = Verify(pump.RatedParas.Nr, curveInfo, _verifyViewModelList);
|
var rpm_diff_dict = new Dictionary<double, double>();
|
var new_verify_vm_rpm_group = verifyViewModelList.GroupBy(x => Math.Round(x.Rpm)).OrderBy(x => x.Key);
|
if (new_verify_vm_rpm_group != null && new_verify_vm_rpm_group.Any())
|
{
|
var str = new StringBuilder();
|
foreach (var group in new_verify_vm_rpm_group)
|
{
|
var points = group.Where(x => Math.Abs(x.HeadDiff) < 10)?.ToList();
|
if (points != null && points.Any())
|
{
|
var arr_src = points.Select(x => x.HeadDiff).ToArray();
|
var arr_avg = arr_src.Average();
|
double std_dev_src = 0, STDP_src = 0;
|
double std_dev = 0, STDP = 0;
|
|
str.AppendLine();
|
if (arr_src.Count() > 1)
|
{
|
STDEV(arr_src, out std_dev_src, out STDP_src);
|
|
|
str.AppendLine($"{group.Key}Rpm Avg:{arr_avg:N8} 样本X:{std_dev_src:N5} 总X:{STDP_src:N5} Count:{arr_src.Count()}");
|
|
var arr_std_first = FilterOutliersHelper.FilterBySTDEV(arr_src, false);
|
// var arr_std_first = arr_src.Where(x => !(Math.Abs(x - arr_avg) > Math.Abs(std_dev_src * 2))).ToArray();
|
//var arr_std_first = arr_src.Where(x => !(x - arr_avg > std_dev_src * 2)).ToArray();
|
|
if (arr_std_first.Any() && arr_std_first.Count() != arr_src.Count())
|
{
|
var avg = arr_std_first.Average();
|
STDEV(arr_std_first, out std_dev, out STDP);
|
str.AppendLine($"std_dev Avg:{avg:N8} 样本X:{std_dev:N7} 总X:{STDP:N7} Count:{arr_std_first.Count()} 过滤:{arr_src.Count() - arr_std_first.Count()}");
|
}
|
|
//var arr_stdp_first = arr_src.Where(x => !(Math.Abs(x - arr_avg) > Math.Abs(STDP * 2))).ToArray();
|
var arr_stdp_first = FilterOutliersHelper.FilterBySTDEV(arr_src, true);
|
//var arr_stdp_first = arr_src.Where(x => !(x-arr_avg > STDP_src * 2)).ToArray();
|
if (arr_stdp_first.Any() && arr_stdp_first.Count() != arr_src.Count())
|
{
|
var avg = arr_stdp_first.Average();
|
STDEV(arr_stdp_first, out std_dev, out STDP);
|
str.AppendLine($"STDP Avg:{avg:N8} 样本X:{std_dev:N7} 总X:{STDP:N7} Count:{arr_stdp_first.Count()} 过滤:{arr_src.Count() - arr_stdp_first.Count()}");
|
}
|
|
}
|
else
|
{
|
str.AppendLine($"{group.Key}Rpm Avg:{arr_avg:N4}");
|
}
|
|
var arr = FilterOutliersHelper.FilterBySTDEV(arr_src, true);
|
var avg_pop = arr.Average();
|
rpm_diff_dict.Add(group.Key, avg_pop);
|
}
|
}
|
memoInfo.Text = str.ToString();
|
}
|
|
foreach (var record in verifyViewModelList)
|
{
|
|
if (record.Flag > 18)
|
{
|
if (record.FlowRate < 1)
|
{
|
continue;
|
}
|
}
|
|
if (record.Head == IStation.Error.Default || record.Head == 0)
|
{
|
continue;
|
}
|
if (record.InstantaneousPower == IStation.Error.Default)
|
{
|
continue;
|
}
|
var rpm = record.Rpm;
|
rpm = Math.Round(rpm);
|
if (rpm_diff_dict.ContainsKey(rpm))
|
{
|
var update_head = rpm_diff_dict[rpm];
|
record.UpdateHeadDiff = VerifyUpdate(pump.RatedParas.Nr, curveInfo, update_head, record);
|
}
|
}
|
|
verifyViewModelBindingSource.DataSource = verifyViewModelList;
|
verifyViewModelBindingSource.ResetBindings(false);
|
}
|
|
|
/// <summary>
|
/// 样本标准差和总体标准差计算
|
/// </summary>
|
/// <param name="arrData">数据数组</param>
|
/// <param name="std_dev">样本标准差</param>
|
/// <param name="STDP">总体标准差</param>
|
void STDEV(double[] arrData, out double std_dev, out double STDP) //计算标准偏差
|
{
|
double xSum = 0F;//样本总和
|
double xAvg = 0F;//样本平均值
|
double sSum = 0F;//方差的分子
|
//float tmpStDev = 0F;
|
int arrNum = arrData.Length;//得到样本数量,分母
|
for (int i = 0; i < arrNum; i++)//循环计算得到样本总和
|
{
|
xSum += arrData[i];
|
}
|
xAvg = xSum / arrNum;//计算得到样本平均值
|
for (int j = 0; j < arrNum; j++)//得到方差的分子
|
{
|
sSum += ((arrData[j] - xAvg) * (arrData[j] - xAvg));
|
}
|
std_dev = Convert.ToSingle(Math.Sqrt((sSum / (arrNum - 1))).ToString());//样本标准差
|
|
STDP = Convert.ToSingle(Math.Sqrt((sSum / arrNum)).ToString());//总体标准差
|
}
|
|
|
private List<VerifyViewModel> Verify(double Nr, FeatCurveExpressGroup curveInfo, List<VerifyViewModel> verifyViewModels)
|
{
|
foreach (var record in verifyViewModels)
|
{
|
if (record.Flag > 18)
|
{
|
if (record.FlowRate < 1)
|
{
|
continue;
|
}
|
}
|
|
if (record.Head == IStation.Error.Default || record.Head == 0)
|
{
|
continue;
|
}
|
if (record.InstantaneousPower == IStation.Error.Default)
|
{
|
continue;
|
}
|
|
var rpm = record.Rpm;
|
if (rpm == IStation.Error.Default || rpm < 1)
|
{
|
if (record.Frequency > 0 && record.Frequency != IStation.Error.Default)
|
{
|
rpm = (record.Frequency / 50) * Nr;
|
}
|
else
|
{
|
continue;
|
}
|
}
|
|
var time = record.Time;
|
var flowRate = record.FlowRate;
|
|
Model.CurveExpress curveQH, curveQP;
|
curveQH = Model.CurveCalcuHelper.CalculateSimilarQH(curveInfo.CurveQH, Nr, record.Rpm);
|
curveQP = Model.CurveCalcuHelper.CalculateSimilarQP(curveInfo.CurveQP, Nr, record.Rpm);
|
if (curveQH == null || curveQP == null)
|
continue;
|
if (flowRate < 1)
|
{
|
var qhPoints = curveQH.GetFitPoints();
|
Model.FitCurveHelper.GetInterPointX(qhPoints, record.Head, out flowRate);
|
}
|
|
record.InterPower = Math.Round(curveQP.GetFitPointY(flowRate), 2);
|
record.PowerDiff = record.InstantaneousPower - record.InterPower;
|
record.PowerDiff = Math.Round(record.PowerDiff, 2);
|
|
if (record.Flag > 19)
|
{
|
record.InterHead = Math.Round(curveQH.GetFitPointY(record.FlowRate), 2);
|
record.HeadDiff = record.Head - record.InterHead;
|
}
|
record.Eff = Model.CurveCalcuHelper.CalculateE(flowRate, record.Head, record.InstantaneousPower);
|
}
|
|
return verifyViewModels;
|
}
|
|
private double VerifyUpdate(double Nr, FeatCurveExpressGroup curveInfo, double update_head, VerifyViewModel record)
|
{
|
double head_diff = 0;
|
if (record.Flag > 18)
|
{
|
if (record.FlowRate < 1)
|
{
|
return default;
|
}
|
}
|
|
if (record.Head == IStation.Error.Default || record.Head == 0)
|
{
|
return default;
|
}
|
if (record.InstantaneousPower == IStation.Error.Default)
|
{
|
return default;
|
}
|
|
var rpm = record.Rpm;
|
if (rpm == IStation.Error.Default || rpm < 1)
|
{
|
if (record.Frequency > 0 && record.Frequency != IStation.Error.Default)
|
{
|
rpm = (record.Frequency / 50) * Nr;
|
}
|
else
|
{
|
return default;
|
}
|
}
|
var curveQhPoints50 = curveInfo.CurveQH.DefinePoints?.Select(x => new Model.CurvePoint(x.X, x.Y + update_head)).ToList();
|
var curveQh50 = new CurveExpress(curveQhPoints50, Model.eCurveFitType.FourM, true);
|
|
var flowRate = record.FlowRate;
|
Model.CurveExpress curveQH;
|
curveQH = Model.CurveCalcuHelper.CalculateSimilarQH(curveQh50, Nr, record.Rpm);
|
if (curveQH == null)
|
return default;
|
|
if (record.Flag > 19)
|
{
|
var inter_head = curveQH.GetFitPointY(flowRate);
|
head_diff = Math.Round(record.Head - inter_head, 2);
|
}
|
|
return head_diff;
|
}
|
|
//刷新
|
private void barBtnRefresh_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
InitialDataSource();
|
}
|
|
|
|
|
//导出表格
|
private void barBtnExportExcel_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
gridView1.ExportExcel();
|
}
|
|
|
private void barBtnExportWaterDesk_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
|
if (_monitorDataSources == null || _equipment == null)
|
return;
|
var dlg = new SetTimeStepDlg();
|
dlg.SetBindingData(300);
|
dlg.ReloadDataEvent += (timeStep) =>
|
{
|
|
WaitFrmHelper.ShowWaitForm("正在导出");
|
ExportWaterDeskHelper.Export(_monitorDataSources.ID, _equipment.BelongID, timeStep);
|
WaitFrmHelper.HideWaitForm();
|
AlertTool.ShowInfo(System.Windows.Forms.Application.OpenForms[0], "提示", "导出完成!");
|
|
|
};
|
dlg.ShowDialog();
|
}
|
|
private void barBtnExportEapnet_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
if (_monitorDataSources == null || _equipment == null)
|
return;
|
|
var dlg = new SetTimeStepDlg();
|
dlg.SetBindingData(300);
|
dlg.ReloadDataEvent += (timeStep) =>
|
{
|
WaitFrmHelper.ShowWaitForm("正在导出");
|
//ExportEpanetHelper.ExportByDay(_monitorDataSources.ID, _equipment.BelongID, year, month, timeStep);
|
ExportEpanetHelper.Export(_monitorDataSources.ID, _equipment.BelongID, timeStep);
|
|
WaitFrmHelper.HideWaitForm();
|
AlertTool.ShowInfo(System.Windows.Forms.Application.OpenForms[0], "提示", "导出完成!");
|
};
|
dlg.ShowDialog();
|
}
|
|
private void barExportHzHeadDiffAvg_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
|
{
|
if (_monitorDataSources == null || _equipment == null)
|
return;
|
var bll = new BLL.Equipment();
|
var enginePumps = bll.GetEnginePumpListByBelongTypeAndBelongID(IStation.ObjectType.Station, _equipment.BelongID);
|
if (enginePumps == null || !enginePumps.Any())
|
return;
|
decimal hz_space = 0.1m;
|
var flag_pump_dict = new Dictionary<int, Model.Equipment<Model.Pump>>();
|
var flag_nr_dict = new Dictionary<int, double>();
|
var flag_hz_adn_head_avg_dict_dict = new Dictionary<int, Dictionary<decimal, double?>>();
|
enginePumps.ForEach(x =>
|
{
|
var pump = bll.GetChildPumpByEnginePumpID(x.ID);
|
if (pump == null)
|
return;
|
var flag = pump.SortCode;
|
|
flag_pump_dict.Add(flag, pump);
|
flag_nr_dict.Add(flag, pump.RatedParas.Nr);
|
|
var dict = new Dictionary<decimal, double?>();
|
for (decimal hz = 0; hz <= 50; hz = hz + hz_space)
|
{
|
dict.Add(hz, null);
|
}
|
flag_hz_adn_head_avg_dict_dict.Add(flag, dict);
|
});
|
|
|
|
var all_packet_list = new BLL.StationSignalRecordPacket().Get(_monitorDataSources.ID, _equipment.BelongID);
|
var all_record_list = new List<Model.StationSignalRecord>();
|
foreach (var packet in all_packet_list)
|
{
|
var stationSignalRecords = packet.StationSignalRecords?.ToList();
|
if (stationSignalRecords == null || !stationSignalRecords.Any())
|
{
|
continue;
|
}
|
all_record_list.AddRange(stationSignalRecords);
|
}
|
|
|
var helper = new FilterOutliersHelper();
|
var pump_record_group = all_record_list.SelectMany(x => x.PumpSignalRecords).GroupBy(x => x.Flag).ToList();
|
foreach (var item_record_list in pump_record_group)
|
{
|
var flag = item_record_list.Key;
|
if (flag < 19)
|
continue;
|
var pump = flag_pump_dict[flag];
|
var nr = flag_nr_dict[flag];
|
var curveInfo = new BLL.PumpCurve().GetDefaultWorkingByPumpID(pump.ID)?.CurveInfo;
|
if (curveInfo == null)
|
continue;
|
var head_diff_list = new List<double>();
|
var rpm_record_list_dict = item_record_list.GroupBy(x => Math.Round(x.Rpm)).ToDictionary(x => x.Key, x => x.ToList());
|
foreach (var item in rpm_record_list_dict)
|
{
|
decimal hz = (decimal)(item.Key / nr * 50);
|
hz = Math.Round(hz, 1);
|
if (hz < 0 || hz > 50)
|
continue;
|
|
var record_list = item.Value;
|
foreach (var record in record_list)
|
{
|
if (record.FlowRate < 1)
|
continue;
|
if (record.Head == IStation.Error.Default || record.Head < 0.1)
|
continue;
|
if (record.InstantaneousPower == IStation.Error.Default)
|
continue;
|
var similar_curve_qh = Model.CurveCalcuHelper.CalculateSimilarQH(curveInfo.CurveQH, nr, record.Rpm);
|
if (similar_curve_qh == null)
|
continue;
|
var inter_head = similar_curve_qh.GetFitPointY(record.FlowRate);
|
var head_diff = record.Head - inter_head;
|
head_diff_list.Add(head_diff);
|
}
|
double? head_diff_avg = null;
|
if (head_diff_list.Any())
|
{
|
var filter_head_diff_array = FilterOutliersHelper.FilterBySTDEV(head_diff_list.ToArray(), true);
|
head_diff_avg = filter_head_diff_array.Average();
|
}
|
|
flag_hz_adn_head_avg_dict_dict[flag][hz] = head_diff_avg;
|
}
|
}
|
|
|
var root_folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "变速修正数据");
|
if (!Directory.Exists(root_folder))
|
Directory.CreateDirectory(root_folder);
|
var fileName = root_folder + "\\" + "2.json";
|
var json = JsonHelper.Object2Json(flag_hz_adn_head_avg_dict_dict);
|
File.WriteAllText(fileName, json);
|
|
|
AlertTool.ShowInfo(System.Windows.Forms.Application.OpenForms[0], "提示", "导出完成!");
|
|
}
|
|
|
}
|
}
|