namespace IStation.Application
|
{
|
/// <summary>
|
/// 调度决策
|
/// </summary>
|
[AllowAnonymous]
|
[Route("Web/ScheduleDecision")]
|
[ApiDescriptionSettings("Web", Name = "决策调度", Order = 2)]
|
public class ScheduleDecision_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);
|
|
|
/// <summary>
|
/// 获取监测值
|
/// </summary>
|
[Route("GetMonitorValue@V1.0")]
|
[HttpGet]
|
public ScheduleMonitorOutput GetMonitorValue()
|
{
|
|
GlobalHelper.GetMonitorRecordList(DateTime.Now, out List<Model.MonitorRecord> monitor_record_list, true);
|
GlobalHelper.GetPipeFlagFlowAndPressureDict(monitor_record_list, out Dictionary<int, Tuple<double?, double?>> station1_pipe_flag_flow_pressure_dict, out Dictionary<int, Tuple<double?, double?>> 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;
|
}
|
|
|
/// <summary>
|
/// 计算
|
/// </summary>
|
[Route("Calculate@V1.0")]
|
[HttpPost]
|
public DecisionCalcOutput 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<Model.MonitorRecord> 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<int> station1_open_flag_list, out List<int> station2_open_flag_list);
|
GlobalHelper.GetStationFlagStateList(monitor_record_list, out List<int> station1_flag_maintenance_list, out List<int> station2_maintenance_flag_list, out List<int> station1_priority_flag_list, out List<int> station2_priority_flag_list);
|
GlobalHelper.GetFlagInletWaterLevelDict(monitor_record_list, out Dictionary<int, double> station1_flag_inlet_water_level_dict, out Dictionary<int, double> station2_flag_inlet_water_level_dict);
|
GlobalHelper.GetPipeFlagFlowAndPressureDict(monitor_record_list, out Dictionary<int, Tuple<double?, double?>> station1_pipe_flag_flow_pressure_dict, out Dictionary<int, Tuple<double?, double?>> station2_pipe_flag_flow_pressure_dict);
|
GlobalHelper.GetFlagRpmAndFlowAndPressureDict(monitor_record_list, out Dictionary<int, Tuple<double?, double?>> station1_flag_rpm_pressure_dict, out Dictionary<int, Tuple<double?, double?, double?>> 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<DecisionPumpCompare>();
|
output.PumpCompares2 = new List<DecisionPumpCompare>();
|
|
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 = Math.Round(pressure, 1);
|
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 = Math.Round(pressure,1);
|
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;
|
}
|
|
|
}
|
}
|