diff --git a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs index abcef62b..06e1f3c4 100644 --- a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs +++ b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs @@ -84,7 +84,7 @@ public class ProcessMapReportDataSaubStatDto /// /// Обороты ВСП, об/мин /// - public ProcessMapReportDataSaubStatParamsDto Turnover { get; set; } = new(); + public ProcessMapReportDataSaubStatParamsDto TopDriveSpeed { get; set; } = new(); /// /// Расход, л/с diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs index ae90510e..86733960 100644 --- a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs +++ b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs @@ -14,345 +14,329 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace AsbCloudInfrastructure.Services.ProcessMaps.Report +namespace AsbCloudInfrastructure.Services.ProcessMaps.Report; + +public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStatService { - public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStatService + private readonly IWellService wellService; + private readonly IChangeLogRepository processMapPlanBaseRepository; + private readonly IDataSaubStatRepository dataSaubStatRepository; + private readonly IWellOperationRepository wellOperationRepository; + private readonly IWellOperationCategoryRepository wellOperationCategoryRepository; + + public ProcessMapReportDataSaubStatService(IWellService wellService, + IChangeLogRepository processMapPlanBaseRepository, + IDataSaubStatRepository dataSaubStatRepository, + IWellOperationRepository wellOperationRepository, + IWellOperationCategoryRepository wellOperationCategoryRepository + ) { - private readonly IWellService wellService; - private readonly IChangeLogRepository processMapPlanBaseRepository; - private readonly IDataSaubStatRepository dataSaubStatRepository; - private readonly IWellOperationRepository wellOperationRepository; - private readonly IWellOperationCategoryRepository wellOperationCategoryRepository; + this.wellService = wellService; + this.processMapPlanBaseRepository = processMapPlanBaseRepository; + this.dataSaubStatRepository = dataSaubStatRepository; + this.wellOperationRepository = wellOperationRepository; + this.wellOperationCategoryRepository = wellOperationCategoryRepository; + } - public ProcessMapReportDataSaubStatService(IWellService wellService, - IChangeLogRepository processMapPlanBaseRepository, - IDataSaubStatRepository dataSaubStatRepository, - IWellOperationRepository wellOperationRepository, - IWellOperationCategoryRepository wellOperationCategoryRepository - ) + public async Task> GetAsync(int idWell, DataSaubStatRequest request, CancellationToken token) + { + var well = await wellService.GetOrDefaultAsync(idWell, token) + ?? throw new ArgumentInvalidException(nameof(idWell), $"Скважина с Id: {idWell} не найдена"); + + if (!well.IdTelemetry.HasValue) + return Enumerable.Empty(); + + var requestProcessMapPlan = new ProcessMapPlanBaseRequestWithWell(idWell); + var processMapPlanWellDrillings = await processMapPlanBaseRepository.Get(requestProcessMapPlan, token); + + if (!processMapPlanWellDrillings.Any()) + return Enumerable.Empty(); + + var geDepth = processMapPlanWellDrillings.Min(p => p.DepthStart); + var leDepth = processMapPlanWellDrillings.Max(p => p.DepthEnd); + + var requestWellOperationFact = new WellOperationRequest() { - this.wellService = wellService; - this.processMapPlanBaseRepository = processMapPlanBaseRepository; - this.dataSaubStatRepository = dataSaubStatRepository; - this.wellOperationRepository = wellOperationRepository; - this.wellOperationCategoryRepository = wellOperationCategoryRepository; - } + IdWell = idWell, + OperationType = WellOperation.IdOperationTypeFact, + GeDepth = geDepth, + LeDepth = leDepth + }; + var wellOperations = await wellOperationRepository + .GetAsync(requestWellOperationFact, token); + if (!wellOperations.Any()) + return Enumerable.Empty(); - public async Task> GetAsync(int idWell, DataSaubStatRequest request, CancellationToken token) + var geDate = wellOperations.Min(p => p.DateStart).ToUniversalTime(); + var leDate = wellOperations.Max(p => (p.DateStart.AddHours(p.DurationHours))).ToUniversalTime(); + var dataSaubStats = + (await dataSaubStatRepository.GetAsync(well.IdTelemetry.Value, geDate, leDate, token)).ToArray(); + + if (!dataSaubStats.Any()) + return Enumerable.Empty(); + + var wellOperationCategories = wellOperationCategoryRepository.Get(false); + var wellSectionTypes = wellOperationRepository.GetSectionTypes(); + + var result = CalcByIntervals( + request, + processMapPlanWellDrillings, + dataSaubStats, + wellOperations, + wellOperationCategories, + wellSectionTypes); + + return result; + } + + private IEnumerable CalcByIntervals( + DataSaubStatRequest request, + IEnumerable processMapPlanWellDrillings, + Span dataSaubStats, + IEnumerable wellOperations, + IEnumerable wellOperationCategories, + IEnumerable wellSectionTypes + ) + { + var list = new List(); + var firstElemInInterval = dataSaubStats[0]; + + int GetSection(DataSaubStatDto data) + => wellOperations.MinBy(o => data.DateStart - o.DateStart)!.IdWellSectionType; + + ProcessMapPlanDrillingDto? GetProcessMapPlan(int idWellSectionType, DataSaubStatDto data) + => processMapPlanWellDrillings + .Where(p => p.IdWellSectionType == idWellSectionType) + .Where(p => p.DepthStart <= data.DepthStart) + .Where(p => p.DepthEnd >= data.DepthStart) + .Where(p => IsModeMatchOperationCategory(p.IdMode, data.IdCategory)) + .WhereActualAtMoment(data.DateStart) + .FirstOrDefault(); + + var idWellSectionType = GetSection(firstElemInInterval); + var prevProcessMapPlan = GetProcessMapPlan(idWellSectionType, firstElemInInterval); + var indexStart = 0; + + for (var i = 1; i < dataSaubStats.Length; i++) { - var well = await wellService.GetOrDefaultAsync(idWell, token) - ?? throw new ArgumentInvalidException(nameof(idWell), $"Скважина с Id: {idWell} не найдена"); + var currentElem = dataSaubStats[i]; + idWellSectionType = GetSection(currentElem); + var processMapPlan = GetProcessMapPlan(idWellSectionType, currentElem); - if (!well.IdTelemetry.HasValue) - return Enumerable.Empty(); - - var requestProcessMapPlan = new ProcessMapPlanBaseRequestWithWell(idWell); - var processMapPlanWellDrillings = await processMapPlanBaseRepository.Get(requestProcessMapPlan, token); - - if (!processMapPlanWellDrillings.Any()) - return Enumerable.Empty(); - - var geDepth = processMapPlanWellDrillings.Min(p => p.DepthStart); - var leDepth = processMapPlanWellDrillings.Max(p => p.DepthEnd); - - var requestWellOperationFact = new WellOperationRequest() + if (IsNewInterval(currentElem, firstElemInInterval, request) || i == dataSaubStats.Length - 1 || processMapPlan != prevProcessMapPlan) { - IdWell = idWell, - OperationType = WellOperation.IdOperationTypeFact, - GeDepth = geDepth, - LeDepth = leDepth - }; - var wellOperations = await wellOperationRepository - .GetAsync(requestWellOperationFact, token); - if (!wellOperations.Any()) - return Enumerable.Empty(); + prevProcessMapPlan = processMapPlan; + var length = i - indexStart; - var geDate = wellOperations.Min(p => p.DateStart).ToUniversalTime(); - var leDate = wellOperations.Max(p => (p.DateStart.AddHours(p.DurationHours))).ToUniversalTime(); - var dataSaubStats = - (await dataSaubStatRepository.GetAsync(well.IdTelemetry.Value, geDate, leDate, token)).ToArray(); + var span = dataSaubStats.Slice(indexStart, length); - if (!dataSaubStats.Any()) - return Enumerable.Empty(); + indexStart = i; + firstElemInInterval = currentElem; - var wellOperationCategories = wellOperationCategoryRepository.Get(false); - var wellSectionTypes = wellOperationRepository.GetSectionTypes(); + var firstElemInSpan = span[0]; + var lastElemInISpan = span[^1]; - var result = CalcByIntervals( - request, - processMapPlanWellDrillings, - dataSaubStats, - wellOperations, - wellOperationCategories, - wellSectionTypes); + var wellOperationCategoryName = wellOperationCategories + .Where(c => c.Id == firstElemInSpan.IdCategory) + .FirstOrDefault()?.Name ?? string.Empty; - return result; - } + var wellSectionTypeName = wellSectionTypes + .Where(c => c.Id == idWellSectionType) + .FirstOrDefault()?.Caption ?? string.Empty; - private IEnumerable CalcByIntervals( - DataSaubStatRequest request, - IEnumerable processMapPlanWellDrillings, - Span dataSaubStats, - IEnumerable wellOperations, - IEnumerable wellOperationCategories, - IEnumerable wellSectionTypes - ) - { - var list = new List(); - var firstElemInInterval = dataSaubStats[0]; - - int GetSection(DataSaubStatDto data) - => wellOperations.MinBy(o => data.DateStart - o.DateStart)!.IdWellSectionType; - - ProcessMapPlanDrillingDto? GetProcessMapPlan(int idWellSectionType, DataSaubStatDto data) - => processMapPlanWellDrillings - .Where(p => p.IdWellSectionType == idWellSectionType) - .Where(p => p.DepthStart <= data.DepthStart) - .Where(p => p.DepthEnd >= data.DepthStart) - .Where(p => IsModeMatchOperationCategory(p.IdMode, data.IdCategory)) - .WhereActualAtMoment(data.DateStart) - .FirstOrDefault(); - - var idWellSectionType = GetSection(firstElemInInterval); - var prevProcessMapPlan = GetProcessMapPlan(idWellSectionType, firstElemInInterval); - var indexStart = 0; - - for (var i = 1; i < dataSaubStats.Length; i++) - { - var currentElem = dataSaubStats[i]; - idWellSectionType = GetSection(currentElem); - var processMapPlan = GetProcessMapPlan(idWellSectionType, currentElem); - - if (IsNewInterval(currentElem, firstElemInInterval, request) || i == dataSaubStats.Length - 1 || processMapPlan != prevProcessMapPlan) - { - prevProcessMapPlan = processMapPlan; - var length = i - indexStart; - - var span = dataSaubStats.Slice(indexStart, length); - - indexStart = i; - firstElemInInterval = currentElem; - - var firstElemInSpan = span[0]; - var lastElemInISpan = span[^1]; - - var wellOperationCategoryName = wellOperationCategories - .Where(c => c.Id == firstElemInSpan.IdCategory) - .FirstOrDefault()?.Name ?? string.Empty; - - var wellSectionTypeName = wellSectionTypes - .Where(c => c.Id == idWellSectionType) - .FirstOrDefault()?.Caption ?? string.Empty; - - var elem = CalcStat(processMapPlan, span, wellOperationCategoryName, wellSectionTypeName); - if (elem is not null) - list.Add(elem); - } + var elem = CalcStat(processMapPlan, span, wellOperationCategoryName, wellSectionTypeName); + if (elem is not null) + list.Add(elem); } - return list; } + return list; + } - private bool IsModeMatchOperationCategory(int idMode, int idCategory) + private static bool IsModeMatchOperationCategory(int idMode, int idCategory) + { + return (idMode == 1 && idCategory == 5003) || (idMode == 2 && idCategory == 5002); + } + + private ProcessMapReportDataSaubStatDto? CalcStat( + ProcessMapPlanDrillingDto? processMapPlanFilteredByDepth, + Span span, + string wellOperationCategoryName, + string wellSectionTypeName + ) + { + var firstElemInInterval = span[0]; + var lastElemInInterval = span[^1]; + + var deltaDepth = lastElemInInterval.DepthEnd - firstElemInInterval.DepthStart; + + var aggregatedValues = CalcAggregate(span); + + return new ProcessMapReportDataSaubStatDto() { - return (idMode == 1 && idCategory == 5003) || (idMode == 2 && idCategory == 5002); - } - - private ProcessMapReportDataSaubStatDto? CalcStat( - ProcessMapPlanDrillingDto? processMapPlanFilteredByDepth, - Span span, - string wellOperationCategoryName, - string wellSectionTypeName - ) - { - var firstElemInInterval = span[0]; - var lastElemInInterval = span[^1]; - - var deltaDepth = lastElemInInterval.DepthEnd - firstElemInInterval.DepthStart; - - - var aggregatedValues = CalcAggregate(span); - - return new ProcessMapReportDataSaubStatDto() + DateStart = firstElemInInterval.DateStart.DateTime, + WellSectionTypeName = wellSectionTypeName, + DepthStart = firstElemInInterval.DepthStart, + DepthEnd = lastElemInInterval.DepthEnd, + DeltaDepth = deltaDepth, + DrilledTime = aggregatedValues.DrilledTime, + DrillingMode = wellOperationCategoryName, + PressureDiff = new ProcessMapReportDataSaubStatParamsDto() { - DateStart = firstElemInInterval.DateStart.DateTime, - WellSectionTypeName = wellSectionTypeName, - DepthStart = firstElemInInterval.DepthStart, - DepthEnd = lastElemInInterval.DepthEnd, - DeltaDepth = deltaDepth, - DrilledTime = aggregatedValues.DrilledTime, - DrillingMode = wellOperationCategoryName, - PressureDiff = new ProcessMapReportDataSaubStatParamsDto() - { - SetpointPlan = processMapPlanFilteredByDepth?.DeltaPressurePlan, - SetpointFact = firstElemInInterval.PressureSp - firstElemInInterval.PressureIdle, - FactWavg = aggregatedValues.Pressure, - Limit = processMapPlanFilteredByDepth?.DeltaPressureLimitMax, - SetpointUsage = aggregatedValues.SetpointUsagePressure - }, - AxialLoad = new ProcessMapReportDataSaubStatParamsDto() - { - SetpointPlan = processMapPlanFilteredByDepth?.AxialLoadPlan, - SetpointFact = aggregatedValues.AxialLoadSp, - FactWavg = aggregatedValues.AxialLoad, - Limit = processMapPlanFilteredByDepth?.AxialLoadLimitMax, - SetpointUsage = aggregatedValues.SetpointUsageAxialLoad - }, - TopDriveTorque = new ProcessMapReportDataSaubStatParamsDto() - { - SetpointPlan = processMapPlanFilteredByDepth?.TopDriveTorquePlan, - SetpointFact = aggregatedValues.RotorTorqueSp, - FactWavg = aggregatedValues.RotorTorque, - FactMax = aggregatedValues.RotorTorqueMax, - Limit = processMapPlanFilteredByDepth?.TopDriveTorqueLimitMax, - SetpointUsage = aggregatedValues.SetpointUsageRotorTorque - }, - SpeedLimit = new ProcessMapReportDataSaubStatParamsDto - { - SetpointPlan = processMapPlanFilteredByDepth?.RopPlan, - SetpointFact = aggregatedValues.BlockSpeedSp, - FactWavg = deltaDepth / aggregatedValues.DrilledTime, - SetpointUsage = aggregatedValues.SetpointUsageRopPlan - }, - Turnover = new ProcessMapReportDataSaubStatParamsDto - { - SetpointPlan = processMapPlanFilteredByDepth?.TopDriveSpeedPlan, - FactWavg = aggregatedValues.RotorSpeed, - FactMax = aggregatedValues.RotorSpeedMax - }, - Flow = new ProcessMapReportDataSaubStatParamsDto - { - SetpointPlan = processMapPlanFilteredByDepth?.FlowPlan, - FactWavg = aggregatedValues.MaxFlow, - Limit = processMapPlanFilteredByDepth?.FlowLimitMax, - }, - Rop = new PlanFactDto - { - Plan = processMapPlanFilteredByDepth?.RopPlan, - Fact = deltaDepth / aggregatedValues.DrilledTime - }, - }; - } - - private ( - double Pressure, - double AxialLoadSp, - double AxialLoad, - double RotorTorqueSp, - double RotorTorque, - double RotorTorqueMax, - double BlockSpeedSp, - double RotorSpeed, - double RotorSpeedMax, - double MaxFlow, - double SetpointUsagePressure, - double SetpointUsageAxialLoad, - double SetpointUsageRotorTorque, - double SetpointUsageRopPlan, - double DrilledTime - ) CalcAggregate(Span span) - { - var sumPressure = 0.0; - var sumAxialLoadSp = 0.0; - var sumAxialLoad = 0.0; - var sumRotorTorqueSp = 0.0; - var sumRotorTorque = 0.0; - var sumBlockSpeedSp = 0.0; - var sumRotorSpeed = 0.0; - var maxFlow = 0.0; - var maxRotorTorque = 0.0; - var maxRotorSpeed = 0.0; - var sumDiffDepthByPressure = 0.0; - var sumDiffDepthByAxialLoad = 0.0; - var sumDiffDepthByRotorTorque = 0.0; - var sumDiffDepthByRopPlan = 0.0; - - var diffDepthTotal = 0.0; - var drilledTime = 0.0; - - for (var i = 0; i < span.Length; i++) + SetpointPlan = processMapPlanFilteredByDepth?.DeltaPressurePlan, + SetpointFact = firstElemInInterval.PressureSp - firstElemInInterval.PressureIdle, + FactWavg = aggregatedValues.Pressure, + Limit = processMapPlanFilteredByDepth?.DeltaPressureLimitMax, + SetpointUsage = aggregatedValues.SetpointUsagePressure + }, + AxialLoad = new ProcessMapReportDataSaubStatParamsDto() { - var diffDepth = span[i].DepthEnd - span[i].DepthStart; - - sumPressure += diffDepth * (span[i].Pressure - (span[i].PressureIdle ?? 0.0)); - sumAxialLoadSp += diffDepth * (span[i].AxialLoadSp ?? 0); - sumAxialLoad += diffDepth * span[i].AxialLoad; - sumRotorTorqueSp += diffDepth * (span[i].RotorTorqueSp ?? 0); - sumRotorTorque += diffDepth * span[i].RotorTorque; - sumBlockSpeedSp += diffDepth * (span[i].BlockSpeedSp ?? 0); - sumRotorSpeed += diffDepth * span[i].RotorSpeed; - maxFlow = span[i].Flow > maxFlow ? span[i].Flow : maxFlow; - maxRotorTorque = span[i].RotorTorque > maxRotorTorque ? span[i].RotorTorque : maxRotorTorque; - maxRotorSpeed = span[i].RotorSpeed > maxRotorSpeed ? span[i].RotorSpeed : maxRotorSpeed; - - if (span[i].IdFeedRegulator == LimitingParameterDto.Pressure) - sumDiffDepthByPressure += diffDepth; - if (span[i].IdFeedRegulator == LimitingParameterDto.AxialLoad) - sumDiffDepthByAxialLoad += diffDepth; - if (span[i].IdFeedRegulator == LimitingParameterDto.RotorTorque) - sumDiffDepthByRotorTorque += diffDepth; - if (span[i].IdFeedRegulator == LimitingParameterDto.RopPlan) - sumDiffDepthByRopPlan += diffDepth; - - diffDepthTotal += diffDepth; - drilledTime += (span[i].DateEnd - span[i].DateStart).TotalHours; - } - return ( - Pressure: sumPressure / diffDepthTotal, - AxialLoadSp: sumAxialLoadSp / diffDepthTotal, - AxialLoad: sumAxialLoad / diffDepthTotal, - RotorTorqueSp: sumRotorTorqueSp / diffDepthTotal, - RotorTorque: sumRotorTorque / diffDepthTotal, - RotorTorqueMax: maxRotorTorque, - BlockSpeedSp: sumBlockSpeedSp / diffDepthTotal, - RotorSpeed: sumRotorSpeed / diffDepthTotal, - RotorSpeedMax: maxRotorSpeed, - MaxFlow: maxFlow, - SetpointUsagePressure: sumDiffDepthByPressure / diffDepthTotal, - SetpointUsageAxialLoad: sumDiffDepthByAxialLoad / diffDepthTotal, - SetpointUsageRotorTorque: sumDiffDepthByRotorTorque / diffDepthTotal, - SetpointUsageRopPlan: sumDiffDepthByRopPlan / diffDepthTotal, - DrilledTime: drilledTime - ); - } - - private double CalcRopPlan(ProcessMapPlanDrillingDto[] processMapPlanFilteredByDepth) - { - var sumRopPlan = 0.0; - var diffDepthTotal = 0.0; - - for (var i = 0; i < processMapPlanFilteredByDepth.Length; i++) + SetpointPlan = processMapPlanFilteredByDepth?.AxialLoadPlan, + SetpointFact = aggregatedValues.AxialLoadSp, + FactWavg = aggregatedValues.AxialLoad, + Limit = processMapPlanFilteredByDepth?.AxialLoadLimitMax, + SetpointUsage = aggregatedValues.SetpointUsageAxialLoad + }, + TopDriveTorque = new ProcessMapReportDataSaubStatParamsDto() { - var diffDepth = processMapPlanFilteredByDepth[i].DepthEnd - processMapPlanFilteredByDepth[i].DepthStart; - sumRopPlan += diffDepth * processMapPlanFilteredByDepth[i].RopPlan; - diffDepthTotal += diffDepth; - } - return sumRopPlan / diffDepthTotal; - } - - private bool IsNewInterval(DataSaubStatDto currentElem, DataSaubStatDto firstElem, DataSaubStatRequest request) - { - bool isNewElemBySpeed(double currentSpeed, double firstSpeed) + SetpointPlan = processMapPlanFilteredByDepth?.TopDriveTorquePlan, + SetpointFact = aggregatedValues.RotorTorqueSp, + FactWavg = aggregatedValues.RotorTorque, + FactMax = aggregatedValues.RotorTorqueMax, + Limit = processMapPlanFilteredByDepth?.TopDriveTorqueLimitMax, + SetpointUsage = aggregatedValues.SetpointUsageRotorTorque + }, + SpeedLimit = new ProcessMapReportDataSaubStatParamsDto { - //2. Изменение уставки скорости подачи от первого значения в начале интервала при условии: - //скорость > 80 м/ч => изменение уставки на ± 20 м/ч; - //скорость > 30 м/ч => изменение уставки на ± 15 м/ч; - //скорость <= 30 м/ч => изменение уставки на ± 5 м/ч; - if (firstSpeed > 80) - return Math.Abs(currentSpeed - firstSpeed) >= 20; - else if (firstSpeed > 30) - return Math.Abs(currentSpeed - firstSpeed) >= 15; - else - return Math.Abs(currentSpeed - firstSpeed) >= 5; - } + SetpointPlan = processMapPlanFilteredByDepth?.RopPlan, + SetpointFact = aggregatedValues.BlockSpeedSp, + FactWavg = deltaDepth / aggregatedValues.DrilledTime, + SetpointUsage = aggregatedValues.SetpointUsageRopPlan + }, + TopDriveSpeed = new ProcessMapReportDataSaubStatParamsDto + { + SetpointPlan = processMapPlanFilteredByDepth?.TopDriveSpeedPlan, + FactWavg = aggregatedValues.RotorSpeed, + FactMax = aggregatedValues.RotorSpeedMax + }, + Flow = new ProcessMapReportDataSaubStatParamsDto + { + SetpointPlan = processMapPlanFilteredByDepth?.FlowPlan, + FactWavg = aggregatedValues.MaxFlow, + Limit = processMapPlanFilteredByDepth?.FlowLimitMax, + }, + Rop = new PlanFactDto + { + Plan = processMapPlanFilteredByDepth?.RopPlan, + Fact = deltaDepth / aggregatedValues.DrilledTime + }, + }; + } - var isNewElem = (currentElem.IdCategory != firstElem.IdCategory) - || (Math.Abs(currentElem.Pressure - firstElem.Pressure) >= request.DeltaPressure) - || (Math.Abs(currentElem.AxialLoad - firstElem.AxialLoad) >= request.DeltaAxialLoad) - || (Math.Abs(currentElem.RotorTorque - firstElem.RotorTorque) >= request.DeltaRotorTorque) - || (Math.Abs((currentElem.AxialLoadSp ?? 0) - (firstElem.AxialLoadSp ?? 0)) >= request.DeltaAxialLoadSp) - || (Math.Abs((currentElem.RotorTorqueSp ?? 0) - (firstElem.RotorTorqueSp ?? 0)) >= request.DeltaRotorTorqueSp) - || (isNewElemBySpeed(currentElem.Speed, firstElem.Speed)); - return isNewElem; + private ( + double Pressure, + double AxialLoadSp, + double AxialLoad, + double RotorTorqueSp, + double RotorTorque, + double RotorTorqueMax, + double BlockSpeedSp, + double RotorSpeed, + double RotorSpeedMax, + double MaxFlow, + double SetpointUsagePressure, + double SetpointUsageAxialLoad, + double SetpointUsageRotorTorque, + double SetpointUsageRopPlan, + double DrilledTime + ) CalcAggregate(Span span) + { + var sumPressure = 0.0; + var sumAxialLoadSp = 0.0; + var sumAxialLoad = 0.0; + var sumRotorTorqueSp = 0.0; + var sumRotorTorque = 0.0; + var sumBlockSpeedSp = 0.0; + var sumRotorSpeed = 0.0; + var maxFlow = 0.0; + var maxRotorTorque = 0.0; + var maxRotorSpeed = 0.0; + var sumDiffDepthByPressure = 0.0; + var sumDiffDepthByAxialLoad = 0.0; + var sumDiffDepthByRotorTorque = 0.0; + var sumDiffDepthByRopPlan = 0.0; + + var diffDepthTotal = 0.0; + var drilledTime = 0.0; + + for (var i = 0; i < span.Length; i++) + { + var diffDepth = span[i].DepthEnd - span[i].DepthStart; + + sumPressure += diffDepth * (span[i].Pressure - (span[i].PressureIdle ?? 0.0)); + sumAxialLoadSp += diffDepth * (span[i].AxialLoadSp ?? 0); + sumAxialLoad += diffDepth * span[i].AxialLoad; + sumRotorTorqueSp += diffDepth * (span[i].RotorTorqueSp ?? 0); + sumRotorTorque += diffDepth * span[i].RotorTorque; + sumBlockSpeedSp += diffDepth * (span[i].BlockSpeedSp ?? 0); + sumRotorSpeed += diffDepth * span[i].RotorSpeed; + maxFlow = span[i].Flow > maxFlow ? span[i].Flow : maxFlow; + maxRotorTorque = span[i].RotorTorque > maxRotorTorque ? span[i].RotorTorque : maxRotorTorque; + maxRotorSpeed = span[i].RotorSpeed > maxRotorSpeed ? span[i].RotorSpeed : maxRotorSpeed; + + if (span[i].IdFeedRegulator == LimitingParameterDto.Pressure) + sumDiffDepthByPressure += diffDepth; + if (span[i].IdFeedRegulator == LimitingParameterDto.AxialLoad) + sumDiffDepthByAxialLoad += diffDepth; + if (span[i].IdFeedRegulator == LimitingParameterDto.RotorTorque) + sumDiffDepthByRotorTorque += diffDepth; + if (span[i].IdFeedRegulator == LimitingParameterDto.RopPlan) + sumDiffDepthByRopPlan += diffDepth; + + diffDepthTotal += diffDepth; + drilledTime += (span[i].DateEnd - span[i].DateStart).TotalHours; } + return ( + Pressure: sumPressure / diffDepthTotal, + AxialLoadSp: sumAxialLoadSp / diffDepthTotal, + AxialLoad: sumAxialLoad / diffDepthTotal, + RotorTorqueSp: sumRotorTorqueSp / diffDepthTotal, + RotorTorque: sumRotorTorque / diffDepthTotal, + RotorTorqueMax: maxRotorTorque, + BlockSpeedSp: sumBlockSpeedSp / diffDepthTotal, + RotorSpeed: sumRotorSpeed / diffDepthTotal, + RotorSpeedMax: maxRotorSpeed, + MaxFlow: maxFlow, + SetpointUsagePressure: sumDiffDepthByPressure / diffDepthTotal, + SetpointUsageAxialLoad: sumDiffDepthByAxialLoad / diffDepthTotal, + SetpointUsageRotorTorque: sumDiffDepthByRotorTorque / diffDepthTotal, + SetpointUsageRopPlan: sumDiffDepthByRopPlan / diffDepthTotal, + DrilledTime: drilledTime + ); + } + + private bool IsNewInterval(DataSaubStatDto currentElem, DataSaubStatDto firstElem, DataSaubStatRequest request) + { + bool isNewElemBySpeed(double currentSpeed, double firstSpeed) + { + //2. Изменение уставки скорости подачи от первого значения в начале интервала при условии: + //скорость > 80 м/ч => изменение уставки на ± 20 м/ч; + //скорость > 30 м/ч => изменение уставки на ± 15 м/ч; + //скорость <= 30 м/ч => изменение уставки на ± 5 м/ч; + if (firstSpeed > 80) + return Math.Abs(currentSpeed - firstSpeed) >= 20; + else if (firstSpeed > 30) + return Math.Abs(currentSpeed - firstSpeed) >= 15; + else + return Math.Abs(currentSpeed - firstSpeed) >= 5; + } + + var isNewElem = (currentElem.IdCategory != firstElem.IdCategory) + || (Math.Abs(currentElem.Pressure - firstElem.Pressure) >= request.DeltaPressure) + || (Math.Abs(currentElem.AxialLoad - firstElem.AxialLoad) >= request.DeltaAxialLoad) + || (Math.Abs(currentElem.RotorTorque - firstElem.RotorTorque) >= request.DeltaRotorTorque) + || (Math.Abs((currentElem.AxialLoadSp ?? 0) - (firstElem.AxialLoadSp ?? 0)) >= request.DeltaAxialLoadSp) + || (Math.Abs((currentElem.RotorTorqueSp ?? 0) - (firstElem.RotorTorqueSp ?? 0)) >= request.DeltaRotorTorqueSp) + || (isNewElemBySpeed(currentElem.Speed, firstElem.Speed)); + return isNewElem; } }