forked from ddrilling/AsbCloudServer
Merge branch 'dev' into feature/#27942032-well-composite-operations
This commit is contained in:
commit
764fcef9b5
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
@ -60,7 +61,15 @@ public class NotificationService
|
||||
|
||||
var notificationTransportService = GetTransportService(request.IdTransportType);
|
||||
|
||||
await notificationTransportService.SendAsync(notification, cancellationToken);
|
||||
//todo Добавить задачу в WorkToSendEmail
|
||||
try
|
||||
{
|
||||
await notificationTransportService.SendAsync(notification, cancellationToken);
|
||||
}
|
||||
catch (SmtpException ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
notification.SentDate = DateTime.UtcNow;
|
||||
await notificationRepository.UpdateAsync(notification, cancellationToken);
|
||||
|
@ -13,4 +13,5 @@ public class DetectableTelemetry
|
||||
public float BlockPosition { get; set; }
|
||||
public float BitDepth { get; set; }
|
||||
public float RotorSpeed { get; set; }
|
||||
}
|
||||
public float AxialLoad { get; set; }
|
||||
}
|
@ -118,13 +118,14 @@ public class DetectedOperationExportService
|
||||
for (int i = 0; i < operations.Count; i++)
|
||||
{
|
||||
var current = operations[i];
|
||||
var dateStart = current.DateStart.ToRemoteDateTime(well.Timezone.Hours);
|
||||
var dateEnd = current.DateEnd.ToRemoteDateTime(well.Timezone.Hours);
|
||||
var dateStart = current.DateStart.DateTime;
|
||||
var dateEnd = current.DateEnd.DateTime;
|
||||
|
||||
var row = sheet.Row(5 + i + headerRowsCount);
|
||||
|
||||
var categoryName = GetCategoryName(wellOperationCategories, current);
|
||||
|
||||
row.Cell(columnDateStart).SetCellValue(dateStart);
|
||||
row.Cell(columnOperationName).SetCellValue(categoryName);
|
||||
row.Cell(columnDateEnd).SetCellValue(dateEnd);
|
||||
row.Cell(columnDuration).SetCellValue((dateEnd - dateStart).TotalMinutes);
|
||||
@ -143,9 +144,7 @@ public class DetectedOperationExportService
|
||||
query.Add("end", dateStart.AddSeconds(1800 * 0.9).ToString("yyyy-MM-ddTHH:mm:ss.fff"));
|
||||
query.Add("range", "1800");
|
||||
|
||||
row.Cell(columnDateStart).SetCellValue(dateStart);
|
||||
|
||||
var link = $"{host}/well/{well.Id}/telemetry/monitoring{query}";
|
||||
var link = $"{host}/well/{well.Id}/telemetry/monitoring{query}";
|
||||
row.Cell(columnDateStart).SetHyperlink(link);
|
||||
|
||||
var deltaDepth = i > 0 && i + 1 < operations.Count
|
||||
@ -180,6 +179,8 @@ public class DetectedOperationExportService
|
||||
1 => "Не определено начало операции",
|
||||
101 => "Разница глубин забоя и положением долота",
|
||||
300 => "Низкое давление",
|
||||
301 => "Высокое давление",
|
||||
700 => "Изменение глубины долота и осевая нагрузка < веса на крюке",
|
||||
_ => idReasonOfEnd.ToString($"Причина № {idReasonOfEnd}"),
|
||||
|
||||
};
|
||||
|
@ -164,6 +164,7 @@ public class DetectedOperationService : IDetectedOperationService
|
||||
BlockPosition = t.BlockPosition,
|
||||
BitDepth = t.BitDepth,
|
||||
RotorSpeed = t.RotorSpeed,
|
||||
AxialLoad = t.AxialLoad,
|
||||
}).ToArray();
|
||||
|
||||
if (detectableTelemetries.Length < gap)
|
||||
|
@ -1,5 +1,4 @@
|
||||
using AsbCloudDb.Model;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
|
||||
@ -7,8 +6,6 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||
{
|
||||
public abstract class DetectorAbstract
|
||||
{
|
||||
private readonly int stepLength = 3;
|
||||
|
||||
protected const int IdReasonOfEnd_NotDetected = 0;
|
||||
protected const int IdReasonOfEnd_NotDetectBegin = 1;
|
||||
|
||||
@ -33,7 +30,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||
|
||||
protected const int IdReasonOfEnd_Drilling = 600;
|
||||
|
||||
protected const int IdReasonOfEnd_Custom1 = 10_000;
|
||||
protected const int IdReasonOfEnd_ChangeBithDepthAndAxiloadLessHookWeight = 700;
|
||||
|
||||
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperationDto? previousOperation,
|
||||
out OperationDetectorResult? result)
|
||||
@ -44,9 +41,10 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||
// Поиск окончания соответствия критерию
|
||||
int idReasonOfEnd = 0;
|
||||
var positionEnd = begin;
|
||||
|
||||
while (positionEnd < end)
|
||||
{
|
||||
positionEnd += stepLength;
|
||||
positionEnd += 1;
|
||||
if (positionEnd > end)
|
||||
break;
|
||||
|
||||
@ -55,15 +53,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||
if (idReasonOfEnd != IdReasonOfEnd_NotDetected)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
var (Begin, End) = RefineEdges(telemetry, begin, positionEnd);
|
||||
|
||||
if (!IsValidTelemetryRange(telemetry, Begin, End))
|
||||
{
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
result = MakeOperationDetectorResult(idTelemetry, telemetry, Begin, End, idReasonOfEnd);
|
||||
|
||||
return IsValidOperationDetectorResult(result);
|
||||
@ -72,10 +64,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool IsValidTelemetryRange(DetectableTelemetry[] telemetry, int begin, int end)
|
||||
=> end - begin > 1;
|
||||
|
||||
|
||||
protected virtual (int Begin, int End) RefineEdges(DetectableTelemetry[] telemetry, int begin, int end)
|
||||
=> (begin, end);
|
||||
|
||||
|
@ -12,29 +12,56 @@ public class DetectorSlipsTime : DetectorAbstract
|
||||
|
||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation)
|
||||
{
|
||||
var point0 = telemetry[position];
|
||||
var delta = point0.WellDepth - point0.BitDepth;
|
||||
if (delta > 2.5d)
|
||||
var currentPoint = telemetry[position];
|
||||
if (currentPoint.BitDepth < 150)
|
||||
return false;
|
||||
|
||||
if (currentPoint.Pressure > 20)
|
||||
return false;
|
||||
|
||||
if (point0.Pressure > 15)
|
||||
var delta = currentPoint.WellDepth - currentPoint.BitDepth;
|
||||
if (delta < 0.1d)
|
||||
return false;
|
||||
|
||||
if (point0.BlockPosition > 8)
|
||||
var nextIndexPoint = telemetry.Length <= position ? position : position + 1;
|
||||
var nextPoint = telemetry[nextIndexPoint];
|
||||
var deltaBitDepth = Math.Abs(currentPoint.BitDepth - nextPoint.BitDepth);
|
||||
if (deltaBitDepth > 0.001d)
|
||||
return false;
|
||||
|
||||
if (point0.HookWeight > 20)
|
||||
var deltaBlockPosition = Math.Abs(currentPoint.BlockPosition - nextPoint.BlockPosition);
|
||||
if (deltaBlockPosition < 0.001d)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override (int IdCategory, IDictionary<string, object> ExtraData) GetSpecificInformation(DetectableTelemetry[] telemetry, int begin, int end)
|
||||
{
|
||||
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation)
|
||||
{
|
||||
var currentPoint = telemetry[position];
|
||||
|
||||
if (currentPoint.Pressure > 20)
|
||||
return IdReasonOfEnd_PressureIsHi;
|
||||
|
||||
var prevPointIndex = position <= 0 ? 0 : position - 1;
|
||||
|
||||
var prevPoint = telemetry[prevPointIndex];
|
||||
|
||||
var deltaBitDepth = Math.Abs(currentPoint.BitDepth - prevPoint.BitDepth);
|
||||
|
||||
if (deltaBitDepth > 0.001d && currentPoint.AxialLoad < currentPoint.HookWeight)
|
||||
return IdReasonOfEnd_ChangeBithDepthAndAxiloadLessHookWeight;
|
||||
|
||||
return IdReasonOfEnd_NotDetected;
|
||||
}
|
||||
|
||||
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 bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
|
||||
Math.Abs((operationDetectorResult.Operation.DateStart - operationDetectorResult.Operation.DateEnd).TotalMinutes) < 30;
|
||||
}
|
@ -3,19 +3,26 @@
|
||||
|
||||
Наращивание бурильного инструмента – операция, во время которой после добуривания очередной трубы/ свечи циркуляция выключается, инструмент разгружается в клиньях (остается только вес крюкоблока и ВСП), происходит развинчивание трубы от верхнего силового привода, берется очередная труба/ свеча, свинчивается с инструментом в клиньях, свинчивается с верхним силовым приводом, происходит подъем инструмента, вес на крюке увеличивается. Далее включается циркуляция и происходит механическое бурение.
|
||||
|
||||
Наращивается определяется как время между:
|
||||
- разгрузкой инструмента на клинья (остается только вес крюкоблока и ВСП). При этом давление менее 15 атм. В случае давления более 15 атм считать началом операции как снижение давления менее 15 атм и началом движения талевого блока вверх.
|
||||
- снятие инструмента с клиньев (вес увеличивается более, чем на 1т). При этом движение талевого блока происходит вверх.
|
||||
Наращивание определяется как время между:
|
||||
- началом разгрузки инструмента на клинья (остается только вес крюкоблока и ВСП). При этом расстояние от долота до забоя в диапазоне от 0.1 до 3м., давление менее 20 атм. В случае Если происходит движение блока без изменения глубины долота—-> идем назад и ищем падение давления ниже 20атм.
|
||||
- снятие инструмента с клиньев (вес увеличивается более, чем на 1т). При этом движение талевого блока происходит вверх ИЛИ увеличение давления больше 20 атм.
|
||||
|
||||
|
||||
## Метод определения
|
||||
|
||||
Признак начала операции =
|
||||
( расстояние от долота до забоя < 2.5м ) И
|
||||
( положение талевого блока < 8 ) И
|
||||
( вес на крюке < 20 тонн ) И
|
||||
( давление < 15 атм );
|
||||
|
||||
Признак окончания операции = НЕ выполняется признак начала операции;
|
||||
( Расстояние от долота до забоя > 0.1 м) И
|
||||
( давление < 20атм) И
|
||||
( движение блока без изменения глубины долота) И
|
||||
( глубина долота > 150 м);
|
||||
|
||||
Признак окончания операции =
|
||||
( давление > 20атм) ИЛИ
|
||||
( время продолжительности > 30 мин) ИЛИ
|
||||
( изменение глубины долота) И
|
||||
( осевая нагрузка < веса на крюке);
|
||||
|
||||
## Ключевой параметр
|
||||
Продолжительность операции.
|
||||
Продолжительность операции.
|
||||
|
||||
Предел времени операции 30 минут, всё что больше 30 минут это уже не наращивание - а НПВ.
|
@ -0,0 +1,20 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Data.ProcessMaps.Report;
|
||||
using AsbCloudApp.Requests;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Refit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Clients;
|
||||
|
||||
public interface IProcessMapReportDrilling
|
||||
{
|
||||
private const string BaseRoute = "/api/well/{idWell}/ProcessMapReportDrilling";
|
||||
|
||||
[Get($"{BaseRoute}/report")]
|
||||
Task<IApiResponse<IEnumerable<ProcessMapReportDataSaubStatDto>>> GetReportAsync(int idWell, [FromQuery] DataSaubStatRequest request, CancellationToken cancellationToken);
|
||||
|
||||
[Get($"{BaseRoute}/report/export")]
|
||||
Task<IApiResponse<PhysicalFileResult>> ExportReportAsync(int idWell, [FromQuery] DataSaubStatRequest request, CancellationToken cancellationToken);
|
||||
|
||||
}
|
@ -0,0 +1,315 @@
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.ProcessMaps;
|
||||
using AsbCloudWebApi.IntegrationTests.Clients;
|
||||
using Org.BouncyCastle.Asn1.Ocsp;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Controllers.ProcessMapPlan;
|
||||
|
||||
public class ProcessMapReportDrillingControllerTest : BaseIntegrationTest
|
||||
{
|
||||
|
||||
private readonly WellSectionType wellSection = new WellSectionType()
|
||||
{
|
||||
Id = 1,
|
||||
Caption = "Секция 1",
|
||||
Order = 1
|
||||
};
|
||||
|
||||
private readonly WellOperationCategory wellOperationCategory = new WellOperationCategory()
|
||||
{
|
||||
Id = 1,
|
||||
IdParent = null,
|
||||
KeyValueName = "Name",
|
||||
Name = "Name"
|
||||
};
|
||||
|
||||
private readonly WellOperation wellOperation = new WellOperation()
|
||||
{
|
||||
CategoryInfo = "CategoryInfo",
|
||||
Id = 10,
|
||||
Comment = "Comment",
|
||||
DateStart = DateTimeOffset.UtcNow,
|
||||
DepthEnd = 1,
|
||||
DepthStart = 0.6,
|
||||
DurationHours = 10,
|
||||
IdCategory = 1,
|
||||
IdPlan = null,
|
||||
IdType = 1,
|
||||
IdUser = 1,
|
||||
IdWell = 1,
|
||||
IdWellSectionType = 1,
|
||||
LastUpdateDate = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
private readonly List<DataSaubStat> dataSaubStats = new List<DataSaubStat>()
|
||||
{
|
||||
|
||||
new DataSaubStat()
|
||||
{
|
||||
AxialLoad = 0,
|
||||
AxialLoadLimitMax = 10,
|
||||
AxialLoadSp = 8,
|
||||
BlockSpeedSp = 50.0,
|
||||
DateEnd = DateTimeOffset.UtcNow.AddMinutes(40),
|
||||
DateStart = DateTimeOffset.UtcNow.AddMinutes(30),
|
||||
DepthEnd = 85.99299621582031,
|
||||
DepthStart = 85.9260025024414,
|
||||
EnabledSubsystems = 0,
|
||||
Flow = 10,
|
||||
HasOscillation = true,
|
||||
Id = 1,
|
||||
IdCategory = 1,
|
||||
IdFeedRegulator = 0,
|
||||
IdTelemetry = 1,
|
||||
Pressure = 24,
|
||||
PressureIdle = 0,
|
||||
PressureSp = 40,
|
||||
RotorSpeed = 11.3,
|
||||
RotorTorque = 1,
|
||||
RotorTorqueLimitMax = 26.5,
|
||||
RotorTorqueSp = 5,
|
||||
Speed = 80.3924560546875
|
||||
},
|
||||
new DataSaubStat()
|
||||
{
|
||||
AxialLoad = 2,
|
||||
AxialLoadLimitMax = 10.0,
|
||||
AxialLoadSp = 8,
|
||||
BlockSpeedSp = 20,
|
||||
DateEnd = DateTimeOffset.UtcNow.AddMinutes(30),
|
||||
DateStart = DateTimeOffset.UtcNow.AddMinutes(20),
|
||||
DepthEnd = 86.28099822998047,
|
||||
DepthStart = 86.21900177001953,
|
||||
EnabledSubsystems = 1,
|
||||
Flow = 20,
|
||||
HasOscillation = true,
|
||||
Id = 2,
|
||||
IdCategory = 1,
|
||||
IdFeedRegulator = 1,
|
||||
IdTelemetry = 1,
|
||||
Pressure = 30,
|
||||
PressureIdle = 20,
|
||||
PressureSp = 40,
|
||||
RotorSpeed = 11.251153300212916,
|
||||
RotorTorque = 7,
|
||||
RotorTorqueLimitMax = 26.5,
|
||||
RotorTorqueSp = 9,
|
||||
Speed = 74.395751953125
|
||||
},
|
||||
new DataSaubStat()
|
||||
{
|
||||
AxialLoad = 4,
|
||||
AxialLoadLimitMax = 15.0,
|
||||
AxialLoadSp = 8,
|
||||
BlockSpeedSp = 110.0,
|
||||
DateEnd = DateTimeOffset.UtcNow.AddMinutes(20),
|
||||
DateStart = DateTimeOffset.UtcNow.AddMinutes(10),
|
||||
DepthEnd = 106.7490005493164,
|
||||
DepthStart = 106.47899627685547,
|
||||
EnabledSubsystems = 1,
|
||||
Flow = 30,
|
||||
HasOscillation = true,
|
||||
Id = 3,
|
||||
IdCategory = 1,
|
||||
IdFeedRegulator = 1,
|
||||
IdTelemetry = 1,
|
||||
Pressure = 36,
|
||||
PressureIdle = 23.0,
|
||||
PressureSp = 63.0,
|
||||
RotorSpeed = 11.334207942999628,
|
||||
RotorTorque = 14,
|
||||
RotorTorqueLimitMax = 15.0,
|
||||
RotorTorqueSp = 13,
|
||||
Speed = 108.001708984375
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
private readonly ProcessMapPlanDrilling entity = new()
|
||||
{
|
||||
Id = 0,
|
||||
IdAuthor = 1,
|
||||
IdEditor = null,
|
||||
Creation = DateTimeOffset.UtcNow,
|
||||
Obsolete = null,
|
||||
IdState = AsbCloudDb.Model.ChangeLogAbstract.IdStateActual,
|
||||
IdPrevious = null,
|
||||
|
||||
IdWell = 1,
|
||||
IdWellSectionType = 1,
|
||||
DepthStart = 0.5,
|
||||
DepthEnd = 1.5,
|
||||
|
||||
IdMode = 1,
|
||||
AxialLoadPlan = 2.718281,
|
||||
AxialLoadLimitMax = 3.1415926,
|
||||
DeltaPressurePlan = 4,
|
||||
DeltaPressureLimitMax = 5,
|
||||
TopDriveTorquePlan = 6,
|
||||
TopDriveTorqueLimitMax = 7,
|
||||
TopDriveSpeedPlan = 8,
|
||||
TopDriveSpeedLimitMax = 9,
|
||||
FlowPlan = 10,
|
||||
FlowLimitMax = 11,
|
||||
RopPlan = 12,
|
||||
UsageSaub = 13,
|
||||
UsageSpin = 14,
|
||||
Comment = "это тестовая запись",
|
||||
};
|
||||
|
||||
private IProcessMapReportDrilling client;
|
||||
|
||||
public ProcessMapReportDrillingControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
client = factory.GetAuthorizedHttpClient<IProcessMapReportDrilling>(string.Empty);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task Get_rtk_report_by_default_request_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ProcessMapPlanDrilling>();
|
||||
var dbset = dbContext.Set<ProcessMapPlanDrilling>();
|
||||
dbset.Add(entity);
|
||||
entity.Id = 1;
|
||||
dbset.Add(entity);
|
||||
entity.Id = 2;
|
||||
dbset.Add(entity);
|
||||
|
||||
var dbSetWellOperationCategory = dbContext.Set<WellOperationCategory>();
|
||||
dbSetWellOperationCategory.Add(wellOperationCategory);
|
||||
|
||||
var dbSetWellOperation = dbContext.Set<WellOperation>();
|
||||
dbSetWellOperation.Add(wellOperation);
|
||||
|
||||
var dbSetDataSaubStat = dbContext.Set<DataSaubStat>();
|
||||
dbSetDataSaubStat.AddRange(dataSaubStats);
|
||||
|
||||
dbContext.SaveChanges();
|
||||
|
||||
//act
|
||||
var request = new DataSaubStatRequest();
|
||||
var response = await client.GetReportAsync(1, request, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Equal(dataSaubStats.Count() - 1, response.Content.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Get_rtk_report_by_parametrize_request_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ProcessMapPlanDrilling>();
|
||||
var dbset = dbContext.Set<ProcessMapPlanDrilling>();
|
||||
dbset.Add(entity);
|
||||
entity.Id = 1;
|
||||
dbset.Add(entity);
|
||||
entity.Id = 2;
|
||||
dbset.Add(entity);
|
||||
|
||||
var dbSetWellOperationCategory = dbContext.Set<WellOperationCategory>();
|
||||
dbSetWellOperationCategory.Add(wellOperationCategory);
|
||||
|
||||
var dbSetWellOperation = dbContext.Set<WellOperation>();
|
||||
dbSetWellOperation.Add(wellOperation);
|
||||
|
||||
var dbSetDataSaubStat = dbContext.Set<DataSaubStat>();
|
||||
dbSetDataSaubStat.AddRange(dataSaubStats);
|
||||
|
||||
dbContext.SaveChanges();
|
||||
|
||||
//act
|
||||
var request = new DataSaubStatRequest()
|
||||
{
|
||||
DeltaAxialLoad = 5,
|
||||
DeltaPressure = 15,
|
||||
DeltaRotorTorque = 10
|
||||
};
|
||||
var response = await client.GetReportAsync(1, request, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Equal(1, response.Content.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Get_rtk_report_returns_BadRequest()
|
||||
{
|
||||
//arrange
|
||||
dbContext.CleanupDbSet<ProcessMapPlanDrilling>();
|
||||
var dbset = dbContext.Set<ProcessMapPlanDrilling>();
|
||||
dbset.Add(entity);
|
||||
entity.Id = 1;
|
||||
dbset.Add(entity);
|
||||
entity.Id = 2;
|
||||
dbset.Add(entity);
|
||||
|
||||
var dbSetWellOperationCategory = dbContext.Set<WellOperationCategory>();
|
||||
dbSetWellOperationCategory.Add(wellOperationCategory);
|
||||
|
||||
var dbSetWellOperation = dbContext.Set<WellOperation>();
|
||||
dbSetWellOperation.Add(wellOperation);
|
||||
|
||||
var dbSetDataSaubStat = dbContext.Set<DataSaubStat>();
|
||||
dbSetDataSaubStat.AddRange(dataSaubStats);
|
||||
|
||||
dbContext.SaveChanges();
|
||||
|
||||
//act
|
||||
var request = new DataSaubStatRequest()
|
||||
{
|
||||
DeltaAxialLoad = 15,
|
||||
DeltaPressure = 25,
|
||||
DeltaRotorTorque = 20
|
||||
};
|
||||
var response = await client.GetReportAsync(1, request, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Export_rtk_report_returns_success()
|
||||
{
|
||||
//clear
|
||||
dbContext.CleanupDbSet<ProcessMapPlanDrilling>();
|
||||
|
||||
//arrange
|
||||
var dbset = dbContext.Set<ProcessMapPlanDrilling>();
|
||||
dbset.Add(entity);
|
||||
entity.Id = 1;
|
||||
dbset.Add(entity);
|
||||
entity.Id = 2;
|
||||
dbset.Add(entity);
|
||||
|
||||
var dbSetWellOperationCategory = dbContext.Set<WellOperationCategory>();
|
||||
dbSetWellOperationCategory.Add(wellOperationCategory);
|
||||
|
||||
var dbSetWellOperation = dbContext.Set<WellOperation>();
|
||||
dbSetWellOperation.Add(wellOperation);
|
||||
|
||||
var dbSetDataSaubStat = dbContext.Set<DataSaubStat>();
|
||||
dbSetDataSaubStat.AddRange(dataSaubStats);
|
||||
|
||||
dbContext.SaveChanges();
|
||||
|
||||
//act
|
||||
var request = new DataSaubStatRequest();
|
||||
var response = await client.ExportReportAsync(1, request, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("application/octet-stream", response.ContentHeaders?.ContentType?.MediaType);
|
||||
Assert.True(response.ContentHeaders?.ContentLength > 0);
|
||||
}
|
||||
}
|
19
AsbCloudWebApi.Tests/CommonExtensions.cs
Normal file
19
AsbCloudWebApi.Tests/CommonExtensions.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using Mapster;
|
||||
using System;
|
||||
|
||||
namespace AsbCloudWebApi.Tests;
|
||||
|
||||
public static class CommonExtensions
|
||||
{
|
||||
public static T Copy<T>(this T obj)
|
||||
{
|
||||
var copy = obj.Adapt<T>();
|
||||
return copy;
|
||||
}
|
||||
|
||||
public static T Mutate<T>(this T obj, Action<T> mutation)
|
||||
{
|
||||
var copy = obj.Copy();
|
||||
return copy;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.Tests.Services.DetectedOperations.Detectors;
|
||||
|
||||
public class DetectorSlipsTimeTests
|
||||
{
|
||||
private const int IdSlipsTime = 5011;
|
||||
|
||||
private readonly DetectableTelemetry telemetry = new() {
|
||||
WellDepth = 300,
|
||||
Pressure = 15,
|
||||
HookWeight = 20,
|
||||
BlockPosition = 20,
|
||||
BitDepth = 151,
|
||||
AxialLoad = 19,
|
||||
};
|
||||
|
||||
private readonly DetectorSlipsTime sut = new();
|
||||
|
||||
[Fact]
|
||||
public void DetectOperation_by_change_block_position_and_axial_load_less_hook_weight_is_success()
|
||||
{
|
||||
//arrange
|
||||
var point0 = telemetry.Copy();
|
||||
|
||||
var point1 = telemetry.Copy();
|
||||
point1.BlockPosition = 21;
|
||||
|
||||
var telemetries = new[] { point0, point1 };
|
||||
|
||||
//act
|
||||
var isDetectOperation = sut.TryDetect(0, telemetries, 0, telemetries.Length - 1, null, out var result);
|
||||
|
||||
//assert
|
||||
Assert.True(isDetectOperation);
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(IdSlipsTime, result.Operation.IdCategory);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectOperation_by_high_pressure_is_success()
|
||||
{
|
||||
//arrange
|
||||
var point0 = telemetry.Copy();
|
||||
|
||||
var point1 = telemetry.Copy();
|
||||
point1.BlockPosition = 21;
|
||||
point1.AxialLoad = 30;
|
||||
point1.HookWeight = 20;
|
||||
point1.Pressure = 23;
|
||||
|
||||
var telemetries = new[] { point0, point1 };
|
||||
|
||||
//act
|
||||
var isDetectOperation = sut.TryDetect(0, telemetries, 0, telemetries.Length - 1, null, out var result);
|
||||
|
||||
//assert
|
||||
Assert.True(isDetectOperation);
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(IdSlipsTime, result.Operation.IdCategory);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ValidateOperation_with_duration_more_30_minutes_is_invalid()
|
||||
{
|
||||
//arrange
|
||||
var point0 = telemetry.Copy();
|
||||
|
||||
var point1 = telemetry.Copy();
|
||||
point1.BlockPosition = 21;
|
||||
point1.DateTime = DateTimeOffset.UtcNow.AddMinutes(30);
|
||||
|
||||
var telemetries = new[] { point0, point1 };
|
||||
|
||||
//act
|
||||
var isDetectOperation = sut.TryDetect(0, telemetries, 0, telemetries.Length - 1, null, out var result);
|
||||
|
||||
//assert
|
||||
Assert.False(isDetectOperation);
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(IdSlipsTime, result.Operation.IdCategory);
|
||||
}
|
||||
}
|
@ -5,11 +5,9 @@ using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Services.WellOperationImport;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Repository;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
|
||||
using NSubstitute;
|
||||
using SignalRSwaggerGen.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -34,41 +32,6 @@ namespace AsbCloudWebApi.Tests.Services.WellOperationExport
|
||||
private WellOperationImportService wellOperationImportService;
|
||||
private IWellOperationExcelParser<WellOperationImportDefaultOptionsDto> wellOperationDefaultExcelParser;
|
||||
|
||||
private readonly WellOperationDto[] operations = new WellOperationDto[2] {
|
||||
new WellOperationDto() {
|
||||
Id = 5,
|
||||
IdWell = idWell,
|
||||
IdUser = 1,
|
||||
IdType = 0,
|
||||
IdWellSectionType = 1,
|
||||
WellSectionTypeName = "1",
|
||||
IdCategory = 1,
|
||||
CategoryName = "1",
|
||||
CategoryInfo = "CategoryInfo 1",
|
||||
DepthStart = 10,
|
||||
DepthEnd = 20,
|
||||
DateStart = GetDate(days: 0),
|
||||
DurationHours = 10,
|
||||
Comment = "Комментарий 1",
|
||||
},
|
||||
new WellOperationDto() {
|
||||
Id = 6,
|
||||
IdWell = idWell,
|
||||
IdUser = 1,
|
||||
IdType = 0,
|
||||
IdWellSectionType = 2,
|
||||
WellSectionTypeName = "2",
|
||||
IdCategory = 2,
|
||||
CategoryName = "2",
|
||||
CategoryInfo = "CategoryInfo 2",
|
||||
DepthStart = 20,
|
||||
DepthEnd = 30,
|
||||
DateStart = GetDate(days: 1),
|
||||
DurationHours = 20,
|
||||
Comment = "Комментарий 2",
|
||||
}
|
||||
};
|
||||
|
||||
private readonly WellSectionTypeDto[] sectionTypes = new WellSectionTypeDto[2]
|
||||
{
|
||||
new WellSectionTypeDto()
|
||||
@ -106,12 +69,6 @@ namespace AsbCloudWebApi.Tests.Services.WellOperationExport
|
||||
};
|
||||
private readonly ITestOutputHelper output;
|
||||
|
||||
private static DateTime GetDate(int days)
|
||||
{
|
||||
var date = DateTime.Now.AddDays(days);
|
||||
return new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second);
|
||||
}
|
||||
|
||||
public WellOperationExportServiceTest(ITestOutputHelper output)
|
||||
{
|
||||
wellService = Substitute.For<IWellService>();
|
||||
@ -123,17 +80,20 @@ namespace AsbCloudWebApi.Tests.Services.WellOperationExport
|
||||
wellOperationImportService = new WellOperationImportService(wellService, wellOperationRepository, wellOperationCategoryRepository);
|
||||
wellOperationDefaultExcelParser = new WellOperationDefaultExcelParser();
|
||||
this.output = output;
|
||||
|
||||
wellService.GetTimezone(idWell).Returns(new SimpleTimezoneDto()
|
||||
{
|
||||
Hours = 5
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Check_Exported_WellOperations_With_Operations_In_Db()
|
||||
{
|
||||
wellService.GetTimezone(idWell).Returns(new SimpleTimezoneDto()
|
||||
{
|
||||
Hours = 5
|
||||
});
|
||||
var operations = getOperations();
|
||||
|
||||
var localOperations = operations.ToArray();
|
||||
|
||||
foreach (var operation in localOperations)
|
||||
operation.Id = 0;
|
||||
|
||||
@ -161,6 +121,7 @@ namespace AsbCloudWebApi.Tests.Services.WellOperationExport
|
||||
public void TestDataContainsNotDefaultProps()
|
||||
{
|
||||
var initOk = true;
|
||||
var operations = getOperations();
|
||||
for (int i = 0; i < operations.Length; i++)
|
||||
{
|
||||
var operation = operations[i];
|
||||
@ -204,5 +165,52 @@ namespace AsbCloudWebApi.Tests.Services.WellOperationExport
|
||||
yield return prop.Name;
|
||||
}
|
||||
}
|
||||
|
||||
private WellOperationDto[] getOperations()
|
||||
{
|
||||
|
||||
var timezone = wellService.GetTimezone(idWell);
|
||||
|
||||
DateTimeOffset GetDate(int days)
|
||||
{
|
||||
var date = DateTimeOffset.UtcNow.AddDays(days);
|
||||
return new DateTimeOffset(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, TimeSpan.FromHours(timezone.Hours));
|
||||
}
|
||||
|
||||
return new WellOperationDto[2] {
|
||||
new WellOperationDto() {
|
||||
Id = 5,
|
||||
IdWell = idWell,
|
||||
IdUser = 1,
|
||||
IdType = 0,
|
||||
IdWellSectionType = 1,
|
||||
WellSectionTypeName = "1",
|
||||
IdCategory = 1,
|
||||
CategoryName = "1",
|
||||
CategoryInfo = "CategoryInfo 1",
|
||||
DepthStart = 10,
|
||||
DepthEnd = 20,
|
||||
DateStart = GetDate(days: 0),
|
||||
DurationHours = 10,
|
||||
Comment = "Комментарий 1",
|
||||
},
|
||||
new WellOperationDto() {
|
||||
Id = 6,
|
||||
IdWell = idWell,
|
||||
IdUser = 1,
|
||||
IdType = 0,
|
||||
IdWellSectionType = 2,
|
||||
WellSectionTypeName = "2",
|
||||
IdCategory = 2,
|
||||
CategoryName = "2",
|
||||
CategoryInfo = "CategoryInfo 2",
|
||||
DepthStart = 20,
|
||||
DepthEnd = 30,
|
||||
DateStart = GetDate(days: 1),
|
||||
DurationHours = 20,
|
||||
Comment = "Комментарий 2",
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user