From 3f7f455281164e88c881a96705ff4bc7303ed941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80=D0=BE=D0=B2=D0=B8=D1=87?= Date: Fri, 18 Aug 2023 15:51:58 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D0=B3=20+=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D1=83?= =?UTF-8?q?=20=D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8?= =?UTF-8?q?=20=D0=BE=20=D1=81=D0=BA=D0=B2=D0=B0=D0=B6=D0=B8=D0=BD=D0=B5=20?= =?UTF-8?q?=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20SignalR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Data/WellInfoDto.cs | 5 ++ AsbCloudApp/Data/WellMapInfoDto.cs | 25 ++++++++ .../Events/WellInfoUpdaterEvent.cs | 7 --- .../IIntegrationEvent.cs | 2 +- .../IIntegrationEventHandler.cs | 3 +- .../IntegrationEvents/UpdateWellEvent.cs | 9 +++ .../IntegrationEvents/UpdateWellInfoEvent.cs | 9 +++ .../Services/WellInfoService.cs | 46 ++++++++++++--- .../Controllers/WellOperationController.cs | 15 ++++- AsbCloudWebApi/DependencyInjection.cs | 5 +- AsbCloudWebApi/SignalR/WellHub.cs | 58 +++++++++++++++++++ AsbCloudWebApi/SignalR/WellInfoHub.cs | 45 ++++++++++++++ AsbCloudWebApi/SignalR/WellInfoUpdaterHub.cs | 49 ---------------- AsbCloudWebApi/Startup.cs | 3 +- 14 files changed, 208 insertions(+), 73 deletions(-) delete mode 100644 AsbCloudApp/IntegrationEvents/Events/WellInfoUpdaterEvent.cs rename AsbCloudApp/IntegrationEvents/{Events => Interfaces}/IIntegrationEvent.cs (73%) rename AsbCloudApp/IntegrationEvents/{ => Interfaces}/IIntegrationEventHandler.cs (85%) create mode 100644 AsbCloudApp/IntegrationEvents/UpdateWellEvent.cs create mode 100644 AsbCloudApp/IntegrationEvents/UpdateWellInfoEvent.cs create mode 100644 AsbCloudWebApi/SignalR/WellHub.cs create mode 100644 AsbCloudWebApi/SignalR/WellInfoHub.cs delete mode 100644 AsbCloudWebApi/SignalR/WellInfoUpdaterHub.cs diff --git a/AsbCloudApp/Data/WellInfoDto.cs b/AsbCloudApp/Data/WellInfoDto.cs index b42d90b4..65d26c50 100644 --- a/AsbCloudApp/Data/WellInfoDto.cs +++ b/AsbCloudApp/Data/WellInfoDto.cs @@ -20,6 +20,11 @@ namespace AsbCloudApp.Data /// Название куста /// public string? Cluster { get; set; } + + /// + /// Название секции + /// + public string? Section { get; set; } /// /// Название месторождения diff --git a/AsbCloudApp/Data/WellMapInfoDto.cs b/AsbCloudApp/Data/WellMapInfoDto.cs index 242ecb6c..65374f47 100644 --- a/AsbCloudApp/Data/WellMapInfoDto.cs +++ b/AsbCloudApp/Data/WellMapInfoDto.cs @@ -89,6 +89,31 @@ namespace AsbCloudApp.Data /// public PlanFactDto ROP { get; set; } = null!; + /// + /// Нагрузка на долота, Т + /// + public PlanFactDto AxialLoad { get; set; } = null!; + + /// + /// Обороты ротора + /// + public PlanFactDto TopDriveSpeed { get; set; } = null!; + + /// + /// Момент ротора кн/м + /// + public PlanFactDto TopDriveTorque { get; set; } = null!; + + /// + /// Перепад давления + /// + public PlanFactDto Pressure { get; set; } = null!; + + /// + /// Действующее задание давления, атм + /// + public double? PressureSp { get; set; } + /// /// Плановая и текущая глубина /// diff --git a/AsbCloudApp/IntegrationEvents/Events/WellInfoUpdaterEvent.cs b/AsbCloudApp/IntegrationEvents/Events/WellInfoUpdaterEvent.cs deleted file mode 100644 index 6e95e72e..00000000 --- a/AsbCloudApp/IntegrationEvents/Events/WellInfoUpdaterEvent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AsbCloudApp.IntegrationEvents.Events; - -/// -/// Обновление информации о скважине -/// -/// -public record WellInfoUpdaterEvent(int IdWell) : IIntegrationEvent; \ No newline at end of file diff --git a/AsbCloudApp/IntegrationEvents/Events/IIntegrationEvent.cs b/AsbCloudApp/IntegrationEvents/Interfaces/IIntegrationEvent.cs similarity index 73% rename from AsbCloudApp/IntegrationEvents/Events/IIntegrationEvent.cs rename to AsbCloudApp/IntegrationEvents/Interfaces/IIntegrationEvent.cs index c44d83a0..a80dfdee 100644 --- a/AsbCloudApp/IntegrationEvents/Events/IIntegrationEvent.cs +++ b/AsbCloudApp/IntegrationEvents/Interfaces/IIntegrationEvent.cs @@ -1,4 +1,4 @@ -namespace AsbCloudApp.IntegrationEvents.Events; +namespace AsbCloudApp.IntegrationEvents.Interfaces; /// /// Интерфейс маркер для доменных событий diff --git a/AsbCloudApp/IntegrationEvents/IIntegrationEventHandler.cs b/AsbCloudApp/IntegrationEvents/Interfaces/IIntegrationEventHandler.cs similarity index 85% rename from AsbCloudApp/IntegrationEvents/IIntegrationEventHandler.cs rename to AsbCloudApp/IntegrationEvents/Interfaces/IIntegrationEventHandler.cs index 1fec260a..18695f07 100644 --- a/AsbCloudApp/IntegrationEvents/IIntegrationEventHandler.cs +++ b/AsbCloudApp/IntegrationEvents/Interfaces/IIntegrationEventHandler.cs @@ -1,8 +1,7 @@ using System.Threading; using System.Threading.Tasks; -using AsbCloudApp.IntegrationEvents.Events; -namespace AsbCloudApp.IntegrationEvents; +namespace AsbCloudApp.IntegrationEvents.Interfaces; /// /// Обработчик событий diff --git a/AsbCloudApp/IntegrationEvents/UpdateWellEvent.cs b/AsbCloudApp/IntegrationEvents/UpdateWellEvent.cs new file mode 100644 index 00000000..3c259e10 --- /dev/null +++ b/AsbCloudApp/IntegrationEvents/UpdateWellEvent.cs @@ -0,0 +1,9 @@ +using AsbCloudApp.IntegrationEvents.Interfaces; + +namespace AsbCloudApp.IntegrationEvents; + +/// +/// Обновление информации о скважине +/// +/// +public record UpdateWellEvent(int IdWell) : IIntegrationEvent; \ No newline at end of file diff --git a/AsbCloudApp/IntegrationEvents/UpdateWellInfoEvent.cs b/AsbCloudApp/IntegrationEvents/UpdateWellInfoEvent.cs new file mode 100644 index 00000000..4ae75a19 --- /dev/null +++ b/AsbCloudApp/IntegrationEvents/UpdateWellInfoEvent.cs @@ -0,0 +1,9 @@ +using AsbCloudApp.IntegrationEvents.Interfaces; + +namespace AsbCloudApp.IntegrationEvents; + +/// +/// Обновление показателей бурения +/// +/// +public record UpdateWellInfoEvent(int IdWell) : IIntegrationEvent; \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/WellInfoService.cs b/AsbCloudInfrastructure/Services/WellInfoService.cs index c05b51a2..ea934b14 100644 --- a/AsbCloudInfrastructure/Services/WellInfoService.cs +++ b/AsbCloudInfrastructure/Services/WellInfoService.cs @@ -17,7 +17,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.IntegrationEvents; -using AsbCloudApp.IntegrationEvents.Events; +using AsbCloudApp.IntegrationEvents.Interfaces; namespace AsbCloudInfrastructure.Services { @@ -71,7 +71,7 @@ namespace AsbCloudInfrastructure.Services var processMapRepository = serviceProvider.GetRequiredService(); var subsystemOperationTimeService = serviceProvider.GetRequiredService(); var telemetryDataSaubCache = serviceProvider.GetRequiredService>(); - var messageHub = serviceProvider.GetRequiredService>(); + var messageHub = serviceProvider.GetRequiredService>(); var activeWells = await wellService.GetAsync(new() {IdState = 1}, token); @@ -103,10 +103,12 @@ namespace AsbCloudInfrastructure.Services double? currentDepth = null; + TelemetryDataSaubDto? lastSaubTelemetry = null; + if (well.IdTelemetry.HasValue) { wellMapInfo.IdTelemetry = well.IdTelemetry.Value; - var lastSaubTelemetry = telemetryDataSaubCache.GetLastOrDefault(well.IdTelemetry.Value); + lastSaubTelemetry = telemetryDataSaubCache.GetLastOrDefault(well.IdTelemetry.Value); if(lastSaubTelemetry is not null) { currentDepth = lastSaubTelemetry.WellDepth; @@ -122,16 +124,16 @@ namespace AsbCloudInfrastructure.Services .OrderBy(p => p.DepthEnd); int? idSection = wellLastFactSection?.Id; - ProcessMapPlanDto? welllProcessMap = null; + ProcessMapPlanDto? wellProcessMap = null; if (idSection.HasValue) { - welllProcessMap = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection); + wellProcessMap = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection); } else if(currentDepth.HasValue) { - welllProcessMap = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth.Value && p.DepthEnd >= currentDepth.Value); - idSection ??= welllProcessMap?.IdWellSectionType; + wellProcessMap = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth.Value && p.DepthEnd >= currentDepth.Value); + idSection ??= wellProcessMap?.IdWellSectionType; } double? planTotalDepth = null; @@ -143,6 +145,32 @@ namespace AsbCloudInfrastructure.Services 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() { Plan = planTotalDepth, @@ -151,7 +179,7 @@ namespace AsbCloudInfrastructure.Services wellMapInfo.ROP = new() { - Plan = welllProcessMap?.RopPlan, + Plan = wellProcessMap?.RopPlan, Fact = wellOperationsStat?.Total.Fact?.Rop, }; @@ -173,7 +201,7 @@ namespace AsbCloudInfrastructure.Services foreach (var idWell in activeWellsIds) { - await messageHub.HandleAsync(new WellInfoUpdaterEvent(idWell), token); + await messageHub.HandleAsync(new UpdateWellInfoEvent(idWell), token); } } diff --git a/AsbCloudWebApi/Controllers/WellOperationController.cs b/AsbCloudWebApi/Controllers/WellOperationController.cs index 0ab6f0c1..76d0777a 100644 --- a/AsbCloudWebApi/Controllers/WellOperationController.cs +++ b/AsbCloudWebApi/Controllers/WellOperationController.cs @@ -11,6 +11,8 @@ using System.ComponentModel.DataAnnotations; using System.IO; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.IntegrationEvents; +using AsbCloudApp.IntegrationEvents.Interfaces; namespace AsbCloudWebApi.Controllers { @@ -23,13 +25,18 @@ namespace AsbCloudWebApi.Controllers [Authorize] public class WellOperationController : ControllerBase { + private readonly IIntegrationEventHandler eventHandler; private readonly IWellOperationRepository operationRepository; private readonly IWellService wellService; private readonly IWellOperationImportService wellOperationImportService; - public WellOperationController(IWellOperationRepository operationService, IWellService wellService, IWellOperationImportService wellOperationImportService) + public WellOperationController(IIntegrationEventHandler eventHandler, + IWellOperationRepository operationRepository, + IWellService wellService, + IWellOperationImportService wellOperationImportService) { - this.operationRepository = operationService; + this.eventHandler = eventHandler; + this.operationRepository = operationRepository; this.wellService = wellService; this.wellOperationImportService = wellOperationImportService; } @@ -212,6 +219,8 @@ namespace AsbCloudWebApi.Controllers var result = await operationRepository.InsertRangeAsync(values, token) .ConfigureAwait(false); + await eventHandler.HandleAsync(new UpdateWellEvent(idWell), token); + return Ok(result); } @@ -306,6 +315,8 @@ namespace AsbCloudWebApi.Controllers { return BadRequest(ex.Message); } + + await eventHandler.HandleAsync(new UpdateWellEvent(idWell), token); return Ok(); } diff --git a/AsbCloudWebApi/DependencyInjection.cs b/AsbCloudWebApi/DependencyInjection.cs index a0a6ab24..00c95b80 100644 --- a/AsbCloudWebApi/DependencyInjection.cs +++ b/AsbCloudWebApi/DependencyInjection.cs @@ -12,7 +12,7 @@ using System.IO; using System.Reflection; using System.Threading.Tasks; using AsbCloudApp.IntegrationEvents; -using AsbCloudApp.IntegrationEvents.Events; +using AsbCloudApp.IntegrationEvents.Interfaces; using AsbCloudApp.Services.Notifications; using AsbCloudWebApi.SignalR; using AsbCloudWebApi.SignalR.Services; @@ -145,6 +145,7 @@ namespace AsbCloudWebApi } public static void AddIntegrationEvents(this IServiceCollection services) => services - .AddTransient, WellInfoUpdaterHub>(); + .AddTransient, WellInfoHub>() + .AddTransient, WellHub>(); } } diff --git a/AsbCloudWebApi/SignalR/WellHub.cs b/AsbCloudWebApi/SignalR/WellHub.cs new file mode 100644 index 00000000..125c4258 --- /dev/null +++ b/AsbCloudWebApi/SignalR/WellHub.cs @@ -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 +{ + private const string groupTemplate = "update_id_well_{0}"; + + private readonly IHubContext hubContext; + private readonly IWellService wellService; + private readonly IWellOperationRepository wellOperationRepository; + + public WellHub(IHubContext 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); + } +} \ No newline at end of file diff --git a/AsbCloudWebApi/SignalR/WellInfoHub.cs b/AsbCloudWebApi/SignalR/WellInfoHub.cs new file mode 100644 index 00000000..31838981 --- /dev/null +++ b/AsbCloudWebApi/SignalR/WellInfoHub.cs @@ -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 +{ + private const string groupTemplate = "well_info_id_well_{0}"; + + private readonly IHubContext hubContext; + private readonly WellInfoService wellInfoService; + + public WellInfoHub(IHubContext 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); + } +} \ No newline at end of file diff --git a/AsbCloudWebApi/SignalR/WellInfoUpdaterHub.cs b/AsbCloudWebApi/SignalR/WellInfoUpdaterHub.cs deleted file mode 100644 index 9490df4d..00000000 --- a/AsbCloudWebApi/SignalR/WellInfoUpdaterHub.cs +++ /dev/null @@ -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 -{ - private const string groupTemplate = "system_operation_updater_well_{0}"; - - private readonly IHubContext hubContext; - private readonly WellInfoService wellInfoService; - - public WellInfoUpdaterHub(IHubContext 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); - } - } - -} \ No newline at end of file diff --git a/AsbCloudWebApi/Startup.cs b/AsbCloudWebApi/Startup.cs index aadaf829..7ea1edf5 100644 --- a/AsbCloudWebApi/Startup.cs +++ b/AsbCloudWebApi/Startup.cs @@ -153,7 +153,8 @@ namespace AsbCloudWebApi app.UseEndpoints(endpoints => { endpoints.MapControllers(); - endpoints.MapHub("/hubs/limitingParameters"); + endpoints.MapHub("/hubs/well"); + endpoints.MapHub("/hubs/wellInfo"); endpoints.MapHub("/hubs/notifications"); endpoints.MapHub("/hubs/telemetry"); endpoints.MapHub("/hubs/reports");