Рефакторинг + добавил отправку информации о скважине через SignalR

This commit is contained in:
parent 47bd9cb56b
commit 3f7f455281
14 changed files with 208 additions and 73 deletions

View File

@ -20,6 +20,11 @@ namespace AsbCloudApp.Data
/// Название куста /// Название куста
/// </summary> /// </summary>
public string? Cluster { get; set; } public string? Cluster { get; set; }
/// <summary>
/// Название секции
/// </summary>
public string? Section { get; set; }
/// <summary> /// <summary>
/// Название месторождения /// Название месторождения

View File

@ -89,6 +89,31 @@ namespace AsbCloudApp.Data
/// </summary> /// </summary>
public PlanFactDto<double?> ROP { get; set; } = null!; public PlanFactDto<double?> ROP { get; set; } = null!;
/// <summary>
/// Нагрузка на долота, Т
/// </summary>
public PlanFactDto<double?> AxialLoad { get; set; } = null!;
/// <summary>
/// Обороты ротора
/// </summary>
public PlanFactDto<double?> TopDriveSpeed { get; set; } = null!;
/// <summary>
/// Момент ротора кн/м
/// </summary>
public PlanFactDto<double?> TopDriveTorque { get; set; } = null!;
/// <summary>
/// Перепад давления
/// </summary>
public PlanFactDto<double?> Pressure { get; set; } = null!;
/// <summary>
/// Действующее задание давления, атм
/// </summary>
public double? PressureSp { get; set; }
/// <summary> /// <summary>
/// Плановая и текущая глубина /// Плановая и текущая глубина
/// </summary> /// </summary>

View File

@ -1,7 +0,0 @@
namespace AsbCloudApp.IntegrationEvents.Events;
/// <summary>
/// Обновление информации о скважине
/// </summary>
/// <param name="IdWell"></param>
public record WellInfoUpdaterEvent(int IdWell) : IIntegrationEvent;

View File

@ -1,4 +1,4 @@
namespace AsbCloudApp.IntegrationEvents.Events; namespace AsbCloudApp.IntegrationEvents.Interfaces;
/// <summary> /// <summary>
/// Интерфейс маркер для доменных событий /// Интерфейс маркер для доменных событий

View File

@ -1,8 +1,7 @@
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.IntegrationEvents.Events;
namespace AsbCloudApp.IntegrationEvents; namespace AsbCloudApp.IntegrationEvents.Interfaces;
/// <summary> /// <summary>
/// Обработчик событий /// Обработчик событий

View File

@ -0,0 +1,9 @@
using AsbCloudApp.IntegrationEvents.Interfaces;
namespace AsbCloudApp.IntegrationEvents;
/// <summary>
/// Обновление информации о скважине
/// </summary>
/// <param name="IdWell"></param>
public record UpdateWellEvent(int IdWell) : IIntegrationEvent;

View File

@ -0,0 +1,9 @@
using AsbCloudApp.IntegrationEvents.Interfaces;
namespace AsbCloudApp.IntegrationEvents;
/// <summary>
/// Обновление показателей бурения
/// </summary>
/// <param name="IdWell"></param>
public record UpdateWellInfoEvent(int IdWell) : IIntegrationEvent;

View File

@ -17,7 +17,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.IntegrationEvents; using AsbCloudApp.IntegrationEvents;
using AsbCloudApp.IntegrationEvents.Events; using AsbCloudApp.IntegrationEvents.Interfaces;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services
{ {
@ -71,7 +71,7 @@ namespace AsbCloudInfrastructure.Services
var processMapRepository = serviceProvider.GetRequiredService<IProcessMapPlanRepository>(); var processMapRepository = serviceProvider.GetRequiredService<IProcessMapPlanRepository>();
var subsystemOperationTimeService = serviceProvider.GetRequiredService<ISubsystemOperationTimeService>(); var subsystemOperationTimeService = serviceProvider.GetRequiredService<ISubsystemOperationTimeService>();
var telemetryDataSaubCache = serviceProvider.GetRequiredService<TelemetryDataCache<TelemetryDataSaubDto>>(); var telemetryDataSaubCache = serviceProvider.GetRequiredService<TelemetryDataCache<TelemetryDataSaubDto>>();
var messageHub = serviceProvider.GetRequiredService<IIntegrationEventHandler<WellInfoUpdaterEvent>>(); var messageHub = serviceProvider.GetRequiredService<IIntegrationEventHandler<UpdateWellInfoEvent>>();
var activeWells = await wellService.GetAsync(new() {IdState = 1}, token); var activeWells = await wellService.GetAsync(new() {IdState = 1}, token);
@ -103,10 +103,12 @@ namespace AsbCloudInfrastructure.Services
double? currentDepth = null; double? currentDepth = null;
TelemetryDataSaubDto? lastSaubTelemetry = null;
if (well.IdTelemetry.HasValue) if (well.IdTelemetry.HasValue)
{ {
wellMapInfo.IdTelemetry = well.IdTelemetry.Value; wellMapInfo.IdTelemetry = well.IdTelemetry.Value;
var lastSaubTelemetry = telemetryDataSaubCache.GetLastOrDefault(well.IdTelemetry.Value); lastSaubTelemetry = telemetryDataSaubCache.GetLastOrDefault(well.IdTelemetry.Value);
if(lastSaubTelemetry is not null) if(lastSaubTelemetry is not null)
{ {
currentDepth = lastSaubTelemetry.WellDepth; currentDepth = lastSaubTelemetry.WellDepth;
@ -122,16 +124,16 @@ namespace AsbCloudInfrastructure.Services
.OrderBy(p => p.DepthEnd); .OrderBy(p => p.DepthEnd);
int? idSection = wellLastFactSection?.Id; int? idSection = wellLastFactSection?.Id;
ProcessMapPlanDto? welllProcessMap = null; ProcessMapPlanDto? wellProcessMap = null;
if (idSection.HasValue) if (idSection.HasValue)
{ {
welllProcessMap = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection); wellProcessMap = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection);
} }
else if(currentDepth.HasValue) else if(currentDepth.HasValue)
{ {
welllProcessMap = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth.Value && p.DepthEnd >= currentDepth.Value); wellProcessMap = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth.Value && p.DepthEnd >= currentDepth.Value);
idSection ??= welllProcessMap?.IdWellSectionType; idSection ??= wellProcessMap?.IdWellSectionType;
} }
double? planTotalDepth = null; double? planTotalDepth = null;
@ -143,6 +145,32 @@ namespace AsbCloudInfrastructure.Services
wellMapInfo.LastPredictOperationDateEnd = wellOperationsStat?.Total.Plan?.End; wellMapInfo.LastPredictOperationDateEnd = wellOperationsStat?.Total.Plan?.End;
wellMapInfo.AxialLoad = new()
{
Plan = wellProcessMap?.AxialLoad.Plan,
Fact = lastSaubTelemetry?.AxialLoad
};
wellMapInfo.TopDriveSpeed = new()
{
Plan = wellProcessMap?.TopDriveSpeed.Plan,
Fact = lastSaubTelemetry?.RotorSpeed
};
wellMapInfo.TopDriveTorque = new()
{
Plan = wellProcessMap?.TopDriveTorque.Plan,
Fact = lastSaubTelemetry?.RotorTorque
};
wellMapInfo.Pressure = new()
{
Plan = wellProcessMap?.Pressure.Plan,
Fact = lastSaubTelemetry?.Pressure
};
wellMapInfo.PressureSp = lastSaubTelemetry?.PressureSp;
wellMapInfo.WellDepth = new() wellMapInfo.WellDepth = new()
{ {
Plan = planTotalDepth, Plan = planTotalDepth,
@ -151,7 +179,7 @@ namespace AsbCloudInfrastructure.Services
wellMapInfo.ROP = new() wellMapInfo.ROP = new()
{ {
Plan = welllProcessMap?.RopPlan, Plan = wellProcessMap?.RopPlan,
Fact = wellOperationsStat?.Total.Fact?.Rop, Fact = wellOperationsStat?.Total.Fact?.Rop,
}; };
@ -173,7 +201,7 @@ namespace AsbCloudInfrastructure.Services
foreach (var idWell in activeWellsIds) foreach (var idWell in activeWellsIds)
{ {
await messageHub.HandleAsync(new WellInfoUpdaterEvent(idWell), token); await messageHub.HandleAsync(new UpdateWellInfoEvent(idWell), token);
} }
} }

View File

@ -11,6 +11,8 @@ using System.ComponentModel.DataAnnotations;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.IntegrationEvents;
using AsbCloudApp.IntegrationEvents.Interfaces;
namespace AsbCloudWebApi.Controllers namespace AsbCloudWebApi.Controllers
{ {
@ -23,13 +25,18 @@ namespace AsbCloudWebApi.Controllers
[Authorize] [Authorize]
public class WellOperationController : ControllerBase public class WellOperationController : ControllerBase
{ {
private readonly IIntegrationEventHandler<UpdateWellEvent> eventHandler;
private readonly IWellOperationRepository operationRepository; private readonly IWellOperationRepository operationRepository;
private readonly IWellService wellService; private readonly IWellService wellService;
private readonly IWellOperationImportService wellOperationImportService; private readonly IWellOperationImportService wellOperationImportService;
public WellOperationController(IWellOperationRepository operationService, IWellService wellService, IWellOperationImportService wellOperationImportService) public WellOperationController(IIntegrationEventHandler<UpdateWellEvent> eventHandler,
IWellOperationRepository operationRepository,
IWellService wellService,
IWellOperationImportService wellOperationImportService)
{ {
this.operationRepository = operationService; this.eventHandler = eventHandler;
this.operationRepository = operationRepository;
this.wellService = wellService; this.wellService = wellService;
this.wellOperationImportService = wellOperationImportService; this.wellOperationImportService = wellOperationImportService;
} }
@ -212,6 +219,8 @@ namespace AsbCloudWebApi.Controllers
var result = await operationRepository.InsertRangeAsync(values, token) var result = await operationRepository.InsertRangeAsync(values, token)
.ConfigureAwait(false); .ConfigureAwait(false);
await eventHandler.HandleAsync(new UpdateWellEvent(idWell), token);
return Ok(result); return Ok(result);
} }
@ -306,6 +315,8 @@ namespace AsbCloudWebApi.Controllers
{ {
return BadRequest(ex.Message); return BadRequest(ex.Message);
} }
await eventHandler.HandleAsync(new UpdateWellEvent(idWell), token);
return Ok(); return Ok();
} }

View File

@ -12,7 +12,7 @@ using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.IntegrationEvents; using AsbCloudApp.IntegrationEvents;
using AsbCloudApp.IntegrationEvents.Events; using AsbCloudApp.IntegrationEvents.Interfaces;
using AsbCloudApp.Services.Notifications; using AsbCloudApp.Services.Notifications;
using AsbCloudWebApi.SignalR; using AsbCloudWebApi.SignalR;
using AsbCloudWebApi.SignalR.Services; using AsbCloudWebApi.SignalR.Services;
@ -145,6 +145,7 @@ namespace AsbCloudWebApi
} }
public static void AddIntegrationEvents(this IServiceCollection services) => services public static void AddIntegrationEvents(this IServiceCollection services) => services
.AddTransient<IIntegrationEventHandler<WellInfoUpdaterEvent>, WellInfoUpdaterHub>(); .AddTransient<IIntegrationEventHandler<UpdateWellInfoEvent>, WellInfoHub>()
.AddTransient<IIntegrationEventHandler<UpdateWellEvent>, WellHub>();
} }
} }

View File

@ -0,0 +1,58 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.IntegrationEvents;
using AsbCloudApp.IntegrationEvents.Interfaces;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Microsoft.AspNetCore.SignalR;
namespace AsbCloudWebApi.SignalR;
public class WellHub : Hub, IIntegrationEventHandler<UpdateWellEvent>
{
private const string groupTemplate = "update_id_well_{0}";
private readonly IHubContext<WellHub> hubContext;
private readonly IWellService wellService;
private readonly IWellOperationRepository wellOperationRepository;
public WellHub(IHubContext<WellHub> hubContext,
IWellService wellService,
IWellOperationRepository wellOperationRepository)
{
this.hubContext = hubContext;
this.wellService = wellService;
this.wellOperationRepository = wellOperationRepository;
}
public async Task OnConnectedAsync(int idWell)
{
await base.OnConnectedAsync();
await Groups.AddToGroupAsync(Context.ConnectionId, string.Format(groupTemplate, idWell));
await HandleAsync(new UpdateWellEvent(idWell), CancellationToken.None);
}
public async Task HandleAsync(UpdateWellEvent integrationEvent, CancellationToken cancellationToken)
{
const string method = "update_well";
var well = await wellService.GetOrDefaultAsync(integrationEvent.IdWell, cancellationToken);
if(well is null)
return;
well.Section = (await wellOperationRepository.GetAsync(new WellOperationRequest
{
IdWell = integrationEvent.IdWell,
OperationType = WellOperation.IdOperationTypeFact
}, cancellationToken)).MaxBy(o => o.DateStart)?.WellSectionTypeName;
await hubContext.Clients.Group(string.Format(groupTemplate, integrationEvent.IdWell))
.SendAsync(method, new object[] { well }, cancellationToken);
}
}

View File

@ -0,0 +1,45 @@
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.IntegrationEvents;
using AsbCloudApp.IntegrationEvents.Interfaces;
using AsbCloudInfrastructure.Services;
using Microsoft.AspNetCore.SignalR;
namespace AsbCloudWebApi.SignalR;
public class WellInfoHub : Hub, IIntegrationEventHandler<UpdateWellInfoEvent>
{
private const string groupTemplate = "well_info_id_well_{0}";
private readonly IHubContext<WellInfoHub> hubContext;
private readonly WellInfoService wellInfoService;
public WellInfoHub(IHubContext<WellInfoHub> hubContext,
WellInfoService wellInfoService)
{
this.hubContext = hubContext;
this.wellInfoService = wellInfoService;
}
public async Task OnConnectedAsync(int idWell)
{
await base.OnConnectedAsync();
await Groups.AddToGroupAsync(Context.ConnectionId, string.Format(groupTemplate, idWell));
await HandleAsync(new UpdateWellInfoEvent(idWell), CancellationToken.None);
}
public async Task HandleAsync(UpdateWellInfoEvent integrationEvent, CancellationToken cancellationToken)
{
const string method = "update_well_info";
var wellInfo = wellInfoService.FirstOrDefault(w => w.Id == integrationEvent.IdWell);
if (wellInfo is null)
return;
await hubContext.Clients.Group(string.Format(groupTemplate, integrationEvent.IdWell))
.SendAsync(method, wellInfo, cancellationToken);
}
}

View File

@ -1,49 +0,0 @@
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.IntegrationEvents;
using AsbCloudApp.IntegrationEvents.Events;
using AsbCloudInfrastructure.Services;
using Microsoft.AspNetCore.SignalR;
namespace AsbCloudWebApi.SignalR;
public class WellInfoUpdaterHub : Hub, IIntegrationEventHandler<WellInfoUpdaterEvent>
{
private const string groupTemplate = "system_operation_updater_well_{0}";
private readonly IHubContext<WellInfoUpdaterHub> hubContext;
private readonly WellInfoService wellInfoService;
public WellInfoUpdaterHub(IHubContext<WellInfoUpdaterHub> hubContext,
WellInfoService wellInfoService)
{
this.hubContext = hubContext;
this.wellInfoService = wellInfoService;
}
public async Task OnConnectedAsync(int idWell)
{
await base.OnConnectedAsync();
await Groups.AddToGroupAsync(Context.ConnectionId, string.Format(groupTemplate, idWell));
await HandleAsync(new WellInfoUpdaterEvent(idWell), CancellationToken.None);
}
public async Task HandleAsync(WellInfoUpdaterEvent integrationEvent, CancellationToken cancellationToken)
{
const string method = "well_info_update";
var wellInfo = wellInfoService.FirstOrDefault(w => w.Id == integrationEvent.IdWell);
if (wellInfo != null)
{
var serializedObject = JsonSerializer.Serialize(wellInfo);
await hubContext.Clients.Group(string.Format(groupTemplate, integrationEvent.IdWell))
.SendCoreAsync(method, new object[] { serializedObject }, cancellationToken);
}
}
}

View File

@ -153,7 +153,8 @@ namespace AsbCloudWebApi
app.UseEndpoints(endpoints => app.UseEndpoints(endpoints =>
{ {
endpoints.MapControllers(); endpoints.MapControllers();
endpoints.MapHub<WellInfoUpdaterHub>("/hubs/limitingParameters"); endpoints.MapHub<WellHub>("/hubs/well");
endpoints.MapHub<WellInfoHub>("/hubs/wellInfo");
endpoints.MapHub<NotificationHub>("/hubs/notifications"); endpoints.MapHub<NotificationHub>("/hubs/notifications");
endpoints.MapHub<TelemetryHub>("/hubs/telemetry"); endpoints.MapHub<TelemetryHub>("/hubs/telemetry");
endpoints.MapHub<ReportsHub>("/hubs/reports"); endpoints.MapHub<ReportsHub>("/hubs/reports");