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;
|
|
|
namespace IStation.Application
|
{
|
/// <summary>
|
/// 调度分析(标准版,简易版)
|
/// </summary>
|
[Route("Dispatch/Analy/Std")]
|
[NonUnify]
|
[ApiDescriptionSettings("Eta", Name = "调度分析", Order = 595)]
|
public class DispatchAnaly_StdController : IDynamicApiController
|
{
|
/// <summary>
|
/// 获取实时调度信息
|
/// </summary>
|
[Route("GetCurrentInfo@V1.0")]
|
[HttpGet]
|
public IStation.Dto.ApiResult GetCurrentInfo([FromQuery][Required] StationIDUnderCorpInput input)
|
{
|
var pipeLineList = new Service.PipeLine().GetByBelongTypeAndBelongID(input.CorpID, IStation.ObjectType.Station, input.StationID);
|
if (pipeLineList == null || pipeLineList.Count < 1)
|
{
|
throw new Exception("未检索到管路信息");
|
}
|
pipeLineList = pipeLineList.Where(x => x.Catalog == IStation.PipeLine.EnginePump && x.SerialNO != null).OrderBy(x => x.SerialNO).ToList();
|
if (pipeLineList.Count < 1)
|
{
|
throw new Exception("未检索到机泵管路信息");
|
}
|
|
var record_station = new Service.EtaMultiRealRecord().GetLastNormalRecord(input.CorpID, IStation.ObjectType.Station, input.StationID);
|
if (record_station == null)
|
{
|
throw new Exception("获取失败");
|
}
|
if (record_station.RunningCount < 1)
|
{
|
throw new Exception("未开机");
|
}
|
var vm_ana_result = new IStation.Dto.DispatchAna.StationEtaAnaRecord(record_station);
|
var serice_product = new IStation.Service.Product();
|
var name_list = new List<string>();
|
for (int i = 0; i < pipeLineList.Count; i++)
|
{
|
var pipeLine = pipeLineList[i];
|
if (record_station.RunningFlag[i] == RunStatus.Run)
|
{
|
name_list.Add(pipeLine.Name);
|
var record_pipe = new Service.EtaSingleRealRecord().GetLastNormalRecord(pipeLine.CorpID, IStation.ObjectType.PipeLine, pipeLine.ID);
|
if (record_pipe != null)
|
{
|
var pipeBindingList = new Service.PipeLineBinding().GetUseByPipeLineID(pipeLine.CorpID,pipeLine.ID);
|
var pipeEnginePumpBinding = pipeBindingList?.Find(x=>x.BindingType==ObjectType.Product);
|
var enginePump = serice_product.GetEnginePumpByProductID(pipeEnginePumpBinding.CorpID,pipeEnginePumpBinding.BindingID);
|
var pump = serice_product.GetChildPumpByEnginePumpID(pipeEnginePumpBinding.CorpID, pipeEnginePumpBinding.BindingID);
|
|
var vm_item = new IStation.Dto.DispatchAna.PumpEtaAnaRecord(record_pipe);
|
if(pump != null)
|
{
|
vm_item.MachineID = enginePump.ID;
|
vm_item.PumpID = pump.ID;
|
}
|
vm_item.Name = pipeLine.Name;
|
vm_ana_result.Items.Add(vm_item);
|
}
|
}
|
}
|
vm_ana_result.Name = string.Join(",", name_list);
|
|
|
IStation.Calculation.IDispatchAnalyCalculator calc_helper =
|
IStation.Calculation.DispatchAnalyCalculatorFactory.CreateCalculator(input.CorpID,
|
IStation.ObjectType.Station,
|
input.StationID, null);
|
if (calc_helper == null)
|
{
|
return new Dto.ApiResult<IStation.Dto.DispatchAna.StationCurrentInfo>( new IStation.Dto.DispatchAna.StationCurrentInfo(vm_ana_result));
|
}
|
else
|
{
|
string error_info = null;
|
var current_dispatch_info = calc_helper.GetCurrentRecord(input.CorpID, input.StationID, out error_info);
|
if(current_dispatch_info == null)
|
{
|
return new Dto.ApiResult<IStation.Dto.DispatchAna.StationCurrentInfo>(new IStation.Dto.DispatchAna.StationCurrentInfo(vm_ana_result));
|
}
|
else
|
{
|
return new Dto.ApiResult<IStation.Dto.DispatchAna.StationCurrentInfo>(new IStation.Dto.DispatchAna.StationCurrentInfo(vm_ana_result, current_dispatch_info));
|
}
|
}
|
}
|
|
|
|
/// <summary>
|
/// 简易计算
|
/// </summary>
|
/// <param name="request"></param>
|
/// <returns></returns>
|
[Route("SimpleCalcScheme@V1.0")]
|
[HttpPost]
|
public IStation.Dto.ApiResult SimpleCalcScheme(
|
IStation.Dto.DispatchAna.CalcBySimple_Request request)
|
{
|
if (request == null)
|
{
|
return IStation.Dto.ApiResult.Error("request为空");
|
}
|
if (request.CorpID <= 0)
|
{
|
return IStation.Dto.ApiResult.Error("CorpID为空");
|
}
|
if (request.StationID <= 0)
|
{
|
return IStation.Dto.ApiResult.Error("StationID为空");
|
}
|
|
string error_info = null;
|
var complex = request.BuildRequestComplex(out error_info);
|
complex.SchemeSortType = (Calculation.DispatchAna.Model.eAnaSchemeSortType)request.SortType;
|
|
|
List<IStation.Calculation.DispatchAna.Model.MachineRunFilter> machine_run_filter_list = null;
|
if (request.RunStatusList == null)
|
{
|
// IStation.LogHelper.Info("RunStatusList none");
|
}
|
else if (request.RunStatusList.Count() == 0)
|
{
|
// IStation.LogHelper.Info("RunStatusList Count==0");
|
}
|
else //if (request.Setting.OpenStatus != null && request.Setting.OpenStatus.Count > 0)
|
{
|
machine_run_filter_list = new List<IStation.Calculation.DispatchAna.Model.MachineRunFilter>();
|
foreach (var d in request.RunStatusList)
|
{
|
var binding_list = new Service.PipeLineBinding().GetByPipeLineID(request.CorpID, d.MachineID);
|
machine_run_filter_list.Add(new IStation.Calculation.DispatchAna.Model.MachineRunFilter()
|
{
|
MachineID = binding_list.First().ID,
|
RunStatus = d.Status,
|
MaxFlow = -1
|
});
|
}
|
}
|
|
|
|
|
IStation.Calculation.IDispatchAnalyCalculator calc_helper =
|
IStation.Calculation.DispatchAnalyCalculatorFactory.CreateCalculator(request.CorpID,
|
IStation.ObjectType.Station,
|
request.StationID, null);
|
if (calc_helper == null)
|
{
|
return IStation.Dto.ApiResult.Error("Calculator 还未构建");
|
}
|
var machine_run_status = new IStation.Calculation.DispatchAna.Model.MachineRunPara() { MachineRunFilter = machine_run_filter_list };
|
|
//调用CalcOptListByPre 因为可能部分参数还需获取实时数据
|
|
var items = calc_helper.CalcOptListByPre(complex, machine_run_status, out error_info);
|
if (items == null || items.Count() == 0)
|
{
|
return IStation.Dto.ApiResult.Alert(error_info);
|
}
|
else
|
{
|
return new IStation.Dto.ApiResult<List<IStation.Calculation.DispatchAna.Model.AnaScheme>>(items);
|
}
|
}
|
|
|
|
/// <summary>
|
/// 修改频率后,重新计算(简易计算)
|
/// </summary>
|
/// <param name="CorpID">公司ID</param>
|
/// <param name="StationID"></param>
|
/// <param name="TargetQ"></param>
|
/// <param name="TargetH"></param>
|
/// <param name="ItemsParas"></param>
|
/// <returns></returns>
|
[Route("ReSimpleCalcByItemFrequency@V1.0")]
|
[HttpGet]
|
public IStation.Dto.ApiResult ReSimpleCalcByItemFrequency(
|
long CorpID,
|
long StationID,
|
double TargetQ,
|
double TargetH,
|
string ItemsParas)
|
{
|
if (CorpID <= 0)
|
{
|
return IStation.Dto.ApiResult.Error("CorpID为空");
|
}
|
|
if (StationID <= 0)
|
{
|
return IStation.Dto.ApiResult.Error("StationID为空");
|
}
|
if (string.IsNullOrEmpty(ItemsParas))
|
{
|
return IStation.Dto.ApiResult.Error("ItemsParas为空");
|
}
|
|
IStation.Service.Product service_product = new IStation.Service.Product();
|
IStation.Service.PumpCurve service_curve = new IStation.Service.PumpCurve();
|
|
string strItemsParas = ItemsParas;
|
var sss = strItemsParas.Split(',');
|
|
IStation.Calculation.DispatchAna.Model.AnaScheme project = new IStation.Calculation.DispatchAna.Model.AnaScheme();
|
project.Items = new List<IStation.Calculation.DispatchAna.Model.AnaSchemeItem>();
|
|
|
foreach (var s in sss)
|
{
|
if (string.IsNullOrEmpty(s) || s == "null")
|
continue;
|
|
var bbb = s.Split('F');
|
if (bbb.Count() < 2)
|
continue;
|
var frequence = Convert.ToDouble(bbb[1]);
|
var aaa = bbb[0].Split('P');
|
var pumpID = Convert.ToInt64(aaa[1].Replace("P", ""));
|
var machineID = Convert.ToInt64(aaa[0].Replace("M", ""));
|
|
var engin = service_product.GetEnginePumpByProductID(CorpID, machineID);
|
if (engin == null)
|
continue;
|
|
var pump = service_product.GetChildPumpByEnginePumpID(CorpID, engin.ID);
|
if (pump == null)
|
continue;
|
|
var pump_curve = service_curve.GetWorkingByPumpID(CorpID, pumpID);
|
if (pump_curve == null)
|
continue;
|
if (pump_curve.CurveInfo == null)
|
continue;
|
|
IStation.Calculation.DispatchAna.Model.AnaCurveItem anaData = new IStation.Calculation.DispatchAna.Model.AnaCurveItem();
|
int ret = IStation.Calculation.DispatchAna.Common.DispatchAnaGeneralHelper.CalcAnaCurve(
|
pump_curve.CurveInfo.CurveQH,
|
pump_curve.CurveInfo.CurveQP,
|
0, TargetH / 102, 0, 0, frequence, ref anaData);
|
if (ret == -1)
|
break;//-1 表示最大扬程都已经低于目标扬程了, 没必要再迭代了
|
if (ret == 0)
|
continue;
|
|
////效率延长不稳定
|
//var maxCurveQP = pump_curve.GetRatedCurveInfoQP();
|
//var exPointsQP = IStation.Common.FitCurveHelper.GetFitPointsByExtend(, DispatchAnaHelper.ExtendMaxRatio, 50);//延长
|
//double power = Math.Round(IStation.Common.FitCurveHelper.GetFitPointY(exPointsQP, curve.WorkPointQ), 1);
|
|
|
IStation.Calculation.DispatchAna.Model.AnaSchemeItem item = new IStation.Calculation.DispatchAna.Model.AnaSchemeItem(new IStation.Calculation.DispatchAna.Model.MachineDetail(engin, pump, pump_curve), anaData);
|
item.WorkPointP = anaData.WorkPointP;
|
item.WorkPointE = IStation.Common.PumpParaHelper.CalculateE(anaData.WorkPointQ, anaData.WorkPointH, anaData.WorkPointP);
|
|
project.Items.Add(item);
|
}
|
project.TotalWrkQ = (from x in project.Items where x.WorkPointQ > 0 select x.WorkPointQ).Sum();
|
project.TotalWrkP = (from x in project.Items where x.WorkPointP > 0 select x.WorkPointP).Sum();
|
project.UWP = Math.Round(IStation.Calculation.DispatchAna.Common.DispatchAnaGeneralHelper.Calcu_UWP(project.TotalWrkP, project.TotalWrkQ, TargetH), 3);
|
project.WP = Math.Round(IStation.Calculation.DispatchAna.Common.DispatchAnaGeneralHelper.Calcu_UWP(project.TotalWrkP, project.TotalWrkQ, TargetH), 3);
|
|
project.SpanQ = Math.Round(project.TotalWrkQ - TargetQ, 0);
|
|
return new IStation.Dto.ApiResult<IStation.Calculation.DispatchAna.Model.AnaScheme>(project);
|
}
|
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="CorpID">公司ID</param>
|
/// <param name="StationID"></param>
|
/// <param name="ItemsParas"></param>
|
/// <returns></returns>
|
[Route("GetAnaItemDetail@V1.0")]
|
[HttpGet]
|
public IStation.Dto.ApiResult GetAnaItemDetail(long CorpID, string StationID,
|
string ItemsParas)
|
{
|
if (CorpID <= 0)
|
{
|
return new IStation.Dto.ApiResult(IStation.Dto.ApiResultCode.Error, "CorpID为空");
|
}
|
if (string.IsNullOrEmpty(StationID))
|
{
|
return new IStation.Dto.ApiResult(IStation.Dto.ApiResultCode.Alert, "StationID 参数未输入");
|
}
|
if (string.IsNullOrEmpty(ItemsParas))
|
{
|
return new IStation.Dto.ApiResult(IStation.Dto.ApiResultCode.Alert, "ItemsParas 参数未输入");
|
}
|
IStation.Service.PumpCurve bllCurve = new IStation.Service.PumpCurve();
|
|
string strItemsParas = ItemsParas;
|
var sss = strItemsParas.Split(',');
|
|
List<IStation.Model.CurveExpress> curveListQH = new List<IStation.Model.CurveExpress>();
|
List<IStation.Model.CurveExpress> curveListQP = new List<IStation.Model.CurveExpress>();
|
double r_maxH = double.MaxValue, r_minH = double.MinValue;
|
List<IStation.Dto.DispatchAna.CurveItem> ParallelCurve = new List<IStation.Dto.DispatchAna.CurveItem>();
|
|
foreach (var s in sss)
|
{
|
if (string.IsNullOrEmpty(s) || s == "null")
|
continue;
|
|
var bbb = s.Split('F');
|
if (bbb.Count() < 2)
|
continue;
|
var frequence = Convert.ToDouble(bbb[1]);
|
var aaa = bbb[0].Split('P');
|
var pumpID = Convert.ToInt64(aaa[1].Replace("P", ""));
|
var machineID = Convert.ToInt64(aaa[0].Replace("M", ""));
|
|
var curve_default = bllCurve.GetDefaultWorkingByPumpID(CorpID, pumpID);
|
//.GetDefaultCurveByPumpID(CorpID, pumpID);
|
if (curve_default == null)
|
continue;
|
if (curve_default.CurveInfo == null)
|
continue;
|
if (frequence > 49.5)
|
{
|
var curve_qh = curve_default.CurveInfo.CurveQH;
|
curve_qh.Max = curve_qh.Max * IStation.Calculation.DispatchAna.Common.DispatchAnaGeneralHelper.ExtendMaxRatio;
|
curveListQH.Add(curve_qh);
|
|
var curve_qp = curve_default.CurveInfo.CurveQP;
|
curve_qp.Max = curve_qp.Max * IStation.Calculation.DispatchAna.Common.DispatchAnaGeneralHelper.ExtendMaxRatio;
|
curveListQP.Add(curve_qp);
|
}
|
else
|
{
|
var ration = frequence / 50.0;
|
|
var maxCurveQH = IStation.Model.FitCurveHelper.GetFitPointsByExtend(curve_default.CurveInfo.CurveQH,
|
IStation.Calculation.DispatchAna.Common.DispatchAnaGeneralHelper.ExtendMaxRatio, 20);
|
var maxCurveQP = IStation.Model.FitCurveHelper.GetFitPointsByExtend(curve_default.CurveInfo.CurveQP,
|
IStation.Calculation.DispatchAna.Common.DispatchAnaGeneralHelper.ExtendMaxRatio, 20);
|
|
List<IStation.Model.CurvePoint> simuPointsQH = new List<IStation.Model.CurvePoint>();
|
foreach (var pt in maxCurveQH)
|
{
|
simuPointsQH.Add(new IStation.Model.CurvePoint(pt.X * ration, pt.Y * ration * ration));
|
}
|
|
List<IStation.Model.CurvePoint> simuPointsQP = new List<IStation.Model.CurvePoint>();
|
foreach (var pt in maxCurveQP)
|
{
|
simuPointsQP.Add(new IStation.Model.CurvePoint(pt.X * ration, pt.Y * ration * ration * ration));
|
}
|
curveListQH.Add(new IStation.Model.CurveExpress(simuPointsQH));
|
curveListQP.Add(new IStation.Model.CurveExpress(simuPointsQP));
|
}
|
double maxH, minH;
|
IStation.Model.FitCurveHelper.GetMinMaxPointY(curveListQH.Last(), out maxH, out minH);
|
r_maxH = Math.Min(r_maxH, maxH);
|
r_minH = Math.Max(r_minH, minH);
|
|
var product = new IStation.Service.Product().GetByID(CorpID, machineID);
|
|
IStation.Dto.DispatchAna.CurveItem item = new IStation.Dto.DispatchAna.CurveItem();
|
item.Type = 0;
|
item.Name = product == null ? "" : product.Name;
|
item.PointQH = IStation.Model.PumpCurve.GetEChartPoint(new IStation.Model.CurveExpress(curveListQH.Last()), 20);
|
item.PointQP = IStation.Model.PumpCurve.GetEChartPoint(new IStation.Model.CurveExpress(curveListQP.Last()), 20);
|
ParallelCurve.Add(item);
|
}
|
|
if (curveListQH.Count < 1)
|
{
|
return new IStation.Dto.ApiResult (IStation.Dto.ApiResultCode.Alert, "NULL1");
|
}
|
else if (curveListQH.Count == 1)
|
{
|
IStation.Dto.DispatchAna.CurveItem item_bl_Same = new IStation.Dto.DispatchAna.CurveItem();
|
item_bl_Same.Type = 1;
|
item_bl_Same.Name = "并联曲线";
|
item_bl_Same.PointQH = ParallelCurve.FirstOrDefault().PointQH;
|
item_bl_Same.PointQP = ParallelCurve.FirstOrDefault().PointQP;
|
ParallelCurve.Add(item_bl_Same);
|
return new IStation.Dto.ApiResult<List<IStation.Dto.DispatchAna.CurveItem>>(ParallelCurve);
|
}
|
//if (curveListQH.Count < 2)
|
//{
|
// return Json(new Result(IStation.Model.Api.Code.Alert, "NULL1"), JsonRequestBehavior.AllowGet);
|
//}
|
if (r_maxH < r_minH)
|
{
|
return new IStation.Dto.ApiResult(IStation.Dto.ApiResultCode.Alert, "NULL2");
|
}
|
|
double space_h = (r_maxH - r_minH) / 19;
|
List<IStation.Model.CurvePoint> conne_curve_qp = new List<IStation.Model.CurvePoint>();
|
List<IStation.Model.CurvePoint> conne_curve_qh = new List<IStation.Model.CurvePoint>();
|
for (var h = r_minH; h <= r_maxH; h = h + space_h)
|
{
|
double total_flow = 0;
|
double total_power = 0;
|
|
for (int j = 0; j < curveListQH.Count; j++)
|
{
|
var curveQH = curveListQH[j];
|
var curveQP = curveListQP[j];
|
var pts = IStation.Model.FitCurveHelper.GetInterPointX(curveQH, h);
|
if (pts != null && pts.Count > 0)
|
{
|
var q = pts.Last().X;
|
total_flow += q;
|
total_power += IStation.Model.FitCurveHelper.GetFitPointY(curveQP, q);
|
}
|
|
}
|
conne_curve_qh.Add(new IStation.Model.CurvePoint(total_flow, h));
|
conne_curve_qp.Add(new IStation.Model.CurvePoint(total_flow, total_power));
|
}
|
|
IStation.Dto.DispatchAna.CurveItem item_bl = new IStation.Dto.DispatchAna.CurveItem();
|
item_bl.Type = 1;
|
item_bl.Name = "并联曲线";
|
item_bl.PointQH = IStation.Model.PumpCurve.GetEChartPoint(new IStation.Model.CurveExpress(conne_curve_qh), 20);
|
item_bl.PointQP = IStation.Model.PumpCurve.GetEChartPoint(new IStation.Model.CurveExpress(conne_curve_qp), 20);
|
ParallelCurve.Insert(0, item_bl);//放在第一个
|
|
return new IStation.Dto.ApiResult<List<IStation.Dto.DispatchAna.CurveItem>>(ParallelCurve);
|
|
}
|
|
|
}
|
}
|