using IStation.Epanet;
using IStation.Epanet.Enums;
using System.Text;
using Yw.Dto;
namespace IStation.Application
{
///
/// 厂站调度
///
[AllowAnonymous]
[Route("Web/Dispatch/Solution")]
[ApiDescriptionSettings("Web", Name = "厂站调度", Order = 1000)]
public class HydraulicModel_Controller : IDynamicApiController, ITransient
{
private static readonly Service.ScheduleRequest _service_schedule_request = new();
private static readonly Service.ScheduleScada _service_schedule_scada = new();
private static readonly Service.ScheduleRule _service_schedule_rule = new();
private static readonly Service.ScheduleConclusion _service_schedule_conclusion = new();
private static readonly Service.SchedulePump _service_schedule_pump = new();
private static readonly Service.Station _service_station = new();
private static readonly Service.ScheduleConfig _service_schedule_config = new();
private static readonly Service.AnalysisFactor _service_analysis_factor = new();
private static readonly Service.AnalysisDeviation _service_analysis_deviation = new();
private static readonly string _model_file = Path.Combine(
Settings.ParasHelper.LocalFile.DataFolderDirectory,
Settings.ParasHelper.LocalFile.HydraulicModelFile);
///
/// 获取监测值
///
[Route("GetMonitorValue@V1.0")]
[HttpGet]
public ScheduleMonitorOutput GetMonitorValue()
{
GlobalHelper.GetMonitorRecordList(DateTime.Now, out List monitor_record_list, true);
GlobalHelper.GetPipeFlagFlowAndPressureDict(monitor_record_list, out Dictionary> station1_pipe_flag_flow_pressure_dict, out Dictionary> station2_pipe_flag_flow_pressure_dict);
var output = new ScheduleMonitorOutput();
var target_flow1 = station1_pipe_flag_flow_pressure_dict.Sum(x => x.Value.Item1) ?? 0;
var target_pressure1 = station1_pipe_flag_flow_pressure_dict.Average(x => x.Value.Item2) ?? 0;
var target_flow2 = station2_pipe_flag_flow_pressure_dict.Sum(x => x.Value.Item1) ?? 0;
var target_pressure2 = station2_pipe_flag_flow_pressure_dict.Average(x => x.Value.Item2) ?? 0;
target_flow1.Round(1);
target_pressure1.M2Mpa();
target_pressure1.Round(5);
target_flow2.Round(1);
target_pressure2.M2Mpa();
target_pressure2.Round(5);
output.TargetFlow1 = target_flow1;
output.TargetFlow2 = target_flow2;
output.TargetPressure1 = target_pressure1;
output.TargetPressure2 = target_pressure2;
return output;
}
#region 水力模型
///
/// 获取模型
///
[Route("GetModel@V1.0")]
[HttpGet]
public ModelOutput GetModel()
{
if (!File.Exists(_model_file))
{
throw Yw.Dto.YOops.Oh(Yw.Dto.eResultCode.Error, Yw.Dto.InternalErrorCodes.A001, $"水力模型文件缺失!文件路径:{_model_file}");
}
IStation.Epanet.NetworkHelper.Open(_model_file, out Epanet.Network.Network network);
if (network == null)
{
throw Yw.Dto.YOops.Oh(Yw.Dto.eResultCode.Error, Yw.Dto.InternalErrorCodes.A001, $"文件解析失败!文件路径:{_model_file}");
}
if (network == null)
return default;
var reservoirs = network.Reservoirs;
var tanks = network.Tanks;
var junctions = network.Junctions;
var pipes = network.Pipes;
var pumps = network.Pumps;
var valves = network.Valves;
var output = new ModelOutput();
if (reservoirs != null && reservoirs.Any())
{
foreach (var item in reservoirs)
{
var dto = new Dto.Inp.Reservoir
{
Id = item.Name,
Coordinate = new Dto.Inp.EnPoint(item.Coordinate.X, item.Coordinate.Y)
};
output.Reservoirs.Add(dto);
}
}
if (tanks != null && tanks.Any())
{
foreach (var item in tanks)
{
var dto = new Dto.Inp.Tank
{
Id = item.Name,
Coordinate = new Dto.Inp.EnPoint(item.Coordinate.X, item.Coordinate.Y),
};
output.Tanks.Add(dto);
}
}
if (junctions != null && junctions.Any())
{
foreach (var item in junctions)
{
var dto = new Dto.Inp.Junction
{
Id = item.Name,
Coordinate = new Dto.Inp.EnPoint(item.Coordinate.X, item.Coordinate.Y),
};
output.Junctions.Add(dto);
}
}
if (pipes != null && pipes.Any())
{
foreach (var item in pipes)
{
var dto = new Dto.Inp.Pipe
{
Id = item.Name,
};
if (item.FirstNode != null)
{
var node = item.FirstNode;
dto.FirstNode = new Dto.Inp.Node()
{
Id = node.Name,
Coordinate = new Dto.Inp.EnPoint(node.Coordinate.X, node.Coordinate.Y),
};
}
if (item.SecondNode != null)
{
var node = item.SecondNode;
dto.SecondNode = new Dto.Inp.Node()
{
Id = node.Name,
Coordinate = new Dto.Inp.EnPoint(node.Coordinate.X, node.Coordinate.Y),
};
}
output.Pipes.Add(dto);
}
}
if (pumps != null && pumps.Any())
{
foreach (var item in pumps)
{
var dto = new Dto.Inp.Pump
{
Id = item.Name,
};
if (item.FirstNode != null)
{
var node = item.FirstNode;
dto.FirstNode = new Dto.Inp.Node()
{
Id = node.Name,
Coordinate = new Dto.Inp.EnPoint(node.Coordinate.X, node.Coordinate.Y),
};
}
if (item.SecondNode != null)
{
var node = item.SecondNode;
dto.SecondNode = new Dto.Inp.Node()
{
Id = node.Name,
Coordinate = new Dto.Inp.EnPoint(node.Coordinate.X, node.Coordinate.Y),
};
}
output.Pumps.Add(dto);
}
}
if (valves != null && valves.Any())
{
foreach (var item in valves)
{
var dto = new Dto.Inp.Valve
{
Id = item.Name,
};
if (item.FirstNode != null)
{
var node = item.FirstNode;
dto.FirstNode = new Dto.Inp.Node()
{
Id = node.Name,
Coordinate = new Dto.Inp.EnPoint(node.Coordinate.X, node.Coordinate.Y),
};
}
if (item.SecondNode != null)
{
var node = item.SecondNode;
dto.SecondNode = new Dto.Inp.Node()
{
Id = node.Name,
Coordinate = new Dto.Inp.EnPoint(node.Coordinate.X, node.Coordinate.Y),
};
}
output.Valves.Add(dto);
}
}
return output;
}
///
/// 计算
///
[Route("Calculate@V1.0")]
[HttpPost]
public ModelCalcOutput Calculate([Required] ScheduleCalcInput input)
{
var receipt_time = DateTime.Now;
var request_id = Yw.YitIdHelper.NextId();
var station_info = _service_station.Get();
if (station_info == null)
{
throw Yw.Dto.YOops.Oh(Yw.Dto.eResultCode.Error, Yw.Dto.InternalErrorCodes.A001, $"基础信息文件缺失!");
}
var target_flow1 = input.TargetFlow1;
var target_mpa_pressure1 = input.TargetPressure1;
var target_flow2 = input.TargetFlow2;
var target_mpa_pressure2 = input.TargetPressure2;
var target_pressure1 = Curve.PumpCalculateHelper.Mpa2M(target_mpa_pressure1);
var target_pressure2 = Curve.PumpCalculateHelper.Mpa2M(target_mpa_pressure2);
GlobalHelper.GetMonitorRecordList(receipt_time, out List monitor_record_list, true);
var station1 = station_info.Station1;
var station2 = station_info.Station2;
var station1_schedule_config = _service_schedule_config.GetStation1();
var station2_schedule_config = _service_schedule_config.GetStation2();
var station1_flag_list = GlobalHelper.Station1FlagList;
var station2_flag_list = GlobalHelper.Station2FlagList;
var analysis_deviation_list = _service_analysis_deviation.GetList();
var analysis_factor_list = _service_analysis_factor.GetList();
GlobalHelper.GetStationOpenFlagList(monitor_record_list, out List station1_open_flag_list, out List station2_open_flag_list);
GlobalHelper.GetStationFlagStateList(monitor_record_list, out List station1_flag_maintenance_list, out List station2_maintenance_flag_list, out List station1_priority_flag_list, out List station2_priority_flag_list);
GlobalHelper.GetFlagInletWaterLevelDict(monitor_record_list, out Dictionary station1_flag_inlet_water_level_dict, out Dictionary station2_flag_inlet_water_level_dict);
GlobalHelper.GetPipeFlagFlowAndPressureDict(monitor_record_list, out Dictionary> station1_pipe_flag_flow_pressure_dict, out Dictionary> station2_pipe_flag_flow_pressure_dict);
GlobalHelper.GetFlagRpmAndFlowAndPressureDict(monitor_record_list, out Dictionary> station1_flag_rpm_pressure_dict, out Dictionary> station2_flag_rpm_flow_pressure_dict);
if (station1_flag_maintenance_list != null && station1_flag_maintenance_list.Any())
{
ScheduleLog.Info(request_id, "机泵检修", $"1输水:{Yw.Untity.IntListHelper.ToString(station1_flag_maintenance_list)}");
station1_schedule_config.MustCloseFlagList.AddRange(station1_flag_maintenance_list);
}
if (station2_maintenance_flag_list != null && station2_maintenance_flag_list.Any())
{
ScheduleLog.Info(request_id, "机泵检修", $"2输水:{Yw.Untity.IntListHelper.ToString(station2_maintenance_flag_list)}");
station2_schedule_config.MustCloseFlagList.AddRange(station2_maintenance_flag_list);
}
if (station1_priority_flag_list != null && station1_priority_flag_list.Any())
{
ScheduleLog.Info(request_id, "机泵优先", $"1输水:{Yw.Untity.IntListHelper.ToString(station1_priority_flag_list)}");
station1_schedule_config.MustOpenFlagList.AddRange(station1_priority_flag_list);
}
if (station2_priority_flag_list != null && station2_priority_flag_list.Any())
{
ScheduleLog.Info(request_id, "机泵优先", $"2输水:{Yw.Untity.IntListHelper.ToString(station2_priority_flag_list)}");
station2_schedule_config.MustOpenFlagList.AddRange(station2_priority_flag_list);
}
analysis_deviation_list = null;
var helper = new Service.ScheduleHelper();
helper.Initial(station1_open_flag_list, station1_schedule_config, analysis_deviation_list);
var optimal_combine1 = helper.GetOptAnaCombine(station1, station1_flag_inlet_water_level_dict, target_flow1, target_pressure1);
helper.Initial(station2_open_flag_list, station2_schedule_config, analysis_deviation_list);
var optimal_combine2 = helper.GetOptAnaCombine(station2, station2_flag_inlet_water_level_dict, target_flow2, target_pressure2);
if (optimal_combine1 == null && optimal_combine2 == null)
{
throw Yw.Dto.YOops.Oh(Yw.Dto.eResultCode.Error, Yw.Dto.InternalErrorCodes.A001, $"计算失败!");
}
var pump_id_mapping_dict = GlobalHelper.ModelPumpIdMappingDict;
var pattern_id_mapping_dict = GlobalHelper.ModelPatternIdMappingDict;
var output = new ModelCalcOutput();
output.PumpCompares1 = new List();
output.PumpCompares2 = new List();
output.PumpDetails = new List();
output.PipeDetails = new List();
if (optimal_combine1 != null)
{
optimal_combine1.Round();
var pump_bp_dict = station1.ToDictionary(x => x.Flag, x => x.IsBp);
foreach (var flag in GlobalHelper.Station1FlagList)
{
var name = $"{flag}#泵";
var detail = new ModelPumpDetail();
detail.ModelId = pump_id_mapping_dict[flag];
detail.Flag = flag;
detail.Name = name;
detail.Flag = flag;
detail.IsBp = pump_bp_dict[flag];
detail.RunStatus = false;
output.PumpDetails.Add(detail);
var rpm_pressure = station1_flag_rpm_pressure_dict[flag];
var compare = new ModelPumpCompare();
compare.Name = name;
compare.SrcSpeed = rpm_pressure.Item1;
compare.SrcPressure = rpm_pressure.Item2;
output.PumpCompares1.Add(compare);
var fre_pump = optimal_combine1.AnaFrePumps.Find(x => x.Flag == flag);
if (fre_pump != null)
{
var wl = station1_flag_inlet_water_level_dict[flag];
var pressure = fre_pump.PressureDiff + wl;
detail.Hz = fre_pump.Frequency;
detail.Flow = fre_pump.Flow;
detail.Pressure = pressure;
detail.Eff = fre_pump.Eff;
detail.Power = fre_pump.Power;
detail.RunStatus = true;
compare.CalcSpeed = fre_pump.Speed;
compare.DiffSpeed = compare.CalcSpeed - compare.SrcSpeed;
compare.CalcFlow = fre_pump.Flow;
//compare.DiffFlow = compare.CalcFlow - compare.SrcFlow;
compare.DiffFlow = null;
compare.CalcPressure = pressure;
compare.DiffPressure = compare.CalcPressure - compare.SrcPressure;
if (compare.DiffSpeed.HasValue)
compare.DiffSpeed = Math.Round(compare.DiffSpeed.Value, 1);
if (compare.DiffPressure.HasValue)
compare.DiffPressure = Math.Round(compare.DiffPressure.Value, 1);
}
}
foreach (var flag in GlobalHelper.Station1PipeFlagList)
{
var name = $"嘉定{flag}线";
var flow_pressure = station1_pipe_flag_flow_pressure_dict[flag];
var detail = new ModelPipeDetail();
detail.Name = name;
detail.Flag = flag;
detail.SrcFlow = flow_pressure.Item1;
detail.SrcPressure = flow_pressure.Item2;
output.PipeDetails.Add(detail);
}
}
if (optimal_combine2 != null)
{
optimal_combine2.Round();
var pump_bp_dict = station2.ToDictionary(x => x.Flag, x => x.IsBp);
foreach (var flag in GlobalHelper.Station2FlagList)
{
var name = $"{flag}#泵";
var detail = new ModelPumpDetail();
detail.ModelId = pump_id_mapping_dict[flag];
detail.Flag = flag;
detail.Name = name;
detail.Flag = flag;
detail.IsBp = pump_bp_dict[flag];
detail.RunStatus = false;
output.PumpDetails.Add(detail);
var rpm_pressure = station2_flag_rpm_flow_pressure_dict[flag];
var compare = new ModelPumpCompare();
compare.Name = name;
compare.SrcSpeed = rpm_pressure.Item1;
compare.SrcFlow = rpm_pressure.Item2;
compare.SrcPressure = rpm_pressure.Item3;
output.PumpCompares2.Add(compare);
var fre_pump = optimal_combine2.AnaFrePumps.Find(x => x.Flag == flag);
if (fre_pump != null)
{
var wl = station2_flag_inlet_water_level_dict[flag];
var pressure = fre_pump.PressureDiff + wl;
detail.Hz = fre_pump.Frequency;
detail.Flow = fre_pump.Flow;
detail.Pressure = pressure;
detail.Eff = fre_pump.Eff;
detail.Power = fre_pump.Power;
detail.RunStatus = true;
compare.CalcSpeed = fre_pump.Speed;
compare.DiffSpeed = compare.CalcSpeed - compare.SrcSpeed;
compare.CalcFlow = fre_pump.Flow;
compare.DiffFlow = compare.CalcFlow - compare.SrcFlow;
compare.CalcPressure = pressure;
compare.DiffPressure = compare.CalcPressure - compare.SrcPressure;
if (compare.DiffSpeed.HasValue)
compare.DiffSpeed = Math.Round(compare.DiffSpeed.Value, 1);
if (compare.DiffPressure.HasValue)
compare.DiffPressure = Math.Round(compare.DiffPressure.Value, 1);
if (compare.DiffFlow.HasValue)
compare.DiffFlow = Math.Round(compare.DiffFlow.Value, 1);
}
}
foreach (var flag in GlobalHelper.Station2PipeFlagList)
{
var name = $"DN{flag}";
var flow_pressure = station2_pipe_flag_flow_pressure_dict[flag];
var detail = new ModelPipeDetail();
detail.Name = name;
detail.Flag = flag;
detail.SrcFlow = flow_pressure.Item1;
detail.SrcPressure = flow_pressure.Item2;
output.PipeDetails.Add(detail);
}
}
var flag_qh_curve_dict = new Dictionary();
foreach (var pump in station1)
flag_qh_curve_dict.Add(pump.Flag, pump.CurveQH);
foreach (var pump in station2)
flag_qh_curve_dict.Add(pump.Flag, pump.CurveQH);
var pump_rpm_ratio_dict = output.PumpDetails.ToDictionary(x => x.ModelId, y => y.Hz / 50);
var record_dict = new Dictionary();
foreach (var item in pattern_id_mapping_dict)
{
var id = item.Key;
var code = item.Value;
var record = monitor_record_list.Find(x => code == x.DataCode);
if (record == null)
continue;
if (pump_rpm_ratio_dict.ContainsKey(id))
{
record_dict.Add(item.Key, pump_rpm_ratio_dict[id]);
}
else
{
record_dict.Add(item.Key, record.DataValue);
}
}
//analysis_factor_list = null;
CalcModel(_model_file, flag_qh_curve_dict, record_dict, output.PipeDetails, output.PumpDetails, analysis_factor_list);
return output;
}
#region Private Calculate
///
/// 计算模型
///
void CalcModel
(
string model_inp,
Dictionary flag_qh_curve_dict,
Dictionary record_dcit,
List pipe_detail_list,
List pump_detail_list,
List ana_factor_list
)
{
if (!File.Exists(model_inp))
{
throw new Exception($"model_inp:is null");
}
var temp_id_build = new StringBuilder(31);
var err = EpanetMethods.ENopen(model_inp, "", "");
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 pump_mapping_list = GetPumpModelMappingList();
var station_mapping_list = GetStationMappingList();
foreach (var mapping in pump_mapping_list)
{
var flag = mapping.Flag;
if (EpanetMethods.ENgetlinkindex(mapping.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(mapping.PressureId, out int pressure_index) != ErrorCode.Ok)
throw new Exception($"ENgetnodeindex:{err}");
if (EpanetMethods.ENgetcurveindex(mapping.CurveId, out int curve_index) != ErrorCode.Ok)
throw new Exception($"ENgetcurveindex:{err}");
mapping.PumpIndex = pump_index;
mapping.PressureIndex = pressure_index;
mapping.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();
err = EpanetMethods.ENsetcurve(mapping.CurveIndex, flow_list, head_list, curve_point_count);
if (err != 0)
{
throw new Exception($"ENsetcurve:{err}");
}
}
foreach (var item in station_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_mapping_list.ToDictionary(x => x.Flag, y => y);
var station_model_mapping_dict = station_mapping_list.ToDictionary(x => x.Flag, y => y);
var pattern_id_list = GlobalHelper.ModelPatternIdList;
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);
}
foreach (var pattern in pattern_id_dict)
{
var pattern_id = pattern.Key;
var pattern_index = pattern.Value;
var pattern_value = 0f;
if (record_dcit.ContainsKey(pattern_id))
{
pattern_value = (float)(record_dcit[pattern_id] ?? 0);
}
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())
{
foreach (var detail in pump_detail_list)
{
if (!detail.RunStatus)
{
continue;
}
var flag = detail.Flag;
var hz = detail.Hz.Value;
var rpm_ratio = detail.IsBp ? 1 : hz / 50;
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($"flag:{flag} hz:{hz0} ana_factor:is null");
}
var mapping = pump_model_mapping_dict[flag];
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 Curve.CurvePoint(x.X, x.Y + head_dev)).ToList();
var qh_ct = Curve.FitHelper.BuildCurveExpress(pt_list_ct, Curve.eFitType.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 detail in pump_detail_list)
{
if (!detail.RunStatus)
{
continue;
}
var flag = detail.Flag;
var hz = detail.Hz.Value;
if (!detail.IsBp)
hz = 50;
var mapping = pump_model_mapping_dict[flag];
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);
detail.ModelFlow = Math.Round(model_flow, 1);
detail.ModelPressure = Math.Round(model_outlet_pressure, 1);
}
foreach (var detail in pipe_detail_list)
{
var flag = detail.Flag;
var mapping = station_model_mapping_dict[flag];
if (mapping == null)
{
continue;
}
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}");
}
detail.ModelFlow = Math.Round(model_flow, 1);
detail.ModelPressure = Math.Round(model_outlet_pressure);
detail.DiffFlow = detail.ModelFlow - detail.SrcFlow;
detail.DiffPressure = detail.ModelPressure - detail.SrcPressure;
if (detail.DiffFlow.HasValue)
detail.DiffFlow = Math.Round(detail.DiffFlow.Value, 1);
if (detail.DiffPressure.HasValue)
detail.DiffPressure = Math.Round(detail.DiffPressure.Value, 1);
}
err = EpanetMethods.ENcloseH();
if ((int)err > 6)
{
throw new Exception($"ENcloseH:{err}");
}
err = EpanetMethods.ENclose();
if ((int)err > 6)
{
throw new Exception($"ENclose:{err}");
}
}
class PumpMapping
{
public int Flag { get; set; }
public string PumpId { get; set; }
public string FlowId { get; set; }
public string PressureId { get; set; }
public string CurveId { get; set; }
public int PumpIndex { get; set; }
public int PressureIndex { get; set; }
public int CurveIndex { get; set; }
}
class StationMapping
{
public int Flag { get; set; }
public string FlowId { get; set; }
public string PressureId { get; set; }
public int FlowIndex { get; set; }
public int PressureIndex { get; set; }
}
static List GetStationMappingList()
{
var list = new List();
var dn2400 = new StationMapping();
var dn2700 = new StationMapping();
var jd1 = new StationMapping();
var jd2 = new StationMapping();
var jd3 = new StationMapping();
jd1.Flag = GlobalHelper.FlagJD1;
jd2.Flag = GlobalHelper.FlagJD2;
jd3.Flag = GlobalHelper.FlagJD3;
dn2400.Flag = GlobalHelper.FlagDN2400;
dn2700.Flag = GlobalHelper.FlagDN2700;
jd1.FlowId = "Pjd1";
jd2.FlowId = "Pjd2";
jd3.FlowId = "Pjd3";
dn2400.FlowId = "Pdn2400";
dn2700.FlowId = "Pdn2700";
jd1.PressureId = "Jjd1";
jd2.PressureId = "Jjd2";
jd3.PressureId = "Jjd3";
dn2400.PressureId = "Jdn2400";
dn2700.PressureId = "Jdn2700";
list.Add(jd1);
list.Add(jd2);
list.Add(jd3);
list.Add(dn2400);
list.Add(dn2700);
return list;
}
static List GetPumpModelMappingList()
{
var list = new List();
var pump11 = new PumpMapping();
var pump12 = new PumpMapping();
var pump13 = new PumpMapping();
var pump14 = new PumpMapping();
var pump15 = new PumpMapping();
var pump16 = new PumpMapping();
var pump17 = new PumpMapping();
var pump18 = new PumpMapping();
var pump21 = new PumpMapping();
var pump22 = new PumpMapping();
var pump23 = new PumpMapping();
var pump24 = new PumpMapping();
var pump25 = new PumpMapping();
var pump26 = new PumpMapping();
var pump27 = new PumpMapping();
pump11.Flag = GlobalHelper.Flag11;
pump12.Flag = GlobalHelper.Flag12;
pump13.Flag = GlobalHelper.Flag13;
pump14.Flag = GlobalHelper.Flag14;
pump15.Flag = GlobalHelper.Flag15;
pump16.Flag = GlobalHelper.Flag16;
pump17.Flag = GlobalHelper.Flag17;
pump18.Flag = GlobalHelper.Flag18;
pump21.Flag = GlobalHelper.Flag21;
pump22.Flag = GlobalHelper.Flag22;
pump23.Flag = GlobalHelper.Flag23;
pump24.Flag = GlobalHelper.Flag24;
pump25.Flag = GlobalHelper.Flag25;
pump26.Flag = GlobalHelper.Flag26;
pump27.Flag = GlobalHelper.Flag27;
pump11.PumpId = "Pump11";
pump12.PumpId = "Pump12";
pump13.PumpId = "Pump13";
pump14.PumpId = "Pump14";
pump15.PumpId = "Pump15";
pump16.PumpId = "Pump16";
pump17.PumpId = "Pump17";
pump18.PumpId = "Pump18";
pump21.PumpId = "Pump21";
pump22.PumpId = "Pump22";
pump23.PumpId = "Pump23";
pump24.PumpId = "Pump24";
pump25.PumpId = "Pump25";
pump26.PumpId = "Pump26";
pump27.PumpId = "Pump27";
pump11.FlowId = "";
pump12.FlowId = "";
pump13.FlowId = "";
pump14.FlowId = "";
pump15.FlowId = "";
pump16.FlowId = "";
pump17.FlowId = "";
pump18.FlowId = "";
pump21.FlowId = "Ppump21";
pump22.FlowId = "Ppump22";
pump23.FlowId = "Ppump23";
pump24.FlowId = "Ppump24";
pump25.FlowId = "Ppump25";
pump26.FlowId = "Ppump26";
pump27.FlowId = "Ppump27";
pump11.PressureId = "Jpump11";
pump12.PressureId = "Jpump12";
pump13.PressureId = "Jpump13";
pump14.PressureId = "Jpump14";
pump15.PressureId = "Jpump15";
pump16.PressureId = "Jpump16";
pump17.PressureId = "Jpump17";
pump18.PressureId = "Jpump18";
pump21.PressureId = "Jpump21";
pump22.PressureId = "Jpump22";
pump23.PressureId = "Jpump23";
pump24.PressureId = "Jpump24";
pump25.PressureId = "Jpump25";
pump26.PressureId = "Jpump26";
pump27.PressureId = "Jpump27";
pump11.CurveId = "11";
pump12.CurveId = "12";
pump13.CurveId = "13";
pump14.CurveId = "14";
pump15.CurveId = "15";
pump16.CurveId = "16";
pump17.CurveId = "17";
pump18.CurveId = "18";
pump21.CurveId = "21";
pump22.CurveId = "22";
pump23.CurveId = "23";
pump24.CurveId = "24";
pump25.CurveId = "25";
pump26.CurveId = "26";
pump27.CurveId = "27";
list.Add(pump11);
list.Add(pump12);
list.Add(pump13);
list.Add(pump14);
list.Add(pump15);
list.Add(pump16);
list.Add(pump17);
list.Add(pump18);
list.Add(pump21);
list.Add(pump22);
list.Add(pump23);
list.Add(pump24);
list.Add(pump25);
list.Add(pump26);
list.Add(pump27);
return list;
}
#endregion
#endregion
#region 调度决策
///
/// 决策计算
///
[Route("DecisionCalc@V1.0")]
[HttpPost]
public DecisionCalcOutput DecisionCalc([Required] ScheduleCalcInput input)
{
var receipt_time = DateTime.Now;
var request_id = Yw.YitIdHelper.NextId();
var station_info = _service_station.Get();
if (station_info == null)
{
throw Yw.Dto.YOops.Oh(Yw.Dto.eResultCode.Error, Yw.Dto.InternalErrorCodes.A001, $"基础信息文件缺失!");
}
var target_flow1 = input.TargetFlow1;
var target_mpa_pressure1 = input.TargetPressure1;
var target_flow2 = input.TargetFlow2;
var target_mpa_pressure2 = input.TargetPressure2;
var target_pressure1 = Curve.PumpCalculateHelper.Mpa2M(target_mpa_pressure1);
var target_pressure2 = Curve.PumpCalculateHelper.Mpa2M(target_mpa_pressure2);
GlobalHelper.GetMonitorRecordList(receipt_time, out List monitor_record_list, true);
var station1 = station_info.Station1;
var station2 = station_info.Station2;
var station1_schedule_config = _service_schedule_config.GetStation1();
var station2_schedule_config = _service_schedule_config.GetStation2();
var station1_flag_list = GlobalHelper.Station1FlagList;
var station2_flag_list = GlobalHelper.Station2FlagList;
var analysis_deviation_list = _service_analysis_deviation.GetList();
var analysis_factor_list = _service_analysis_factor.GetList();
GlobalHelper.GetStationOpenFlagList(monitor_record_list, out List station1_open_flag_list, out List station2_open_flag_list);
GlobalHelper.GetStationFlagStateList(monitor_record_list, out List station1_flag_maintenance_list, out List station2_maintenance_flag_list, out List station1_priority_flag_list, out List station2_priority_flag_list);
GlobalHelper.GetFlagInletWaterLevelDict(monitor_record_list, out Dictionary station1_flag_inlet_water_level_dict, out Dictionary station2_flag_inlet_water_level_dict);
GlobalHelper.GetPipeFlagFlowAndPressureDict(monitor_record_list, out Dictionary> station1_pipe_flag_flow_pressure_dict, out Dictionary> station2_pipe_flag_flow_pressure_dict);
GlobalHelper.GetFlagRpmAndFlowAndPressureDict(monitor_record_list, out Dictionary> station1_flag_rpm_pressure_dict, out Dictionary> station2_flag_rpm_flow_pressure_dict);
if (station1_flag_maintenance_list != null && station1_flag_maintenance_list.Any())
{
ScheduleLog.Info(request_id, "机泵检修", $"1输水:{Yw.Untity.IntListHelper.ToString(station1_flag_maintenance_list)}");
station1_schedule_config.MustCloseFlagList.AddRange(station1_flag_maintenance_list);
}
if (station2_maintenance_flag_list != null && station2_maintenance_flag_list.Any())
{
ScheduleLog.Info(request_id, "机泵检修", $"2输水:{Yw.Untity.IntListHelper.ToString(station2_maintenance_flag_list)}");
station2_schedule_config.MustCloseFlagList.AddRange(station2_maintenance_flag_list);
}
if (station1_priority_flag_list != null && station1_priority_flag_list.Any())
{
ScheduleLog.Info(request_id, "机泵优先", $"1输水:{Yw.Untity.IntListHelper.ToString(station1_priority_flag_list)}");
station1_schedule_config.MustOpenFlagList.AddRange(station1_priority_flag_list);
}
if (station2_priority_flag_list != null && station2_priority_flag_list.Any())
{
ScheduleLog.Info(request_id, "机泵优先", $"2输水:{Yw.Untity.IntListHelper.ToString(station2_priority_flag_list)}");
station2_schedule_config.MustOpenFlagList.AddRange(station2_priority_flag_list);
}
analysis_deviation_list = null;
var helper = new Service.ScheduleHelper();
helper.Initial(station1_open_flag_list, station1_schedule_config, analysis_deviation_list);
var optimal_combine1 = helper.GetOptAnaCombine(station1, station1_flag_inlet_water_level_dict, target_flow1, target_pressure1);
helper.Initial(station2_open_flag_list, station2_schedule_config, analysis_deviation_list);
var optimal_combine2 = helper.GetOptAnaCombine(station2, station2_flag_inlet_water_level_dict, target_flow2, target_pressure2);
if (optimal_combine1 == null && optimal_combine2 == null)
{
throw Yw.Dto.YOops.Oh(Yw.Dto.eResultCode.Error, Yw.Dto.InternalErrorCodes.A001, $"计算失败!");
}
var pump_id_mapping_dict = GlobalHelper.ModelPumpIdMappingDict;
var pattern_id_mapping_dict = GlobalHelper.ModelPatternIdMappingDict;
var output = new DecisionCalcOutput();
output.PumpCompares1 = new List();
output.PumpCompares2 = new List();
if (optimal_combine1 != null)
{
optimal_combine1.Round();
var pump_bp_dict = station1.ToDictionary(x => x.Flag, x => x.IsBp);
foreach (var flag in GlobalHelper.Station1FlagList)
{
var name = $"{flag}#泵";
var rpm_pressure = station1_flag_rpm_pressure_dict[flag];
var wl = station1_flag_inlet_water_level_dict[flag];
var compare = new DecisionPumpCompare();
compare.SrcWaterLevel = wl;
compare.Name = name;
compare.SrcSpeed = rpm_pressure.Item1;
compare.SrcPressure = rpm_pressure.Item2;
output.PumpCompares1.Add(compare);
var fre_pump = optimal_combine1.AnaFrePumps.Find(x => x.Flag == flag);
if (fre_pump != null)
{
var pressure = fre_pump.PressureDiff + wl;
compare.CalcSpeed = fre_pump.Speed;
compare.DiffSpeed = compare.CalcSpeed - compare.SrcSpeed;
compare.CalcFlow = fre_pump.Flow;
//compare.DiffFlow = compare.CalcFlow - compare.SrcFlow;
compare.DiffFlow = null;
compare.CalcPressure = pressure;
compare.DiffPressure = compare.CalcPressure - compare.SrcPressure;
if (compare.DiffSpeed.HasValue)
compare.DiffSpeed = Math.Round(compare.DiffSpeed.Value, 1);
if (compare.DiffPressure.HasValue)
compare.DiffPressure = Math.Round(compare.DiffPressure.Value, 1);
}
}
}
if (optimal_combine2 != null)
{
optimal_combine2.Round();
var pump_bp_dict = station2.ToDictionary(x => x.Flag, x => x.IsBp);
foreach (var flag in GlobalHelper.Station2FlagList)
{
var name = $"{flag}#泵";
var rpm_pressure = station2_flag_rpm_flow_pressure_dict[flag];
var wl = station2_flag_inlet_water_level_dict[flag];
var compare = new DecisionPumpCompare();
compare.Name = name;
compare.SrcWaterLevel = wl;
compare.SrcSpeed = rpm_pressure.Item1;
compare.SrcFlow = rpm_pressure.Item2;
compare.SrcPressure = rpm_pressure.Item3;
output.PumpCompares2.Add(compare);
var fre_pump = optimal_combine2.AnaFrePumps.Find(x => x.Flag == flag);
if (fre_pump != null)
{
var pressure = fre_pump.PressureDiff + wl;
compare.CalcSpeed = fre_pump.Speed;
compare.DiffSpeed = compare.CalcSpeed - compare.SrcSpeed;
compare.CalcFlow = fre_pump.Flow;
compare.DiffFlow = compare.CalcFlow - compare.SrcFlow;
compare.CalcPressure = pressure;
compare.DiffPressure = compare.CalcPressure - compare.SrcPressure;
if (compare.DiffSpeed.HasValue)
compare.DiffSpeed = Math.Round(compare.DiffSpeed.Value, 1);
if (compare.DiffPressure.HasValue)
compare.DiffPressure = Math.Round(compare.DiffPressure.Value, 1);
if (compare.DiffFlow.HasValue)
compare.DiffFlow = Math.Round(compare.DiffFlow.Value, 1);
}
}
}
return output;
}
#endregion
#region 热力图
///
/// 通过日期区间获取热力区间列表
///
[Route("GetRectListOfDayRange@V1.0")]
[HttpGet]
public List GetRectListOfDayRange([FromQuery][Required] QueryEtaAnalyRunHeatRectInput input)
{
var list = new IStation.Service.EtaMultiRealRecord().GetRunQHETRectByObjectOfDayRange
(input.Station, input.Qspace, input.Hspace, input.StartDay, input.EndDay);
var vm_list = list?.Select(x => new EtaAnalyRunHeatRectItemDto()
{
Qmax = x.Qmax,
Qmin = x.Qmin,
Hmax = x.Hmax,
Hmin = x.Hmin,
Eavg = x.Eavg,
Tsum = x.Tsum
}).ToList();
return vm_list;
}
///
/// 通过日期区间获取热力区间列表(包含坐标信息)
///
[Route("GetRectListExOfDayRange@V1.0")]
[HttpGet]
public EtaAnalyRunHeatRectListDto GetRectListExOfDayRange([FromQuery][Required] QueryEtaAnalyRunHeatRectInput input)
{
var list = new IStation.Service.EtaMultiRealRecord().GetRunQHETRectListByObjectOfDayRange
(input.Station, input.Qspace, input.Hspace, input.StartDay, input.EndDay);
var vm = new EtaAnalyRunHeatRectListDto();
vm.Qmax = list.Qmax;
vm.Qmin = list.Qmin;
vm.Qspace = list.Qspace;
vm.Hmax = list.Hmax;
vm.Hmin = list.Hmin;
vm.Hspace = list.Hspace;
vm.Items = list.RectList?.Select(x => new EtaAnalyRunHeatRectItemDto()
{
Qmax = x.Qmax,
Qmin = x.Qmin,
Hmax = x.Hmax,
Hmin = x.Hmin,
Eavg = x.Eavg,
Tsum = x.Tsum
}).ToList();
return vm;
}
///
/// 通过日期区间获取热力区间详细列表
///
[Route("GetRectDetailListOfDayRange@V1.0")]
[HttpGet]
public List GetRectDetailListOfDayRange([FromQuery][Required] QueryEtaAnalyRunHeatRectDetailInput input)
{
var list = new IStation.Service.EtaMultiRealRecord().GetRunSummaryContentByStationOfQHDayRange
(input.Station, input.Qmin, input.Qmax, input.Hmin, input.Hmax, input.StartDay, input.EndDay);
if (list == null || list.Count < 1)
{
return default;
}
var vm_list = new List();
foreach (var item in list)
{
var vm = new EtaAnalyRunHeatRectDetailItemDto();
vm.Qavg = item.Qavg;
vm.Havg = item.Havg;
vm.Pavg = item.Pavg;
vm.Eavg = item.Eavg;
vm.Tsum = item.Tsum;
vm.Count = item.RunningCount;
var nameList = new List();
for (int i = 0; i < item.RunningFlag.Count; i++)
{
nameList.Add(item.RunningFlag[i] + "#泵");
}
vm.Name = string.Join(",", nameList);
vm_list.Add(vm);
}
return vm_list;
}
#endregion
}
}