From bb107c8f5b3914b3928e5f97a618c00b73d3bb73 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Mon, 12 Feb 2024 08:51:31 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A4=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20TelemetryDataSaubS?= =?UTF-8?q?ervice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/SAUB/TelemetryDataSaubService.cs | 306 +++++++++--------- 1 file changed, 151 insertions(+), 155 deletions(-) diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs index 43356941..fdced02c 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs @@ -1,176 +1,172 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Data.SAUB; +using AsbCloudApp.Data.SAUB; using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Services; using AsbCloudDb.Model; using Mapster; using Microsoft.EntityFrameworkCore; -using Org.BouncyCastle.Asn1.Pkcs; using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; -using System.Text; using System.Text.Csv; using System.Threading; using System.Threading.Tasks; -namespace AsbCloudInfrastructure.Services.SAUB +namespace AsbCloudInfrastructure.Services.SAUB; + +public class TelemetryDataSaubService : TelemetryDataBaseService, ITelemetryDataSaubService { + private readonly ITelemetryUserService telemetryUserService; - public class TelemetryDataSaubService : TelemetryDataBaseService, ITelemetryDataSaubService + public TelemetryDataSaubService( + IAsbCloudDbContext db, + ITelemetryService telemetryService, + ITelemetryUserService telemetryUserService, + ITelemetryDataCache telemetryDataCache) + : base(db, telemetryService, telemetryDataCache) { - private readonly ITelemetryUserService telemetryUserService; - - public TelemetryDataSaubService( - IAsbCloudDbContext db, - ITelemetryService telemetryService, - ITelemetryUserService telemetryUserService, - ITelemetryDataCache telemetryDataCache) - : base(db, telemetryService, telemetryDataCache) - { - this.telemetryUserService = telemetryUserService; - } - - public async Task> Get(int idTelemetry, bool isBitOnBottom, DateTimeOffset geDate, DateTimeOffset leDate, int take, CancellationToken token) - { - var offset = telemetryService.GetTimezone(idTelemetry).Offset; - var geDateUtc = geDate.ToUniversalTime(); - var leDateUtc = leDate.ToUniversalTime(); - - var query = db.Set() - .Where(t => t.IdTelemetry == idTelemetry) - .Where(t => t.DateTime >= geDateUtc) - .Where(t => t.DateTime <= leDateUtc); - - if (isBitOnBottom) - query = query.Where(t => Math.Abs(t.BitDepth - t.WellDepth) < 0.0001); - - query = query - .OrderBy(t => t.DateTime) - .Take(take); - - var entities = await query.ToArrayAsync(token); - var dtos = entities.Select(e => Convert(e, offset.TotalHours)); - return dtos; - } - - public async Task> GetTelemetryDataStatAsync(int idTelemetry, CancellationToken token) - { - var timezone = telemetryService.GetTimezone(idTelemetry); - var timezoneOffset = TimeSpan.FromHours(timezone.Hours); - int[] modes = new int[] { 0, 1, 3 }; - - db.Database.SetCommandTimeout(TimeSpan.FromMinutes(1.5)); - - var query = db.Set() - .Where(t => t.IdTelemetry == idTelemetry) - .Where(t => t.BlockPosition > 0.0001) - .Where(t => t.WellDepth > 0.0001) - .Where(t => modes.Contains(t.Mode)) - .Where(t => t.WellDepth - t.BitDepth < 0.01) - .GroupBy(t => new { - t.DateTime.Hour, - WellDepthX10 = Math.Truncate(t.WellDepth * 10), - t.Mode, - t.IdFeedRegulator}) - .Select(g => new TelemetryDataSaubStatDto - { - Count = g.Count(), - IdMode = g.Key.Mode, - IdFeedRegulator = g.Key.IdFeedRegulator, - - DateMin = DateTime.SpecifyKind(g.Min(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified), - DateMax = DateTime.SpecifyKind(g.Max(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified), - - WellDepthMin = g.Min(t => t.WellDepth), - WellDepthMax = g.Max(t => t.WellDepth), - - Pressure = g.Average(t => t.Pressure), - PressureSp = g.Average(t => t.PressureSp!.Value), - PressureIdle = g.Average(t => t.PressureIdle!.Value), - PressureDeltaLimitMax = g.Average(t => t.PressureDeltaLimitMax!.Value), - PressureDelta = g.Average(t => t.Pressure - t.PressureIdle!.Value), - PressureSpDelta = g.Average(t => t.PressureSp!.Value - t.PressureIdle!.Value), - - AxialLoad = g.Average(t => t.AxialLoad), - AxialLoadSp = g.Average(t => t.AxialLoadSp!.Value), - AxialLoadLimitMax = g.Average(t => t.AxialLoadLimitMax!.Value), - - RotorTorque = g.Average(t => t.RotorTorque), - RotorTorqueSp = g.Average(t => t.RotorTorqueSp!.Value), - RotorTorqueLimitMax = g.Average(t => t.RotorTorqueLimitMax!.Value), - - BlockSpeed = g.Average(t => t.BlockSpeed!.Value), - BlockSpeedSp = g.Average(t => t.BlockSpeedSp!.Value), - }) - .Where(s => s.WellDepthMin != s.WellDepthMax) - .Where(s => s.Count > 3) - .OrderBy(t => t.DateMin); - - return await query.ToArrayAsync(token); - } - - public override TelemetryDataSaub Convert(TelemetryDataSaubDto src, double timezoneOffset) - { - var entity = src.Adapt(); - var telemetryUser = telemetryUserService - .GetUsers(src.IdTelemetry, u => (u.Name == src.User || u.Surname == src.User)) - .FirstOrDefault(); - entity.IdUser = telemetryUser?.Id; - entity.DateTime = src.DateTime.ToUtcDateTimeOffset(timezoneOffset); - return entity; - } - - public override TelemetryDataSaubDto Convert(TelemetryDataSaub src, double timezoneOffset) - { - var dto = src.Adapt(); - var telemetryUser = telemetryUserService.GetOrDefault(src.IdTelemetry, src.IdUser??int.MinValue); - dto.User = telemetryUser?.MakeDisplayName(); - dto.DateTime = src.DateTime.ToRemoteDateTime(timezoneOffset); - dto.BitDepth = src.BitDepth <= src.WellDepth - ? src.BitDepth - : src.WellDepth; - return dto; - } - - public async Task GetZippedCsv(int idWell, DateTime beginDate, DateTime endDate, CancellationToken token) - { - double intervalSec = (endDate - beginDate).TotalSeconds; - if (intervalSec > 60*60*24*3) - throw new ArgumentInvalidException(nameof(endDate), "Слишком большой диапазон"); - - var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell) - ?? throw new ArgumentInvalidException(nameof(idWell), $"Скважина id:{idWell} не содержит телеметрии"); - - var approxPointsCount = intervalSec switch - { - < 2048 => 2048, - < 8_192 => 4_096, - < 131_072 => 16_384, - _ => 32_768 - }; - - var data = await GetAsync(idWell, beginDate, intervalSec, approxPointsCount, token ); - - var fileName = $"DataSaub idWell{idWell}"; - if (telemetry.Info is not null) - fileName += $" {telemetry.Info?.Cluster}, {telemetry.Info?.Well}"; - fileName += $" {beginDate:yyyy-MM-DDTHH-mm} - {endDate:yyyy-MM-DDTHH-mm}.csv"; - - var outStream = new MemoryStream(); - using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true)) - { - var entryFile = archive.CreateEntry(fileName, CompressionLevel.Optimal); - using var entryStream = entryFile.Open(); - var serializer = new CsvSerializer(); - serializer.Serialize(data, entryStream); - } - outStream.Seek(0, SeekOrigin.Begin); - return outStream; - } + this.telemetryUserService = telemetryUserService; } + public async Task> Get(int idTelemetry, bool isBitOnBottom, DateTimeOffset geDate, DateTimeOffset leDate, int take, CancellationToken token) + { + var offset = telemetryService.GetTimezone(idTelemetry).Offset; + var geDateUtc = geDate.ToUniversalTime(); + var leDateUtc = leDate.ToUniversalTime(); + + var query = db.Set() + .Where(t => t.IdTelemetry == idTelemetry) + .Where(t => t.DateTime >= geDateUtc) + .Where(t => t.DateTime <= leDateUtc); + + if (isBitOnBottom) + query = query.Where(t => Math.Abs(t.BitDepth - t.WellDepth) < 0.0001); + + query = query + .OrderBy(t => t.DateTime) + .Take(take); + + var entities = await query.ToArrayAsync(token); + var dtos = entities.Select(e => Convert(e, offset.TotalHours)); + return dtos; + } + + public async Task> GetTelemetryDataStatAsync(int idTelemetry, CancellationToken token) + { + var timezone = telemetryService.GetTimezone(idTelemetry); + var timezoneOffset = TimeSpan.FromHours(timezone.Hours); + int[] modes = new int[] { 0, 1, 3 }; + + db.Database.SetCommandTimeout(TimeSpan.FromMinutes(1.5)); + + var query = db.Set() + .Where(t => t.IdTelemetry == idTelemetry) + .Where(t => t.BlockPosition > 0.0001) + .Where(t => t.WellDepth > 0.0001) + .Where(t => modes.Contains(t.Mode)) + .Where(t => t.WellDepth - t.BitDepth < 0.01) + .GroupBy(t => new + { + t.DateTime.Hour, + WellDepthX10 = Math.Truncate(t.WellDepth * 10), + t.Mode, + t.IdFeedRegulator + }) + .Select(g => new TelemetryDataSaubStatDto + { + Count = g.Count(), + IdMode = g.Key.Mode, + IdFeedRegulator = g.Key.IdFeedRegulator, + + DateMin = DateTime.SpecifyKind(g.Min(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified), + DateMax = DateTime.SpecifyKind(g.Max(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified), + + WellDepthMin = g.Min(t => t.WellDepth), + WellDepthMax = g.Max(t => t.WellDepth), + + Pressure = g.Average(t => t.Pressure), + PressureSp = g.Average(t => t.PressureSp!.Value), + PressureIdle = g.Average(t => t.PressureIdle!.Value), + PressureDeltaLimitMax = g.Average(t => t.PressureDeltaLimitMax!.Value), + PressureDelta = g.Average(t => t.Pressure - t.PressureIdle!.Value), + PressureSpDelta = g.Average(t => t.PressureSp!.Value - t.PressureIdle!.Value), + + AxialLoad = g.Average(t => t.AxialLoad), + AxialLoadSp = g.Average(t => t.AxialLoadSp!.Value), + AxialLoadLimitMax = g.Average(t => t.AxialLoadLimitMax!.Value), + + RotorTorque = g.Average(t => t.RotorTorque), + RotorTorqueSp = g.Average(t => t.RotorTorqueSp!.Value), + RotorTorqueLimitMax = g.Average(t => t.RotorTorqueLimitMax!.Value), + + BlockSpeed = g.Average(t => t.BlockSpeed!.Value), + BlockSpeedSp = g.Average(t => t.BlockSpeedSp!.Value), + }) + .Where(s => s.WellDepthMin != s.WellDepthMax) + .Where(s => s.Count > 3) + .OrderBy(t => t.DateMin); + + return await query.ToArrayAsync(token); + } + + public override TelemetryDataSaub Convert(TelemetryDataSaubDto src, double timezoneOffset) + { + var entity = src.Adapt(); + var telemetryUser = telemetryUserService + .GetUsers(src.IdTelemetry, u => (u.Name == src.User || u.Surname == src.User)) + .FirstOrDefault(); + entity.IdUser = telemetryUser?.Id; + entity.DateTime = src.DateTime.ToUtcDateTimeOffset(timezoneOffset); + return entity; + } + + public override TelemetryDataSaubDto Convert(TelemetryDataSaub src, double timezoneOffset) + { + var dto = src.Adapt(); + var telemetryUser = telemetryUserService.GetOrDefault(src.IdTelemetry, src.IdUser ?? int.MinValue); + dto.User = telemetryUser?.MakeDisplayName(); + dto.DateTime = src.DateTime.ToRemoteDateTime(timezoneOffset); + dto.BitDepth = src.BitDepth <= src.WellDepth + ? src.BitDepth + : src.WellDepth; + return dto; + } + + public async Task GetZippedCsv(int idWell, DateTime beginDate, DateTime endDate, CancellationToken token) + { + double intervalSec = (endDate - beginDate).TotalSeconds; + if (intervalSec > 60 * 60 * 24 * 3) + throw new ArgumentInvalidException(nameof(endDate), "Слишком большой диапазон"); + + var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell) + ?? throw new ArgumentInvalidException(nameof(idWell), $"Скважина id:{idWell} не содержит телеметрии"); + + var approxPointsCount = intervalSec switch + { + < 2048 => 2048, + < 8_192 => 4_096, + < 131_072 => 16_384, + _ => 32_768 + }; + + var data = await GetAsync(idWell, beginDate, intervalSec, approxPointsCount, token); + + var fileName = $"DataSaub idWell{idWell}"; + if (telemetry.Info is not null) + fileName += $" {telemetry.Info?.Cluster}, {telemetry.Info?.Well}"; + fileName += $" {beginDate:yyyy-MM-DDTHH-mm} - {endDate:yyyy-MM-DDTHH-mm}.csv"; + + var outStream = new MemoryStream(); + using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true)) + { + var entryFile = archive.CreateEntry(fileName, CompressionLevel.Optimal); + using var entryStream = entryFile.Open(); + var serializer = new CsvSerializer(); + serializer.Serialize(data, entryStream); + } + outStream.Seek(0, SeekOrigin.Begin); + return outStream; + } }