using Microsoft.AspNetCore.Mvc; using System.Net; using System.Net.Http.Headers; using Microsoft.Extensions.Hosting.Internal; using Microsoft.AspNetCore.Http.Extensions; using IStation.Untity; using Furion.DynamicApiController; using System.ComponentModel.DataAnnotations; using Mapster; using Microsoft.AspNetCore.Authorization; using SqlSugar; namespace IStation.Application { /// /// ShysDispatchAna /// [Route("OpenApi/DispatchAna/SHYS")] [ApiDescriptionSettings("OpenApi", Name = "上海原水调度分析", Order = 1000)] public class DispatchAna_ShysController : IDynamicApiController { /// /// 计算保持的方案 /// [AllowAnonymous] [NonUnify] [Route("CalcuKeepDispatch")] [HttpPost] public IStation.Application.DispatchAnaSchemeOutput CalcuKeepDispatch([Required] StationDispatchExInput input) { if (input == null) return default; //众毅连续两次调用解决方案 if (!string.IsNullOrEmpty(_lastFlowId)) { if (_lastFlowId == input.flowId) { LogHelper.Debug($"众毅重复入参:{JsonHelper.Object2Json(input)}"); return default; } } _lastFlowId = input.flowId; LogHelper.Debug($"众毅入参:{JsonHelper.Object2Json(input)}"); var url_sg = Settings.WebApi.OpenApi.SanGaoDispatchUrl; var responseText = HttpRequestHelper.Post(url_sg, JsonHelper.Object2Json(input)); LogHelper.Debug($"三高出参:{responseText}"); var result_sg = JsonHelper.Json2Object(responseText); if (result_sg == null) return default; string error_info = null; switch (input.type) { case 1://长兴泵站 { var result = shys_cxd(input, result_sg, out error_info); LogHelper.Debug($"义维出参:{JsonHelper.Object2Json(result)}"); return result; } default: return default; } } private static string _lastFlowId = null; /// /// 计算保持的方案 /// [AllowAnonymous] [NonUnify] [Route("CalcuKeepDispatch@Debug")] [HttpPost] public DispatchAnaSchemeOutput CalcuKeepDispatchDebug([Required] StationDispatchExInput input) { if (input == null) return default; var responseText = System.IO.File.ReadAllText(@"D:\result.txt");//(测试用的) var result_sg = JsonHelper.Json2Object(responseText); if (result_sg == null) return default; string error_info = null; switch (input.type) { case 1://长兴泵站 { return shys_cxd(input, result_sg, out error_info); } default: return default; } } /// /// 计算长兴保持的方案 /// [AllowAnonymous] [NonUnify] [Route("CalcuCxKeepDispatch@Debug")] [HttpGet] public DispatchAnaSchemeOutput CalcuCxKeepDispatchDebug ( double waterLevel,//水位 double flow1,//管道1流量 double press1,//管道1压力 double valveStatus1,//管道1阀门状态 double flow2,//管道2流量 double press2,//管道2压力 double valveStatus2,//管道2阀门状态 int middleValveStatus,//中间阀门状态 int runStatus1,//1#机泵运行状态 int runStatus2,//2#机泵运行状态 int runStatus3,//3#机泵运行状态 int runStatus4//4#机泵运行状态 ) { waterLevel = 2.558; flow1 = 2573; flow2 = 0; press1 = 9.5527 / 102; press2 = 9.5527 / 102; valveStatus1 = 1; valveStatus2 = 0; middleValveStatus = 1; runStatus1 = 1; runStatus2 = 0; runStatus3 = 0; runStatus4 = 1; var input = new StationDispatchExInput(); input.flowId = "测试"; input.type = 1; input.factory = new List() { new FactoryDispatchInput() { id = 1, value = 200 } }; var result_sg = new DispatchFactoryDto(); result_sg.result = new List(); result_sg.result.Add(new DispatchBranchDto() { key = "stationCX_1#_flow", value = flow1 }); result_sg.result.Add(new DispatchBranchDto() { key = "stationCX_1#_pressure", value = press1 }); result_sg.result.Add(new DispatchBranchDto() { key = "stationCX_2#_flow", value = flow2 }); result_sg.result.Add(new DispatchBranchDto() { key = "stationCX_2#_pressure", value = press2 }); result_sg.scada = new List(); result_sg.scada.Add(new DispatchScadaDto() { tagname = "_0402010404030103001", value = waterLevel }); result_sg.scada.Add(new DispatchScadaDto() { tagname = "_0402010403150103003", value = middleValveStatus }); result_sg.scada.Add(new DispatchScadaDto() { tagname = "_0402010403010101003", value = runStatus1 }); result_sg.scada.Add(new DispatchScadaDto() { tagname = "_0402010403010201003", value = runStatus2 }); result_sg.scada.Add(new DispatchScadaDto() { tagname = "_0402010403010301003", value = runStatus3 }); result_sg.scada.Add(new DispatchScadaDto() { tagname = "_0402010403010401003", value = runStatus4 }); result_sg.scada.Add(new DispatchScadaDto() { tagname = "_0402010403150101003", value = valveStatus1 }); result_sg.scada.Add(new DispatchScadaDto() { tagname = "_0402010403150102003", value = valveStatus2 }); string error_info = null; switch (input.type) { case 1://长兴泵站 { return shys_cxd(input, result_sg, out error_info); } default: return default; } } /// /// 长兴岛 /// /// /// /// /// private IStation.Application.DispatchAnaSchemeOutput shys_cxd( StationDispatchExInput input, DispatchFactoryDto result_sg, out string error_info) { error_info = null; var complex_request_paras = new IStation.Calculation.DispatchAna.Model.RequestParasComplex(); complex_request_paras.CorpID = 4; complex_request_paras.StationID = 2; //水位 var scada_water = result_sg.scada.Find(t => t.tagname == "_0402010404030103001"); double water_level = 0; if (scada_water == null) { error_info = "水位无法获取"; return null; } else { water_level = Math.Round( scada_water.value,2); } complex_request_paras.InletPipePara = new List(); complex_request_paras.InletPipePara.Add(new IStation.Calculation.DispatchAna.Model.InletPipePara() { Name = "吸水井液位", Value = water_level }); //1号管与2号管连接阀状态 0402010403150103003 int middleValveStatus = 1; var scada_middle_vavle = result_sg.scada.Find(t => t.tagname == "_0402010403150103003"); if (scada_middle_vavle != null) middleValveStatus = (int)scada_middle_vavle.value; complex_request_paras.ValvePara = new List(); complex_request_paras.ValvePara.Add(new IStation.Calculation.DispatchAna.Model.ValvePara() { Name = "中间阀门", OpenStatus = middleValveStatus }); //机泵 开停机状态 List machine_id_array = new List { 19, 22, 25, 28 }; List machine_run_status = new List(4); //1号泵开机状态 var scada_runstatus1 = result_sg.scada.Find(t => t.tagname == "_0402010403010101003"); if (scada_runstatus1 != null && (int)scada_runstatus1.value == 1) machine_run_status.Add(machine_id_array[0]); //2号泵开机状态 var scada_runstatus2 = result_sg.scada.Find(t => t.tagname == "_0402010403010201003"); if (scada_runstatus2 != null && (int)scada_runstatus2.value == 1) machine_run_status.Add(machine_id_array[1]); //3号泵开机状态 var scada_runstatus3 = result_sg.scada.Find(t => t.tagname == "_0402010403010301003"); if (scada_runstatus3 != null && (int)scada_runstatus3.value == 1) machine_run_status.Add(machine_id_array[2]); //4号泵开机状态 var scada_runstatus4 = result_sg.scada.Find(t => t.tagname == "_0402010403010401003"); if (scada_runstatus4 != null && (int)scada_runstatus4.value == 1) machine_run_status.Add(machine_id_array[3]); if (machine_run_status.Count == 0) { error_info = "没有任何泵开启.无法计算"; return null; } //1号管 IStation.Calculation.DispatchAna.Model.OutletPipePara pipe1 = new Calculation.DispatchAna.Model.OutletPipePara(); pipe1.Name = "一号管"; var flow1 = result_sg.result.Find(x => x.key == "stationCX_1#_flow"); if (flow1 == null) { error_info = "一号管流量无法获取"; return null; } else { pipe1.TargetFlow = Math.Round(flow1.value,0); } var press1 = result_sg.result.Find(x => x.key == "stationCX_1#_pressure"); if (press1 == null) { error_info = "一号管压力无法获取"; return null; } else { pipe1.TargetPress = Math.Round(press1.value,4); } var pipe1_val = result_sg.scada.Find(t => t.tagname == "_0402010403150101003"); if (pipe1_val != null) { pipe1.ValveStatus = (int)pipe1_val.value; } //2号管 IStation.Calculation.DispatchAna.Model.OutletPipePara pipe2 = new Calculation.DispatchAna.Model.OutletPipePara(); pipe2.Name = "二号管"; var flow2 = result_sg.result.Find(x => x.key == "stationCX_2#_flow"); if (flow2 == null) { error_info = "二号管流量无法获取"; return null; } else { pipe2.TargetFlow = Math.Round(flow2.value,0); } var press2 = result_sg.result.Find(x => x.key == "stationCX_2#_pressure"); if (press2 == null) { error_info = "二号管压力无法获取"; return null; } else { pipe2.TargetPress = Math.Round(press2.value,4); } var pipe2_val = result_sg.scada.Find(t => t.tagname == "_0402010403150102003"); if (pipe2_val != null) { pipe2.ValveStatus = (int)pipe2_val.value; } complex_request_paras.OutletPipePara = new List(2); complex_request_paras.OutletPipePara.Add(pipe1); complex_request_paras.OutletPipePara.Add(pipe2); complex_request_paras.SchemeSortType = Calculation.DispatchAna.Model.eAnaSchemeSortType.功率; complex_request_paras.SchemeNumber = 1; //构造计算器 var calulator = IStation.Calculation.DispatchAnalyCalculatorFactory.CreateKeepStatusCalculator(4, IStation.ObjectType.Station, 2, null); calulator.IntialRequest(complex_request_paras, null, machine_run_status); #region 实时量 double real_total_flow_pipe1 = 0; var pipe1_val_flow_real = result_sg.scada.Find(t => t.tagname == "_0402010403030002001"); if (pipe1_val_flow_real != null && pipe1_val_flow_real.value > 100) {//实时量, stationCX_2#_flow" 三高给的目标量 real_total_flow_pipe1 = pipe1_val_flow_real.value; } double real_oulet_press_pipe1 = 0; var pipe1_val_press_real = result_sg.scada.Find(t => t.tagname == "_0402010403030002005"); if (pipe1_val_press_real != null) {//实时量, "stationCX_2#_flow" 是 三高给的目标量 real_oulet_press_pipe1 = pipe1_val_press_real.value; } double real_total_flow_pipe2 = 0; var pipe2_val_flow_real = result_sg.scada.Find(t => t.tagname == "_0402010403030002002"); if (pipe2_val_flow_real != null && pipe2_val_flow_real.value > 100) { real_total_flow_pipe2 = pipe2_val_flow_real.value; } double real_oulet_press_pipe2 = 0; var pipe2_val_press_real = result_sg.scada.Find(t => t.tagname == "_0402010403030002006"); if (pipe2_val_press_real != null) {//实时量, stationCX_2#_flow" 三高给的目标量 real_oulet_press_pipe2 = pipe2_val_press_real.value; } #endregion //出方案 var scheme = calulator.Calc(out error_info); if (scheme == null) return default; var result = new IStation.Application.DispatchAnaSchemeOutput(); result.flowId = input.flowId; result.Q = scheme.TotalWrkQ; result.H = scheme.TotalWrkH; result.E = scheme.TotalWrkE; result.P = scheme.TotalWrkP; result.WP = scheme.WP; result.UWP = scheme.UWP; result.Scheme = new DispatchAnaCurrentOutput(); result.Scheme.MiddleValveStatus = middleValveStatus; result.Scheme.Pipes = new List(); result.Scheme.Pipes.Add( new DispatchAnaCurrentOutput.PipeParaOutput() { Name = "1#管", TargetFlow = pipe1.TargetFlow, TargetPressure = pipe1.TargetPress, CurrentFlow = real_total_flow_pipe1, CurrentPressure = real_oulet_press_pipe1 } ); result.Scheme.Pipes.Add( new DispatchAnaCurrentOutput.PipeParaOutput() { Name = "2#管", TargetFlow = pipe2.TargetFlow, TargetPressure = pipe2.TargetPress, CurrentFlow = real_total_flow_pipe2, CurrentPressure = real_oulet_press_pipe2 } ); List machine_frq_hz_target_name = new List { "_0402010403010112007", "_0402010403010212019", "_0402010403010312007", "_0402010403010412019" }; List machine_speed_target_name = new List { "_0402010403010112008", "_0402010403010212020", "_0402010403010312008", "_0402010403010412020" }; List machine_names = new List { "长兴泵房1号机泵", "长兴泵房2号机泵", "长兴泵房3号机泵", "长兴泵房4号机泵" }; result.Pumps = new List(); foreach (IStation.Calculation.DispatchAna.Model.AnaSchemeItem item in scheme.Items) { var pump_item = new IStation.Application.DispatchAnaSchemeItemOutput(); pump_item.Id = item.MachineID.ToString(); pump_item.Index = machine_id_array.IndexOf(item.MachineID); pump_item.Name = item.MachineName; pump_item.IsFrequency = item.IsFrequency; pump_item.IsCurveExtend = item.IsCurveExtend; pump_item.Q = item.WorkPointQ; pump_item.H = item.WorkPointH; pump_item.E = item.WorkPointE; pump_item.P = item.WorkPointP; pump_item.Frequency = item.Frequence; pump_item.Speed = item.Speed; if (pump_item.Index >= 0 && pump_item.Index < 4) { //获取实时频率 var fr_hz_tag_name = machine_frq_hz_target_name[pump_item.Index]; var current_val_fr_hz = result_sg.scada.Find(t => t.tagname == fr_hz_tag_name); if (current_val_fr_hz != null && current_val_fr_hz.value > 10) { pump_item.CurrentFrequency = current_val_fr_hz.value; } //获取实时转速 var speed_tag_name = machine_speed_target_name[pump_item.Index]; var current_val_speed = result_sg.scada.Find(t => t.tagname == speed_tag_name); if (current_val_speed != null && current_val_speed.value > 10) { pump_item.CurrentSpeed = current_val_speed.value; } //机泵名称 pump_item.Name = machine_names[pump_item.Index]; } result.Pumps.Add(pump_item); } if (machine_run_status.Count == 1) {//保证开一台泵时, 流量大 频率也大, 流量小 , 频率也小 if (pipe1.TargetFlow + pipe2.TargetFlow > 100) { double current_total_flow = 0; if (pipe1.TargetFlow > 100) current_total_flow = pipe1.TargetFlow; else current_total_flow = pipe2.TargetFlow; var open_pump = result.Pumps.First(); var fr_hz_tag_name = machine_frq_hz_target_name[open_pump.Index]; var current_val_fr_hz = result_sg.scada.Find(t => t.tagname == fr_hz_tag_name); if (current_val_fr_hz != null && current_val_fr_hz.value > 10) { if (current_total_flow < scheme.TotalWrkQ && current_val_fr_hz.value > open_pump.Frequency) {//保证趋势正确 open_pump.Frequency = Math.Round(current_val_fr_hz.value * scheme.TotalWrkQ / current_total_flow, 1); } else if (current_total_flow > scheme.TotalWrkQ && current_val_fr_hz.value < open_pump.Frequency) {//保证趋势正确 open_pump.Frequency = Math.Round(current_val_fr_hz.value * scheme.TotalWrkQ / current_total_flow, 1); } else {//原水反馈 , 用曲线计算, 频率偏低, 人为增加0.5HZ if (open_pump.Frequency < 49.5) { //open_pump.Speed = Math.Round // (open_pump.Speed * (open_pump.Frequency + 0.5) / (open_pump.Frequency),0); open_pump.Frequency = open_pump.Frequency + 0.5; open_pump.Speed = Math.Round(740 * open_pump.Frequency / 50, 1); } } } } } else { result.Pumps.ForEach(x => {//原水反馈 , 用曲线计算, 频率偏低, 人为增加0.5HZ if (x.Frequency > 10) { if (x.Frequency < 49.5) { //x.Speed = Math.Round // (x.Speed * (x.Frequency + 0.5) / (x.Frequency), 0); x.Frequency = x.Frequency + 0.5; x.Speed = Math.Round(740 * x.Frequency / 50, 1); } } }); } result.Pumps.ForEach(x => {//再检查一下转速 if (x.Frequency > 10) { x.Frequency = Math.Round(x.Frequency, 1); x.Speed = Math.Round(740 * x.Frequency / 50, 1); } if (x.Frequency >= 50) { x.Frequency = 50; x.Speed = 740; } }); return result; } } }