Изменения из dev

This commit is contained in:
Olga Nemt 2024-03-25 10:51:43 +05:00
commit 612dd6b7ce
9 changed files with 278 additions and 100 deletions

View File

@ -64,4 +64,12 @@ public class ProcessMapPlanBaseRepository<TDto, TEntity> : ChangeLogRepositoryAb
dto.Section = entity.WellSectionType.Caption; dto.Section = entity.WellSectionType.Caption;
return dto; return dto;
} }
protected override TEntity Convert(TDto dto)
{
var entity = base.Convert(dto);
entity.Author = null;
entity.Editor = null;
return entity;
}
} }

View File

@ -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; }
} }

View File

@ -25,14 +25,15 @@ 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(
IDetectedOperationRepository operationRepository, IDetectedOperationRepository operationRepository,
IWellOperationCategoryRepository wellOperationCategoryRepository, IWellOperationCategoryRepository wellOperationCategoryRepository,
IWellService wellService, IWellService wellService,
IRepositoryWellRelated<OperationValueDto> operationValueRepository, IRepositoryWellRelated<OperationValueDto> operationValueRepository,
IScheduleRepository scheduleRepository, IScheduleRepository scheduleRepository,
ITelemetryDataSaubService telemetryDataSaubService) ITelemetryDataSaubService telemetryDataSaubService)
{ {
@ -86,9 +87,9 @@ public class DetectedOperationService : IDetectedOperationService
if (well?.IdTelemetry is null) if (well?.IdTelemetry is null)
return Enumerable.Empty<WellOperationCategoryDto>(); return Enumerable.Empty<WellOperationCategoryDto>();
var request = new DetectedOperationByTelemetryRequest() var request = new DetectedOperationByTelemetryRequest()
{ {
IdTelemetry = well.IdTelemetry.Value IdTelemetry = well.IdTelemetry.Value
}; };
var operations = await operationRepository.Get(request, token); var operations = await operationRepository.Get(request, token);
@ -111,7 +112,7 @@ public class DetectedOperationService : IDetectedOperationService
if (!operations.Any()) if (!operations.Any())
return Enumerable.Empty<DetectedOperationStatDto>(); return Enumerable.Empty<DetectedOperationStatDto>();
var dtos = operations var dtos = operations
.GroupBy(o => (o.IdCategory, o.OperationCategory.Name)) .GroupBy(o => (o.IdCategory, o.OperationCategory.Name))
.OrderBy(g => g.Key) .OrderBy(g => g.Key)
@ -135,39 +136,39 @@ public class DetectedOperationService : IDetectedOperationService
public async Task<IEnumerable<DetectedOperationDto>> DetectOperationsAsync(int idTelemetry, DateTimeOffset? beginDate, CancellationToken token) public async Task<IEnumerable<DetectedOperationDto>> DetectOperationsAsync(int idTelemetry, DateTimeOffset? beginDate, CancellationToken token)
{ {
const int take = 4 * 86_400; const int take = 4 * 86_400;
var detectedOperations = new List<DetectedOperationDto>(); var detectedOperations = new List<DetectedOperationDto>();
DetectedOperationDto? lastDetectedOperation = null; DetectedOperationDto? lastDetectedOperation = null;
const int minOperationLength = 5; const int minOperationLength = 5;
const int maxDetectorsInterpolationFrameLength = 30; const int maxDetectorsInterpolationFrameLength = 30;
const int gap = maxDetectorsInterpolationFrameLength + minOperationLength; const int gap = maxDetectorsInterpolationFrameLength + minOperationLength;
while (true) while (true)
{ {
var request = new TelemetryDataRequest var request = new TelemetryDataRequest
{ {
GeDate = beginDate, GeDate = beginDate,
Take = take, Take = take,
Order = 0 Order = 0
}; };
var detectableTelemetries = (await telemetryDataSaubService.GetByTelemetryAsync(idTelemetry, request, token)) var detectableTelemetries = (await telemetryDataSaubService.GetByTelemetryAsync(idTelemetry, request, token))
.Where(t => t.BlockPosition >= 0) .Where(t => t.BlockPosition >= 0)
.Select(t => new DetectableTelemetry .Select(t => new DetectableTelemetry
{ {
DateTime = t.DateTime, DateTime = t.DateTime,
IdUser = t.IdUser, IdUser = t.IdUser,
Mode = t.Mode, Mode = t.Mode,
WellDepth = t.WellDepth, WellDepth = t.WellDepth,
Pressure = t.Pressure, Pressure = t.Pressure,
HookWeight = t.HookWeight, HookWeight = t.HookWeight,
BlockPosition = t.BlockPosition, BlockPosition = t.BlockPosition,
BitDepth = t.BitDepth, BitDepth = t.BitDepth,
RotorSpeed = t.RotorSpeed, RotorSpeed = t.RotorSpeed,
AxialLoad = t.AxialLoad, AxialLoad = t.AxialLoad,
}).ToArray(); }).ToArray();
if (detectableTelemetries.Length < gap) if (detectableTelemetries.Length <= gap)
break; break;
var isDetected = false; var isDetected = false;
@ -179,14 +180,14 @@ public class DetectedOperationService : IDetectedOperationService
{ {
if (!detector.TryDetect(idTelemetry, detectableTelemetries, positionBegin, positionEnd, lastDetectedOperation, out var result)) if (!detector.TryDetect(idTelemetry, detectableTelemetries, positionBegin, positionEnd, lastDetectedOperation, out var result))
continue; continue;
detectedOperations.Add(result!.Operation); detectedOperations.Add(result!.Operation);
lastDetectedOperation = result.Operation; lastDetectedOperation = result.Operation;
isDetected = true; isDetected = true;
positionBegin = result.TelemetryEnd; positionBegin = result.TelemetryEnd;
break; break;
} }
positionBegin += 1; positionBegin += 1;
} }

View File

@ -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)
{ {

View File

@ -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>());
}
}
}

View File

@ -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 м);
## Ключевой параметр ## Ключевой параметр

View File

@ -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())

View File

@ -10,6 +10,8 @@ using AsbCloudWebApi.IntegrationTests.Data;
using Refit; using Refit;
using Xunit; using Xunit;
using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.ProcessMaps;
using AsbCloudDb.Model;
using AsbCloudApp.Data.User;
namespace AsbCloudWebApi.IntegrationTests.Controllers.ProcessMapPlan; namespace AsbCloudWebApi.IntegrationTests.Controllers.ProcessMapPlan;
@ -194,6 +196,9 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
var startTime = DateTimeOffset.UtcNow; var startTime = DateTimeOffset.UtcNow;
var dbset = dbContext.Set<ProcessMapPlanDrilling>(); var dbset = dbContext.Set<ProcessMapPlanDrilling>();
var user = dbContext.Set<User>().First().Adapt<UserDto>();
user.Surname = "userSurname";
user.Email = "user@mail.domain";
var entry = dbset.Add(entity); var entry = dbset.Add(entity);
dbContext.SaveChanges(); dbContext.SaveChanges();
@ -216,6 +221,7 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
dtoUpdate.TopDriveSpeedLimitMax++; dtoUpdate.TopDriveSpeedLimitMax++;
dtoUpdate.TopDriveTorquePlan++; dtoUpdate.TopDriveTorquePlan++;
dtoUpdate.TopDriveTorqueLimitMax++; dtoUpdate.TopDriveTorqueLimitMax++;
dtoUpdate.Author = user;
var dtoInsert = dtoUpdate.Adapt<ProcessMapPlanDrillingDto>(); var dtoInsert = dtoUpdate.Adapt<ProcessMapPlanDrillingDto>();
dtoInsert.Id = 0; dtoInsert.Id = 0;
@ -233,6 +239,7 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
dtoInsert.TopDriveSpeedLimitMax++; dtoInsert.TopDriveSpeedLimitMax++;
dtoInsert.TopDriveTorquePlan++; dtoInsert.TopDriveTorquePlan++;
dtoInsert.TopDriveTorqueLimitMax++; dtoInsert.TopDriveTorqueLimitMax++;
dtoInsert.Author = user;
// act // act
var result = await client.UpdateOrInsertRange(entity.IdWell, new ProcessMapPlanDrillingDto[] { dtoUpdate, dtoInsert }); var result = await client.UpdateOrInsertRange(entity.IdWell, new ProcessMapPlanDrillingDto[] { dtoUpdate, dtoInsert });

View File

@ -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"]);
}
}