diff --git a/AsbCloudApp/Data/DetectedOperation/DetectedOperationDto.cs b/AsbCloudApp/Data/DetectedOperation/DetectedOperationDto.cs
index 0b9a2f91..cdc6571b 100644
--- a/AsbCloudApp/Data/DetectedOperation/DetectedOperationDto.cs
+++ b/AsbCloudApp/Data/DetectedOperation/DetectedOperationDto.cs
@@ -39,9 +39,9 @@ namespace AsbCloudApp.Data.DetectedOperation
public DateTime DateEnd { get; set; }
///
- /// Продолжительность операции в часах
+ /// Продолжительность операции в минутах
///
- public double DurationHours => (DateEnd - DateStart).TotalHours;
+ public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
///
/// глубина на начало операции, м
diff --git a/AsbCloudApp/Requests/SubsystemRequest.cs b/AsbCloudApp/Requests/SubsystemRequest.cs
index 79c88530..23a7e70a 100644
--- a/AsbCloudApp/Requests/SubsystemRequest.cs
+++ b/AsbCloudApp/Requests/SubsystemRequest.cs
@@ -17,6 +17,11 @@ namespace AsbCloudApp.Requests
[Required]
public int IdWell { get; set; }
+ ///
+ /// Идентификатор бурильщика
+ ///
+ public int? IdDriller { get; set; }
+
///
/// Больше или равно дате
///
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs
index 3e8b0fa1..68eda39e 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs
@@ -71,9 +71,7 @@ public class DetectorDrilling : DetectorAbstract
private static (double avgRotorSpeed, double dispersionOfNormalizedRotorSpeed) CalcCriteries(DetectableTelemetry[] telemetry, int begin, int end)
{
- var telemetryRange = telemetry[begin..end]
- .OrderBy(t => t.DateTime).ToList();
-
+ var telemetryRange = telemetry[begin..end];
var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed);
var dispersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed / avgRotorSpeed - 1, 2));
return (avgRotorSpeed, dispersion);
diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs
index 6b5970b9..7ff4076a 100644
--- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs
+++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs
@@ -27,6 +27,8 @@ internal class SubsystemService : ISubsystemService
private readonly IDetectedOperationService detectedOperationService;
private readonly ITelemetryDataSaubService telemetryDataSaubService;
+ private IDictionary subsystems = new Dictionary();
+
public SubsystemService(ICrudRepository subsystemRepository,
IWellService wellService,
IDetectedOperationService detectedOperationService,
@@ -43,21 +45,25 @@ internal class SubsystemService : ISubsystemService
var well = await wellService.GetOrDefaultAsync(request.IdWell, token)
?? throw new ArgumentInvalidException(nameof(request.IdWell), $"Well Id: {request.IdWell} does not exist");
- var detectedOperationSummaryRequest = new DetectedOperationSummaryRequest
+ var detectedOperationSummaryRequest = new DetectedOperationRequest
{
+ IdWell = request.IdWell,
IdsTelemetries = new[] { well.IdTelemetry!.Value },
- IdsOperationCategories = WellOperationCategory.MechanicalDrillingSubIds,
+ IdsCategories = WellOperationCategory.MechanicalDrillingSubIds,
GeDateStart = request.GeDate,
- LeDateStart = request.LeDate,
+ LeDateEnd = request.LeDate,
- GeDepthStart = request.GeDepth,
- LeDepthStart = request.LeDepth,
+ GeDepth = request.GeDepth,
+ LeDepth = request.LeDepth,
};
- var operations = await detectedOperationService.GetOperationSummaryAsync(detectedOperationSummaryRequest,
+ var operations = await detectedOperationService.GetOperationsAsync(detectedOperationSummaryRequest,
token);
+ if (request.IdDriller.HasValue)
+ operations = operations.Where(o => o.Driller is not null && o.Driller.Id == request.IdDriller.Value);
+
if (!operations.Any())
return Enumerable.Empty();
@@ -81,89 +87,119 @@ internal class SubsystemService : ISubsystemService
var result = await GetStatAsync(activeWells, null, null, token);
return result;
}
-
- private async Task> CalcStatAsync(IEnumerable operations, CancellationToken token)
+
+ private async Task> CalcStatAsync(IEnumerable operations, CancellationToken token)
{
- var subsystems = await subsystemRepository.GetAllAsync(token);
+ if (!subsystems.Any())
+ subsystems = (await subsystemRepository.GetAllAsync(token)).ToDictionary(s => s.Id, s => s);
- var groupedOperations = operations
- .GroupBy(o => o.IdCategory);
+ var oscillationStat = CalcOscillationStat(operations);
+ var apdStat = CalcApdStat(operations);
- var stat = groupedOperations.Select(groupOperations =>
+ var stat = new List { oscillationStat };
+ stat.AddRange(apdStat);
+
+ return stat;
+ }
+
+ private SubsystemStatDto CalcOscillationStat(IEnumerable operations)
+ {
+ operations = operations.Where(o => o.IdCategory == WellOperationCategory.IdSlide);
+
+ var (sumDepthInterval, usedTimeHours, operationCount) = AggregateOperations(IdSubsystemOscillation, operations);
+
+ var oscillationStat = new SubsystemStatDto
{
- var idSubsystem = groupOperations.Key switch
+ IdSubsystem = IdSubsystemOscillation,
+ SubsystemName = subsystems.TryGetValue(IdSubsystemOscillation, out var subsystemDto) ? subsystemDto.Name : "unknown",
+ UsedTimeHours = usedTimeHours,
+ SumOperationDepthInterval = operations.Sum(o => o.DepthEnd - o.DepthStart),
+ SumOperationDurationHours = operations.Sum(o => o.DurationMinutes / 60),
+ SumDepthInterval = sumDepthInterval,
+ OperationCount = operationCount,
+ };
+
+ oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval;
+
+ return oscillationStat;
+ }
+
+ private IEnumerable CalcApdStat(IEnumerable operations)
+ {
+ var apdRotorAndSlide = operations
+ .Where(o => WellOperationCategory.MechanicalDrillingSubIds.Contains(o.IdCategory))
+ .GroupBy(o => o.IdCategory)
+ .Select(group =>
{
- WellOperationCategory.IdRotor => IdSubsystemAPDRotor,
- WellOperationCategory.IdSlide => IdSubsystemAPDSlide,
- _ => throw new ArgumentException($"IdCategory: {groupOperations.Key} does not supported in this method",
- nameof(groupOperations.Key)),
- };
-
- var operationsWithEnableSubsystems = groupOperations.Where(o =>
- (EnabledSubsystemsFlags.AutoRotor |
- EnabledSubsystemsFlags.AutoSlide |
- EnabledSubsystemsFlags.AutoOscillation).HasEnabledSubsystems(o.EnabledSubsystems));
-
- var subsystemStat = new SubsystemStatDto
- {
- IdSubsystem = idSubsystem,
- SubsystemName = subsystems.FirstOrDefault(s => s.Id == idSubsystem)?.Name ?? "unknown",
- UsedTimeHours = operationsWithEnableSubsystems.Sum(o => o.SumDurationHours),
- SumOperationDepthInterval = groupOperations.Sum(o => o.SumDepthIntervals),
- SumOperationDurationHours = groupOperations.Sum(o => o.SumDurationHours),
- SumDepthInterval = operationsWithEnableSubsystems.Sum(o => o.SumDepthIntervals),
- OperationCount = operationsWithEnableSubsystems.Sum(o => o.Count),
- };
+ var idSubsystem = group.Key switch
+ {
+ WellOperationCategory.IdRotor => IdSubsystemAPDRotor,
+ WellOperationCategory.IdSlide => IdSubsystemAPDSlide,
+ _ => throw new ArgumentException($"IdCategory: {group.Key} does not supported in this method", nameof(group.Key))
+ };
- subsystemStat.KUsage = subsystemStat.SumDepthInterval / subsystemStat.SumOperationDepthInterval;
-
- return subsystemStat;
- });
+ var (sumDepthInterval, usedTimeHours, operationCount) = AggregateOperations(idSubsystem, group);
- var apdSlidePart = stat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemAPDSlide);
+ var subsystemStat = new SubsystemStatDto
+ {
+ IdSubsystem = idSubsystem,
+ SubsystemName = subsystems.TryGetValue(idSubsystem, out var subsystemDto) ? subsystemDto.Name : "unknown",
+ UsedTimeHours = usedTimeHours,
+ SumOperationDepthInterval = group.Sum(o => o.DepthEnd - o.DepthStart),
+ SumOperationDurationHours = group.Sum(o => o.DurationMinutes / 60),
+ SumDepthInterval = sumDepthInterval,
+ OperationCount = operationCount,
+ };
- if (apdSlidePart is not null)
- {
- var operationsWithOscillation =
- operations.Where(o => EnabledSubsystemsFlags.AutoOscillation.HasEnabledSubsystems(o.EnabledSubsystems));
+ subsystemStat.KUsage = subsystemStat.SumDepthInterval / subsystemStat.SumOperationDepthInterval;
- var spinMaster = new SubsystemStatDto
- {
- IdSubsystem = IdSubsystemOscillation,
- SubsystemName = subsystems.FirstOrDefault(s => s.Id == IdSubsystemOscillation)?.Name ?? "unknown",
- UsedTimeHours = operationsWithOscillation.Sum(o => o.SumDurationHours),
- SumOperationDepthInterval = apdSlidePart.SumOperationDepthInterval,
- SumOperationDurationHours = apdSlidePart.SumOperationDurationHours,
- SumDepthInterval = operationsWithOscillation.Sum(o => o.SumDepthIntervals),
- OperationCount = operationsWithOscillation.Sum(s => s.Count)
- };
-
- spinMaster.KUsage = spinMaster.SumDepthInterval / spinMaster.SumOperationDepthInterval;
-
- stat = stat.Append(spinMaster);
- }
-
- var apdParts = stat.Where(s => s.IdSubsystem is IdSubsystemAPDRotor or IdSubsystemAPDSlide);
-
- if (!apdParts.Any())
- return stat;
+ return subsystemStat;
+ });
+
+ if (!apdRotorAndSlide.Any())
+ return Enumerable.Empty();
var apdSum = new SubsystemStatDto
{
IdSubsystem = IdSubsystemAPD,
- SubsystemName = "АПД",
- UsedTimeHours = apdParts.Sum(part => part.UsedTimeHours),
- SumOperationDepthInterval = apdParts.Sum(part => part.SumOperationDepthInterval),
- SumOperationDurationHours = apdParts.Sum(part => part.SumOperationDurationHours),
- SumDepthInterval = apdParts.Sum(part => part.SumDepthInterval),
- OperationCount = apdParts.Sum(part => part.OperationCount),
+ SubsystemName = subsystems.TryGetValue(IdSubsystemAPD, out var subsystemDto) ? subsystemDto.Name : "unknown",
+ UsedTimeHours = apdRotorAndSlide.Sum(part => part.UsedTimeHours),
+ SumOperationDepthInterval = apdRotorAndSlide.Sum(part => part.SumOperationDepthInterval),
+ SumOperationDurationHours = apdRotorAndSlide.Sum(part => part.SumOperationDurationHours),
+ SumDepthInterval = apdRotorAndSlide.Sum(part => part.SumDepthInterval),
+ OperationCount = apdRotorAndSlide.Sum(part => part.OperationCount),
};
apdSum.KUsage = apdSum.SumDepthInterval / apdSum.SumOperationDepthInterval;
-
- stat = stat.Append(apdSum).OrderBy(m => m.IdSubsystem);
- return stat;
+ var apdStat = new List { apdSum };
+ apdStat.AddRange(apdRotorAndSlide);
+
+ return apdStat;
+ }
+
+ private static (double SumDepthInterval, double UsedTimeHours, int Count) AggregateOperations(int idSubsystem,
+ IEnumerable operations) =>
+ idSubsystem switch
+ {
+ IdSubsystemAPDRotor => CalcOperationsByEnableSubsystems(operations, EnabledSubsystemsFlags.AutoRotor),
+ IdSubsystemAPDSlide => CalcOperationsByEnableSubsystems(operations,
+ EnabledSubsystemsFlags.AutoSlide | EnabledSubsystemsFlags.AutoOscillation),
+ IdSubsystemOscillation => CalcOperationsByEnableSubsystems(operations, EnabledSubsystemsFlags.AutoOscillation),
+ _ => throw new ArgumentException($"IdSubsystem: {idSubsystem} does not supported in this method", nameof(idSubsystem))
+ };
+
+ private static (double SumDepthInterval, double UsedTimeHours, int OperationCount) CalcOperationsByEnableSubsystems(
+ IEnumerable operations,
+ EnabledSubsystemsFlags enabledSubsystems)
+ {
+ var filtered = operations.Where(o => enabledSubsystems.HasEnabledSubsystems(o.EnabledSubsystems));
+
+ var sumDepthInterval = filtered.Sum(o => o.DepthEnd - o.DepthStart);
+ var usedTimeHours = filtered.Sum(o => o.DurationMinutes / 60);
+ var operationCount = filtered.Count();
+
+ return (sumDepthInterval, usedTimeHours, operationCount);
}
private async Task> GetStatAsync(IEnumerable wells,
@@ -195,14 +231,16 @@ internal class SubsystemService : ISubsystemService
? ltDate.Value.ToUtcDateTimeOffset(hoursOffset)
: dateRange.To.ToUtcDateTimeOffset(hoursOffset);
+ var request = new DetectedOperationRequest
+ {
+ IdsTelemetries = idsTelemetries,
+ IdsCategories = WellOperationCategory.MechanicalDrillingSubIds,
+ GeDateStart = beginUTC,
+ LeDateEnd = endUTC,
+ };
+
var operations = await detectedOperationService
- .GetOperationSummaryAsync(new()
- {
- IdsTelemetries = idsTelemetries,
- IdsOperationCategories = WellOperationCategory.MechanicalDrillingSubIds,
- GeDateStart = beginUTC,
- LeDateEnd = endUTC,
- }, token);
+ .GetOperationsAsync(request, token);
var wellStat = new SubsystemActiveWellStatDto { Well = well };