diff --git a/AsbCloudApp/Data/LimitingParameterDto.cs b/AsbCloudApp/Data/LimitingParameterDto.cs
index 73a8a5b7..19b182a5 100644
--- a/AsbCloudApp/Data/LimitingParameterDto.cs
+++ b/AsbCloudApp/Data/LimitingParameterDto.cs
@@ -11,27 +11,27 @@ namespace AsbCloudApp.Data
///
/// Нет ограничения
///
- public static int NoLimit = 0;
+ public const int NoLimit = 0;
///
/// МСП
///
- public static int RopPlan = 1;
+ public const int RopPlan = 1;
///
/// Давление
///
- public static int Pressure = 2;
+ public const int Pressure = 2;
///
/// Осевая нагрузка
///
- public static int AxialLoad = 3;
+ public const int AxialLoad = 3;
///
/// Момент
///
- public static int RotorTorque = 4;
+ public const int RotorTorque = 4;
///
/// Идентификатор скважины
///
diff --git a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs
new file mode 100644
index 00000000..abcef62b
--- /dev/null
+++ b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs
@@ -0,0 +1,98 @@
+using System;
+
+namespace AsbCloudApp.Data.ProcessMaps.Report;
+
+///
+/// Модель РТК
+///
+public class ProcessMapReportDataSaubStatDto
+{
+ ///
+ /// Время, затраченное на бурение интервала, в часах
+ ///
+ public double DrilledTime { get; set; } = 0;
+
+ ///
+ /// Идентификатор скважины
+ ///
+ public int IdWell { get; set; }
+
+ ///
+ /// Id секции скважины
+ ///
+ public int IdWellSectionType { get; set; }
+
+ ///
+ /// Название секции скважины
+ ///
+ public string WellSectionTypeName { get; set; } = null!;
+
+ ///
+ /// Глубина по стволу от, м
+ ///
+ /// на начало интервала
+ ///
+ ///
+ public double DepthStart { get; set; }
+
+ ///
+ /// Глубина по стволу до, м
+ ///
+ /// на конец интервала
+ ///
+ ///
+ public double DepthEnd { get; set; }
+
+ ///
+ /// Дата/ время
+ ///
+ /// на начало интервала
+ ///
+ ///
+ public DateTime DateStart { get; set; }
+
+ ///
+ /// Режим бурения (Ротор/слайд/ручной)
+ ///
+ public string DrillingMode { get; set; } = null!;
+
+ ///
+ /// Проходка, м
+ ///
+ public double? DeltaDepth { get; set; }
+
+ ///
+ /// Перепад давления, атм
+ ///
+ public ProcessMapReportDataSaubStatParamsDto PressureDiff { get; set; } = new();
+
+ ///
+ /// Нагрузка, т
+ ///
+ public ProcessMapReportDataSaubStatParamsDto AxialLoad { get; set; } = new();
+
+ ///
+ /// Момент на ВСП, кНхМ
+ ///
+ public ProcessMapReportDataSaubStatParamsDto TopDriveTorque { get; set; } = new();
+
+ ///
+ /// Ограничение скорости, м/ч
+ ///
+ public ProcessMapReportDataSaubStatParamsDto SpeedLimit { get; set; } = new();
+
+ ///
+ /// Обороты ВСП, об/мин
+ ///
+ public ProcessMapReportDataSaubStatParamsDto Turnover { get; set; } = new();
+
+ ///
+ /// Расход, л/с
+ ///
+ public ProcessMapReportDataSaubStatParamsDto Flow { get; set; } = new();
+
+ ///
+ /// Механическая скорость, м/ч
+ ///
+ public PlanFactDto Rop { get; set; } = new();
+}
\ No newline at end of file
diff --git a/AsbCloudApp/Extensions/ChangeLogExtensions.cs b/AsbCloudApp/Extensions/ChangeLogExtensions.cs
new file mode 100644
index 00000000..c52e33dd
--- /dev/null
+++ b/AsbCloudApp/Extensions/ChangeLogExtensions.cs
@@ -0,0 +1,32 @@
+using AsbCloudApp.Data;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AsbCloudApp.Extensions
+{
+ ///
+ /// Расширения для поиска в истории
+ ///
+ public static class ChangeLogExtensions
+ {
+ ///
+ /// Действительные на момент времени значения
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static IEnumerable WhereActualAtMoment(this IEnumerable items, DateTimeOffset moment)
+ where T : ChangeLogAbstract
+ {
+ var actualItems = items
+ .Where(item => item.Creation >= moment)
+ .Where(item => item.Obsolete is null || item.Obsolete <= moment);
+
+ return actualItems;
+ }
+ }
+}
diff --git a/AsbCloudApp/Repositories/IDataSaubStatRepository.cs b/AsbCloudApp/Repositories/IDataSaubStatRepository.cs
index d03554ea..941d6465 100644
--- a/AsbCloudApp/Repositories/IDataSaubStatRepository.cs
+++ b/AsbCloudApp/Repositories/IDataSaubStatRepository.cs
@@ -14,9 +14,11 @@ namespace AsbCloudApp.Repositories
/// Получение записей по ключу телеметрии
///
/// ключ телеметрии
+ /// начальная глубина
+ /// конечная глубина
///
///
- Task> GetAsync(int idTelemetry, CancellationToken token);
+ Task> GetAsync(int idTelemetry, double geDepth, double leDepth, CancellationToken token);
///
/// Получение последних по дате окончания бурения записей в разрезе телеметрий
diff --git a/AsbCloudApp/Requests/DataSaubStatRequest.cs b/AsbCloudApp/Requests/DataSaubStatRequest.cs
index 78bedc14..b4400f3e 100644
--- a/AsbCloudApp/Requests/DataSaubStatRequest.cs
+++ b/AsbCloudApp/Requests/DataSaubStatRequest.cs
@@ -1,4 +1,6 @@
-namespace AsbCloudApp.Requests
+using System.ComponentModel.DataAnnotations;
+
+namespace AsbCloudApp.Requests
{
///
/// Параметры запроса для построения отчёта
@@ -7,18 +9,24 @@
{
///
/// Изменение уставки факт перепада давления от первого значения в начале интервала
+ /// Не менее 5 атм и не более 15(50) атм;
///
- public double DeltaPressure { get; set; }
+ [Range(5, 15, ErrorMessage = "Изменение уставки факт перепада давления не может быть меньше 5 и больше 15 атм")]
+ public double DeltaPressure { get; set; } = 5d;
///
- /// Изменение уставки факт осевой нагрузки от первого значения в начале интервала
+ /// Изменение уставки факт осевой нагрузки от первого значения в начале интервала
+ /// Не менее 1 т и не более 5(20) т;
///
- public double DeltaAxialLoad { get; set; }
+ [Range(1, 5, ErrorMessage = "Изменение уставки факт осевой нагрузки не может быть меньше 1 и больше 5 т")]
+ public double DeltaAxialLoad { get; set; } = 1d;
///
- /// Изменение уставки момента от первого значения в начале интервала
+ /// Изменение уставки момента от первого значения в начале интервала
+ /// Не менее 5 кН*м и не более 10(20) кН*м.
///
- public double DeltaRotorTorque { get; set; }
+ [Range(5, 10, ErrorMessage = "Изменение уставки момента не может быть меньше 5 и больше 10 кН*м")]
+ public double DeltaRotorTorque { get; set; } = 5d;
///
/// Изменение ограничения нагрузки от первого значения в начале интервала
diff --git a/AsbCloudInfrastructure/Repository/DataSaubStatRepository.cs b/AsbCloudInfrastructure/Repository/DataSaubStatRepository.cs
index 3e18e42e..72737a0b 100644
--- a/AsbCloudInfrastructure/Repository/DataSaubStatRepository.cs
+++ b/AsbCloudInfrastructure/Repository/DataSaubStatRepository.cs
@@ -40,12 +40,14 @@ namespace AsbCloudInfrastructure.Repository
return result;
}
- public async Task> GetAsync(int idTelemetry, CancellationToken token)
+ public async Task> GetAsync(int idTelemetry, double geDepth, double leDepth, CancellationToken token)
{
var timeSpan = TimeSpan.FromHours(telemetryService.GetTimezone(idTelemetry).Hours);
var stats = await db.Set()
.Where(s => s.IdTelemetry == idTelemetry)
+ .Where(s => s.DepthStart >= geDepth)
+ .Where(s => s.DepthEnd <= leDepth)
.ToArrayAsync(token);
var result = stats.Select(s => ConvertToDto(s, timeSpan));
diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs
index 93751e36..35bf06a8 100644
--- a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs
+++ b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs
@@ -2,6 +2,7 @@
using AsbCloudApp.Data.ProcessMapPlan;
using AsbCloudApp.Data.ProcessMaps.Report;
using AsbCloudApp.Exceptions;
+using AsbCloudApp.Extensions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
@@ -48,24 +49,30 @@ namespace AsbCloudInfrastructure.Services.ProcessMaps.Report
if (!processMapPlanWellDrillings.Any())
return Enumerable.Empty();
- var dataSaubStats =
- (await dataSaubStatRepository.GetAsync(well.IdTelemetry.Value, token)).ToArray();
-
- if (!dataSaubStats.Any())
- return Enumerable.Empty();
+ var geDepth = processMapPlanWellDrillings.Min(p => p.DepthStart);
+ var leDepth = processMapPlanWellDrillings.Max(p => p.DepthEnd);
var requestWellOperationFact = new WellOperationRequest()
{
IdWell = idWell,
- OperationType = WellOperation.IdOperationTypeFact
+ OperationType = WellOperation.IdOperationTypeFact,
+ GeDepth = geDepth,
+ LeDepth = leDepth
};
var wellOperations = await wellOperationRepository
.GetAsync(requestWellOperationFact, token);
if (!wellOperations.Any())
return Enumerable.Empty();
- var timeZone = TimeSpan.FromHours(wellService.GetTimezone(idWell).Hours);
- var result = CalcByIntervals(request, processMapPlanWellDrillings, dataSaubStats, wellOperations, timeZone);
+ var dataSaubStats =
+ (await dataSaubStatRepository.GetAsync(well.IdTelemetry.Value, geDepth, leDepth, token)).ToArray();
+
+ if (!dataSaubStats.Any())
+ return Enumerable.Empty();
+
+ var wellOperationCategories = wellOperationRepository.GetCategories(false);
+
+ var result = CalcByIntervals(request, processMapPlanWellDrillings, dataSaubStats, wellOperations, wellOperationCategories);
return result;
}
@@ -75,7 +82,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMaps.Report
IEnumerable processMapPlanWellDrillings,
Span dataSaubStats,
IEnumerable wellOperations,
- TimeSpan timeZone
+ IEnumerable wellOperationCategories
)
{
var list = new List();
@@ -88,56 +95,66 @@ namespace AsbCloudInfrastructure.Services.ProcessMaps.Report
if (IsNewInterval(currentElem, firstElemInInterval, request) || i == dataSaubStats.Length - 1)
{
var length = i - indexStart;
- var elem = CalcStat(processMapPlanWellDrillings, dataSaubStats, indexStart, length, wellOperations, timeZone);
- if (elem != null)
- list.Add(elem);
+
+ var span = dataSaubStats.Slice(indexStart, length);
indexStart = i;
firstElemInInterval = currentElem;
+
+ var firstElemInSpan = span[0];
+ var lastElemInISpan = span[^1];
+
+ var nearestOperation = wellOperations.MinBy(o => firstElemInSpan.DateStart - o.DateStart);
+ if (nearestOperation is null)
+ continue;
+
+ var processMapPlanFilteredByDepth = processMapPlanWellDrillings
+ .Where(x => x.IdWellSectionType == nearestOperation.IdWellSectionType)
+ .Where(x => x.DepthStart >= firstElemInSpan.DepthStart)
+ .Where(x => x.DepthEnd <= lastElemInISpan.DepthEnd)
+ .WhereActualAtMoment(DateTimeOffset.Now)
+ .ToArray();
+
+ if (!processMapPlanFilteredByDepth.Any())
+ continue;
+
+ var wellOperationCategoryName = wellOperationCategories.
+ Where(c => c.Id == currentElem.IdCategory)
+ .FirstOrDefault()
+ ?.Name ?? string.Empty;
+
+ var elem = CalcStat(processMapPlanFilteredByDepth, span, nearestOperation, wellOperationCategoryName);
+ if (elem is not null)
+ list.Add(elem);
}
}
return list;
}
private ProcessMapReportDataSaubStatDto? CalcStat(
- IEnumerable processMapPlanDrillingDtos,
- Span dataSaubStats,
- int indexStart,
- int length,
- IEnumerable wellOperations,
- TimeSpan timeZone
+ ProcessMapPlanDrillingDto[] processMapPlanFilteredByDepth,
+ Span span,
+ WellOperationDto nearestOperation,
+ string wellOperationCategoryName
)
{
- var span = dataSaubStats.Slice(indexStart, length);
var firstElemInInterval = span[0];
var lastElemInInterval = span[^1];
- var nearestOperation = wellOperations?.MinBy(o => firstElemInInterval.DateStart - o.DateStart);
- if (nearestOperation is null)
- return null;
-
- var processMapPlanFilteredByDepth = processMapPlanDrillingDtos
- .Where(x => x.IdWellSectionType == nearestOperation.IdWellSectionType)
- .Where(x => x.DepthStart >= firstElemInInterval.DepthStart)
- .Where(x => x.DepthEnd <= lastElemInInterval.DepthEnd)
- .ToArray();
- if (!processMapPlanFilteredByDepth.Any())
- return null;
-
var deltaDepth = lastElemInInterval.DepthEnd - firstElemInInterval.DepthStart;
- var drilledTime = (lastElemInInterval.DateEnd - firstElemInInterval.DateStart).TotalHours;
+
var aggregatedValues = CalcAggregate(span);
return new ProcessMapReportDataSaubStatDto()
{
- DateStart = firstElemInInterval.DateStart.ToOffset(timeZone).DateTime,
+ DateStart = firstElemInInterval.DateStart.DateTime,
WellSectionTypeName = nearestOperation.WellSectionTypeName ?? string.Empty,
DepthStart = firstElemInInterval.DepthStart,
DepthEnd = lastElemInInterval.DepthEnd,
DeltaDepth = deltaDepth,
- DrilledTime = drilledTime,
- DrillingMode = nearestOperation.CategoryName ?? string.Empty,
+ DrilledTime = aggregatedValues.DrilledTime,
+ DrillingMode = wellOperationCategoryName,
PressureDiff = new ProcessMapReportDataSaubStatParamsDto()
{
SetpointPlanMax = processMapPlanFilteredByDepth.Max(p => p.DeltaPressurePlan),
@@ -171,7 +188,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMaps.Report
SetpointPlanMax = processMapPlanFilteredByDepth.Max(p => p.RopPlan),
SetpointPlanMin = processMapPlanFilteredByDepth.Min(p => p.RopPlan),
SetpointFact = aggregatedValues.BlockSpeedSp,
- FactWavg = deltaDepth / drilledTime,
+ FactWavg = deltaDepth / aggregatedValues.DrilledTime,
SetpointUsage = aggregatedValues.SetpointUsageRopPlan
},
Turnover = new ProcessMapReportDataSaubStatParamsDto
@@ -191,7 +208,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMaps.Report
Rop = new PlanFactDto
{
Plan = CalcRopPlan(processMapPlanFilteredByDepth),
- Fact = deltaDepth / drilledTime
+ Fact = deltaDepth / aggregatedValues.DrilledTime
},
};
}
@@ -210,7 +227,8 @@ namespace AsbCloudInfrastructure.Services.ProcessMaps.Report
double SetpointUsagePressure,
double SetpointUsageAxialLoad,
double SetpointUsageRotorTorque,
- double SetpointUsageRopPlan
+ double SetpointUsageRopPlan,
+ double DrilledTime
) CalcAggregate(Span span)
{
var sumPressure = 0.0;
@@ -229,11 +247,13 @@ namespace AsbCloudInfrastructure.Services.ProcessMaps.Report
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;
+ sumPressure += diffDepth * ((span[i].PressureIdle ?? 0) - span[i].Pressure);
sumAxialLoadSp += diffDepth * (span[i].AxialLoadSp ?? 0);
sumAxialLoad += diffDepth * span[i].AxialLoad;
sumRotorTorqueSp += diffDepth * (span[i].RotorTorqueSp ?? 0);
@@ -254,8 +274,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMaps.Report
sumDiffDepthByRopPlan += span[i].DepthEnd - span[i].DepthStart;
diffDepthTotal += diffDepth;
-
-
+ drilledTime += (span[i].DateEnd - span[i].DateStart).TotalHours;
}
return (
Pressure: sumPressure / diffDepthTotal,
@@ -271,7 +290,8 @@ namespace AsbCloudInfrastructure.Services.ProcessMaps.Report
SetpointUsagePressure: sumDiffDepthByPressure / diffDepthTotal,
SetpointUsageAxialLoad: sumDiffDepthByAxialLoad / diffDepthTotal,
SetpointUsageRotorTorque: sumDiffDepthByRotorTorque / diffDepthTotal,
- SetpointUsageRopPlan: sumDiffDepthByRopPlan / diffDepthTotal
+ SetpointUsageRopPlan: sumDiffDepthByRopPlan / diffDepthTotal,
+ DrilledTime: drilledTime
);
}