DetectedOperationController переделаны route. Добавлено 2 детектора

This commit is contained in:
ngfrolov 2022-06-17 17:21:14 +05:00
parent 6d908478dd
commit 5cc3f50163
8 changed files with 108 additions and 64 deletions

View File

@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Requests
{
@ -9,9 +9,16 @@ namespace AsbCloudApp.Requests
public class DetectedOperationRequest : RequestBase
{
/// <summary>
/// категории операций
/// категория операций
/// </summary>
public IEnumerable<int> CategoryIds { get; set; }
[Required]
public int IdWell { get; set; }
/// <summary>
/// категория операций
/// </summary>
[Required]
public int IdCategory { get; set; }
/// <summary>
/// Больше или равно дате

View File

@ -8,8 +8,8 @@ namespace AsbCloudApp.Services
{
public interface IDetectedOperationService
{
Task<IEnumerable<WellOperationCategoryDto>> GetCategoriesAsync(CancellationToken token);
Task<DetectedOperationListDto> GetAsync(int idWell, Requests.DetectedOperationRequest request, CancellationToken token);
Task<int> DeleteAsync(int idWell, DetectedOperationRequest request, CancellationToken token);
Task<IEnumerable<WellOperationCategoryDto>> GetCategoriesAsync(int? idWell, CancellationToken token);
Task<DetectedOperationListDto> GetAsync(DetectedOperationRequest request, CancellationToken token);
Task<int> DeleteAsync(DetectedOperationRequest request, CancellationToken token);
}
}

View File

@ -33,9 +33,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
this.scheduleService = scheduleService;
}
public async Task<DetectedOperationListDto> GetAsync(int idWell, DetectedOperationRequest request, CancellationToken token)
public async Task<DetectedOperationListDto> GetAsync(DetectedOperationRequest request, CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(idWell, token);
var well = await wellService.GetOrDefaultAsync(request.IdWell, token);
if (well?.IdTelemetry is null || well.Timezone is null)
return null;
@ -44,8 +44,8 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
var data = await query.ToListAsync(token);
var operationValues = await operationValueService.GetByIdWellAsync(idWell, token);
var schedules = await scheduleService.GetByIdWellAsync(idWell, token);
var operationValues = await operationValueService.GetByIdWellAsync(request.IdWell, token);
var schedules = await scheduleService.GetByIdWellAsync(request.IdWell, token);
var dtos = data.Select(o => Convert(o, well, operationValues, schedules));
var groups = dtos.GroupBy(o => o.Driller);
@ -78,9 +78,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
return result;
}
public async Task<int> DeleteAsync(int idWell, DetectedOperationRequest request, CancellationToken token)
public async Task<int> DeleteAsync(DetectedOperationRequest request, CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(idWell, token);
var well = await wellService.GetOrDefaultAsync(request.IdWell, token);
if (well?.IdTelemetry is null || well.Timezone is null)
return 0;
@ -122,8 +122,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
if (request is not null)
{
if (request.CategoryIds is not null)
query = query.Where(o => request.CategoryIds.Contains(o.IdCategory));
query = query.Where(o => request.IdCategory == o.IdCategory);
if (request.GtDate is not null)
query = query.Where(o => o.DateStart >= request.GtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours));
@ -183,15 +182,32 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
return dto;
}
public async Task<IEnumerable<WellOperationCategoryDto>> GetCategoriesAsync(CancellationToken token)
public async Task<IEnumerable<WellOperationCategoryDto>> GetCategoriesAsync(int? idWell, CancellationToken token)
{
var result = await db.WellOperationCategories
IQueryable<WellOperationCategory> query = null;
if(idWell is null)
{
query = db.WellOperationCategories;
}
else
{
var well = await wellService.GetOrDefaultAsync((int )idWell, token);
if (well?.IdTelemetry is null)
return null;
var idTelemetry = (int)well.IdTelemetry;
query = db.DetectedOperations
.Include(o => o.OperationCategory)
.Where(o => o.IdTelemetry == idTelemetry)
.Select(o => o.OperationCategory)
.Distinct();
}
var result = await query
.Where(c => c.Id < 1000)
.AsNoTracking()
.Select(c => c.Adapt<WellOperationCategoryDto>())
.ToArrayAsync(token);
return result;
}
}
}

View File

@ -12,7 +12,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
public int IdCategory { get; }
// TODO: assert MaxDurationSeconds and MinDurationSeconds
public double MaxDurationSeconds { get; } = 31 * 24 * 60 * 60;
public double MaxDurationSeconds { get; } = 24 * 60 * 60;
public double MinDurationSeconds { get; } = 3;
/// <summary>

View File

@ -6,7 +6,12 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
#nullable enable
class DetectorDrillingRotor : DetectorAbstract
{
public DetectorDrillingRotor() : base(1)
const double minRop = 5; //м/час
const double minRotorSpeed = 5; //об/мин
const double ticksPerHour = 60 * 60 * 10_000_000d;
const double minPressure = 25;
public DetectorDrillingRotor() : base(2)
{
FragmentLength = 15;
StepLength = 10;
@ -15,17 +20,19 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
protected override bool DetectStart(DetectableTelemetry[] telemetry, int position)
{
var firstItem = telemetry[position];
var delta = firstItem.WellDepth - firstItem.BitDepth;
if (delta is not null &&
System.Math.Abs((float)delta) > 1d)
var deltaDepth = firstItem.WellDepth - firstItem.BitDepth;
if (deltaDepth is not null &&
System.Math.Abs((float)deltaDepth) > 1d)
return false;
if(firstItem.RotorSpeed > minRotorSpeed)
return false;
if (firstItem.Pressure < minPressure)
return false;
var fragment = telemetry[position..(position + FragmentLength)];
const double minRop = 5; //м/час
const double minRotorSpeed = 5; //об/мин
const double ticksPerHour = 60 * 60 * 10_000_000d;
var lineBlockPosition = new InterpolationLine(fragment.Select(d => (d.BlockPosition ?? 0d, d.DateTime.Ticks / ticksPerHour)));
if (!lineBlockPosition.IsYDecreases(minRop))
return false;
@ -34,19 +41,19 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
if (!lineWellDepth.IsYIncreases(minRop))
return false;
var lineRotorSpeed = new InterpolationLine(fragment.Select(d => (d.RotorSpeed ?? 0d, d.DateTime.Ticks / ticksPerHour)));
if (!lineRotorSpeed.IsAverageYLessThanBound(minRotorSpeed))
return false;
return true;
}
protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position)
=> !DetectStart(telemetry, position);
/// <summary>
/// Рассчитываем МСП, м/час
/// </summary>
/// <param name="result"></param>
protected override void CalcValue(ref DetectedOperation result)
{
throw new System.NotImplementedException();
{
result.Value = (result.DepthEnd - result.DepthStart) / (result.DateEnd - result.DateStart).TotalHours;
}
}
#nullable disable

View File

@ -6,6 +6,11 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
#nullable enable
class DetectorDrillingSlide : DetectorAbstract
{
const double minRop = 5; //м/час
const double minRotorSpeed = 5; //об/мин
const double ticksPerHour = 60 * 60 * 10_000_000d;
const double minPressure = 25;
public DetectorDrillingSlide() : base(3)
{
FragmentLength = 10;
@ -14,17 +19,19 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
protected override bool DetectStart(DetectableTelemetry[] telemetry, int position)
{
var firstItem = telemetry[position];
var delta = firstItem.WellDepth - firstItem.BitDepth;
if (delta is not null &&
System.Math.Abs((float)delta) > 1d)
var deltaDepth = firstItem.WellDepth - firstItem.BitDepth;
if (deltaDepth is not null &&
System.Math.Abs((float)deltaDepth) > 1d)
return false;
if(firstItem.RotorSpeed < minRotorSpeed)
return false;
if (firstItem.Pressure < minPressure)
return false;
var fragment = telemetry[position..(position + FragmentLength)];
const double minRop = 5; //м/час
const double minRotorSpeed = 5; //об/мин
const double ticksPerHour = 60 * 60 * 10_000_000d;
var lineBlockPosition = new InterpolationLine(fragment.Select(d => (d.BlockPosition ?? 0d, d.DateTime.Ticks / ticksPerHour)));
if (!lineBlockPosition.IsYDecreases(minRop))
return false;
@ -33,19 +40,19 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
if (!lineWellDepth.IsYIncreases(minRop))
return false;
var lineRotorSpeed = new InterpolationLine(fragment.Select(d => (d.RotorSpeed ?? 0d, d.DateTime.Ticks / ticksPerHour)));
if (!lineRotorSpeed.IsAverageYMoreThanBound(minRotorSpeed))
return false;
return true;
}
protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position)
=> !DetectStart(telemetry, position);
/// <summary>
/// Рассчитываем МСП, м/час
/// </summary>
/// <param name="result"></param>
protected override void CalcValue(ref DetectedOperation result)
{
throw new System.NotImplementedException();
result.Value = (result.DepthEnd - result.DepthStart) / (result.DateEnd - result.DateStart).TotalHours;
}
}
#nullable disable

View File

@ -16,8 +16,8 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
private readonly IEnumerable<DetectorAbstract> detectors = new List<DetectorAbstract>
{
new Detectors.DetectorSlipsTime(),
// new Detectors.DetectorDrillingRotor(),
// new Detectors.DetectorDrillingSlide(),
new Detectors.DetectorDrillingRotor(),
new Detectors.DetectorDrillingSlide(),
};
private readonly int minStepLength;

View File

@ -1,8 +1,10 @@
using AsbCloudApp.Data;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading;
using System.Threading.Tasks;
@ -11,8 +13,9 @@ namespace AsbCloudWebApi.Controllers.SAUB
/// <summary>
/// Операции определенные по телеметрии САУБ
/// </summary>
[Route("api/well/{idWell}/[controller]")]
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class DetectedOperationController : ControllerBase
{
private readonly IDetectedOperationService detectedOperationService;
@ -25,38 +28,36 @@ namespace AsbCloudWebApi.Controllers.SAUB
}
/// <summary>
/// получить справочник операций. Отличается от операций заводимых вручную
/// получить справочник операций. Отличается от операций заводимых вручную.
/// При задании id скважины вернет только те операции, которые определились в телеметрии этой скважины.
/// </summary>
/// <param name="idWell">[опционально] id скважины</param>
/// <param name="token"></param>
/// <returns></returns>
[HttpGet("categories")]
[ProducesResponseType(typeof(IEnumerable<WellOperationCategoryDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetCategoriesAsync(CancellationToken token = default)
public async Task<IActionResult> GetCategoriesAsync([FromQuery] int? idWell, CancellationToken token = default)
{
var result = await detectedOperationService.GetCategoriesAsync(token);
var result = await detectedOperationService.GetCategoriesAsync(idWell, token);
return Ok(result);
}
/// <summary>
/// Получить фильтрованный список операций по телеметрии САУБ
/// </summary>
/// <param name="idWell"></param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpGet]
[ProducesResponseType(typeof(DetectedOperationListDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetAsync(
int idWell,
[FromQuery] DetectedOperationRequest request,
CancellationToken token = default)
{
int? idCompany = User.GetCompanyId();
if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
idWell, token).ConfigureAwait(false))
if (!await UserHasAccesToWellAsync(request.IdWell, token))
return Forbid();
var result = await detectedOperationService.GetAsync(idWell, request, token);
var result = await detectedOperationService.GetAsync(request, token);
return Ok(result);
}
@ -65,7 +66,6 @@ namespace AsbCloudWebApi.Controllers.SAUB
/// Удаленные операции будут определены повторно сервисом автоматизированного определения операций.
/// Может потребоваться при изменении алгоритмов определения
/// </summary>
/// <param name="idWell"></param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
@ -73,17 +73,24 @@ namespace AsbCloudWebApi.Controllers.SAUB
[Permission]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> DeleteAsync(
int idWell,
[FromQuery] DetectedOperationRequest request,
CancellationToken token = default)
CancellationToken token)
{
int? idCompany = User.GetCompanyId();
if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
idWell, token).ConfigureAwait(false))
if (!await UserHasAccesToWellAsync(request.IdWell, token))
return Forbid();
var result = await detectedOperationService.DeleteAsync(idWell, request, token);
var result = await detectedOperationService.DeleteAsync(request, token);
return Ok(result);
}
protected async Task<bool> UserHasAccesToWellAsync(int idWell, CancellationToken token)
{
var idCompany = User.GetCompanyId();
if (idCompany is not null &&
await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token)
.ConfigureAwait(false))
return true;
return false;
}
}
}