forked from ddrilling/AsbCloudServer
Merge remote-tracking branch 'origin/feature/refactoring_well_operation' into feature/refactoring_well_operation
This commit is contained in:
commit
41695502b0
@ -180,7 +180,7 @@ namespace AsbCloudInfrastructure
|
|||||||
|
|
||||||
services.AddTransient<
|
services.AddTransient<
|
||||||
IChangeLogRepository<ProcessMapPlanReamDto, ProcessMapPlanBaseRequestWithWell>,
|
IChangeLogRepository<ProcessMapPlanReamDto, ProcessMapPlanBaseRequestWithWell>,
|
||||||
ProcessMapPlanBaseRepository<ProcessMapPlanReamDto, ProcessMapPlanDrilling>>();
|
ProcessMapPlanBaseRepository<ProcessMapPlanReamDto, ProcessMapPlanReam>>();
|
||||||
|
|
||||||
services.AddTransient<IProcessMapReportDrillingService, ProcessMapReportDrillingService>();
|
services.AddTransient<IProcessMapReportDrillingService, ProcessMapReportDrillingService>();
|
||||||
|
|
||||||
|
@ -4,14 +4,53 @@ namespace AsbCloudInfrastructure.Services.DetectOperations;
|
|||||||
|
|
||||||
public class DetectableTelemetry
|
public class DetectableTelemetry
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Дата начала
|
||||||
|
/// </summary>
|
||||||
public DateTimeOffset DateTime { get; set; }
|
public DateTimeOffset DateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Режим
|
||||||
|
/// </summary>
|
||||||
public int Mode { get; set; }
|
public int Mode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ключ пользователя
|
||||||
|
/// </summary>
|
||||||
public int? IdUser { get; set; }
|
public int? IdUser { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Глубина забоя
|
||||||
|
/// </summary>
|
||||||
public float WellDepth { get; set; }
|
public float WellDepth { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Давление
|
||||||
|
/// </summary>
|
||||||
public float Pressure { get; set; }
|
public float Pressure { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Вес на крюке
|
||||||
|
/// </summary>
|
||||||
public float HookWeight { get; set; }
|
public float HookWeight { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Положение талевого блока
|
||||||
|
/// </summary>
|
||||||
public float BlockPosition { get; set; }
|
public float BlockPosition { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Глубина долота
|
||||||
|
/// </summary>
|
||||||
public float BitDepth { get; set; }
|
public float BitDepth { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Обороты ротора
|
||||||
|
/// </summary>
|
||||||
public float RotorSpeed { get; set; }
|
public float RotorSpeed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Осевая нагрузка
|
||||||
|
/// </summary>
|
||||||
public float AxialLoad { get; set; }
|
public float AxialLoad { get; set; }
|
||||||
}
|
}
|
@ -26,7 +26,8 @@ public class DetectedOperationService : IDetectedOperationService
|
|||||||
|
|
||||||
private static readonly DetectorAbstract[] detectors = {
|
private static readonly DetectorAbstract[] detectors = {
|
||||||
new DetectorDrilling(),
|
new DetectorDrilling(),
|
||||||
new DetectorSlipsTime()
|
new DetectorSlipsTime(),
|
||||||
|
new DetectorFlashing(),
|
||||||
};
|
};
|
||||||
|
|
||||||
public DetectedOperationService(
|
public DetectedOperationService(
|
||||||
@ -168,7 +169,7 @@ public class DetectedOperationService : IDetectedOperationService
|
|||||||
AxialLoad = t.AxialLoad,
|
AxialLoad = t.AxialLoad,
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
|
|
||||||
if (detectableTelemetries.Length < gap)
|
if (detectableTelemetries.Length <= gap)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
var isDetected = false;
|
var isDetected = false;
|
||||||
|
@ -32,6 +32,10 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
|
|
||||||
protected const int IdReasonOfEnd_ChangeBithDepthAndAxiloadLessHookWeight = 700;
|
protected const int IdReasonOfEnd_ChangeBithDepthAndAxiloadLessHookWeight = 700;
|
||||||
|
|
||||||
|
protected const int IdReasonOfEnd_DeltaWellDepthAndBithDepthIsLo = 800;
|
||||||
|
|
||||||
|
protected const int IdReasonOfEnd_BithDepthIsLo = 900;
|
||||||
|
|
||||||
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperationDto? previousOperation,
|
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperationDto? previousOperation,
|
||||||
out OperationDetectorResult? result)
|
out OperationDetectorResult? result)
|
||||||
{
|
{
|
||||||
|
@ -1,59 +1,67 @@
|
|||||||
// using AsbCloudDb.Model;
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
//
|
using AsbCloudDb.Model;
|
||||||
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
using System;
|
||||||
// {
|
using System.Collections.Generic;
|
||||||
//
|
|
||||||
// /// <summary>
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
// /// Промывка
|
{
|
||||||
// /// </summary>
|
|
||||||
// internal class DetectorFlashing : DetectorAbstract
|
/// <summary>
|
||||||
// {
|
/// Промывка
|
||||||
// public DetectorFlashing()
|
/// </summary>
|
||||||
// : base(WellOperationCategory.IdFlashing)
|
public class DetectorFlashing : DetectorAbstract
|
||||||
// { }
|
{
|
||||||
//
|
|
||||||
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
// => CalcDeltaMinutes(telemetry, begin, end);
|
=> CalcDeltaMinutes(telemetry, begin, end);
|
||||||
//
|
|
||||||
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation)
|
||||||
// {
|
{
|
||||||
// if (!((previousOperation?.IdCategory == WellOperationCategory.IdRotor) ||
|
|
||||||
// (previousOperation?.IdCategory == WellOperationCategory.IdSlide)))
|
var currentPoint = telemetry[position];
|
||||||
// return false;
|
if (currentPoint.Pressure < 10)
|
||||||
//
|
return false;
|
||||||
// var point0 = telemetry[position];
|
|
||||||
// var delta = point0.WellDepth - point0.BitDepth;
|
var delta = currentPoint.WellDepth - currentPoint.BitDepth;
|
||||||
// if (delta > 0.05d)
|
if (delta < 0.03d)
|
||||||
// return false;
|
return false;
|
||||||
//
|
|
||||||
// if (point0.Pressure < 15)
|
if (currentPoint.RotorSpeed > 8)
|
||||||
// return false;
|
return false;
|
||||||
//
|
|
||||||
// if (point0.BlockPosition < 3)
|
var nextIndexPoint = telemetry.Length <= position ? position : position + 1;
|
||||||
// return false;
|
var nextPoint = telemetry[nextIndexPoint];
|
||||||
//
|
if (Math.Abs(currentPoint.WellDepth - nextPoint.WellDepth) > 0)
|
||||||
// if (ContainsDeviationApprox(telemetry, t => t.WellDepth, position, 150, 0.0001))
|
return false;
|
||||||
// return false;
|
|
||||||
//
|
if (currentPoint.BitDepth < 150)
|
||||||
// return true;
|
return false;
|
||||||
// }
|
|
||||||
//
|
return true;
|
||||||
// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
|
||||||
// {
|
}
|
||||||
// var point0 = telemetry[position];
|
|
||||||
// var delta = point0.WellDepth - point0.BitDepth;
|
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation)
|
||||||
// if ((delta > 0.03d )
|
{
|
||||||
// && (point0.Pressure > 15)
|
var currentPoint = telemetry[position];
|
||||||
// && ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03))
|
|
||||||
// return IdReasonOfEnd_Custom1;
|
if (currentPoint.Pressure < 10)
|
||||||
//
|
return IdReasonOfEnd_PressureIsLo;
|
||||||
// return IdReasonOfEnd_NotDetected;
|
if ((currentPoint.WellDepth - currentPoint.BitDepth) < 0.03d)
|
||||||
// }
|
return IdReasonOfEnd_DeltaWellDepthAndBithDepthIsLo;
|
||||||
//
|
if (currentPoint.RotorSpeed > 8)
|
||||||
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
return IdReasonOfEnd_RotorSpeedIsHi;
|
||||||
// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
if (currentPoint.BitDepth < 150)
|
||||||
// }
|
return IdReasonOfEnd_BithDepthIsLo;
|
||||||
//
|
return IdReasonOfEnd_NotDetected;
|
||||||
//
|
}
|
||||||
// }
|
|
||||||
//
|
protected override (int IdCategory, IDictionary<string, object> ExtraData) GetSpecificInformation(DetectableTelemetry[] telemetry,
|
||||||
|
int begin,
|
||||||
|
int end)
|
||||||
|
{
|
||||||
|
return (WellOperationCategory.IdFlashing, new Dictionary<string, object>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -2,25 +2,26 @@
|
|||||||
|
|
||||||
## Описание
|
## Описание
|
||||||
|
|
||||||
Промывка – операция, во время которой после добуривания очередной трубы происходит снижение осевой нагрузки и дифференциального давления, талевый блок остается условно неподвижным.
|
Промывка – операция, во время которой давление условно постоянное, а вращение колонны отсутствует, талевый блок при этом может быть как в движении, так и статичным.
|
||||||
|
|
||||||
Проработка перед наращиванием определяется как время между:
|
Промывка определяется как время между:
|
||||||
- окончанием операции бурения (ротор/ слайд/ ручное бурение)
|
- окончанием операции бурения или выходом на режим буровых насосов (рост давления)
|
||||||
- началом операции проработки/ шаблонировки перед наращивании
|
- началом операции проработки/шаблонировки перед наращиванием или остановкой буровых насосов (снижение давления).
|
||||||
|
|
||||||
## Метод определения
|
## Метод определения
|
||||||
|
|
||||||
Признак начала операции =
|
Признак начала операции =
|
||||||
( предыдущая операция == бурение в роторе или слайде)
|
( давление >= 10 атм ) И
|
||||||
( расстояние от долота до забоя < 0,05м ) И
|
( обороты ротора <= 8 об/мин) И
|
||||||
( давление > 15 атм ) И
|
( расстояние от долота до забоя >= 0.03 м) И
|
||||||
( положение блока > 3м ) И
|
( глубина забоя не изменяется) И
|
||||||
( глубина забоя изменяется менее чем на 0,0001м в течении 150 сек)
|
( глубина долота >= 150 м);
|
||||||
|
|
||||||
Признак окончания операции =
|
Признак окончания операции =
|
||||||
( расстояние от долота до забоя > 0.03м ) И
|
( давление < 10 атм ) ИЛИ
|
||||||
( давление > 15 атм ) И
|
( расстояние от долота до забоя < 0.03 м ) ИЛИ
|
||||||
( высота блока изменяется больше чем на 0.03м в течении 60 сек с начала операции);
|
( обороты ротора > 8 об/мин) ИЛИ
|
||||||
|
( глубина долота < 150 м);
|
||||||
|
|
||||||
|
|
||||||
## Ключевой параметр
|
## Ключевой параметр
|
||||||
|
@ -44,7 +44,7 @@ public class WorkOperationDetection: Work
|
|||||||
|
|
||||||
var beginDate = lastDetectedDates.TryGetValue(telemetryId, out var date) ? date : (DateTimeOffset?)null;
|
var beginDate = lastDetectedDates.TryGetValue(telemetryId, out var date) ? date : (DateTimeOffset?)null;
|
||||||
|
|
||||||
onProgressCallback($"Start detecting telemetry: {telemetryId} from {beginDate}", i++ / telemetryIds.Length);
|
onProgressCallback($"Start detecting telemetry: {telemetryId} from {beginDate}", i / telemetryIds.Length);
|
||||||
var detectedOperations = await detectedOperationService.DetectOperationsAsync(telemetryId, beginDate, token);
|
var detectedOperations = await detectedOperationService.DetectOperationsAsync(telemetryId, beginDate, token);
|
||||||
|
|
||||||
if (detectedOperations.Any())
|
if (detectedOperations.Any())
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
|
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace AsbCloudWebApi.Tests.Services.DetectedOperations.Detectors;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Тестирование автоопределения операции "Промывка"
|
||||||
|
/// </summary>
|
||||||
|
public class DetectorFlashingTests : DetectorFlashing
|
||||||
|
{
|
||||||
|
private readonly DetectorFlashing detector = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Операция, попадающая под автоопределение операции промывки
|
||||||
|
/// </summary>
|
||||||
|
private readonly DetectableTelemetry telemetry = new()
|
||||||
|
{
|
||||||
|
Pressure = 21,
|
||||||
|
WellDepth = 152,
|
||||||
|
BitDepth = 151,
|
||||||
|
RotorSpeed = 8,
|
||||||
|
DateTime = System.DateTimeOffset.Now
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DetectOperation_find_startOperation_notFind_endOperation()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var point0 = telemetry.Copy();
|
||||||
|
var point1 = telemetry.Copy();
|
||||||
|
point1.DateTime = System.DateTimeOffset.Now.AddMinutes(5);
|
||||||
|
|
||||||
|
var telemetries = new[] { point0, point1 };
|
||||||
|
|
||||||
|
//act
|
||||||
|
var isDetectOperation = detector.TryDetect(0, telemetries, 0, telemetries.Length - 1, null, out var result);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.True(isDetectOperation);
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(WellOperationCategory.IdFlashing, result.Operation.IdCategory);
|
||||||
|
Assert.Equal(IdReasonOfEnd_NotDetected, result.Operation.ExtraData["IdReasonOfEnd"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DetectOperation_with_BitDepth_LE_150_is_fail()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var point0 = telemetry.Copy();
|
||||||
|
point0.BitDepth = 150;
|
||||||
|
|
||||||
|
var point1 = telemetry.Copy();
|
||||||
|
|
||||||
|
var telemetries = new[] { point0, point1 };
|
||||||
|
|
||||||
|
//act
|
||||||
|
|
||||||
|
var isDetectOperation = detector.TryDetect(0, telemetries, 0, telemetries.Length - 1, null, out var result);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.False(isDetectOperation);
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(WellOperationCategory.IdFlashing, result.Operation.IdCategory);
|
||||||
|
Assert.Equal(IdReasonOfEnd_NotDetected, result.Operation.ExtraData["IdReasonOfEnd"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DetectOperation_with_DeltaWellDepth_NotEqual_0_is_fail()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var point0 = telemetry.Copy();
|
||||||
|
var point1 = telemetry.Copy();
|
||||||
|
point1.WellDepth = point0.WellDepth + 10;
|
||||||
|
|
||||||
|
var telemetries = new[] { point0, point1 };
|
||||||
|
|
||||||
|
//act
|
||||||
|
var isDetectOperation = detector.TryDetect(0, telemetries, 0, telemetries.Length - 1, null, out var result);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.False(isDetectOperation);
|
||||||
|
Assert.Null(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DetectOperations_Begin_And_End_by_Pressure_Less_10_is_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var point0 = telemetry.Copy();
|
||||||
|
var point1 = telemetry.Copy();
|
||||||
|
point1.Pressure = 9;
|
||||||
|
point1.BitDepth = 140.0001f;
|
||||||
|
point1.RotorSpeed = 10;
|
||||||
|
|
||||||
|
var telemetries = new[] { point0, point1 };
|
||||||
|
|
||||||
|
//act
|
||||||
|
var isDetectOperation = detector.TryDetect(0, telemetries, 0, telemetries.Length - 1, null, out var result);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.False(isDetectOperation);
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(WellOperationCategory.IdFlashing, result.Operation.IdCategory);
|
||||||
|
Assert.Equal(IdReasonOfEnd_PressureIsLo, result.Operation.ExtraData["IdReasonOfEnd"]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user