diff --git a/AsbCloudApp/Requests/TelemetryRequest.cs b/AsbCloudApp/Requests/TelemetryRequest.cs new file mode 100644 index 00000000..66b43cb5 --- /dev/null +++ b/AsbCloudApp/Requests/TelemetryRequest.cs @@ -0,0 +1,59 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace AsbCloudApp.Requests; + +/// +/// Параметры запроса телеметрии +/// +public class TelemetryDataRequest +{ + /// + /// Максимально допустимое кол-во строк данных + /// + public const int MaxTake = 3072; + + /// + /// greater or equal then Date + /// + public DateTimeOffset? GeDate { get; set; } + + /// + /// less or equal then Date + /// + public DateTimeOffset? LeDate { get; set; } + + /// + /// Делитель для прореживания выборки. + /// + /// 1 - без прореживания (default); + /// 2 - каждое 2-е значение; + /// 10 - каждое 10-е значение; + /// + /// + [Range(0, 300)] + public int Divider { get; set; } = 1; + + /// + /// сортировка/выравнивание данных в запросе по дате + /// + /// 0 - более ранние данные вперед; + /// 1 - более поздние данные вперед; + /// + /// + [Range(0, 1)] + public int Order { get; set; } = 0; + + /// + /// Пропустить с начала + /// + [Range(0, int.MaxValue)] + public int Skip { get; set; } = 0; + + /// + /// Кол-во возвращаемых, но не больше MaxTake + /// + [Range(1, MaxTake)] + public int Take { get; set; } = 1024; + +} diff --git a/AsbCloudApp/Services/ITelemetryDataService.cs b/AsbCloudApp/Services/ITelemetryDataService.cs index c1704509..a2034c7f 100644 --- a/AsbCloudApp/Services/ITelemetryDataService.cs +++ b/AsbCloudApp/Services/ITelemetryDataService.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using System; using System.Collections.Generic; using System.Threading; @@ -25,6 +26,7 @@ namespace AsbCloudApp.Services Task> GetAsync(int idWell, DateTime dateBegin = default, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default); + Task> GetAsync(int idWell, TelemetryDataRequest request, CancellationToken token); /// /// Получение статистики за период diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs index 8d76ee70..634e2cd1 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Exceptions; using AsbCloudApp.Services; using AsbCloudDb; using AsbCloudDb.Model; @@ -137,10 +138,57 @@ namespace AsbCloudInfrastructure.Services.SAUB } var entities = await query - .OrderBy(d => d.DateTime) .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); + .ToArrayAsync(token); + + var dtos = entities.Select(e => Convert(e, timezone.Hours)); + + return dtos; + } + + /// + public virtual async Task> GetAsync(int idWell, AsbCloudApp.Requests.TelemetryDataRequest request, CancellationToken token) + { + var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell); + if (telemetry is null) + return Enumerable.Empty(); + + var timezone = telemetryService.GetTimezone(telemetry.Id); + + var dbSet = db.Set(); + + var query = dbSet + .Where(d => d.IdTelemetry == telemetry.Id) + .AsNoTracking(); + + if (request.GeDate.HasValue) + query = query.Where(d => d.DateTime >= request.GeDate); + + if (request.LeDate.HasValue) + query = query.Where(d => d.DateTime >= request.LeDate); + + if (request.Divider > 1) + query = query.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % request.Divider == 0); + + switch (request.Order) + { + case 1:// Поздние вперед + query = query + .OrderByDescending(d => d.DateTime) + .Skip(request.Skip) + .Take(request.Take) + .OrderBy(d => d.DateTime); + break; + default:// Ранние вперед + query = query + .OrderBy(d => d.DateTime) + .Skip(request.Skip) + .Take(request.Take); + break; + } + + var entities = await query + .ToArrayAsync(token); var dtos = entities.Select(e => Convert(e, timezone.Hours)); diff --git a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs index f80693a1..cd9eb7b5 100644 --- a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; using Microsoft.AspNetCore.Authorization; @@ -96,6 +97,36 @@ namespace AsbCloudWebApi.Controllers.SAUB return Ok(content); } + /// + /// Новая версия. Возвращает данные САУБ по скважине. + /// По умолчанию за последние 10 минут. + /// + /// id скважины + /// + /// Токен завершения задачи + /// + [HttpGet("{idWell}/data")] + [Permission] + public virtual async Task>> GetData2Async(int idWell, + [FromQuery]TelemetryDataRequest request, + CancellationToken token) + { + int? idCompany = User.GetCompanyId(); + + if (idCompany is null) + return Forbid(); + + bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, + idWell, token).ConfigureAwait(false); + + if (!isCompanyOwnsWell) + return Forbid(); + + var content = await telemetryDataService.GetAsync(idWell, request, token); + + return Ok(content); + } + /// /// Возвращает диапазон дат за которые есть телеметрия за период времени ///