наполнение сервисов

1)фоновый сервис
2)сервис работы с апи (OperationTimeService)
This commit is contained in:
eugeniy_ivanov 2022-08-01 13:55:51 +05:00
parent 421c706ca1
commit d3bbbd5bd6
16 changed files with 409 additions and 64 deletions

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
@ -6,10 +6,6 @@
<Nullable>disable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\AsbCloudWebApi\DependencyInjection.cs" Link="DependencyInjection.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Linq" Version="4.3.0" />
</ItemGroup>

View File

@ -23,7 +23,7 @@ namespace AsbCloudApp.Data.Subsystems
/// <summary>
/// наработка подсистемы
/// </summary>
public DateTime UsedTime { get; set; }
public TimeSpan UsedTime { get; set; }
/// <summary>
/// коэффициент использования
/// </summary>
@ -32,7 +32,5 @@ namespace AsbCloudApp.Data.Subsystems
/// коэффициент применения
/// </summary>
public TimeSpan K2 { get; set; }
}
}

View File

@ -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
/// <summary>
/// класс с фильтрами для запроса
/// </summary>
public class SubsystemOperationTimeRequest: RequestBase
{
/// <summary>
/// идентификатор скважины, может не указыватся пользователем
/// </summary>
[Required]
public int IdWell { get; set; }
/// <summary>
/// идентификатор подсистемы
/// </summary>
public IEnumerable<int>? IdsSubsystems { get; set; }
/// <summary>
/// Больше или равно дате
/// </summary>
public DateTime? GtDate { get; set; }
/// <summary>
/// Меньше или равно дате
/// </summary>
public DateTime? LtDate { get; set; }
/// <summary>
/// Больше или равно глубины забоя
/// </summary>
public double? GtDepth { get; set; }
/// <summary>
/// Меньше или равно глубины забоя
/// </summary>
public double? LtDepth { get; set; }
/// <summary>
/// информация попадает в выборку, если интервал выборки частично или полностью пересекается с запрашиваемым интервалом
/// </summary>
public const int SelectModeOuter = 0;
/// <summary>
///
/// </summary>
public const int SelectModeInner = 1;
public const int SelectModeTrim = 2;
public int SelectMode { get; set; } = SelectModeOuter;
}
#nullable disable
}

View File

@ -33,6 +33,7 @@ namespace AsbCloudApp.Services
/// <returns>null if not found</returns>
Task<TDto?> GetOrDefaultAsync(int id, CancellationToken token);
/// <summary>
/// Получить запись по id
/// </summary>

View File

@ -19,7 +19,7 @@ namespace AsbCloudApp.Services
string GetStateText(int state);
DateTimeOffset GetLastTelemetryDate(int idWell);
Task<IEnumerable<int>> GetClusterWellsIdsAsync(int idWell, CancellationToken token);
SimpleTimezoneDto GetTimezone(int idWell);
SimpleTimezoneDto GetTimezone(int idWell);
DatesRangeDto GetDatesRange(int idWell);
Task EnshureTimezonesIsSetAsync(CancellationToken token);
}

View File

@ -11,8 +11,8 @@ namespace AsbCloudApp.Services.Subsystems
{
public interface ISubsystemOperationTimeService
{
Task<IEnumerable<SubsystemDto>> GetSubsystemAsync(int? idWell, CancellationToken token);
Task<IEnumerable<SubsystemStatisticsDto>> GetStatisticAsync(SubsystemOperationTimeRequest request, CancellationToken token);
Task<IEnumerable<SubsystemDto>> GetSubsystemAsync(int idWell, CancellationToken token);
Task<IEnumerable<SubsystemStatisticsDto>> GetStatAsync(SubsystemOperationTimeRequest request, CancellationToken token);
Task<int> DeleteAsync(SubsystemOperationTimeRequest request, CancellationToken token);
Task<IEnumerable<SubsystemOperationTimeDto>> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token);

View File

@ -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<RelationUserUserRole> RelationUserUserRoles => Set<RelationUserUserRole>();
public virtual DbSet<ReportProperty> ReportProperties => Set<ReportProperty>();
public virtual DbSet<SetpointsRequest> SetpointsRequests => Set<SetpointsRequest>();
public virtual DbSet<Subsystem> Subsystems => Set<Subsystem>();
public virtual DbSet<SubsystemOperationTime> SubsystemOperationTimes => Set<SubsystemOperationTime>();
public virtual DbSet<Telemetry> Telemetries => Set<Telemetry>();
public virtual DbSet<TelemetryDataSaub> TelemetryDataSaub => Set<TelemetryDataSaub>();
public virtual DbSet<TelemetryDataSaubStat> TelemetryDataSaubStats => Set<TelemetryDataSaubStat>();
@ -99,7 +102,7 @@ namespace AsbCloudDb.Model
entity.Property(e => e.Timezone)
.HasJsonConversion();
});
});
modelBuilder.Entity<Well>(entity =>
{

View File

@ -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<RelationUserRolePermission> RelationUserRolePermissions { get; }
DbSet<RelationUserUserRole> RelationUserUserRoles { get; }
DbSet<ReportProperty> ReportProperties { get; }
DbSet<Subsystem> Subsystems { get; }
DbSet<SubsystemOperationTime> SubsystemOperationTimes { get; }
DbSet<Telemetry> Telemetries { get; }
DbSet<TelemetryDataSaub> TelemetryDataSaub { get; }
DbSet<TelemetryDataSaubStat> TelemetryDataSaubStats { get; }

View File

@ -21,6 +21,9 @@ namespace AsbCloudDb.Model.Subsystems
[Column("description")]
[StringLength(255)]
public string? Description { get; set; }
[InverseProperty(nameof(SubsystemOperationTime.Subsystem))]
public virtual ICollection<SubsystemOperationTime> SubsystemOperationTimes { get; set; }
}
}

View File

@ -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; }

View File

@ -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<IEmailService, EmailService>();
services.AddHostedService<OperationDetectionBackgroundService>();
//services.AddHostedService<SubsystemOperationTimeBackgroundService>();
services.AddSingleton(new WitsInfoService());
services.AddSingleton(new CacheDb());
services.AddSingleton(new InstantDataRepository());

View File

@ -75,7 +75,7 @@ namespace AsbCloudInfrastructure.Repository
return default;
var dto = Convert(entity);
return dto;
}
}
/// <inheritdoc/>
public virtual TDto? GetOrDefault(int id)

View File

@ -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; }
}
}

View File

@ -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<int> 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<IEnumerable<SubsystemOperationTime>> 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<SubsystemOperationTime>();
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<IEnumerable<SubsystemOperationTime>> 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<SubsystemOperationTime>();
// 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;
//}
}
}

View File

@ -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<IEnumerable<SubsystemDto>> GetSubsystemAsync(int? idWell, CancellationToken token)
{
var result = new List<SubsystemDto>() {
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 <IEnumerable<SubsystemDto>> 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<int> 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<IEnumerable<SubsystemOperationTimeDto>> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token)
public async Task<IEnumerable<SubsystemOperationTimeDto>> 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<IEnumerable<SubsystemStatisticsDto>?> 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<SubsystemStatisticsDto> CalcStat(List<IGrouping<int, SubsystemOperationTime>> groupedData, SubsystemOperationTimeRequest request)
{
throw new NotImplementedException();
var result = new List<SubsystemStatisticsDto>();
var periodGroupTotal = groupedData.Sum(g => g.Sum(o=> o.DateEnd.ToUnixTimeSeconds()-o.DateStart.ToUnixTimeSeconds()));
foreach (IEnumerable<SubsystemOperationTime> 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<IEnumerable<SubsystemStatisticsDto>> ISubsystemOperationTimeService.GetStatisticAsync(SubsystemOperationTimeRequest request, CancellationToken token)
private TimeSpan ConvertToTimeSpan(long sec)
{
throw new NotImplementedException();
TimeSpan ts = TimeSpan.FromSeconds(sec);
return ts;
}
private IQueryable<SubsystemOperationTime>? 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<SubsystemOperationTimeDto>();
return dto;
}
}
}

View File

@ -33,7 +33,7 @@ namespace AsbCloudWebApi.Controllers.Subsystems
/// <summary>
/// получить статистику
/// </summary>
[HttpGet("statistic")]
[HttpGet("stat")]
[ProducesResponseType(typeof(IEnumerable<SubsystemStatisticsDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> 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
/// </summary>
[HttpGet("subsystem")]
[ProducesResponseType(typeof(IEnumerable<SubsystemDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetSubsystemAsync([FromQuery] int? idWell, CancellationToken token = default)
public async Task<IActionResult> GetSubsystemAsync([FromQuery] int idWell, CancellationToken token = default)
{
var result = await subsystemOperationTimeService.GetSubsystemAsync(idWell, token);
return Ok(result);