DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/WellInfoService.cs

246 lines
10 KiB
C#
Raw Normal View History

2023-02-16 16:27:14 +05:00
using AsbCloudApp.Data;
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Data.WITS;
2023-02-16 16:27:14 +05:00
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudApp.Services.Subsystems;
using AsbCloudInfrastructure.Background;
using AsbCloudInfrastructure.Services.SAUB;
2023-02-16 16:27:14 +05:00
using Mapster;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.IntegrationEvents;
using AsbCloudApp.IntegrationEvents.Interfaces;
2023-02-16 16:27:14 +05:00
namespace AsbCloudInfrastructure.Services;
public class WellInfoService
2023-02-16 16:27:14 +05:00
{
public class WorkWellInfoUpdate : Work
2023-02-16 16:27:14 +05:00
{
public WorkWellInfoUpdate()
: base("Well statistics update")
2023-02-16 16:27:14 +05:00
{
Timeout = TimeSpan.FromMinutes(30);
2023-02-16 16:27:14 +05:00
}
protected override async Task Action(string id, IServiceProvider services, Action<string, double?> onProgressCallback, CancellationToken token)
2023-02-16 16:27:14 +05:00
{
var wellService = services.GetRequiredService<IWellService>();
var operationsStatService = services.GetRequiredService<IOperationsStatService>();
var processMapPlanWellDrillingRepository = services.GetRequiredService<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>>();
var subsystemOperationTimeService = services.GetRequiredService<ISubsystemOperationTimeService>();
var telemetryDataSaubCache = services.GetRequiredService<TelemetryDataCache<TelemetryDataSaubDto>>();
var messageHub = services.GetRequiredService<IIntegrationEventHandler<UpdateWellInfoEvent>>();
var wells = await wellService.GetAllAsync(token);
var activeWells = wells.Where(well => well.IdState == 1);
2023-02-16 16:27:14 +05:00
var wellsIds = activeWells.Select(w => w.Id);
2023-02-16 16:27:14 +05:00
var processMapPlanWellDrillingRequests = wellsIds.Select(id => new ProcessMapPlanRequest { IdWell = id });
var processMapPlanWellDrillings = await processMapPlanWellDrillingRepository.GetAsync(processMapPlanWellDrillingRequests, token);
2023-02-16 16:27:14 +05:00
var wellDepthByProcessMap = processMapPlanWellDrillings
2023-02-16 16:27:14 +05:00
.GroupBy(p => p.IdWell)
.Select(g => new
{
Id = g.Key,
DepthEnd = g.Max(p => p.DepthEnd)
});
var operationsStat = await operationsStatService.GetWellsStatAsync(wellsIds, token);
var subsystemStat = await subsystemOperationTimeService
.GetStatByActiveWells(wellsIds, token);
2023-10-10 15:06:58 +05:00
subsystemStat = subsystemStat.ToArray();
var count = activeWells.Count();
var i = 0d;
WellMapInfo = activeWells.Select(well => {
2023-02-16 16:27:14 +05:00
var wellMapInfo = well.Adapt<WellMapInfoWithComanies>();
wellMapInfo.IdState = well.IdState;
onProgressCallback($"Start updating info by well({well.Id}): {well.Caption}", i++ / count);
double? currentDepth = null;
2023-02-16 16:27:14 +05:00
TelemetryDataSaubDto? lastSaubTelemetry = null;
if (well.IdTelemetry.HasValue)
{
wellMapInfo.IdTelemetry = well.IdTelemetry.Value;
lastSaubTelemetry = telemetryDataSaubCache.GetLastOrDefault(well.IdTelemetry.Value);
if (lastSaubTelemetry is not null)
{
currentDepth = lastSaubTelemetry.WellDepth;
}
}
var wellOperationsStat = operationsStat.FirstOrDefault(s => s.Id == well.Id);
var wellLastFactSection = wellOperationsStat?.Sections.LastOrDefault(s => s.Fact is not null);
currentDepth ??= wellLastFactSection?.Fact?.WellDepthEnd;
2023-02-16 16:27:14 +05:00
var wellProcessMaps = processMapPlanWellDrillings
2023-02-16 16:27:14 +05:00
.Where(p => p.IdWell == well.Id)
.OrderBy(p => p.DepthEnd);
int? idSection = wellLastFactSection?.Id;
ProcessMapPlanWellDrillingDto? processMapPlanWellDrilling = null;
2023-02-16 16:27:14 +05:00
if (idSection.HasValue)
2023-02-16 16:27:14 +05:00
{
processMapPlanWellDrilling = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection);
2023-02-16 16:27:14 +05:00
}
else if (currentDepth.HasValue)
2023-02-16 16:27:14 +05:00
{
processMapPlanWellDrilling = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth.Value && p.DepthEnd >= currentDepth.Value);
2023-02-16 16:27:14 +05:00
}
double? planTotalDepth = null;
planTotalDepth = wellDepthByProcessMap.FirstOrDefault(p => p.Id == well.Id)?.DepthEnd;
planTotalDepth ??= wellOperationsStat?.Total.Plan?.WellDepthEnd;
wellMapInfo.Section = wellLastFactSection?.Caption;
wellMapInfo.FirstFactOperationDateStart = wellOperationsStat?.Total.Fact?.Start
?? wellOperationsStat?.Total.Plan?.Start;
wellMapInfo.LastPredictOperationDateEnd = wellOperationsStat?.Total.Plan?.End;
wellMapInfo.AxialLoad = new()
{
Plan = processMapPlanWellDrilling?.AxialLoad.Plan,
Fact = lastSaubTelemetry?.AxialLoad
};
wellMapInfo.TopDriveSpeed = new()
{
Plan = processMapPlanWellDrilling?.TopDriveSpeed.Plan,
Fact = lastSaubTelemetry?.RotorSpeed
};
wellMapInfo.TopDriveTorque = new()
{
Plan = processMapPlanWellDrilling?.TopDriveTorque.Plan,
Fact = lastSaubTelemetry?.RotorTorque
};
wellMapInfo.Pressure = new()
{
Plan = processMapPlanWellDrilling?.Pressure.Plan,
Fact = lastSaubTelemetry?.Pressure
};
wellMapInfo.PressureSp = lastSaubTelemetry?.PressureSp;
2023-02-16 16:27:14 +05:00
wellMapInfo.WellDepth = new()
{
Plan = planTotalDepth,
2023-02-16 16:27:14 +05:00
Fact = currentDepth,
};
wellMapInfo.ROP = new()
{
Plan = processMapPlanWellDrilling?.RopPlan,
2023-02-16 16:27:14 +05:00
Fact = wellOperationsStat?.Total.Fact?.Rop,
};
wellMapInfo.RaceSpeed = new()
{
Plan = wellOperationsStat?.Total.Plan?.RouteSpeed,
Fact = wellOperationsStat?.Total.Fact?.RouteSpeed,
};
var wellSubsystemStat = subsystemStat.FirstOrDefault(s => s.Well.Id == well.Id);
2023-02-16 16:27:14 +05:00
wellMapInfo.SaubUsage = wellSubsystemStat?.SubsystemAKB?.KUsage ?? 0d;
wellMapInfo.SpinUsage = wellSubsystemStat?.SubsystemSpinMaster?.KUsage ?? 0d;
wellMapInfo.TorqueKUsage = wellSubsystemStat?.SubsystemTorqueMaster?.KUsage ?? 0d;
wellMapInfo.TvdLagDays = wellOperationsStat?.TvdLagDays;
wellMapInfo.TvdDrillingDays = wellOperationsStat?.TvdDrillingDays;
2023-02-16 16:27:14 +05:00
wellMapInfo.IdsCompanies = well.Companies.Select(c => c.Id);
2023-02-16 16:27:14 +05:00
return wellMapInfo;
}).ToArray();
var updateWellInfoEventTasks = wellsIds.Select(idWell =>
messageHub.HandleAsync(new UpdateWellInfoEvent(idWell), token));
await Task.WhenAll(updateWellInfoEventTasks);
2023-02-16 16:27:14 +05:00
}
}
2023-02-16 16:27:14 +05:00
class WellMapInfoWithComanies : WellMapInfoDto
{
public int? IdTelemetry { get; set; }
public IEnumerable<int> IdsCompanies { get; set; } = null!;
}
private readonly TelemetryDataCache<TelemetryDataSaubDto> telemetryDataSaubCache;
private readonly TelemetryDataCache<TelemetryDataSpinDto> telemetryDataSpinCache;
private readonly IWitsRecordRepository<Record7Dto> witsRecord7Repository;
private readonly IWitsRecordRepository<Record1Dto> witsRecord1Repository;
private readonly IGtrRepository gtrRepository;
private static IEnumerable<WellMapInfoWithComanies> WellMapInfo = Enumerable.Empty<WellMapInfoWithComanies>();
public WellInfoService(
TelemetryDataCache<TelemetryDataSaubDto> telemetryDataSaubCache,
TelemetryDataCache<TelemetryDataSpinDto> telemetryDataSpinCache,
IWitsRecordRepository<Record7Dto> witsRecord7Repository,
IWitsRecordRepository<Record1Dto> witsRecord1Repository,
IGtrRepository gtrRepository)
{
this.telemetryDataSaubCache = telemetryDataSaubCache;
this.telemetryDataSpinCache = telemetryDataSpinCache;
this.witsRecord7Repository = witsRecord7Repository;
this.witsRecord1Repository = witsRecord1Repository;
this.gtrRepository = gtrRepository;
}
private WellMapInfoWithTelemetryStat Convert(WellMapInfoWithComanies wellInfo)
{
var result = wellInfo.Adapt<WellMapInfoWithTelemetryStat>();
if (wellInfo.IdTelemetry.HasValue)
{
var idTelemetry = wellInfo.IdTelemetry.Value;
result.LastDataSaub = telemetryDataSaubCache.GetLastOrDefault(idTelemetry);
result.LastDataSpin = telemetryDataSpinCache.GetLastOrDefault(idTelemetry);
result.LastDataDdsDate = GetLastOrDefaultDdsTelemetry(idTelemetry);
result.LastDataGtrDate = gtrRepository.GetLastData(wellInfo.Id)
.MaxOrDefault(item => item.Date);
result.LastDataDpcsDate = null;
result.LastDataDpcsDate = null;
}
2023-02-16 16:27:14 +05:00
return result;
}
private DateTime? GetLastOrDefaultDdsTelemetry(int idTelemetry)
{
var lastDdsRecord1Date = witsRecord1Repository.GetLastOrDefault(idTelemetry)?.DateTime;
var lastDdsRecord7Date = witsRecord7Repository.GetLastOrDefault(idTelemetry)?.DateTime;
if (lastDdsRecord1Date.HasValue && lastDdsRecord7Date.HasValue)
if (lastDdsRecord1Date.Value > lastDdsRecord7Date.Value)
return lastDdsRecord1Date.Value;
else
return lastDdsRecord7Date.Value;
return lastDdsRecord1Date ?? lastDdsRecord7Date;
}
public WellMapInfoWithTelemetryStat? FirstOrDefault(Func<WellMapInfoDto, bool> predicate)
{
var first = WellMapInfo.FirstOrDefault(predicate);
if (first is WellMapInfoWithComanies wellMapInfoWithComanies)
return Convert(wellMapInfoWithComanies);
return null;
}
2023-02-16 16:27:14 +05:00
}