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
|
{
|
/// <summary>
|
/// ShysDispatchAna
|
/// </summary>
|
[Route("OpenApi/DispatchAna/SHYS")]
|
[ApiDescriptionSettings("OpenApi", Name = "上海原水调度分析", Order = 1000)]
|
public class DispatchAna_ShysController : IDynamicApiController
|
{
|
/// <summary>
|
/// 计算保持的方案
|
/// </summary>
|
[AllowAnonymous]
|
[NonUnify]
|
[Route("CalcuKeepDispatch")]
|
[HttpPost]
|
public IStation.Application.DispatchAnaSchemeOutput CalcuKeepDispatch([Required] StationDispatchExInput input)
|
{
|
if (input == null)
|
return default;
|
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<DispatchFactoryDto>(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;
|
}
|
}
|
|
/// <summary>
|
/// 计算保持的方案
|
/// </summary>
|
[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<DispatchFactoryDto>(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;
|
}
|
}
|
|
/// <summary>
|
/// 计算长兴保持的方案
|
/// </summary>
|
[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<FactoryDispatchInput>() { new FactoryDispatchInput() { id=1,value=200} };
|
|
var result_sg = new DispatchFactoryDto();
|
result_sg.result = new List<DispatchBranchDto>();
|
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<DispatchScadaDto>();
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 长兴岛
|
/// </summary>
|
/// <param name="input"></param>
|
/// <param name="result_sg"></param>
|
/// <param name="error_info"></param>
|
/// <returns></returns>
|
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 = scada_water.value;
|
}
|
|
complex_request_paras.InletPipePara = new List<IStation.Calculation.DispatchAna.Model.InletPipePara>();
|
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<IStation.Calculation.DispatchAna.Model.ValvePara>();
|
complex_request_paras.ValvePara.Add(new IStation.Calculation.DispatchAna.Model.ValvePara() { Name = "中间阀门", OpenStatus = middleValveStatus });
|
|
|
//机泵 开停机状态
|
List<long> machine_id_array = new List<long> { 19, 22, 25, 28 };
|
List<long> machine_run_status = new List<long>(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 = flow1.value;
|
}
|
var press1 = result_sg.result.Find(x => x.key == "stationCX_1#_pressure");
|
if (press1 == null)
|
{
|
error_info = "一号管压力无法获取";
|
return null;
|
}
|
else
|
{
|
pipe1.TargetPress = press1.value;
|
}
|
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 = flow2.value;
|
}
|
|
var press2 = result_sg.result.Find(x => x.key == "stationCX_2#_pressure");
|
if (press2 == null)
|
{
|
error_info = "二号管压力无法获取";
|
return null;
|
}
|
else
|
{
|
pipe2.TargetPress = press2.value;
|
}
|
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<IStation.Calculation.DispatchAna.Model.OutletPipePara>(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 && pipe1_val_press_real.value > 100)
|
{//实时量, 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 && pipe2_val_press_real.value > 100)
|
{//实时量, 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<DispatchAnaCurrentOutput.PipeParaOutput>();
|
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<string> machine_frq_hz_target_name = new List<string> {
|
"_0402010403010112007",
|
"_0402010403010212019",
|
"_0402010403010312007",
|
"_0402010403010412019" };
|
|
List<string> machine_speed_target_name = new List<string> {
|
"_0402010403010112008",
|
"_0402010403010212020",
|
"_0402010403010312008",
|
"_0402010403010412020" };
|
|
List<string> machine_names = new List<string> {
|
"长兴泵房1号机泵",
|
"长兴泵房2号机泵",
|
"长兴泵房3号机泵",
|
"长兴泵房4号机泵" };
|
|
result.Pumps = new List<IStation.Application.DispatchAnaSchemeItemOutput>();
|
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, 2);
|
}
|
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, 2);
|
}
|
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 =>
|
{//原水反馈 , 用曲线计算, 频率偏低, 人为增加0.5HZ
|
if (x.Frequency > 10)
|
{
|
x.Speed = Math.Round(740 * x.Frequency / 50, 1);
|
}
|
if (x.Frequency >= 50)
|
{
|
x.Frequency = 50;
|
x.Speed = 740;
|
}
|
});
|
return result;
|
}
|
|
|
}
|
}
|