forked from ddrilling/AsbCloudServer
Фильтрация статистики ртк не по глубине, а по датам
This commit is contained in:
commit
29cf09f9bf
@ -84,7 +84,7 @@ public class ProcessMapReportDataSaubStatDto
|
||||
/// <summary>
|
||||
/// Обороты ВСП, об/мин
|
||||
/// </summary>
|
||||
public ProcessMapReportDataSaubStatParamsDto Turnover { get; set; } = new();
|
||||
public ProcessMapReportDataSaubStatParamsDto TopDriveSpeed { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Расход, л/с
|
||||
|
@ -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<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell> processMapPlanBaseRepository;
|
||||
private readonly IDataSaubStatRepository dataSaubStatRepository;
|
||||
private readonly IWellOperationRepository wellOperationRepository;
|
||||
private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
|
||||
|
||||
public ProcessMapReportDataSaubStatService(IWellService wellService,
|
||||
IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell> processMapPlanBaseRepository,
|
||||
IDataSaubStatRepository dataSaubStatRepository,
|
||||
IWellOperationRepository wellOperationRepository,
|
||||
IWellOperationCategoryRepository wellOperationCategoryRepository
|
||||
)
|
||||
{
|
||||
private readonly IWellService wellService;
|
||||
private readonly IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell> 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<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell> processMapPlanBaseRepository,
|
||||
IDataSaubStatRepository dataSaubStatRepository,
|
||||
IWellOperationRepository wellOperationRepository,
|
||||
IWellOperationCategoryRepository wellOperationCategoryRepository
|
||||
)
|
||||
public async Task<IEnumerable<ProcessMapReportDataSaubStatDto>> 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<ProcessMapReportDataSaubStatDto>();
|
||||
|
||||
var requestProcessMapPlan = new ProcessMapPlanBaseRequestWithWell(idWell);
|
||||
var processMapPlanWellDrillings = await processMapPlanBaseRepository.Get(requestProcessMapPlan, token);
|
||||
|
||||
if (!processMapPlanWellDrillings.Any())
|
||||
return Enumerable.Empty<ProcessMapReportDataSaubStatDto>();
|
||||
|
||||
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<ProcessMapReportDataSaubStatDto>();
|
||||
|
||||
public async Task<IEnumerable<ProcessMapReportDataSaubStatDto>> 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<ProcessMapReportDataSaubStatDto>();
|
||||
|
||||
var wellOperationCategories = wellOperationCategoryRepository.Get(false);
|
||||
var wellSectionTypes = wellOperationRepository.GetSectionTypes();
|
||||
|
||||
var result = CalcByIntervals(
|
||||
request,
|
||||
processMapPlanWellDrillings,
|
||||
dataSaubStats,
|
||||
wellOperations,
|
||||
wellOperationCategories,
|
||||
wellSectionTypes);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private IEnumerable<ProcessMapReportDataSaubStatDto> CalcByIntervals(
|
||||
DataSaubStatRequest request,
|
||||
IEnumerable<ProcessMapPlanDrillingDto> processMapPlanWellDrillings,
|
||||
Span<DataSaubStatDto> dataSaubStats,
|
||||
IEnumerable<WellOperationDto> wellOperations,
|
||||
IEnumerable<WellOperationCategoryDto> wellOperationCategories,
|
||||
IEnumerable<WellSectionTypeDto> wellSectionTypes
|
||||
)
|
||||
{
|
||||
var list = new List<ProcessMapReportDataSaubStatDto>();
|
||||
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<ProcessMapReportDataSaubStatDto>();
|
||||
|
||||
var requestProcessMapPlan = new ProcessMapPlanBaseRequestWithWell(idWell);
|
||||
var processMapPlanWellDrillings = await processMapPlanBaseRepository.Get(requestProcessMapPlan, token);
|
||||
|
||||
if (!processMapPlanWellDrillings.Any())
|
||||
return Enumerable.Empty<ProcessMapReportDataSaubStatDto>();
|
||||
|
||||
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<ProcessMapReportDataSaubStatDto>();
|
||||
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<ProcessMapReportDataSaubStatDto>();
|
||||
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<ProcessMapReportDataSaubStatDto> CalcByIntervals(
|
||||
DataSaubStatRequest request,
|
||||
IEnumerable<ProcessMapPlanDrillingDto> processMapPlanWellDrillings,
|
||||
Span<DataSaubStatDto> dataSaubStats,
|
||||
IEnumerable<WellOperationDto> wellOperations,
|
||||
IEnumerable<WellOperationCategoryDto> wellOperationCategories,
|
||||
IEnumerable<WellSectionTypeDto> wellSectionTypes
|
||||
)
|
||||
{
|
||||
var list = new List<ProcessMapReportDataSaubStatDto>();
|
||||
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<DataSaubStatDto> 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<DataSaubStatDto> 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<double?>
|
||||
{
|
||||
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<DataSaubStatDto> 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<double?>
|
||||
{
|
||||
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<DataSaubStatDto> 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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user