Merge branch 'dev' into feature/fact_trajectory

This commit is contained in:
ngfrolov 2023-06-30 17:29:18 +05:00
commit 12fa0ab0c7
Signed by: ng.frolov
GPG Key ID: E99907A0357B29A7
5 changed files with 96 additions and 47 deletions

View File

@ -15,9 +15,85 @@ namespace AsbCloudApp.Data
public int IdState { get; set; } public int IdState { get; set; }
/// <summary> /// <summary>
/// Дата/время кода приходили данные последний раз /// Режим АПД:
/// 0 - "РУЧНОЙ"
/// 1 - "БУРЕНИЕ В РОТОРЕ"
/// 2 - "ПРОРАБОТКА"
/// 3 - "БУРЕНИЕ В СЛАЙДЕ"
/// 4 - "СПУСК СПО"
/// 5 - "ПОДЪЕМ СПО"
/// 6 - "ПОДЪЕМ С ПРОРАБОТКОЙ"
/// 10 - "БЛОКИРОВКА"
/// </summary> /// </summary>
public DateTime LastTelemetryDate { get; set; } public int IdMode { get; set; }
/// <summary>
/// Коэф-т использования автоподачи долота (суммарный ротор + слайд)
/// </summary>
public double SaubUsage { get; set; }
/// <summary>
/// Коэф-т использования осциллятора
/// </summary>
public double SpinUsage { get; set; }
/// <summary>
/// Коэф-т использования демпфера
/// </summary>
public double TorqueKUsage { get; set; }
/// <summary>
/// Состояние МСЕ
/// </summary>
public double IdStateMse { get; set; }
/// <summary>
/// Дата/время получения данных от системы АПД
/// </summary>
public DateTime LastTelemetrySaubDate { get; set; }
/// <summary>
/// Дата/время получения данных от системы осцилляции
/// </summary>
public DateTime LastTelemetrySpinDate { get; set; }
/// <summary>
/// Дата/время получения данных от ННБ
/// </summary>
public DateTime LastTelemetryDdsDate { get; set; }
/// <summary>
/// Дата/время получения данных от ГТИ
/// </summary>
public DateTime LastTelemetryGtrDate { get; set; }
/// <summary>
/// Дата/время получения данных от СКПБ
/// </summary>
public DateTime LastTelemetryDpcsDate { get; set; }
/// <summary>
/// <para>Дата начала первой фактической операции</para>
/// <para>Используется как дата начала бурения</para>
/// </summary>
public DateTime? FirstFactOperationDateStart { get; set; }
/// <summary>
/// <para>Дата окончания последней прогнозируемой операции</para>
/// <para>Если скважина завершена, то дата окончания последней фактической операции</para>
/// <para>Используется как прогноз окончания бурения</para>
/// </summary>
public DateTime? LastPredictOperationDateEnd { get; set; }
/// <summary>
/// Рейсовая скорость проходки, последнего рейса
/// </summary>
public PlanFactDto<double?> RaceSpeed { get; set; } = null!;
/// <summary>
/// Механическая скорость проходки, последней операции бурения
/// </summary>
public PlanFactDto<double?> ROP { get; set; } = null!;
/// <summary> /// <summary>
/// Плановая и текущая глубина /// Плановая и текущая глубина
@ -29,24 +105,5 @@ namespace AsbCloudApp.Data
/// </summary> /// </summary>
public double TvdLagPercent { get; set; } public double TvdLagPercent { get; set; }
/// <summary>
/// Механическая скорость проходки, последней операции бурения
/// </summary>
public PlanFactDto<double?> ROP { get; set; } = null!;
/// <summary>
/// Рейсовая скорость проходки, последнего рейса
/// </summary>
public PlanFactDto<double?> RaceSpeed { get; set; } = null!;
/// <summary>
/// Процент использования АКБ
/// </summary>
public double SaubUsage { get; set; }
/// <summary>
/// Процент использования Спин мастера
/// </summary>
public double SpinUsage { get; set; }
} }
} }

View File

@ -37,7 +37,7 @@ namespace AsbCloudApp.Services
/// <param name="idTelemetry">The id telemetry.</param> /// <param name="idTelemetry">The id telemetry.</param>
/// <param name="token">The token.</param> /// <param name="token">The token.</param>
/// <returns>A Task.</returns> /// <returns>A Task.</returns>
Task<IEnumerable<TDto>> GetLastAsync(int idTelemetry, CancellationToken token); TDto? GetLastOrDefault(int idTelemetry);
/// <summary> /// <summary>
/// получить статистику по всему архиву: дата самой ранней записи, самой поздней и общее количество /// получить статистику по всему архиву: дата самой ранней записи, самой поздней и общее количество

View File

@ -3,6 +3,7 @@ using AsbCloudDb.Model;
using Mapster; using Mapster;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
@ -10,16 +11,17 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Repository namespace AsbCloudInfrastructure.Repository
{ {
public class WitsRecordRepository<TDto, TEntity> : IWitsRecordRepository<TDto> public class WitsRecordRepository<TDto, TEntity> : IWitsRecordRepository<TDto>
where TEntity : AsbCloudDb.Model.WITS.RecordBase, ITelemetryData where TEntity : AsbCloudDb.Model.WITS.RecordBase, ITelemetryData
where TDto : AsbCloudApp.Data.ITelemetryData where TDto : AsbCloudApp.Data.ITelemetryData
{ {
private static Random random = new Random((int)(DateTime.Now.Ticks % 0xFFFFFFFF)); private static readonly Random random = new Random((int)(DateTime.Now.Ticks % 0xFFFFFFFF));
private readonly DbSet<TEntity> dbset; private readonly DbSet<TEntity> dbset;
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
private readonly ITelemetryService telemetryService; private readonly ITelemetryService telemetryService;
private static readonly ConcurrentDictionary<int, TDto> cache = new ();
public WitsRecordRepository(IAsbCloudDbContext db, ITelemetryService telemetryService) public WitsRecordRepository(IAsbCloudDbContext db, ITelemetryService telemetryService)
{ {
dbset = db.Set<TEntity>(); dbset = db.Set<TEntity>();
@ -56,25 +58,16 @@ namespace AsbCloudInfrastructure.Repository
return data.Select(d => Convert(d, timezoneHours)); return data.Select(d => Convert(d, timezoneHours));
} }
public async Task<IEnumerable<TDto>> GetLastAsync(int idTelemetry, CancellationToken token) public TDto? GetLastOrDefault(int idTelemetry)
{ => cache.GetValueOrDefault(idTelemetry);
var timezoneHours = telemetryService.GetTimezone(idTelemetry).Hours;
var query = dbset
.Where(d => d.IdTelemetry == idTelemetry)
.OrderBy(d => d.DateTime)
.AsNoTracking();
var data = await query.LastOrDefaultAsync(token);
if(data is not null)
return new TDto[] { Convert(data, timezoneHours) };
return Enumerable.Empty<TDto>();
}
public async Task SaveDataAsync(int idTelemetry, IEnumerable<TDto> dtos, CancellationToken token) public async Task SaveDataAsync(int idTelemetry, IEnumerable<TDto> dtos, CancellationToken token)
{ {
if (dtos?.Any() != true) if (!dtos.Any())
return; return;
cache.AddOrUpdate(idTelemetry, dtos.Last(), (_,_) => dtos.OrderBy(r => r.DateTime).Last());
var timezoneHours = telemetryService.GetTimezone(idTelemetry).Hours; var timezoneHours = telemetryService.GetTimezone(idTelemetry).Hours;
var entities = dtos var entities = dtos
.DistinctBy(d => d.DateTime) .DistinctBy(d => d.DateTime)
@ -144,7 +137,5 @@ namespace AsbCloudInfrastructure.Repository
data.DateTime = entity.DateTime.ToRemoteDateTime(timezoneHours); data.DateTime = entity.DateTime.ToRemoteDateTime(timezoneHours);
return data; return data;
} }
} }
} }

View File

@ -67,16 +67,15 @@ namespace AsbCloudWebApi.Controllers.WITS
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet("{idWell}/last")] [HttpGet("{idWell}/last")]
public async virtual Task<ActionResult<IEnumerable<TDto>>> GetLastDataAsync( public virtual ActionResult<IEnumerable<TDto>> GetLastData(
int idWell, int idWell,
[FromServices] IWitsRecordRepository<TDto> witsRecordRepository, [FromServices] IWitsRecordRepository<TDto> witsRecordRepository)
CancellationToken token)
{ {
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell); var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);
if (telemetry is null) if (telemetry is null)
return NoContent(); return NoContent();
var dtos = await witsRecordRepository.GetLastAsync(telemetry.Id, token); var dto = witsRecordRepository.GetLastOrDefault(telemetry.Id);
return Ok(dtos); return Ok(new[] { dto });
} }
/// <summary> /// <summary>

View File

@ -1,7 +1,6 @@
using AsbCloudApp.Exceptions; using AsbCloudApp.Exceptions;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using System; using System;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AsbCloudWebApi.Middlewares namespace AsbCloudWebApi.Middlewares
@ -36,12 +35,15 @@ namespace AsbCloudWebApi.Middlewares
context.Response.Clear(); context.Response.Clear();
context.Response.StatusCode = 403; context.Response.StatusCode = 403;
} }
catch (TaskCanceledException ex) catch (OperationCanceledException ex)
{ {
Console.WriteLine(ex.Message); Console.WriteLine(ex.Message);
} }
catch (Exception ex) // TODO: find explicit exception. Use Trace. Add body size to message. catch (Exception ex) // TODO: find explicit exception. Use Trace. Add body size to message.
{ {
context.Response.Clear();
context.Response.StatusCode = 500;
if (ex.Message.Contains("Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate.")) if (ex.Message.Contains("Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate."))
Console.WriteLine("Reading the request body timed out due to data arriving too slowly."); Console.WriteLine("Reading the request body timed out due to data arriving too slowly.");
else else