forked from ddrilling/AsbCloudServer
218 lines
7.6 KiB
C#
218 lines
7.6 KiB
C#
using AsbCloudApp.Data;
|
|
using AsbCloudApp.Data.DetectedOperation;
|
|
using AsbCloudApp.Data.Subsystems;
|
|
using AsbCloudApp.Exceptions;
|
|
using AsbCloudApp.Requests;
|
|
using AsbCloudApp.Services;
|
|
using AsbCloudDb.Model;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AsbCloudInfrastructure.Services.Subsystems;
|
|
|
|
internal class SubsystemService : ISubsystemService
|
|
{
|
|
private const int IdEnabledSubsystemSpinMaster = 128;
|
|
|
|
private const int IdSubsystemAPD = 1;
|
|
private const int IdSubsystemAPDRotor = 11;
|
|
private const int IdSubsystemAPDSlide = 12;
|
|
private const int IdSubsystemSpinMaster = 65536;
|
|
|
|
private readonly ICrudRepository<SubsystemDto> subsystemRepository;
|
|
|
|
private readonly IWellService wellService;
|
|
private readonly IDetectedOperationService detectedOperationService;
|
|
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
|
|
|
public SubsystemService(ICrudRepository<SubsystemDto> subsystemRepository,
|
|
IWellService wellService,
|
|
IDetectedOperationService detectedOperationService,
|
|
ITelemetryDataSaubService telemetryDataSaubService)
|
|
{
|
|
this.wellService = wellService;
|
|
this.subsystemRepository = subsystemRepository;
|
|
this.detectedOperationService = detectedOperationService;
|
|
this.telemetryDataSaubService = telemetryDataSaubService;
|
|
}
|
|
|
|
public async Task<IEnumerable<SubsystemStatDto>> GetStatAsync(SubsystemTimeRequest request, CancellationToken token)
|
|
{
|
|
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
|
|
{
|
|
IdsTelemetries = new[] { well.IdTelemetry!.Value },
|
|
IdsOperationCategories = WellOperationCategory.MechanicalDrillingSubIds,
|
|
|
|
GeDateStart = request.GeDate,
|
|
LeDateStart = request.LtDate,
|
|
|
|
GeDepthStart = request.GtDepth,
|
|
LeDepthStart = request.LtDepth,
|
|
};
|
|
|
|
var operations = await detectedOperationService.GetOperationSummaryAsync(detectedOperationSummaryRequest,
|
|
token);
|
|
|
|
if (!operations.Any())
|
|
return Enumerable.Empty<SubsystemStatDto>();
|
|
|
|
var stat = await CalcStatAsync(operations, token);
|
|
return stat;
|
|
}
|
|
|
|
public async Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatByActiveWells(int idCompany, DateTime? gtDate, DateTime? ltDate,
|
|
CancellationToken token)
|
|
{
|
|
var activeWells = await wellService.GetAsync(new() { IdCompany = idCompany, IdState = 1 }, token);
|
|
var result = await GetStatAsync(activeWells, gtDate, ltDate, token);
|
|
return result;
|
|
}
|
|
|
|
public async Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatByActiveWells(IEnumerable<int> wellIds, CancellationToken token)
|
|
{
|
|
var activeWells = await wellService.GetAsync(new() { Ids = wellIds, IdState = 1 }, token);
|
|
var result = await GetStatAsync(activeWells, null, null, token);
|
|
return result;
|
|
}
|
|
|
|
private async Task<IEnumerable<SubsystemStatDto>> CalcStatAsync(IEnumerable<OperationsSummaryDto> operations, CancellationToken token)
|
|
{
|
|
var subsystems = await subsystemRepository.GetAllAsync(token);
|
|
|
|
var groupedOperations = operations
|
|
.GroupBy(o => o.IdCategory);
|
|
|
|
var stat = groupedOperations.Select(groupOperations =>
|
|
{
|
|
var idSubsystem = groupOperations.Key switch
|
|
{
|
|
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 => o.EnabledSubsystems >= 1);
|
|
|
|
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),
|
|
};
|
|
|
|
subsystemStat.KUsage = subsystemStat.SumDepthInterval / subsystemStat.SumOperationDepthInterval;
|
|
|
|
return subsystemStat;
|
|
});
|
|
|
|
var apdSlidePart = stat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemAPDSlide);
|
|
|
|
if (apdSlidePart is not null)
|
|
{
|
|
var operationsWithSpinMaster = operations.Where(s => s.EnabledSubsystems == IdEnabledSubsystemSpinMaster);
|
|
|
|
var spin = new SubsystemStatDto
|
|
{
|
|
IdSubsystem = IdSubsystemSpinMaster,
|
|
SubsystemName = subsystems.FirstOrDefault(s => s.Id == IdSubsystemSpinMaster)?.Name ?? "unknown",
|
|
UsedTimeHours = operationsWithSpinMaster.Sum(o => o.SumDurationHours),
|
|
SumOperationDepthInterval = apdSlidePart.SumOperationDepthInterval,
|
|
SumOperationDurationHours = apdSlidePart.SumOperationDurationHours,
|
|
SumDepthInterval = operationsWithSpinMaster.Sum(o => o.SumDepthIntervals),
|
|
OperationCount = operationsWithSpinMaster.Sum(s => s.Count)
|
|
};
|
|
|
|
spin.KUsage = spin.SumDepthInterval / spin.SumOperationDepthInterval;
|
|
|
|
stat = stat.Append(spin);
|
|
}
|
|
|
|
var apdParts = stat.Where(s => s.IdSubsystem is IdSubsystemAPDRotor or IdSubsystemAPDSlide);
|
|
|
|
if (!apdParts.Any())
|
|
return stat;
|
|
|
|
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),
|
|
};
|
|
|
|
apdSum.KUsage = apdSum.SumDepthInterval / apdSum.SumOperationDepthInterval;
|
|
|
|
stat = stat.Append(apdSum).OrderBy(m => m.IdSubsystem);
|
|
|
|
return stat;
|
|
}
|
|
|
|
private async Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatAsync(IEnumerable<WellDto> wells, DateTime? gtDate, DateTime? ltDate,
|
|
CancellationToken token)
|
|
{
|
|
if (!wells.Any())
|
|
return Enumerable.Empty<SubsystemActiveWellStatDto>();
|
|
|
|
var idsTelemetries = wells
|
|
.Where(w => w.IdTelemetry is not null)
|
|
.Select(w => w.IdTelemetry!.Value)
|
|
.Distinct();
|
|
|
|
var wellsStat = new List<SubsystemActiveWellStatDto>();
|
|
|
|
foreach (var well in wells)
|
|
{
|
|
var hoursOffset = well.Timezone.Hours;
|
|
|
|
var dateRange = telemetryDataSaubService.GetRange(well.Id);
|
|
|
|
var beginUTC = gtDate.HasValue
|
|
? gtDate.Value.ToUtcDateTimeOffset(hoursOffset)
|
|
: dateRange.From.ToUtcDateTimeOffset(hoursOffset);
|
|
|
|
var endUTC = ltDate.HasValue
|
|
? ltDate.Value.ToUtcDateTimeOffset(hoursOffset)
|
|
: dateRange.To.ToUtcDateTimeOffset(hoursOffset);
|
|
|
|
var operations = await detectedOperationService
|
|
.GetOperationSummaryAsync(new()
|
|
{
|
|
IdsTelemetries = idsTelemetries,
|
|
IdsOperationCategories = WellOperationCategory.MechanicalDrillingSubIds,
|
|
GeDateStart = beginUTC,
|
|
LeDateEnd = endUTC,
|
|
}, token);
|
|
|
|
var wellStat = new SubsystemActiveWellStatDto { Well = well };
|
|
|
|
var telemetryOperations = operations.Where(o => o.IdTelemetry == well.IdTelemetry);
|
|
|
|
if (!telemetryOperations.Any())
|
|
continue;
|
|
|
|
var subsystemStat = await CalcStatAsync(telemetryOperations, token);
|
|
|
|
if (!subsystemStat.Any())
|
|
continue;
|
|
|
|
wellStat.SubsystemAPD = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemAPD);
|
|
wellStat.SubsystemSpinMaster = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemSpinMaster);
|
|
}
|
|
|
|
return wellsStat;
|
|
}
|
|
} |