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("Ключевой показатель операции")]
public double Value { get; set; }
[Column("enabled_subsystems"), Comment("флаги аключенных подсистем")]
public int EnabledSubsystems { get; set; }
[Column("extra_data", TypeName = "jsonb"), Comment("доп. инфо по операции")]
public IDictionary<string, object> ExtraData { get; set; } = null!;
@ -54,5 +57,57 @@ namespace AsbCloudDb.Model
public override string ToString()
=> $"{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;
}
private string? CreateComment(OperationDetectorResult operationDetectorResult)
private static string CreateComment(OperationDetectorResult operationDetectorResult)
{
var operation = operationDetectorResult.Operation;
switch (operation.IdCategory)
@ -214,7 +214,7 @@ public class DetectedOperationExportService
return comment;
}
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)
return 0;
var query = BuildQuery(well, request);
var query = BuildQueryBase(well, request);
if (query is null)
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>()
.Include(o => o.OperationCategory)
.Where(o => o.IdTelemetry == well.IdTelemetry);
if (request is not null)
@ -262,6 +259,14 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
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)
{
query = query.SortBy(request.SortFields);

View File

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

View File

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

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
@ -27,14 +28,12 @@ public class DetectorSlipsTime : DetectorAbstract
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) =>
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,
CancellationToken token)
{
if (!await UserHasAccesToWellAsync(request.IdWell, token))
if (!await UserHasAccessToWellAsync(request.IdWell, token))
return Forbid();
var result = await detectedOperationService.GetAsync(request, token);
@ -79,7 +79,7 @@ namespace AsbCloudWebApi.Controllers.SAUB
[FromQuery] DetectedOperationRequest request,
CancellationToken token)
{
if (!await UserHasAccesToWellAsync(request.IdWell, token))
if (!await UserHasAccessToWellAsync(request.IdWell, token))
return Forbid();
var result = await detectedOperationService.GetOperationsStatAsync(request, token);
@ -101,14 +101,14 @@ namespace AsbCloudWebApi.Controllers.SAUB
[FromQuery] DetectedOperationRequest request,
CancellationToken token)
{
if (!await UserHasAccesToWellAsync(request.IdWell, token))
if (!await UserHasAccessToWellAsync(request.IdWell, token))
return Forbid();
var result = await detectedOperationService.DeleteAsync(request, token);
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();
if (idCompany is not null &&

View File

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