forked from ddrilling/AsbCloudServer
155 lines
6.2 KiB
C#
155 lines
6.2 KiB
C#
using AsbCloudApp.Data;
|
|
using AsbCloudApp.Data.ProcessMap;
|
|
using AsbCloudApp.Repositories;
|
|
using AsbCloudApp.Requests;
|
|
using AsbCloudApp.Services;
|
|
using AsbCloudApp.Services.Subsystems;
|
|
using AsbCloudDb.Model;
|
|
using AsbCloudInfrastructure.Background;
|
|
using Mapster;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AsbCloudInfrastructure.Services
|
|
{
|
|
#nullable enable
|
|
public class WellInfoService
|
|
{
|
|
class WellMapInfoWithComanies : WellMapInfoDto
|
|
{
|
|
public IEnumerable<int> IdsCompanies { get; set; } = null!;
|
|
}
|
|
|
|
private const string workId = "Well statistics update";
|
|
private static readonly TimeSpan workPeriod = TimeSpan.FromMinutes(30);
|
|
|
|
private static IEnumerable<WellMapInfoWithComanies> WellMapInfo = Enumerable.Empty<WellMapInfoWithComanies>();
|
|
|
|
public static WorkPeriodic MakeWork()
|
|
{
|
|
var workPeriodic = new WorkPeriodic(workId, WorkAction, workPeriod)
|
|
{
|
|
Timeout = TimeSpan.FromMinutes(30)
|
|
};
|
|
return workPeriodic;
|
|
}
|
|
|
|
private static async Task WorkAction(string workName, IServiceProvider serviceProvider, CancellationToken token)
|
|
{
|
|
var db = serviceProvider.GetRequiredService<IAsbCloudDbContext>();
|
|
var wellService = serviceProvider.GetRequiredService<IWellService>();
|
|
var operationsStatService = serviceProvider.GetRequiredService<IOperationsStatService>();
|
|
var processMapRepository = serviceProvider.GetRequiredService<IProcessMapRepository>();
|
|
var subsystemOperationTimeService = serviceProvider.GetRequiredService<ISubsystemOperationTimeService>();
|
|
|
|
var activeWells = await wellService.GetAsync(new() {IdState = 1}, token);
|
|
|
|
IEnumerable<int> activeWellsIds = activeWells
|
|
.Select(w => w.Id);
|
|
|
|
var idTelemetries = activeWells
|
|
.Where(w => w.IdTelemetry != null)
|
|
.Select(t => t.IdTelemetry);
|
|
|
|
var lastTelemetryInfo = await db.TelemetryDataSaub
|
|
.Where(t => idTelemetries.Contains(t.IdTelemetry))
|
|
.Select(t => new
|
|
{
|
|
t.IdTelemetry,
|
|
t.WellDepth,
|
|
t.DateTime,
|
|
})
|
|
.GroupBy(t => t.IdTelemetry)
|
|
.Select(g => g.OrderByDescending(t => t.DateTime)
|
|
.First()
|
|
)
|
|
.AsNoTracking()
|
|
.ToArrayAsync(token);
|
|
|
|
var processMapRequests = activeWellsIds.Select(id => new ProcessMapRequest { IdWell = id });
|
|
var processMaps = await processMapRepository.GetProcessMapAsync(processMapRequests, token);
|
|
|
|
var wellDepthByProcessMap = processMaps
|
|
.GroupBy(p => p.IdWell)
|
|
.Select(g => new
|
|
{
|
|
Id = g.Key,
|
|
DepthEnd = g.Max(p => p.DepthEnd)
|
|
});
|
|
|
|
var operationsStat = await operationsStatService.GetWellsStatAsync(activeWellsIds, token);
|
|
var subsystemStat = await subsystemOperationTimeService.GetStatByActiveWells(activeWellsIds, token);
|
|
|
|
WellMapInfo = activeWells.Select(well => {
|
|
var wellMapInfo = well.Adapt<WellMapInfoWithComanies>();
|
|
|
|
// From teltemetryTracker
|
|
var wellLastTelemetryInfo = lastTelemetryInfo.FirstOrDefault(t => t.IdTelemetry == well.IdTelemetry);
|
|
|
|
var wellOperationsStat = operationsStat.FirstOrDefault(s => s.Id == well.Id);
|
|
var wellLastFactSection = wellOperationsStat?.Sections.LastOrDefault(s => s.Fact is not null);
|
|
|
|
var wellSubsystemStat = subsystemStat.FirstOrDefault(s => s.Well.Id == well.Id);
|
|
|
|
double currentDepth = wellLastTelemetryInfo?.WellDepth
|
|
?? wellLastFactSection?.Fact?.WellDepthEnd
|
|
?? 0d;
|
|
|
|
var wellProcessMaps = processMaps
|
|
.Where(p => p.IdWell == well.Id)
|
|
.OrderBy(p => p.DepthEnd);
|
|
|
|
int? idSection = wellLastFactSection?.Id;
|
|
|
|
ProcessMapDto? welllProcessMap;
|
|
if (idSection is not null)
|
|
{
|
|
welllProcessMap = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection);
|
|
}
|
|
else
|
|
{
|
|
welllProcessMap = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth && p.DepthEnd >= currentDepth);
|
|
idSection ??= welllProcessMap?.IdWellSectionType;
|
|
}
|
|
|
|
wellMapInfo.LastTelemetryDate = wellLastTelemetryInfo?.DateTime.ToRemoteDateTime(5) ?? new DateTime();
|
|
wellMapInfo.WellDepth = new()
|
|
{
|
|
Plan = wellDepthByProcessMap.FirstOrDefault(p => p.Id == well.Id)?.DepthEnd,
|
|
Fact = currentDepth,
|
|
};
|
|
|
|
wellMapInfo.ROP = new()
|
|
{
|
|
Plan = welllProcessMap?.RopPlan,
|
|
Fact = wellOperationsStat?.Total.Fact?.Rop,
|
|
};
|
|
|
|
wellMapInfo.RaceSpeed = new()
|
|
{
|
|
Plan = wellOperationsStat?.Total.Plan?.RouteSpeed,
|
|
Fact = wellOperationsStat?.Total.Fact?.RouteSpeed,
|
|
};
|
|
|
|
wellMapInfo.SaubUsage = wellSubsystemStat?.SubsystemAKB?.KUsage ?? 0d;
|
|
wellMapInfo.SpinUsage = wellSubsystemStat?.SubsystemSpinMaster?.KUsage ?? 0d;
|
|
wellMapInfo.TvdLagPercent = 0;// From WellOperationService?
|
|
wellMapInfo.IdsCompanies = well.Companies.Select(c => c.Id);
|
|
return wellMapInfo;
|
|
}).ToArray();
|
|
}
|
|
|
|
public static IEnumerable<WellMapInfoDto> Where(Func<WellMapInfoDto, bool> predicate)
|
|
=> WellMapInfo.Where(predicate);
|
|
|
|
public static WellMapInfoDto? FirstOrDefault(Func<WellMapInfoDto, bool> predicate)
|
|
=> WellMapInfo.FirstOrDefault(predicate);
|
|
}
|
|
#nullable disable
|
|
}
|