DetectorAbstract добавлено определение включенных подсистем во время выполнения операции.

This commit is contained in:
ngfrolov 2023-12-05 10:56:49 +05:00
parent 948002955d
commit fdc615d343
Signed by untrusted user who does not match committer: ng.frolov
GPG Key ID: E99907A0357B29A7
8 changed files with 144 additions and 57 deletions

View File

@ -41,6 +41,9 @@ namespace AsbCloudDb.Model
[Column("value"), Comment("Ключевой показатель операции")] [Column("value"), Comment("Ключевой показатель операции")]
public double Value { get; set; } public double Value { get; set; }
[Column("enabled_subsystems"), Comment("флаги аключенных подсистем")]
public int EnabledSubsystems { get; set; }
[Column("extra_data", TypeName = "jsonb"), Comment("доп. инфо по операции")] [Column("extra_data", TypeName = "jsonb"), Comment("доп. инфо по операции")]
public IDictionary<string, object> ExtraData { get; set; } = null!; public IDictionary<string, object> ExtraData { get; set; } = null!;
@ -54,5 +57,57 @@ namespace AsbCloudDb.Model
public override string ToString() public override string ToString()
=> $"{IdCategory}\t{DateStart:G}\t{DateEnd:G}\t{DurationMinutes:#0.#}\t{DepthStart:#0.#}\t{DepthEnd:#0.#}"; => $"{IdCategory}\t{DateStart:G}\t{DateEnd:G}\t{DurationMinutes:#0.#}\t{DepthStart:#0.#}\t{DepthEnd:#0.#}";
/// <summary>
/// Флаги аключенных подсистем
/// </summary>
[Flags]
public enum EnabledSubsystemsFlags
{
/// <summary>
/// Автоподача долота
/// </summary>
AutoRotor = 1 << 0,
/// <summary>
/// БУРЕНИЕ В СЛАЙДЕ
/// </summary>
AutoSlide = 1 << 1,
/// <summary>
/// ПРОРАБОТКА
/// </summary>
AutoConditionig = 1 << 2,
/// <summary>
/// СПУСК СПО
/// </summary>
AutoSinking = 1 << 3,
/// <summary>
/// ПОДЪЕМ СПО
/// </summary>
AutoLifting = 1 << 4,
/// <summary>
/// ПОДЪЕМ С ПРОРАБОТКОЙ
/// </summary>
AutoLiftingWithConditionig = 1 << 5,
/// <summary>
/// блокировка
/// </summary>
AutoBlocknig = 1 << 6,
}
/// <summary>
/// Есть ли флаг подсистемы у операции
/// </summary>
/// <param name="flag"></param>
/// <returns></returns>
public bool HasSubsystemFlag(EnabledSubsystemsFlags flag)
=> HasSubsystemFlag((int)flag);
/// <summary>
/// Есть ли флаг/флаги подсистемы у операции
/// </summary>
/// <param name="flags"></param>
/// <returns></returns>
public bool HasSubsystemFlag(int flags)
=> (EnabledSubsystems & flags) > 0;
} }
} }

View File

@ -193,7 +193,7 @@ public class DetectedOperationExportService
return memoryStream; return memoryStream;
} }
private string? CreateComment(OperationDetectorResult operationDetectorResult) private static string CreateComment(OperationDetectorResult operationDetectorResult)
{ {
var operation = operationDetectorResult.Operation; var operation = operationDetectorResult.Operation;
switch (operation.IdCategory) switch (operation.IdCategory)
@ -214,7 +214,7 @@ public class DetectedOperationExportService
return comment; return comment;
} }
default: default:
return null; return string.Empty;
} }
} }

View File

@ -201,7 +201,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
if (well?.IdTelemetry is null || well.Timezone is null) if (well?.IdTelemetry is null || well.Timezone is null)
return 0; return 0;
var query = BuildQuery(well, request); var query = BuildQueryBase(well, request);
if (query is null) if (query is null)
return 0; return 0;
@ -232,13 +232,10 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
}; };
} }
private IQueryable<DetectedOperation>? BuildQuery(WellDto well, DetectedOperationRequest request)
{
if (well?.IdTelemetry is null || well.Timezone is null)
return null;
private IQueryable<DetectedOperation> BuildQueryBase(WellDto well, DetectedOperationRequest request)
{
var query = db.Set<DetectedOperation>() var query = db.Set<DetectedOperation>()
.Include(o => o.OperationCategory)
.Where(o => o.IdTelemetry == well.IdTelemetry); .Where(o => o.IdTelemetry == well.IdTelemetry);
if (request is not null) if (request is not null)
@ -262,6 +259,14 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
query = query.Where(o => o.IdUsersAtStart == request.EqIdTelemetryUser); query = query.Where(o => o.IdUsersAtStart == request.EqIdTelemetryUser);
} }
return query;
}
private IQueryable<DetectedOperation> BuildQuery(WellDto well, DetectedOperationRequest request)
{
IQueryable<DetectedOperation> query = BuildQueryBase(well, request)
.Include(o => o.OperationCategory);
if (request?.SortFields?.Any() == true) if (request?.SortFields?.Any() == true)
{ {
query = query.SortBy(request.SortFields); query = query.SortBy(request.SortFields);

View File

@ -96,7 +96,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
int end, int end,
int idReasonOfEnd) int idReasonOfEnd)
{ {
var operation = MakeOperation(idTelemetry, telemetry, begin, end); var operation = MakeDetectedOperation(idTelemetry, telemetry, begin, end);
operation.ExtraData["IdReasonOfEnd"] = idReasonOfEnd; operation.ExtraData["IdReasonOfEnd"] = idReasonOfEnd;
@ -110,57 +110,83 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
return result; return result;
} }
protected abstract DetectedOperation MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end); private DetectedOperation MakeDetectedOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end)
protected abstract double CalcValue(DetectableTelemetry[] telemetry, int begin, int end);
protected DetectedOperation MakeDetectedOperationBlank(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end)
{ {
var pBegin = telemetry[begin]; var pBegin = telemetry[begin];
var pEnd = telemetry[end]; var pEnd = telemetry[end];
var (IdCategory, ExtraData) = GetSpecificInformation(telemetry, begin, end);
var operation = new DetectedOperation var operation = new DetectedOperation
{ {
IdCategory = IdCategory,
IdTelemetry = idTelemetry, IdTelemetry = idTelemetry,
IdUsersAtStart = pBegin.IdUser ?? -1, IdUsersAtStart = pBegin.IdUser ?? -1,
DateStart = pBegin.DateTime, DateStart = pBegin.DateTime,
DateEnd = pEnd.DateTime, DateEnd = pEnd.DateTime,
DepthStart = (double)pBegin.WellDepth, DepthStart = (double)pBegin.WellDepth,
DepthEnd = (double)pEnd.WellDepth, DepthEnd = (double)pEnd.WellDepth,
ExtraData = new Dictionary<string, object>(), ExtraData = ExtraData,
Value = CalcValue(telemetry, begin, end), Value = CalcValue(telemetry, begin, end),
EnabledSubsystems = DetectEnabledSubsystems(telemetry, begin, end)
}; };
return operation; return operation;
} }
/// <summary> /// <summary>
/// Среднее арифметическое /// Получение информации специфичной для конкретного детектора
/// IdCategory - одна из констант WellOperationCategory
/// ExtraData - дополнительная информация для отладки алгоритмов авто определения
/// </summary>
/// <returns></returns>
protected abstract (int IdCategory, IDictionary<string, object> ExtraData) GetSpecificInformation(DetectableTelemetry[] telemetry, int begin, int end);
/// <summary>
/// Расчет ключевого параметра операции
/// </summary> /// </summary>
/// <param name="yGetter"></param>
/// <param name="telemetry"></param> /// <param name="telemetry"></param>
/// <param name="begin"></param> /// <param name="begin"></param>
/// <param name="fragmentLength"></param> /// <param name="end"></param>
/// <returns></returns> /// <returns></returns>
protected static double CalcAvgAppr( protected abstract double CalcValue(DetectableTelemetry[] telemetry, int begin, int end);
Func<DetectableTelemetry, double> yGetter,
DetectableTelemetry[] telemetry, /// <summary>
int begin, /// Определение включенных подсистем во время выполнения операции
int fragmentLength) /// </summary>
/// <param name="telemetry"></param>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <returns></returns>
private static int DetectEnabledSubsystems(DetectableTelemetry[] telemetry, int begin, int end)
{ {
var end = begin + fragmentLength; var enabledSubsystems = 0;
end = end < telemetry.Length
? end for (var i = begin; i < end; i += 2)
: telemetry.Length;
var subData = telemetry[begin..end].Select(yGetter);
if (end - begin > 10)
{ {
var ratio = (end - begin) / 5; var mode = telemetry[i].Mode;
subData = subData.Where((_, i) => i % ratio > 0);
if(mode == 1)
enabledSubsystems |= (int)DetectedOperation.EnabledSubsystemsFlags.AutoRotor;
if (mode == 3)
enabledSubsystems |= (int)DetectedOperation.EnabledSubsystemsFlags.AutoSlide;
if (mode == 2)
enabledSubsystems |= (int)DetectedOperation.EnabledSubsystemsFlags.AutoConditionig;
if (mode == 4)
enabledSubsystems |= (int)DetectedOperation.EnabledSubsystemsFlags.AutoSinking;
if (mode == 5)
enabledSubsystems |= (int)DetectedOperation.EnabledSubsystemsFlags.AutoLifting;
if (mode == 6)
enabledSubsystems |= (int)DetectedOperation.EnabledSubsystemsFlags.AutoLiftingWithConditionig;
if (mode == 10)
enabledSubsystems |= (int)DetectedOperation.EnabledSubsystemsFlags.AutoBlocknig;
} }
var avg = subData.Average(); return enabledSubsystems;
return avg;
} }
/// <summary> /// <summary>

View File

@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq; using System.Linq;
using AsbCloudDb.Model; using AsbCloudDb.Model;
@ -55,25 +57,23 @@ public class DetectorDrilling : DetectorAbstract
return (begin, i); return (begin, i);
} }
protected override DetectedOperation MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end) protected override (int IdCategory, IDictionary<string, object> ExtraData) GetSpecificInformation(DetectableTelemetry[] telemetry, int begin, int end)
{ {
var (avgRotorSpeed, dispersionOfNormalizedRotorSpeed, isAfbEnabled) = CalcCriteries(telemetry, begin, end); var (avgRotorSpeed, dispersionOfNormalizedRotorSpeed) = CalcCriteries(telemetry, begin, end);
var operation = MakeDetectedOperationBlank(idTelemetry, telemetry, begin, end); var idCategory = GetIdOperation(avgRotorSpeed, dispersionOfNormalizedRotorSpeed);
operation.IdCategory = GetIdOperation(avgRotorSpeed, dispersionOfNormalizedRotorSpeed); var extraData = new Dictionary<string, object>();
operation.ExtraData[ExtraDataKeyAvgRotorSpeed] = avgRotorSpeed; extraData[ExtraDataKeyAvgRotorSpeed] = avgRotorSpeed;
operation.ExtraData[ExtraDataKeyDispersionOfNormalizedRotorSpeed] = dispersionOfNormalizedRotorSpeed; extraData[ExtraDataKeyDispersionOfNormalizedRotorSpeed] = dispersionOfNormalizedRotorSpeed;
operation.ExtraData[ExtraDataKeyHasOscillation] = dispersionOfNormalizedRotorSpeed > dispersionOfNormalizedRotorSpeedThreshold; extraData[ExtraDataKeyHasOscillation] = dispersionOfNormalizedRotorSpeed > dispersionOfNormalizedRotorSpeedThreshold;
operation.ExtraData[ExtraDataKeyIsAfbEnabled] = isAfbEnabled; return (idCategory, extraData);
return operation;
} }
private static (double avgRotorSpeed, double dispersionOfNormalizedRotorSpeed, bool isAfbEnabled) CalcCriteries(DetectableTelemetry[] telemetry, int begin, int end) private static (double avgRotorSpeed, double dispersionOfNormalizedRotorSpeed) CalcCriteries(DetectableTelemetry[] telemetry, int begin, int end)
{ {
var telemetryRange = telemetry[begin..end]; var telemetryRange = telemetry[begin..end];
var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed); var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed);
var dispersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed / avgRotorSpeed - 1, 2)); var dispersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed / avgRotorSpeed - 1, 2));
var isAfbEnabled = telemetryRange.Any(t => t.Mode > 0); return (avgRotorSpeed, dispersion);
return (avgRotorSpeed, dispersion, isAfbEnabled);
} }
private static int GetIdOperation(double avgRotorSpeed, double dispersionOfNormalizedRotorSpeed) private static int GetIdOperation(double avgRotorSpeed, double dispersionOfNormalizedRotorSpeed)
@ -88,4 +88,5 @@ public class DetectorDrilling : DetectorAbstract
else else
return idSlideWithOscillation; return idSlideWithOscillation;
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using AsbCloudDb.Model; using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors; namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
@ -27,14 +28,12 @@ public class DetectorSlipsTime : DetectorAbstract
return true; return true;
} }
protected override (int IdCategory, IDictionary<string, object> ExtraData) GetSpecificInformation(DetectableTelemetry[] telemetry, int begin, int end)
{
return (WellOperationCategory.IdSlipsTime, new Dictionary<string, object>());
}
protected override bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) => protected override bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01; Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01;
protected override DetectedOperation MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end)
{
var operation = MakeDetectedOperationBlank(idTelemetry, telemetry, begin, end);
operation.IdCategory = WellOperationCategory.IdSlipsTime;
return operation;
}
} }

View File

@ -60,7 +60,7 @@ namespace AsbCloudWebApi.Controllers.SAUB
[FromQuery] DetectedOperationRequest request, [FromQuery] DetectedOperationRequest request,
CancellationToken token) CancellationToken token)
{ {
if (!await UserHasAccesToWellAsync(request.IdWell, token)) if (!await UserHasAccessToWellAsync(request.IdWell, token))
return Forbid(); return Forbid();
var result = await detectedOperationService.GetAsync(request, token); var result = await detectedOperationService.GetAsync(request, token);
@ -79,7 +79,7 @@ namespace AsbCloudWebApi.Controllers.SAUB
[FromQuery] DetectedOperationRequest request, [FromQuery] DetectedOperationRequest request,
CancellationToken token) CancellationToken token)
{ {
if (!await UserHasAccesToWellAsync(request.IdWell, token)) if (!await UserHasAccessToWellAsync(request.IdWell, token))
return Forbid(); return Forbid();
var result = await detectedOperationService.GetOperationsStatAsync(request, token); var result = await detectedOperationService.GetOperationsStatAsync(request, token);
@ -101,14 +101,14 @@ namespace AsbCloudWebApi.Controllers.SAUB
[FromQuery] DetectedOperationRequest request, [FromQuery] DetectedOperationRequest request,
CancellationToken token) CancellationToken token)
{ {
if (!await UserHasAccesToWellAsync(request.IdWell, token)) if (!await UserHasAccessToWellAsync(request.IdWell, token))
return Forbid(); return Forbid();
var result = await detectedOperationService.DeleteAsync(request, token); var result = await detectedOperationService.DeleteAsync(request, token);
return Ok(result); return Ok(result);
} }
protected async Task<bool> UserHasAccesToWellAsync(int idWell, CancellationToken token) protected async Task<bool> UserHasAccessToWellAsync(int idWell, CancellationToken token)
{ {
var idCompany = User.GetCompanyId(); var idCompany = User.GetCompanyId();
if (idCompany is not null && if (idCompany is not null &&

View File

@ -7,6 +7,7 @@ namespace AsbCloudWebApi
{ {
// Uncomment next line to find wired exceptions by tracing. // Uncomment next line to find wired exceptions by tracing.
//static TraceListenerView trace4debug = new TraceListenerView(); //static TraceListenerView trace4debug = new TraceListenerView();
enum A { a = 1 << 2 }
public static void Main(string[] args) public static void Main(string[] args)
{ {