forked from ddrilling/AsbCloudServer
DetectorAbstract добавлено определение включенных подсистем во время выполнения операции.
This commit is contained in:
parent
948002955d
commit
fdc615d343
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 &&
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user