using System; using AsbCloudApp.Data.ProcessMaps.Report; using AsbCloudApp.Data.SAUB; namespace AsbCloudInfrastructure.Services.ProcessMaps.Report.Data; internal class ParamStat { private double spWSum; private double pvWSum; private double limitMaxWSum; private double deltaDepthSum; private readonly Func getterSp; private readonly Func getterPv; private readonly Func? getterLimitMax; private readonly int idFeedRegulator; private readonly int idMode; private TelemetryDataSaubStatDto? previous; public double SpUsageDepth { get; private set; } private static double spUsageTotal; public ParamStat(Func getterSp, Func getterPv, Func? getterLimitMax, int idFeedRegulator, int idMode) { this.getterSp = getterSp; this.getterPv = getterPv; this.getterLimitMax = getterLimitMax; this.idFeedRegulator = idFeedRegulator; this.idMode = idMode; spUsageTotal = 0d; } public void UpdateStat(TelemetryDataSaubStatDto current) { if (previous is not null) { var deltaDepth = current.WellDepthMin - previous.WellDepthMin; if (deltaDepth > 0) { var deltaDepthHalf = deltaDepth / 2; double CalculateWeight(Func getter) => (getter(previous!) + getter(current)) * deltaDepthHalf; spWSum += CalculateWeight(getterSp); pvWSum += CalculateWeight(getterPv); if (getterLimitMax is not null) limitMaxWSum += CalculateWeight(getterLimitMax!); if (current.IdFeedRegulator is not null) if (current.IdFeedRegulator == idFeedRegulator) { SpUsageDepth += deltaDepth; spUsageTotal += deltaDepth; } else { var pvErr = (getterSp(current) - getterPv(current)) / getterSp(current); if (pvErr < 0.03d) //3% { SpUsageDepth += deltaDepth; spUsageTotal += deltaDepth; } } deltaDepthSum += deltaDepth; } } previous = current; } public ProcessMapReportWellDrillingParamsDto MakeParams(double? spPlan) { var result = new ProcessMapReportWellDrillingParamsDto { SetpointPlan = spPlan, Fact = DivideValByDepth(pvWSum), }; if (idMode == 0) { result.SetpointFact = null; result.Limit = null; result.SetpointUsage = null; } else { result.SetpointFact = DivideValByDepth(spWSum); result.Limit = getterLimitMax is not null ? DivideValByDepth(limitMaxWSum) : null; result.SetpointUsage = deltaDepthSum > 0d ? 100d * SpUsageDepth / spUsageTotal : null; } return result; } private double? DivideValByDepth(double? val) { if (val is null || val == 0d || deltaDepthSum == 0d) return null; return val / deltaDepthSum; } }