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/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs
index 03a19c44..0e364319 100644
--- a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs
+++ b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs
@@ -66,8 +66,6 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
if (datesRange is null)
return result;
-
- result.Count = (int)(Math.Ceiling((datesRange.To - DateTime.UnixEpoch).TotalDays) - Math.Floor((datesRange.From - DateTime.UnixEpoch).TotalDays));
if (request.StartDate.HasValue)
{
@@ -87,6 +85,9 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
datesRange.To = finishDate;
}
+ if (datesRange.From.AddDays(result.Skip) <= datesRange.To)
+ result.Count = (int)(Math.Ceiling((datesRange.To - DateTime.UnixEpoch).TotalDays) - Math.Floor((datesRange.From - DateTime.UnixEpoch).TotalDays));
+
for (int day = result.Skip; (day - result.Skip) < result.Take && (datesRange.From.AddDays(day)) <= datesRange.To; day++)
{
var reportDate = DateOnly.FromDateTime(datesRange.From.AddDays(day));
@@ -149,8 +150,8 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
return new DatesRangeDto
{
- From = factOperations.Min(o => o.DateStart),
- To = factOperations.Max(o => o.DateStart)
+ From = factOperations.Min(o => o.DateStart).Date,
+ To = factOperations.Max(o => o.DateStart).Date
};
}
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs
index 8d76ee70..bfb173da 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,67 @@ 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 cache = telemetryDataCache.GetOrDefault(telemetry.Id, request);
+ if(cache is not null)
+ return cache;
+
+ var dbSet = db.Set();
+
+ var query = dbSet
+ .Where(d => d.IdTelemetry == telemetry.Id)
+ .AsNoTracking();
+
+ if (request.GeDate.HasValue)
+ {
+ var geDate = request.GeDate.Value.UtcDateTime;
+ query = query.Where(d => d.DateTime >= geDate);
+ }
+
+ if (request.LeDate.HasValue)
+ {
+ var leDate = request.LeDate.Value.UtcDateTime;
+ query = query.Where(d => d.DateTime <= 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/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
index 53089f17..c99b6c95 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
@@ -11,6 +11,7 @@ using Microsoft.Extensions.DependencyInjection;
using AsbCloudInfrastructure.Background;
using System.Threading;
using AsbCloudApp.Data;
+using AsbCloudApp.Requests;
namespace AsbCloudInfrastructure.Services.SAUB
{
@@ -21,6 +22,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
{
public TDto? FirstByDate { get; init; }
public CyclycArray LastData { get; init; } = null!;
+ public double TimezoneHours { get; init; } = 5;
}
private IServiceProvider provider = null!;
@@ -225,8 +227,62 @@ namespace AsbCloudInfrastructure.Services.SAUB
{
FirstByDate = first,
LastData = cacheItem,
+ TimezoneHours = hoursOffset,
};
return item;
}
+
+ public IEnumerable? GetOrDefault(int idTelemetry, TelemetryDataRequest request)
+ {
+ if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem))
+ return null;
+
+ IEnumerable data = cacheItem.LastData;
+
+ if (!data.Any())
+ return null;
+
+ if (request.GeDate.HasValue)
+ {
+ var geDate = request.GeDate.Value.ToRemoteDateTime(cacheItem.TimezoneHours);
+ if (data.First().DateTime > geDate)
+ return null;
+
+ data = data.Where(d => d.DateTime >= geDate);
+ }
+ else
+ {
+ if (request.Order == 0)
+ return null;
+ }
+
+ if (request.LeDate.HasValue)
+ {
+ var leDate = request.LeDate.Value.ToRemoteDateTime(cacheItem.TimezoneHours);
+ data = data.Where(d => d.DateTime >= request.LeDate);
+ }
+
+ if (request.Divider > 1)
+ data = data.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: // Поздние вперед
+ data = data
+ .OrderByDescending(d => d.DateTime)
+ .Skip(request.Skip)
+ .Take(request.Take)
+ .OrderBy(d => d.DateTime);
+ break;
+ default: // Ранние вперед
+ data = data
+ .OrderBy(d => d.DateTime)
+ .Skip(request.Skip)
+ .Take(request.Take);
+ break;
+ }
+
+ return data;
+ }
}
}
diff --git a/AsbCloudInfrastructure/Services/WellContactService.cs b/AsbCloudInfrastructure/Services/WellContactService.cs
index a8e280da..261ed9f9 100644
--- a/AsbCloudInfrastructure/Services/WellContactService.cs
+++ b/AsbCloudInfrastructure/Services/WellContactService.cs
@@ -29,18 +29,21 @@ namespace AsbCloudInfrastructure.Services
{
Caption = c.Caption,
Id = c.Id,
- Users = c.Users.Select(u => new UserContactDto()
- {
- Id = u.Id,
- Name = u.Name,
- Patronymic = u.Patronymic,
- Surname = u.Surname,
- Company = u.Company.Adapt(),
- Email = u.Email,
- Phone = u.Phone,
- Position = u.Position,
- IsContact = u.RelationContactsWells.Any(rel => rel.IdWell == wellId)
- })
+ Users = c.Users
+ .Where(u => u.IdState == 1)
+ .OrderBy(u => u.Surname)
+ .Select(u => new UserContactDto()
+ {
+ Id = u.Id,
+ Name = u.Name,
+ Patronymic = u.Patronymic,
+ Surname = u.Surname,
+ Company = u.Company.Adapt(),
+ Email = u.Email,
+ Phone = u.Phone,
+ Position = u.Position,
+ IsContact = u.RelationContactsWells.Any(rel => rel.IdWell == wellId)
+ })
});
var entities = await query.AsNoTracking()
diff --git a/AsbCloudInfrastructure/Services/WellboreService.cs b/AsbCloudInfrastructure/Services/WellboreService.cs
index 79ef8a3c..5e0e439e 100644
--- a/AsbCloudInfrastructure/Services/WellboreService.cs
+++ b/AsbCloudInfrastructure/Services/WellboreService.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -58,8 +59,8 @@ public class WellboreService : IWellboreService
Id = group.Key,
Name = sections[group.Key].Caption,
Well = well.Adapt(),
- DateStart = group.Min(operation => operation.DateStart),
- DateEnd = group.Max(operation => operation.DateStart.AddHours(operation.DurationHours)),
+ DateStart = group.Min(operation => operation.DateStart).ToUtcDateTimeOffset(well.Timezone.Hours).ToOffset(TimeSpan.FromHours(well.Timezone.Hours)),
+ DateEnd = group.Max(operation => operation.DateStart.AddHours(operation.DurationHours)).ToUtcDateTimeOffset(well.Timezone.Hours).ToOffset(TimeSpan.FromHours(well.Timezone.Hours)),
DepthStart = group.Min(operation => operation.DepthStart),
DepthEnd = group.Max(operation => operation.DepthEnd),
});
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);
+ }
+
///
/// Возвращает диапазон дат за которые есть телеметрия за период времени
///