2023-04-05 13:36:56 +05:00
|
|
|
|
using AsbCloudApp.Data.ProcessMap;
|
2023-04-03 14:59:59 +05:00
|
|
|
|
using AsbCloudApp.Data.SAUB;
|
|
|
|
|
using AsbCloudApp.Exceptions;
|
|
|
|
|
using AsbCloudApp.Repositories;
|
2022-12-14 08:41:19 +05:00
|
|
|
|
using AsbCloudApp.Services;
|
2023-04-03 14:59:59 +05:00
|
|
|
|
using System;
|
2022-12-14 08:41:19 +05:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace AsbCloudInfrastructure.Services.ProcessMap
|
|
|
|
|
{
|
2023-04-18 16:22:53 +05:00
|
|
|
|
|
2023-04-03 14:59:59 +05:00
|
|
|
|
public partial class ProcessMapReportService : IProcessMapReportService
|
2022-12-14 08:41:19 +05:00
|
|
|
|
{
|
2023-04-03 14:59:59 +05:00
|
|
|
|
private readonly IWellService wellService;
|
|
|
|
|
private readonly IWellOperationRepository wellOperationRepository;
|
|
|
|
|
private readonly IProcessMapPlanRepository processMapPlanRepository;
|
|
|
|
|
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
|
|
|
|
|
|
|
|
|
public ProcessMapReportService(
|
|
|
|
|
IWellService wellService,
|
2023-04-05 13:36:56 +05:00
|
|
|
|
IWellOperationRepository wellOperationRepository,
|
2023-04-03 14:59:59 +05:00
|
|
|
|
IProcessMapPlanRepository processMapPlanRepository,
|
2023-04-05 13:36:56 +05:00
|
|
|
|
ITelemetryDataSaubService telemetryDataSaubService)
|
2022-12-14 08:41:19 +05:00
|
|
|
|
{
|
2023-04-03 14:59:59 +05:00
|
|
|
|
this.wellService = wellService;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
this.wellOperationRepository = wellOperationRepository;
|
2023-04-03 14:59:59 +05:00
|
|
|
|
this.processMapPlanRepository = processMapPlanRepository;
|
|
|
|
|
this.telemetryDataSaubService = telemetryDataSaubService;
|
2023-01-17 08:56:07 +05:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-03 14:59:59 +05:00
|
|
|
|
/// <inheritdoc/>
|
2023-04-06 10:25:51 +05:00
|
|
|
|
public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapReportAsync(int idWell, CancellationToken token)
|
2023-01-17 08:56:07 +05:00
|
|
|
|
{
|
2023-04-03 14:59:59 +05:00
|
|
|
|
var well = wellService.GetOrDefault(idWell)
|
|
|
|
|
?? throw new ArgumentInvalidException("idWell not found", nameof(idWell));
|
2023-01-17 08:56:07 +05:00
|
|
|
|
|
2023-04-03 14:59:59 +05:00
|
|
|
|
var idTelemetry = well.IdTelemetry
|
|
|
|
|
?? throw new ArgumentInvalidException("telemetry by well not found", nameof(idWell));
|
2023-02-06 13:13:23 +05:00
|
|
|
|
|
2023-04-03 14:59:59 +05:00
|
|
|
|
var processMapPlan = await processMapPlanRepository.GetByIdWellAsync(idWell, token);
|
2023-01-17 08:56:07 +05:00
|
|
|
|
|
2023-04-05 13:36:56 +05:00
|
|
|
|
if (!processMapPlan.Any())
|
2023-04-03 14:59:59 +05:00
|
|
|
|
return Enumerable.Empty<ProcessMapReportDto>();
|
2023-01-17 08:56:07 +05:00
|
|
|
|
|
2023-04-05 13:36:56 +05:00
|
|
|
|
var telemetryDataStat = (await telemetryDataSaubService.GetTelemetryDataStatAsync(idTelemetry, token)).ToArray();
|
|
|
|
|
if (!telemetryDataStat.Any())
|
|
|
|
|
return Enumerable.Empty<ProcessMapReportDto>();
|
2023-01-17 08:56:07 +05:00
|
|
|
|
|
2023-04-03 14:59:59 +05:00
|
|
|
|
var result = CalcByIntervals(processMapPlan, telemetryDataStat);
|
2023-01-17 08:56:07 +05:00
|
|
|
|
|
2023-04-03 14:59:59 +05:00
|
|
|
|
return result;
|
2023-01-17 08:56:07 +05:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-05 13:36:56 +05:00
|
|
|
|
private IEnumerable<ProcessMapReportDto> CalcByIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan, TelemetryDataSaubStatDto[] telemetryDataStat)
|
2023-01-17 08:56:07 +05:00
|
|
|
|
{
|
2023-04-06 10:25:51 +05:00
|
|
|
|
var processMapIntervals = CalcDepthIntervals(processMapPlan);
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
|
|
|
|
var result = new List<ProcessMapReportDto>(processMapIntervals.Count() * 4);
|
|
|
|
|
|
|
|
|
|
var telemetryIndexStart = Array.FindIndex(telemetryDataStat, t => t.WellDepthMin >= processMapIntervals.First().DepthStart);
|
|
|
|
|
if (telemetryIndexStart < 0)
|
|
|
|
|
return Enumerable.Empty<ProcessMapReportDto>();
|
|
|
|
|
|
|
|
|
|
IDictionary<int, string> sectionTypes = wellOperationRepository.GetSectionTypes();
|
|
|
|
|
|
|
|
|
|
foreach (var interval in processMapIntervals)
|
|
|
|
|
{
|
|
|
|
|
var processMapPlanInterval = processMapPlan
|
|
|
|
|
.Where(p => p.DepthStart >= interval.DepthStart && p.DepthEnd <= interval.DepthEnd);
|
|
|
|
|
|
|
|
|
|
var telemetryIndexEnd = Array.FindIndex(telemetryDataStat, telemetryIndexStart, t => t.WellDepthMin >= interval.DepthEnd);
|
2023-04-06 10:25:51 +05:00
|
|
|
|
if (telemetryIndexEnd < 0)
|
|
|
|
|
telemetryIndexEnd = telemetryDataStat.Length - 1;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
var telemetryDataInterval = telemetryDataStat.AsSpan(telemetryIndexStart, telemetryIndexEnd - telemetryIndexStart);
|
|
|
|
|
|
|
|
|
|
IEnumerable<ProcessMapReportDto> subIntervalsResult = CalcSubIntervals(interval, processMapPlanInterval, telemetryDataInterval, sectionTypes);
|
|
|
|
|
|
|
|
|
|
result.AddRange(subIntervalsResult);
|
|
|
|
|
telemetryIndexStart = telemetryIndexEnd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
private static IEnumerable<(double DepthStart, double DepthEnd)> CalcDepthIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan)
|
|
|
|
|
{
|
|
|
|
|
if(!processMapPlan.Any())
|
|
|
|
|
yield break;
|
|
|
|
|
|
|
|
|
|
var intervalStarts = processMapPlan
|
|
|
|
|
.OrderBy(i => i.DepthStart)
|
|
|
|
|
.Select(p => p.DepthStart)
|
|
|
|
|
.Distinct()
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
|
|
|
|
for (var i = 1; i < intervalStarts.Length; i++)
|
|
|
|
|
yield return (intervalStarts[i - 1], intervalStarts[i]);
|
|
|
|
|
|
|
|
|
|
yield return (intervalStarts[^1], processMapPlan.Max(p=>p.DepthEnd));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static IEnumerable<ProcessMapReportDto> CalcSubIntervals(
|
2023-04-05 13:36:56 +05:00
|
|
|
|
(double DepthStart, double DepthEnd) interval,
|
|
|
|
|
IEnumerable<ProcessMapPlanDto> processMapPlanInterval,
|
|
|
|
|
Span<TelemetryDataSaubStatDto> telemetryDataInterval,
|
|
|
|
|
IDictionary<int, string> sectionTypes)
|
|
|
|
|
{
|
|
|
|
|
var telemetryDataIntervalLength = telemetryDataInterval.Length;
|
|
|
|
|
if (telemetryDataInterval.Length == 0)
|
|
|
|
|
return Enumerable.Empty<ProcessMapReportDto>();
|
|
|
|
|
|
|
|
|
|
var result = new List<ProcessMapReportDto>();
|
|
|
|
|
var telemetryIndexStart = 0;
|
|
|
|
|
var subInterval = interval;
|
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
for (var i = telemetryIndexStart + 1; i < telemetryDataIntervalLength; i++)
|
2023-04-05 13:36:56 +05:00
|
|
|
|
{
|
2023-04-06 10:25:51 +05:00
|
|
|
|
if (IsDifferent(telemetryDataInterval[telemetryIndexStart], telemetryDataInterval[i]))
|
2023-04-05 13:36:56 +05:00
|
|
|
|
{
|
2023-04-06 10:25:51 +05:00
|
|
|
|
subInterval.DepthEnd = telemetryDataInterval[i - 1].WellDepthMax;
|
|
|
|
|
var telemetryRowSpan = telemetryDataInterval[telemetryIndexStart..(i - 1)];
|
|
|
|
|
if (!telemetryRowSpan.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
var intervalReportRow = CalcSubIntervalReportRow(subInterval, processMapPlanInterval, telemetryRowSpan, sectionTypes);
|
|
|
|
|
result.Add(intervalReportRow);
|
|
|
|
|
}
|
2023-04-05 13:36:56 +05:00
|
|
|
|
telemetryIndexStart = i;
|
|
|
|
|
subInterval.DepthStart = subInterval.DepthEnd;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
subInterval.DepthEnd = interval.DepthEnd;
|
|
|
|
|
var intervalReportRowLast = CalcSubIntervalReportRow(subInterval, processMapPlanInterval, telemetryDataInterval[telemetryIndexStart..telemetryDataIntervalLength], sectionTypes);
|
|
|
|
|
result.Add(intervalReportRowLast);
|
2023-04-03 14:59:59 +05:00
|
|
|
|
return result;
|
2023-01-17 08:56:07 +05:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
private static ProcessMapReportDto CalcSubIntervalReportRow(
|
2023-04-05 13:36:56 +05:00
|
|
|
|
(double DepthStart, double DepthEnd) subInterval,
|
|
|
|
|
IEnumerable<ProcessMapPlanDto> processMap,
|
|
|
|
|
Span<TelemetryDataSaubStatDto> telemetryRowSpan,
|
|
|
|
|
IDictionary<int, string> sectionTypes)
|
2023-01-17 08:56:07 +05:00
|
|
|
|
{
|
2023-04-06 17:16:53 +05:00
|
|
|
|
var telemetryStat = new TelemetryStat(telemetryRowSpan);
|
|
|
|
|
var processMapByMode = processMap.FirstOrDefault(p => p.IdMode == telemetryStat.IdMode);
|
2023-04-05 13:36:56 +05:00
|
|
|
|
var processMapFirst = processMap.First();
|
|
|
|
|
var idWellSectionType = processMapByMode?.IdWellSectionType ?? processMapFirst.IdWellSectionType;
|
2023-04-06 17:16:53 +05:00
|
|
|
|
|
2023-04-05 13:36:56 +05:00
|
|
|
|
var result = new ProcessMapReportDto
|
|
|
|
|
{
|
|
|
|
|
IdWell = processMapByMode?.IdWell ?? processMapFirst.IdWell,
|
|
|
|
|
IdWellSectionType = idWellSectionType,
|
|
|
|
|
WellSectionTypeName = sectionTypes[idWellSectionType],
|
|
|
|
|
|
|
|
|
|
DepthStart = subInterval.DepthStart,
|
|
|
|
|
DepthEnd = subInterval.DepthEnd,
|
2023-04-06 17:16:53 +05:00
|
|
|
|
DateStart = telemetryStat.DateStart,
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
2023-04-06 17:16:53 +05:00
|
|
|
|
MechDrillingHours = telemetryStat.MechDrillingHours,
|
|
|
|
|
DrillingMode = telemetryStat.ModeName,
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
2023-04-06 17:16:53 +05:00
|
|
|
|
DeltaDepth = telemetryStat.DeltaDepth,
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
2023-04-06 17:16:53 +05:00
|
|
|
|
PressureDiff = telemetryStat.Pressure.MakeParams(processMapByMode?.Pressure.Plan),
|
|
|
|
|
AxialLoad = telemetryStat.AxialLoad.MakeParams(processMapByMode?.AxialLoad.Plan),
|
|
|
|
|
TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan),
|
|
|
|
|
SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan),
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
|
|
|
|
Rop = telemetryStat.Rop,
|
2023-04-06 17:27:31 +05:00
|
|
|
|
UsagePlan = processMapByMode?.UsageSaub ?? telemetryStat.UsagePredictPlan,
|
|
|
|
|
UsageFact = telemetryStat.UsageSaub,
|
2023-04-05 13:36:56 +05:00
|
|
|
|
};
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
private static bool IsDifferent(TelemetryDataSaubStatDto intervalStart, TelemetryDataSaubStatDto current)
|
2022-12-27 14:30:52 +05:00
|
|
|
|
{
|
2023-04-06 10:25:51 +05:00
|
|
|
|
if (intervalStart.WellDepthMin > current.WellDepthMin)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (intervalStart.IdMode != current.IdMode)
|
|
|
|
|
return true;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
if (Math.Abs(intervalStart.PressureSp - current.PressureSp) > 5d)
|
|
|
|
|
return true;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
if (Math.Abs(intervalStart.AxialLoadSp - current.AxialLoadSp) > 1d)
|
|
|
|
|
return true;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
if (Math.Abs(intervalStart.RotorTorqueSp - current.RotorTorqueSp) > 5d)
|
|
|
|
|
return true;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
var blockSpeedSpDiff = Math.Abs(intervalStart.BlockSpeedSp - current.BlockSpeedSp);
|
2023-04-05 13:36:56 +05:00
|
|
|
|
if (blockSpeedSpDiff > 5d)
|
2023-04-03 14:59:59 +05:00
|
|
|
|
{
|
2023-04-06 10:25:51 +05:00
|
|
|
|
if (intervalStart.BlockSpeedSp <= 30)
|
|
|
|
|
return true;
|
|
|
|
|
else if (intervalStart.BlockSpeedSp > 30 && blockSpeedSpDiff > 15d)
|
|
|
|
|
return true;
|
|
|
|
|
else if (intervalStart.BlockSpeedSp > 80 && blockSpeedSpDiff > 20d)
|
|
|
|
|
return true;
|
2023-04-03 14:59:59 +05:00
|
|
|
|
}
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
return false;
|
2022-12-14 08:41:19 +05:00
|
|
|
|
}
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
2022-12-14 08:41:19 +05:00
|
|
|
|
}
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
|
|
|
|
class ParamStat
|
|
|
|
|
{
|
|
|
|
|
private double spWSum;
|
|
|
|
|
private double pvWSum;
|
2023-04-06 10:25:51 +05:00
|
|
|
|
private double limitMaxWSum;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
|
|
|
|
private double deltaDepthSum;
|
|
|
|
|
|
|
|
|
|
private readonly Func<TelemetryDataSaubStatDto, double> getterSp;
|
|
|
|
|
private readonly Func<TelemetryDataSaubStatDto, double> getterPv;
|
|
|
|
|
private readonly Func<TelemetryDataSaubStatDto, double>? getterLimitMax;
|
|
|
|
|
|
|
|
|
|
private readonly int idFeedRegulator;
|
2023-04-06 17:16:53 +05:00
|
|
|
|
private readonly int idMode;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
private TelemetryDataSaubStatDto? previous;
|
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
public double SpUsageDepth { get; private set; }
|
2023-04-06 17:16:53 +05:00
|
|
|
|
private static double spUsageTotal;
|
2023-04-06 10:25:51 +05:00
|
|
|
|
|
2023-04-05 13:36:56 +05:00
|
|
|
|
public ParamStat(Func<TelemetryDataSaubStatDto, double> getterSp,
|
|
|
|
|
Func<TelemetryDataSaubStatDto, double> getterPv,
|
|
|
|
|
Func<TelemetryDataSaubStatDto, double>? getterLimitMax,
|
2023-04-06 17:16:53 +05:00
|
|
|
|
int idFeedRegulator,
|
|
|
|
|
int idMode)
|
2023-04-05 13:36:56 +05:00
|
|
|
|
{
|
|
|
|
|
this.getterSp = getterSp;
|
|
|
|
|
this.getterPv = getterPv;
|
|
|
|
|
this.getterLimitMax = getterLimitMax;
|
|
|
|
|
this.idFeedRegulator = idFeedRegulator;
|
2023-04-06 17:16:53 +05:00
|
|
|
|
this.idMode = idMode;
|
|
|
|
|
spUsageTotal = 0d;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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<TelemetryDataSaubStatDto, double> getter) => (getter(previous!) + getter(current)) * deltaDepthHalf;
|
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
spWSum += CalculateWeight(getterSp);
|
|
|
|
|
pvWSum += CalculateWeight(getterPv);
|
2023-04-05 13:36:56 +05:00
|
|
|
|
if(getterLimitMax is not null)
|
2023-04-06 10:25:51 +05:00
|
|
|
|
limitMaxWSum += CalculateWeight(getterLimitMax!);
|
|
|
|
|
|
|
|
|
|
if (current.IdFeedRegulator is not null)
|
|
|
|
|
{
|
2023-04-06 17:16:53 +05:00
|
|
|
|
if (current.IdFeedRegulator == idFeedRegulator)
|
|
|
|
|
{
|
2023-04-06 10:25:51 +05:00
|
|
|
|
SpUsageDepth += deltaDepth;
|
2023-04-06 17:16:53 +05:00
|
|
|
|
spUsageTotal += deltaDepth;
|
|
|
|
|
}
|
2023-04-06 10:25:51 +05:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var pvErr = (getterSp(current) - getterPv(current)) / getterSp(current);
|
|
|
|
|
if (pvErr < 0.03d) //3%
|
2023-04-06 17:16:53 +05:00
|
|
|
|
{
|
2023-04-06 10:25:51 +05:00
|
|
|
|
SpUsageDepth += deltaDepth;
|
2023-04-06 17:16:53 +05:00
|
|
|
|
spUsageTotal += deltaDepth;
|
|
|
|
|
}
|
2023-04-06 10:25:51 +05:00
|
|
|
|
}
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
|
|
|
|
deltaDepthSum += deltaDepth;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
previous = current;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 17:16:53 +05:00
|
|
|
|
public ProcessMapReportParamsDto MakeParams(double? spPlan)
|
|
|
|
|
{
|
|
|
|
|
var result = new ProcessMapReportParamsDto
|
2023-04-05 13:36:56 +05:00
|
|
|
|
{
|
|
|
|
|
SetpointPlan = spPlan,
|
2023-04-06 10:25:51 +05:00
|
|
|
|
Fact = DivideValByDepth(pvWSum),
|
2023-04-05 13:36:56 +05:00
|
|
|
|
};
|
2023-04-06 10:25:51 +05:00
|
|
|
|
|
2023-04-06 17:16:53 +05:00
|
|
|
|
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;
|
2023-04-06 17:27:31 +05:00
|
|
|
|
result.SetpointUsage = deltaDepthSum > 0d ? 100d * SpUsageDepth / spUsageTotal : null;
|
2023-04-06 17:16:53 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
private double? DivideValByDepth(double? val)
|
|
|
|
|
{
|
|
|
|
|
if(val is null || val == 0d || deltaDepthSum == 0d)
|
|
|
|
|
return null;
|
|
|
|
|
return val / deltaDepthSum;
|
|
|
|
|
}
|
2023-04-05 13:36:56 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class TelemetryStat {
|
|
|
|
|
public ParamStat Pressure { get; }
|
|
|
|
|
public ParamStat AxialLoad {get; }
|
|
|
|
|
public ParamStat RotorTorque {get; }
|
|
|
|
|
public ParamStat BlockSpeed {get; }
|
|
|
|
|
|
|
|
|
|
private TelemetryDataSaubStatDto? previous;
|
|
|
|
|
private double depthSum = 0d;
|
|
|
|
|
private double hoursSum = 0d;
|
|
|
|
|
|
2023-04-06 10:25:51 +05:00
|
|
|
|
public double? Rop => hoursSum == 0d ? null : depthSum / hoursSum;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
|
|
|
|
|
private double depthWithSaub = 0d;
|
2023-04-06 17:27:31 +05:00
|
|
|
|
public double UsageSaub { get; }
|
|
|
|
|
public double UsagePredictPlan { get; }
|
|
|
|
|
public DateTime DateStart { get; }
|
|
|
|
|
public float DeltaDepth { get; }
|
|
|
|
|
public int IdMode { get; }
|
|
|
|
|
public string ModeName { get; }
|
|
|
|
|
public double MechDrillingHours { get; }
|
2023-04-06 17:16:53 +05:00
|
|
|
|
|
|
|
|
|
public TelemetryStat(Span<TelemetryDataSaubStatDto> telemetry)
|
2023-04-05 13:36:56 +05:00
|
|
|
|
{
|
2023-04-06 17:16:53 +05:00
|
|
|
|
var telemetryFirst = telemetry[0];
|
|
|
|
|
var telemetryLast = telemetry[^1];
|
|
|
|
|
|
|
|
|
|
IdMode = telemetryFirst.IdMode;
|
|
|
|
|
ModeName = GetModeName(IdMode);
|
|
|
|
|
DateStart = telemetryFirst.DateMin;
|
|
|
|
|
DeltaDepth = telemetryLast.WellDepthMax - telemetryFirst.WellDepthMin;
|
|
|
|
|
MechDrillingHours = (telemetryLast.DateMax - telemetryFirst.DateMin).TotalHours;
|
|
|
|
|
|
|
|
|
|
BlockSpeed = new(t => t.BlockSpeedSp, t => t.BlockSpeed, null, 1, IdMode);
|
2023-05-23 13:41:27 +05:00
|
|
|
|
Pressure = new(t => t.PressureSpDelta, t => t.PressureDelta, t=>t.PressureDeltaLimitMax, 2, IdMode);
|
2023-04-06 17:16:53 +05:00
|
|
|
|
RotorTorque = new(t => t.RotorTorqueSp, t => t.RotorTorque, t=>t.RotorTorqueLimitMax, 3, IdMode);
|
|
|
|
|
AxialLoad = new(t => t.AxialLoadSp, t => t.AxialLoad, t=>t.AxialLoadLimitMax, 4, IdMode);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < telemetry.Length; i++)
|
|
|
|
|
UpdateStat(telemetry[i]);
|
|
|
|
|
|
2023-04-06 17:27:31 +05:00
|
|
|
|
UsageSaub = 100d * depthWithSaub / depthSum;
|
|
|
|
|
UsagePredictPlan = IdMode != 0 ? 100d : 0d;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 17:16:53 +05:00
|
|
|
|
private void UpdateStat(TelemetryDataSaubStatDto current)
|
2023-04-05 13:36:56 +05:00
|
|
|
|
{
|
|
|
|
|
if(previous is not null)
|
|
|
|
|
{
|
|
|
|
|
var deltaDepth = current.WellDepthMin - previous.WellDepthMin;
|
|
|
|
|
if(deltaDepth > 0)
|
|
|
|
|
{
|
|
|
|
|
var deltaHours = (current.DateMin - previous.DateMax).TotalHours;
|
|
|
|
|
depthSum += deltaDepth;
|
|
|
|
|
hoursSum += deltaHours;
|
|
|
|
|
|
|
|
|
|
if(current.IdMode == 1 || current.IdMode == 3)
|
|
|
|
|
depthWithSaub += deltaDepth;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 17:16:53 +05:00
|
|
|
|
previous = current;
|
2023-04-05 13:36:56 +05:00
|
|
|
|
Pressure.UpdateStat(current);
|
|
|
|
|
AxialLoad.UpdateStat(current);
|
|
|
|
|
RotorTorque.UpdateStat(current);
|
|
|
|
|
BlockSpeed.UpdateStat(current);
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 17:16:53 +05:00
|
|
|
|
private static string GetModeName(int idMode)
|
|
|
|
|
=> idMode switch
|
|
|
|
|
{
|
|
|
|
|
1 => "Ротор",
|
|
|
|
|
3 => "Слайд",
|
|
|
|
|
_ => "Ручной",
|
|
|
|
|
};
|
|
|
|
|
}
|
2023-04-18 16:22:53 +05:00
|
|
|
|
|
2023-04-03 14:59:59 +05:00
|
|
|
|
}
|