From d3bbbd5bd6373a7b8bba197d0ff8d90288b3c2d9 Mon Sep 17 00:00:00 2001 From: eugeniy_ivanov Date: Mon, 1 Aug 2022 13:55:51 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BD=D0=B0=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81=D0=BE?= =?UTF-8?q?=D0=B2=201)=D1=84=D0=BE=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20=D1=81?= =?UTF-8?q?=D0=B5=D1=80=D0=B2=D0=B8=D1=81=202)=D1=81=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=B8=D1=81=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=81=20?= =?UTF-8?q?=D0=B0=D0=BF=D0=B8=20(OperationTimeService)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/AsbCloudApp.csproj | 6 +- .../Data/Subsystems/SubsystemStatisticsDto.cs | 4 +- .../Requests/SubsystemOperationTimeRequest.cs | 43 ++++ AsbCloudApp/Services/ICrudService.cs | 1 + AsbCloudApp/Services/IWellService.cs | 2 +- .../ISubsystemOperationTimeService.cs | 4 +- AsbCloudDb/Model/AsbCloudDbContext.cs | 7 +- AsbCloudDb/Model/IAsbCloudDbContext.cs | 5 +- AsbCloudDb/Model/Subsystems/Subsystem.cs | 3 + .../Subsystems/SubsystemOperationTime.cs | 11 +- AsbCloudInfrastructure/DependencyInjection.cs | 3 +- .../Repository/CrudServiceBase.cs | 2 +- .../Services/Subsystems/OperationTimeData.cs | 15 ++ ...SubsystemOperationTimeBackgroundService.cs | 169 +++++++++++++++- .../SubsystemOperationTimeService.cs | 188 ++++++++++++++---- .../OperatingTimeSubsystemController.cs | 10 +- 16 files changed, 409 insertions(+), 64 deletions(-) create mode 100644 AsbCloudInfrastructure/Services/Subsystems/OperationTimeData.cs diff --git a/AsbCloudApp/AsbCloudApp.csproj b/AsbCloudApp/AsbCloudApp.csproj index 200ee51b..6b214070 100644 --- a/AsbCloudApp/AsbCloudApp.csproj +++ b/AsbCloudApp/AsbCloudApp.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -6,10 +6,6 @@ disable - - - - diff --git a/AsbCloudApp/Data/Subsystems/SubsystemStatisticsDto.cs b/AsbCloudApp/Data/Subsystems/SubsystemStatisticsDto.cs index 6363bf2c..38707c72 100644 --- a/AsbCloudApp/Data/Subsystems/SubsystemStatisticsDto.cs +++ b/AsbCloudApp/Data/Subsystems/SubsystemStatisticsDto.cs @@ -23,7 +23,7 @@ namespace AsbCloudApp.Data.Subsystems /// /// наработка подсистемы /// - public DateTime UsedTime { get; set; } + public TimeSpan UsedTime { get; set; } /// /// коэффициент использования /// @@ -32,7 +32,5 @@ namespace AsbCloudApp.Data.Subsystems /// коэффициент применения /// public TimeSpan K2 { get; set; } - - } } diff --git a/AsbCloudApp/Requests/SubsystemOperationTimeRequest.cs b/AsbCloudApp/Requests/SubsystemOperationTimeRequest.cs index 4276ba75..449690a5 100644 --- a/AsbCloudApp/Requests/SubsystemOperationTimeRequest.cs +++ b/AsbCloudApp/Requests/SubsystemOperationTimeRequest.cs @@ -1,15 +1,58 @@ using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AsbCloudApp.Requests { +#nullable enable /// /// класс с фильтрами для запроса /// public class SubsystemOperationTimeRequest: RequestBase { + /// + /// идентификатор скважины, может не указыватся пользователем + /// + [Required] + public int IdWell { get; set; } + /// + /// идентификатор подсистемы + /// + public IEnumerable? IdsSubsystems { get; set; } + + /// + /// Больше или равно дате + /// + public DateTime? GtDate { get; set; } + + /// + /// Меньше или равно дате + /// + public DateTime? LtDate { get; set; } + + /// + /// Больше или равно глубины забоя + /// + public double? GtDepth { get; set; } + + /// + /// Меньше или равно глубины забоя + /// + public double? LtDepth { get; set; } + + /// + /// информация попадает в выборку, если интервал выборки частично или полностью пересекается с запрашиваемым интервалом + /// + public const int SelectModeOuter = 0; + /// + /// + /// + public const int SelectModeInner = 1; + public const int SelectModeTrim = 2; + public int SelectMode { get; set; } = SelectModeOuter; } +#nullable disable } diff --git a/AsbCloudApp/Services/ICrudService.cs b/AsbCloudApp/Services/ICrudService.cs index d9a2ad37..bbb7fce8 100644 --- a/AsbCloudApp/Services/ICrudService.cs +++ b/AsbCloudApp/Services/ICrudService.cs @@ -33,6 +33,7 @@ namespace AsbCloudApp.Services /// null if not found Task GetOrDefaultAsync(int id, CancellationToken token); + /// /// Получить запись по id /// diff --git a/AsbCloudApp/Services/IWellService.cs b/AsbCloudApp/Services/IWellService.cs index b655566a..faef9d1a 100644 --- a/AsbCloudApp/Services/IWellService.cs +++ b/AsbCloudApp/Services/IWellService.cs @@ -19,7 +19,7 @@ namespace AsbCloudApp.Services string GetStateText(int state); DateTimeOffset GetLastTelemetryDate(int idWell); Task> GetClusterWellsIdsAsync(int idWell, CancellationToken token); - SimpleTimezoneDto GetTimezone(int idWell); + SimpleTimezoneDto GetTimezone(int idWell); DatesRangeDto GetDatesRange(int idWell); Task EnshureTimezonesIsSetAsync(CancellationToken token); } diff --git a/AsbCloudApp/Services/Subsystems/ISubsystemOperationTimeService.cs b/AsbCloudApp/Services/Subsystems/ISubsystemOperationTimeService.cs index d55a9167..f6ff4b0e 100644 --- a/AsbCloudApp/Services/Subsystems/ISubsystemOperationTimeService.cs +++ b/AsbCloudApp/Services/Subsystems/ISubsystemOperationTimeService.cs @@ -11,8 +11,8 @@ namespace AsbCloudApp.Services.Subsystems { public interface ISubsystemOperationTimeService { - Task> GetSubsystemAsync(int? idWell, CancellationToken token); - Task> GetStatisticAsync(SubsystemOperationTimeRequest request, CancellationToken token); + Task> GetSubsystemAsync(int idWell, CancellationToken token); + Task> GetStatAsync(SubsystemOperationTimeRequest request, CancellationToken token); Task DeleteAsync(SubsystemOperationTimeRequest request, CancellationToken token); Task> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token); diff --git a/AsbCloudDb/Model/AsbCloudDbContext.cs b/AsbCloudDb/Model/AsbCloudDbContext.cs index f061d084..cfe9d7c9 100644 --- a/AsbCloudDb/Model/AsbCloudDbContext.cs +++ b/AsbCloudDb/Model/AsbCloudDbContext.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore; +using AsbCloudDb.Model.Subsystems; +using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -29,6 +30,8 @@ namespace AsbCloudDb.Model public virtual DbSet RelationUserUserRoles => Set(); public virtual DbSet ReportProperties => Set(); public virtual DbSet SetpointsRequests => Set(); + public virtual DbSet Subsystems => Set(); + public virtual DbSet SubsystemOperationTimes => Set(); public virtual DbSet Telemetries => Set(); public virtual DbSet TelemetryDataSaub => Set(); public virtual DbSet TelemetryDataSaubStats => Set(); @@ -99,7 +102,7 @@ namespace AsbCloudDb.Model entity.Property(e => e.Timezone) .HasJsonConversion(); - }); + }); modelBuilder.Entity(entity => { diff --git a/AsbCloudDb/Model/IAsbCloudDbContext.cs b/AsbCloudDb/Model/IAsbCloudDbContext.cs index ce965004..94bf7885 100644 --- a/AsbCloudDb/Model/IAsbCloudDbContext.cs +++ b/AsbCloudDb/Model/IAsbCloudDbContext.cs @@ -1,4 +1,5 @@ -using AsbCloudDb.Model.WITS; +using AsbCloudDb.Model.Subsystems; +using AsbCloudDb.Model.WITS; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using System; @@ -28,6 +29,8 @@ namespace AsbCloudDb.Model DbSet RelationUserRolePermissions { get; } DbSet RelationUserUserRoles { get; } DbSet ReportProperties { get; } + DbSet Subsystems { get; } + DbSet SubsystemOperationTimes { get; } DbSet Telemetries { get; } DbSet TelemetryDataSaub { get; } DbSet TelemetryDataSaubStats { get; } diff --git a/AsbCloudDb/Model/Subsystems/Subsystem.cs b/AsbCloudDb/Model/Subsystems/Subsystem.cs index b781d4cb..5fc7938c 100644 --- a/AsbCloudDb/Model/Subsystems/Subsystem.cs +++ b/AsbCloudDb/Model/Subsystems/Subsystem.cs @@ -21,6 +21,9 @@ namespace AsbCloudDb.Model.Subsystems [Column("description")] [StringLength(255)] public string? Description { get; set; } + + [InverseProperty(nameof(SubsystemOperationTime.Subsystem))] + public virtual ICollection SubsystemOperationTimes { get; set; } } } diff --git a/AsbCloudDb/Model/Subsystems/SubsystemOperationTime.cs b/AsbCloudDb/Model/Subsystems/SubsystemOperationTime.cs index 3e86ca6d..28a02365 100644 --- a/AsbCloudDb/Model/Subsystems/SubsystemOperationTime.cs +++ b/AsbCloudDb/Model/Subsystems/SubsystemOperationTime.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Text.Json.Serialization; namespace AsbCloudDb.Model.Subsystems { @@ -19,17 +20,19 @@ namespace AsbCloudDb.Model.Subsystems public int IdSubsystem { get; set; } [Column("date_end"), Comment("дата/время включения подсистемы")] - public DateTime DateStart { get; set; } + public DateTimeOffset DateStart { get; set; } [Column("date_end"), Comment("дата/время выключения подсистемы")] - public DateTime DateEnd { get; set; } + public DateTimeOffset DateEnd { get; set; } [Column("depth_start"), Comment("глубина забоя на момент включения подсистемы")] - public double DepthStart { get; set; } + public float? DepthStart { get; set; } [Column("depth_end"), Comment("глубина забоя на момент выключения подсистемы")] - public double DepthEnd { get; set; } + public float? DepthEnd { get; set; } + [JsonIgnore] [ForeignKey(nameof(IdSubsystem))] public virtual Subsystem Subsystem { get; set; } + [JsonIgnore] [ForeignKey(nameof(IdTelemetry))] public virtual Telemetry Telemetry { get; set; } diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index de9a1889..3e98c630 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -11,6 +11,7 @@ using AsbCloudInfrastructure.Services.DailyReport; using AsbCloudInfrastructure.Services.DetectOperations; using AsbCloudInfrastructure.Services.DrillingProgram; using AsbCloudInfrastructure.Services.SAUB; +using AsbCloudInfrastructure.Services.Subsystems; using AsbCloudInfrastructure.Services.WellOperationService; using AsbCloudInfrastructure.Validators; using FluentValidation.AspNetCore; @@ -86,7 +87,7 @@ namespace AsbCloudInfrastructure services.AddScoped(); services.AddHostedService(); - + //services.AddHostedService(); services.AddSingleton(new WitsInfoService()); services.AddSingleton(new CacheDb()); services.AddSingleton(new InstantDataRepository()); diff --git a/AsbCloudInfrastructure/Repository/CrudServiceBase.cs b/AsbCloudInfrastructure/Repository/CrudServiceBase.cs index 15c8dc4f..c6e96d09 100644 --- a/AsbCloudInfrastructure/Repository/CrudServiceBase.cs +++ b/AsbCloudInfrastructure/Repository/CrudServiceBase.cs @@ -75,7 +75,7 @@ namespace AsbCloudInfrastructure.Repository return default; var dto = Convert(entity); return dto; - } + } /// public virtual TDto? GetOrDefault(int id) diff --git a/AsbCloudInfrastructure/Services/Subsystems/OperationTimeData.cs b/AsbCloudInfrastructure/Services/Subsystems/OperationTimeData.cs new file mode 100644 index 00000000..0002490d --- /dev/null +++ b/AsbCloudInfrastructure/Services/Subsystems/OperationTimeData.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Services.Subsystems +{ + internal class OperationTimeData + { + public DateTimeOffset DateTime { get; internal set; } + public short? Mode { get; internal set; } + public float? Depth { get; internal set; } + } +} diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs index 6c6fe8d8..ae97e8b7 100644 --- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs +++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs @@ -1,4 +1,6 @@ using AsbCloudDb.Model; +using AsbCloudDb.Model.Subsystems; +using AsbCloudInfrastructure.Services.DetectOperations; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; @@ -15,9 +17,11 @@ namespace AsbCloudInfrastructure.Services.Subsystems internal class SubsystemOperationTimeBackgroundService : BackgroundService { private readonly string connectionString; + private readonly TimeSpan period = TimeSpan.FromHours(1); public SubsystemOperationTimeBackgroundService(IConfiguration configuration) { connectionString = configuration.GetConnectionString("DefaultConnection"); + } protected override async Task ExecuteAsync(CancellationToken token) { @@ -30,22 +34,179 @@ namespace AsbCloudInfrastructure.Services.Subsystems { if (DateTime.Now > timeToStartAnalysis) { - timeToStartAnalysis = DateTime.Now + TimeSpan.FromHours(1); + timeToStartAnalysis = DateTime.Now + period; try { - + using var context = new AsbCloudDbContext(options); + var added = await OperationTimeAllTelemetriesAsync(context, token); + Trace.TraceInformation($"Total operation time subsystem complete. Added {added} operations time."); } catch (Exception ex) { Trace.TraceError(ex.Message); } - //GC.Collect(); + GC.Collect(); } - var ms = (int)(timeToStartAnalysis - DateTime.Now).TotalMilliseconds; ms = ms > 100 ? ms : 100; await Task.Delay(ms, token).ConfigureAwait(false); } + } + + public override async Task StopAsync(CancellationToken token) + { + await base.StopAsync(token).ConfigureAwait(false); } + + private static async Task OperationTimeAllTelemetriesAsync(IAsbCloudDbContext db, CancellationToken token) + { + var lastDetectedDates = await db.DetectedOperations + .GroupBy(o => o.IdTelemetry) + .Select(g => new + { + IdTelemetry = g.Key, + LastDate = g.Max(o => o.DateEnd) + }) + .ToListAsync(token); + + var telemetryIds = await db.Telemetries + .Where(t => t.Info != null && t.TimeZone != null) + .Select(t => t.Id) + .ToListAsync(token); + + var JounedlastDetectedDates = telemetryIds + .GroupJoin(lastDetectedDates, + t => t, + o => o.IdTelemetry, + (outer, inner) => new + { + IdTelemetry = outer, + inner.SingleOrDefault()?.LastDate, + }); + var affected = 0; + foreach (var item in JounedlastDetectedDates) + { + var stopwatch = Stopwatch.StartNew(); + var newOperations = await OperationTimeSaubAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token); + stopwatch.Stop(); + if (newOperations.Any()) + { + db.SubsystemOperationTimes.AddRange(newOperations); + affected += await db.SaveChangesAsync(token); + } + } + return affected; + } + + private static async Task> OperationTimeSaubAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token) + { + var query = db.TelemetryDataSaub + .AsNoTracking() + .Where(d => d.IdTelemetry == idTelemetry) + .Select(d => new OperationTimeData + { + DateTime = d.DateTime, + Mode = d.Mode, + Depth = d.WellDepth + }) + .OrderBy(d => d.DateTime); + + var take = 4 * 86_400; // 4 дня + var startDate = begin; + var resultSubsystemOperationTime = new List(); + var firstItem = query.FirstOrDefault(); + if (firstItem is null) + return null; + short? mode = firstItem.Mode; + DateTimeOffset dateBegin = firstItem.DateTime; + float? depthStart = firstItem.Depth; + while (true) + { + var data = await query + .Where(d => d.DateTime > startDate) + .Take(take) + .ToArrayAsync(token); + for(int i = 1;i<=data.Length ;i++) + { + if( data[i].Mode!= mode) + { + var operationTimeItem = new SubsystemOperationTime() + { + IdTelemetry = idTelemetry, + DateStart = dateBegin, + DateEnd = data[i - 1].DateTime, + DepthStart = depthStart, + DepthEnd = data[i - 1].Depth + + }; + resultSubsystemOperationTime.Add(operationTimeItem); + mode = data[i].Mode; + dateBegin = data[i].DateTime; + depthStart = data[i].Depth; + } + } + startDate = data.Last().DateTime; + } + return resultSubsystemOperationTime; + } + + //private static async Task> OperationTimeSpinAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token) + //{ + // var query = db.TelemetryDataSpin + // .AsNoTracking() + // .Where(d => d.IdTelemetry == idTelemetry) + // .Select(d => new OperationTimeData + // { + // DateTime = d.DateTime, + // Mode = d.Mode + // // Depth = d.d + // }) + // .OrderBy(d => d.DateTime); + + // var take = 4 * 86_400; // 4 дня + // var startDate = begin; + // var operationTime = new List(); + // const int minOperationLength = 5; + // const int maxDetectorsInterpolationFrameLength = 30; + // const int gap = maxDetectorsInterpolationFrameLength + minOperationLength; + + // while (true) + // { + // var data = await query + // .Where(d => d.DateTime > startDate) + // .Take(take) + // .ToArrayAsync(token); + + // if (data.Length < gap) + // break; + + // short? modeCount = data[0].Mode; + // DateTimeOffset dateBegin = data[0].DateTime; + // float? depthStart = data[0].Depth; + // for (int i = 1; i <= data.Length; i++) + // { + // if (data[i].Mode != modeCount) + // { + // var operationTimeItem = new SubsystemOperationTime() + // { + // IdTelemetry = idTelemetry, + // DateStart = dateBegin, + // DateEnd = data[i - 1].DateTime, + // DepthStart = depthStart, + // DepthEnd = data[i - 1].Depth + + // }; + // operationTime.Add(operationTimeItem); + // modeCount = data[i].Mode; + // dateBegin = data[i].DateTime; + // depthStart = data[i].Depth; + // } + // } + // } + // var depths = db.TelemetryDataSaub.Where(t => true/*by date*/) + // .GroupBy(t => t.IdTelemetry) + // .Select(group => group.Min(t => t.WellDepth)); + // return operationTime; + //} } } diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs index eb8d9e6c..48991852 100644 --- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs +++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs @@ -2,9 +2,14 @@ using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudApp.Services.Subsystems; +using AsbCloudDb; using AsbCloudDb.Model; +using AsbCloudDb.Model.Subsystems; +using Mapster; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -15,60 +20,173 @@ namespace AsbCloudInfrastructure.Services.Subsystems private readonly IAsbCloudDbContext db; private readonly IWellService wellService; + private readonly SubsystemService subsystemService; - public SubsystemOperationTimeService(IAsbCloudDbContext db, IWellService wellService) + public SubsystemOperationTimeService(IAsbCloudDbContext db, IWellService wellService, SubsystemService subsystemService) { this.db = db; - this.wellService = wellService; + this.wellService = wellService; + this.subsystemService = subsystemService; } - public async Task> GetSubsystemAsync(int? idWell, CancellationToken token) - { - var result = new List() { - new SubsystemDto() - { - Id = 1, - Name = "test1", - Description = "test desription1" - }, - new SubsystemDto() - { - Id = 2, - Name = "test2", - Description = "test desription2" - }, - new SubsystemDto() - { - Id = 3, - Name = "test3", - Description = "test desription3" - } - }; - - return result; + public async Task > GetSubsystemAsync(int idWell, CancellationToken token) + { + var well = await wellService.GetOrDefaultAsync(idWell, token); + if (well?.IdTelemetry is null || well.Timezone is null) + return null; + var wellSubsystem = db.SubsystemOperationTimes + .Include(e=>e.Subsystem) + .AsNoTracking() + .Where(o => o.IdTelemetry == well.IdTelemetry) + .DistinctBy(o => o.IdSubsystem) + .Select(d => new SubsystemDto + { + Id = d.Subsystem.Id, + Name = d.Subsystem.Name, + Description = d.Subsystem.Description, + }); + return wellSubsystem; } public async Task DeleteAsync(SubsystemOperationTimeRequest request, CancellationToken token) { - throw new NotImplementedException(); + var well = await wellService.GetOrDefaultAsync(request.IdWell, token); + if (well?.IdTelemetry is null || well.Timezone is null) + return 0; + var query = BuildQuery(request); + db.SubsystemOperationTimes.RemoveRange(query); + return await db.SaveChangesAsync(token); } - public Task> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token) + public async Task> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token) + { + + var query = BuildQuery(request) + .AsNoTracking(); + if (query is null) + return null; + var data = await query.ToListAsync(token); + var dtos = data.Select(o => Convert(o)); + + return dtos; + } + + + + public async Task?> GetStatAsync(SubsystemOperationTimeRequest request, CancellationToken token) + { + var query = BuildQuery(request) + ?.AsNoTracking(); + if (query is null) + return null; + var groupedData = await query + .GroupBy(o => o.IdSubsystem) + .ToListAsync(token); + var statList = CalcStat(groupedData,request); + return statList; + } + + + + private IEnumerable CalcStat(List> groupedData, SubsystemOperationTimeRequest request) { - throw new NotImplementedException(); + var result = new List(); + var periodGroupTotal = groupedData.Sum(g => g.Sum(o=> o.DateEnd.ToUnixTimeSeconds()-o.DateStart.ToUnixTimeSeconds())); + foreach (IEnumerable item in groupedData) + { + var periodGroup = item.Sum(g => g.DateEnd.ToUnixTimeSeconds() - g.DateStart.ToUnixTimeSeconds()); + var periodRequest = item.Where(o => o.DateStart==request.GtDate & o.DateEnd == request.LtDate) + .Sum(o => o.DateEnd.ToUnixTimeSeconds() - o.DateStart.ToUnixTimeSeconds()); + int idSubsystem = item.First().IdSubsystem; + var subsystemStat = new SubsystemStatisticsDto() + { + IdSubsystem = idSubsystem, + Subsystem = subsystemService.GetOrDefault(idSubsystem)?.Name ?? "unknown", + UsedTime = ConvertToTimeSpan(periodGroup), + KUsage = ConvertToTimeSpan(periodGroup / periodRequest), + K2 = ConvertToTimeSpan(periodGroup / periodGroupTotal), + }; + result.Add(subsystemStat); + } + return result; } - - - Task> ISubsystemOperationTimeService.GetStatisticAsync(SubsystemOperationTimeRequest request, CancellationToken token) + private TimeSpan ConvertToTimeSpan(long sec) { - throw new NotImplementedException(); + TimeSpan ts = TimeSpan.FromSeconds(sec); + return ts; } - + private IQueryable? BuildQuery(SubsystemOperationTimeRequest request) + { + var idTelemetry = wellService.GetOrDefault(request.IdWell)?.IdTelemetry; + if (idTelemetry is null) + return null; + + var query = db.SubsystemOperationTimes + .Include(o => o.Subsystem) + .Where(o => o.IdTelemetry == idTelemetry); + + if(request.IdsSubsystems?.Any() == true) + query = query.Where(o => request.IdsSubsystems.Contains(o.IdSubsystem)); + + switch(request.SelectMode) + { + case 0: + case 2: + if (request.GtDate is not null) + query = query.Where(o => o.DateStart >= request.GtDate.Value||o.DateEnd >= request.GtDate.Value); + + if (request.LtDate is not null) + query = query.Where(o => o.DateEnd <= request.LtDate.Value||o.DateStart <= request.LtDate.Value); + break; + + case 1: + if (request.GtDate is not null) + query = query.Where(o => o.DateStart >= request.GtDate.Value); + + if (request.LtDate is not null) + query = query.Where(o => o.DateEnd <= request.LtDate.Value); + break; + + } + + if (request.GtDepth is not null) + query = query.Where(o => o.DepthStart >= request.GtDepth.Value); + + if (request.LtDepth is not null) + query = query.Where(o => o.DepthEnd <= request.LtDepth.Value); + + + if (request?.SortFields?.Any() == true) + { + query = query.SortBy(request.SortFields); + } + else + query = query + .OrderBy(o => o.DateStart) + .ThenBy(o => o.DepthStart); + + if (request?.Skip > 0) + query = query.Skip((int)request.Skip); + + if (request?.Take > 0) + query = query.Take((int)request.Take); + else + query = query.Take(3000); + + return query; + } + + private SubsystemOperationTimeDto Convert(SubsystemOperationTime operationTime) + { + var dto = operationTime.Adapt(); + return dto; + } + + - } } diff --git a/AsbCloudWebApi/Controllers/Subsystems/OperatingTimeSubsystemController.cs b/AsbCloudWebApi/Controllers/Subsystems/OperatingTimeSubsystemController.cs index 91697b30..ccadc673 100644 --- a/AsbCloudWebApi/Controllers/Subsystems/OperatingTimeSubsystemController.cs +++ b/AsbCloudWebApi/Controllers/Subsystems/OperatingTimeSubsystemController.cs @@ -33,7 +33,7 @@ namespace AsbCloudWebApi.Controllers.Subsystems /// /// получить статистику /// - [HttpGet("statistic")] + [HttpGet("stat")] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public async Task GetStatisticsAsync(CancellationToken token = default) { @@ -42,7 +42,7 @@ namespace AsbCloudWebApi.Controllers.Subsystems new SubsystemStatisticsDto(){ IdSubsystem = 1, Subsystem = "test1", - UsedTime = System.DateTime.Now, + UsedTime = System.TimeSpan.MinValue, K2 = System.TimeSpan.MinValue, KUsage = System.TimeSpan.MinValue @@ -50,14 +50,14 @@ namespace AsbCloudWebApi.Controllers.Subsystems new SubsystemStatisticsDto(){ IdSubsystem = 2, Subsystem = "test2", - UsedTime = System.DateTime.Now, + UsedTime = System.TimeSpan.MinValue, K2 = System.TimeSpan.Zero, KUsage = System.TimeSpan.Zero }, new SubsystemStatisticsDto(){ IdSubsystem = 3, Subsystem = "test3", - UsedTime = System.DateTime.Now, + UsedTime = System.TimeSpan.MinValue, K2 = System.TimeSpan.MaxValue, KUsage = System.TimeSpan.MaxValue } @@ -71,7 +71,7 @@ namespace AsbCloudWebApi.Controllers.Subsystems /// [HttpGet("subsystem")] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - public async Task GetSubsystemAsync([FromQuery] int? idWell, CancellationToken token = default) + public async Task GetSubsystemAsync([FromQuery] int idWell, CancellationToken token = default) { var result = await subsystemOperationTimeService.GetSubsystemAsync(idWell, token); return Ok(result);