diff --git a/AsbCloudApp/Services/IDetectedOperationService.cs b/AsbCloudApp/Services/IDetectedOperationService.cs
index 120cfef8..1117d8e3 100644
--- a/AsbCloudApp/Services/IDetectedOperationService.cs
+++ b/AsbCloudApp/Services/IDetectedOperationService.cs
@@ -1,9 +1,7 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.DetectedOperation;
using AsbCloudApp.Requests;
-using System;
using System.Collections.Generic;
-using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -62,13 +60,5 @@ namespace AsbCloudApp.Services
///
///
Task?> GetOperationsStatAsync(DetectedOperationRequest request, CancellationToken token);
-
- ///
- /// Выгрузка в Excel
- ///
- ///
- ///
- ///
- Task ExportAsync(IEnumerable idsWells, CancellationToken token);
}
}
diff --git a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
index 2c2bd528..d731d329 100644
--- a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
+++ b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
@@ -30,6 +30,7 @@
+
diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs
index 28bde671..e5095db4 100644
--- a/AsbCloudInfrastructure/DependencyInjection.cs
+++ b/AsbCloudInfrastructure/DependencyInjection.cs
@@ -1,4 +1,5 @@
-using AsbCloudApp.Data;
+using System;
+using AsbCloudApp.Data;
using AsbCloudApp.Data.AutogeneratedDailyReport;
using AsbCloudApp.Data.DrillTestReport;
using AsbCloudApp.Data.Manuals;
@@ -39,7 +40,6 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using System;
namespace AsbCloudInfrastructure
{
@@ -161,14 +161,16 @@ namespace AsbCloudInfrastructure
services.AddMemoryCache();
services.AddScoped(provider => provider.GetRequiredService());
- services.AddSingleton(new WitsInfoService());
- services.AddSingleton>(provider => TelemetryDataCache.GetInstance(provider));
- services.AddSingleton>(provider => TelemetryDataCache.GetInstance(provider));
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton(provider => ReduceSamplingService.GetInstance(configuration));
+ services.AddSingleton(new WitsInfoService());
+ services.AddSingleton>(provider =>
+ TelemetryDataCache.GetInstance(provider));
+ services.AddSingleton>(provider =>
+ TelemetryDataCache.GetInstance(provider));
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton(provider => ReduceSamplingService.GetInstance(configuration));
services.AddTransient();
services.AddTransient, ProcessMapPlanRepository>();
@@ -295,8 +297,10 @@ namespace AsbCloudInfrastructure
services.AddTransient, WellOperationDefaultExcelParser>();
services.AddTransient, WellOperationGazpromKhantosExcelParser>();
+ services.AddTransient();
+
return services;
- }
+ }
public static IServiceCollection AddTransientLazy(this IServiceCollection services)
where TService : class
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx b/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx
new file mode 100644
index 00000000..9073c58d
Binary files /dev/null and b/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx differ
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs
index f8f0296d..3c1550c1 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs
@@ -1,120 +1,224 @@
-using AsbCloudApp.Data;
-using AsbCloudApp.Services;
-using AsbCloudDb.Model;
+using AsbCloudDb.Model;
using ClosedXML.Excel;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
+using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
-namespace AsbCloudInfrastructure.Services.DetectOperations
+namespace AsbCloudInfrastructure.Services.DetectOperations;
+
+public class DetectedOperationExportService
{
+ private readonly DetectorAbstract[] detectors = { new DetectorDrilling(), new DetectorSlipsTime() };
- internal class DetectedOperationExportService
- {
- private readonly IAsbCloudDbContext db;
- private readonly IWellService wellService;
+ private readonly IDictionary domains = new Dictionary
+ {
+ { 1, "https://cloud.digitaldrilling.ru" },
+ { 2, "https://cloud.autodrilling.ru" }
+ };
- public DetectedOperationExportService(IAsbCloudDbContext db, IWellService wellService)
- {
- this.db = db;
- this.wellService = wellService;
- }
+ private const int headerRowsCount = 1;
- public async Task ExportAsync(IEnumerable idsWells, CancellationToken token)
- {
- using var workbook = new XLWorkbook(XLEventTracking.Disabled);
+ private const string cellDepositName = "B1";
+ private const string cellClusterName = "B2";
+ private const string cellWellName = "B3";
+ private const string cellDeltaDate = "H2";
- await AddSheetsAsync(workbook, idsWells, token);
+ private const int columnOperationName = 1;
+ private const int columnDateStart = 2;
+ private const int columnDateEnd = 3;
+ private const int columnDuration = 4;
+ private const int columnDepthStart = 5;
+ private const int columnDepthEnd = 6;
+ private const int columnDeltaDepth = 7;
+ private const int columnDepth = 8;
+ private const int columnIdReasonOfEnd = 9;
- MemoryStream memoryStream = new MemoryStream();
- workbook.SaveAs(memoryStream, new SaveOptions { });
- memoryStream.Seek(0, SeekOrigin.Begin);
- return memoryStream;
- }
+ private readonly IAsbCloudDbContext dbContext;
- private async Task AddSheetsAsync(XLWorkbook workbook, IEnumerable idsWells, CancellationToken token)
- {
- if(!idsWells.Any())
- return;
+ public DetectedOperationExportService(IAsbCloudDbContext dbContext)
+ {
+ this.dbContext = dbContext;
+ }
- var wells = idsWells.Select(i => wellService.GetOrDefault(i))
- .Where(w => w is not null && w.IdTelemetry is not null)
- .Select(w => w!);
+ public async Task ExportAsync(int idWell, int idDomain, CancellationToken cancellationToken)
+ {
+ var well = await dbContext.Wells
+ .Include(w => w.Cluster)
+ .ThenInclude(c => c.Deposit)
+ .SingleOrDefaultAsync(w => w.Id == idWell, cancellationToken);
- if (!wells.Any())
- return;
+ if (well is null)
+ throw new ArgumentNullException(nameof(well));
- var idsTelemetries = wells.Select(w => w.IdTelemetry);
- if (!idsTelemetries.Any())
- return;
+ if (!well.IdTelemetry.HasValue)
+ throw new ArgumentNullException(nameof(well));
- var operations = await db.DetectedOperations
- .Include(o => o.OperationCategory)
- .AsNoTracking()
- .Where(o => idsTelemetries.Contains(o.IdTelemetry))
- .OrderBy(o => o.IdTelemetry)
- .ThenBy(o => o.DateStart)
- .ToListAsync(token);
+ var operations = await DetectOperationsAsync(well.IdTelemetry.Value, new DateTime(2023, 10, 14)
+ .ToUtcDateTimeOffset(well.Timezone.Hours), cancellationToken);
- var groups = operations.GroupBy(o => o.IdTelemetry);
+ return await GenerateExcelFileStreamAsync(well, idDomain, operations, cancellationToken);
+ }
- foreach (var well in wells)
- {
- var ops = groups.FirstOrDefault(g => g.Key == well.IdTelemetry)
- ?.ToList();
-
- if(ops?.Any() != true)
- continue;
+ private async Task GenerateExcelFileStreamAsync(Well well, int idDomain, IEnumerable detectedOperations,
+ CancellationToken cancellationToken)
+ {
+ using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken);
- var sheetName = $"{well.Cluster}_{well.Caption}"
- .Replace('.','_');
+ using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
- var sheet = workbook.AddWorksheet(sheetName);
- AddHeader(sheet);
- const int headerHeight = 1;
- for(var i = 0; i< ops.Count; i++ )
- AddRow(sheet, ops[i], well, i + 1 + headerHeight);
- }
- }
+ await AddToWorkbookAsync(workbook, well, idDomain, detectedOperations, cancellationToken);
- private static void AddHeader(IXLWorksheet sheet)
- {
- var rowNumber = 1;
- sheet.Cell(rowNumber, 1).Value = "Name";
- sheet.Column(1).Width = 34;
-
- sheet.Cell(rowNumber, 2).Value = "DateStart";
- sheet.Column(2).Width = 17;
-
- sheet.Cell(rowNumber, 3).Value = "DateEnd";
- sheet.Column(3).Width = 17;
-
- sheet.Cell(rowNumber, 4).Value = "DepthStart";
- sheet.Column(4).Width = 9;
-
- sheet.Cell(rowNumber, 5).Value = "DepthEnd";
- sheet.Column(5).Width = 9;
-
- sheet.Cell(rowNumber, 6).Value = "KeyValue";
- sheet.Column(6).Width = 9;
+ MemoryStream memoryStream = new MemoryStream();
+ workbook.SaveAs(memoryStream, new SaveOptions { });
+ memoryStream.Seek(0, SeekOrigin.Begin);
+ return memoryStream;
+ }
- sheet.SheetView.FreezeRows(rowNumber);
- }
+ private async Task AddToWorkbookAsync(XLWorkbook workbook, Well well, int idDomain, IEnumerable detectedOperations,
+ CancellationToken cancellationToken)
+ {
+ const string sheetName = "Операции";
- private static void AddRow(IXLWorksheet sheet, DetectedOperation operation, WellDto well, int rowNumber)
- {
- var timezoneoffsetHours = well.Timezone.Hours;
- sheet.Cell(rowNumber, 1).Value = operation.OperationCategory.Name;
- sheet.Cell(rowNumber, 2).Value = operation.DateStart.ToRemoteDateTime(timezoneoffsetHours);
- sheet.Cell(rowNumber, 3).Value = operation.DateEnd.ToRemoteDateTime(timezoneoffsetHours);
- sheet.Cell(rowNumber, 4).Value = operation.DepthStart;
- sheet.Cell(rowNumber, 5).Value = operation.DepthEnd;
- sheet.Cell(rowNumber, 6).Value = operation.Value;
- }
- }
+ if (!detectedOperations.Any())
+ return;
-}
+ var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName)
+ ?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}.");
+
+ await AddToSheetAsync(sheet, well, idDomain, detectedOperations.OrderBy(x => x.DateStart).ThenBy(x => x.DepthStart).ToArray(),
+ cancellationToken);
+ }
+
+ private async Task AddToSheetAsync(IXLWorksheet sheet, Well well, int idDomain, IList detectedOperations,
+ CancellationToken cancellationToken)
+ {
+ var wellOperationCategories = await dbContext.WellOperationCategories.ToListAsync(cancellationToken);
+
+ sheet.Cell(cellDepositName).Value = well.Cluster.Deposit.Caption;
+ sheet.Cell(cellClusterName).Value = well.Cluster.Caption;
+ sheet.Cell(cellWellName).Value = well.Caption;
+ sheet.Cell(cellDeltaDate).Value = detectedOperations.Max(o => o.DateEnd) - detectedOperations.Min(o => o.DateStart);
+
+ var timeZoneWell = TimeSpan.FromHours(well.Timezone.Hours);
+
+ for (int i = 0; i < detectedOperations.Count; i++)
+ {
+ var dateStart = detectedOperations[i].DateStart.ToOffset(timeZoneWell);
+ var dateEnd = detectedOperations[i].DateEnd.ToOffset(timeZoneWell);
+
+ var row = sheet.Row(5 + i + headerRowsCount);
+
+ row.Cell(columnOperationName).Value = detectedOperations[i].IdCategory == 12000
+ ? "Бурение в слайде с осцилляцией"
+ : wellOperationCategories.Single(o => o.Id == detectedOperations[i].IdCategory).Name;
+ row.Cell(columnDateEnd).Value = dateEnd;
+ row.Cell(columnDuration).Value = (dateEnd - dateStart).TotalMinutes;
+ row.Cell(columnDepthStart).Value = detectedOperations[i].DepthStart;
+ row.Cell(columnDepthEnd).Value = detectedOperations[i].DepthEnd;
+ row.Cell(columnDepth).Value = detectedOperations[i].DepthEnd - detectedOperations[i].DepthStart;
+ row.Cell(columnIdReasonOfEnd).Value = detectedOperations[i].IdReasonOfEnd;
+
+ var link =
+ $"{domains[idDomain]}/well/{well.Id}/telemetry/monitoring?end={Uri.EscapeDataString(dateStart.AddSeconds(3544).ToString("yyyy-MM-ddTHH:mm:ss.fff"))}&range=3600";
+
+ row.Cell(columnDateStart).Value = dateStart;
+ row.Cell(columnDateStart).SetHyperlink(new XLHyperlink(link));
+
+ row.Cell(columnDeltaDepth).Value = i > 0 && i + 1 < detectedOperations.Count
+ ? detectedOperations[i].DepthStart - detectedOperations[i - 1].DepthEnd
+ : 0;
+ }
+ }
+
+ private async Task GetExcelTemplateStreamAsync(CancellationToken cancellationToken)
+ {
+ string resourceName = Assembly.GetExecutingAssembly()
+ .GetManifestResourceNames()
+ .FirstOrDefault(n => n.EndsWith("DetectOperations.xlsx"))!;
+
+ using var stream = Assembly.GetExecutingAssembly()
+ .GetManifestResourceStream(resourceName)!;
+
+ var memoryStream = new MemoryStream();
+ await stream.CopyToAsync(memoryStream, cancellationToken);
+ memoryStream.Position = 0;
+
+ return memoryStream;
+ }
+
+ private async Task> DetectOperationsAsync(int idTelemetry, DateTimeOffset begin,
+ CancellationToken token)
+ {
+ var query = dbContext.TelemetryDataSaub
+ .AsNoTracking()
+ .Where(d => d.IdTelemetry == idTelemetry)
+ .Where(d => d.BlockPosition >= 0)
+ .Select(d => new DetectableTelemetry
+ {
+ DateTime = d.DateTime,
+ IdUser = d.IdUser,
+ WellDepth = d.WellDepth,
+ Pressure = d.Pressure,
+ HookWeight = d.HookWeight,
+ BlockPosition = d.BlockPosition,
+ BitDepth = d.BitDepth,
+ RotorSpeed = d.RotorSpeed,
+ })
+ .OrderBy(d => d.DateTime);
+
+ var startDate = begin;
+ var detectedOperations = new List(8);
+ DetectedOperation? lastDetectedOperation = null;
+ const int minOperationLength = 5;
+ const int maxDetectorsInterpolationFrameLength = 30;
+ const int gap = maxDetectorsInterpolationFrameLength + minOperationLength;
+
+ while (true)
+ {
+ var data = await query
+ .Where(d => d.DateTime > startDate)
+ .ToArrayAsync(token);
+
+ if (data.Length < gap)
+ break;
+
+ var isDetected = false;
+ var positionBegin = 0;
+ var positionEnd = data.Length - gap;
+ var step = 10;
+ while (positionEnd > positionBegin)
+ {
+ step++;
+ foreach (var detector in detectors)
+ {
+ if (!detector.TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out var result))
+ continue;
+
+ detectedOperations.Add(result!.Operation);
+ lastDetectedOperation = result.Operation;
+ isDetected = true;
+ step = 1;
+ positionBegin = result.TelemetryEnd;
+ break;
+ }
+
+ if (step > 20)
+ step = 10;
+ positionBegin += step;
+ }
+
+ if (isDetected)
+ startDate = lastDetectedOperation!.DateEnd;
+ else
+ startDate = data[positionEnd].DateTime;
+ }
+
+ return detectedOperations;
+ }
+}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs
index c3246e05..a3cf05c4 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs
@@ -6,9 +6,7 @@ using AsbCloudDb;
using AsbCloudDb.Model;
using Mapster;
using Microsoft.EntityFrameworkCore;
-using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -333,13 +331,6 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
.ToArrayAsync(token);
return result;
}
-
- public Task ExportAsync(IEnumerable idsWells, CancellationToken token)
- {
- var exportService = new DetectedOperationExportService(db, wellService);
- return exportService.ExportAsync(idsWells, token);
- }
-
}
}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
index d14a5829..38a3aeac 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
@@ -5,9 +5,8 @@ using System.Linq;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{
- internal abstract class DetectorAbstract
+ internal abstract class DetectorAbstract
{
- private readonly int idOperation;
private readonly int stepLength = 3;
protected const int IdReasonOfEnd_NotDetected = 0;
@@ -32,33 +31,39 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
protected const int IdReasonOfEnd_BlockPositionIsHi = 501;
protected const int IdReasonOfEnd_BlockPositionDeviates = 502;
- protected const int IdReasonOfEnd_Custom1 = 10_000;
+ protected const int IdReasonOfEnd_Drilling = 600;
- protected DetectorAbstract(int idOperation)
- {
- this.idOperation = idOperation;
- }
+ protected const int IdReasonOfEnd_Custom1 = 10_000;
+
+ public abstract Func GetIdOperation { get; }
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperation? previousOperation, out OperationDetectorResult? result)
{
// Проверка соответствия критерию начала операции
if (DetectBegin(telemetry, begin, previousOperation))
- {
+ {
// Поиск окончания соответствия критерию
+ int idReasonOfEnd = 0;
var positionEnd = begin;
while (positionEnd < end)
{
positionEnd += stepLength;
- if ((positionEnd > end))
+ if (positionEnd > end)
break;
- var idReasonOfEnd = DetectEnd(telemetry, positionEnd, previousOperation);
- if (idReasonOfEnd != IdReasonOfEnd_NotDetected)
- {
- result = MakeOperation(idTelemetry, telemetry, begin, positionEnd, idReasonOfEnd);
- return true;
- }
+ idReasonOfEnd = DetectEnd(telemetry, positionEnd, previousOperation);
+
+ if(idReasonOfEnd is IdReasonOfEnd_DeltaDepthIsHi or IdReasonOfEnd_PressureIsLo &&
+ !IsValidByWellDepthDoesNotChange(telemetry, begin, positionEnd))
+ break;
+
+ if (idReasonOfEnd != IdReasonOfEnd_NotDetected)
+ break;
}
+
+ result = null;
+ result = MakeOperation(idTelemetry, telemetry, begin, positionEnd, idReasonOfEnd);
+ return true;
}
result = null;
return false;
@@ -81,7 +86,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
Operation = new DetectedOperation
{
IdTelemetry = idTelemetry,
- IdCategory = idOperation,
+ IdCategory = GetIdOperation.Invoke(telemetry, begin, end),
IdUsersAtStart = pBegin.IdUser ?? -1,
DateStart = pBegin.DateTime,
DateEnd = pEnd.DateTime,
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs
index e858b49b..64c01f6c 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs
@@ -1,4 +1,5 @@
-using AsbCloudDb.Model;
+using System;
+using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{
@@ -7,12 +8,12 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
/// Проработка перед наращиванием
///
internal class DetectorDevelopment : DetectorAbstract
- {
- public DetectorDevelopment()
- : base(WellOperationCategory.IdDevelopment) { }
-
+ {
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
=> CalcDeltaMinutes(telemetry, begin, end);
+
+ public override Func GetIdOperation => (_, _, _)
+ => WellOperationCategory.IdDevelopment;
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
{
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs
new file mode 100644
index 00000000..3e7af4af
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Linq;
+using AsbCloudDb.Model;
+
+namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
+
+internal class DetectorDrilling : DetectorAbstract
+{
+ public override Func GetIdOperation => DefineDrillingOperation;
+
+ protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+ {
+ var point0 = telemetry[position];
+ var delta = point0.WellDepth - point0.BitDepth;
+ if (delta > 0.03d)
+ return false;
+
+ if (point0.Pressure < 25)
+ return false;
+
+ if (point0.RotorSpeed < 5)
+ return false;
+
+ return true;
+ }
+
+ protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+ {
+ var point0 = telemetry[position];
+ var delta = point0.WellDepth - point0.BitDepth;
+
+ if (delta > 0.03d)
+ return IdReasonOfEnd_DeltaDepthIsHi;
+
+ if (point0.Pressure < 25)
+ return IdReasonOfEnd_PressureIsLo;
+
+ return IdReasonOfEnd_NotDetected;
+ }
+
+ protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
+ => IsValidByWellDepthIncreasing(telemetry, begin, end);
+
+ protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
+ => CalcRop(telemetry, begin, end);
+
+ private static int DefineDrillingOperation(DetectableTelemetry[] telemetry, int begin, int end)
+ {
+ const int idSlideWithOscillation = 12000;
+
+ var telemetryRange = telemetry[begin.. end];
+
+ var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed);
+
+ if (avgRotorSpeed < 10)
+ return WellOperationCategory.IdSlide;
+
+ var despersion = telemetryRange
+ .Average(t => Math.Pow((t.RotorSpeed - avgRotorSpeed) / avgRotorSpeed, 2));
+
+ return despersion < 0.2d ? WellOperationCategory.IdRotor : idSlideWithOscillation;
+ }
+}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorFlashing.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorFlashing.cs
index 65040e9a..ac93fd45 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorFlashing.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorFlashing.cs
@@ -1,59 +1,59 @@
-using AsbCloudDb.Model;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-
- ///
- /// Промывка
- ///
- internal class DetectorFlashing : DetectorAbstract
- {
- public DetectorFlashing()
- : base(WellOperationCategory.IdFlashing)
- { }
-
- protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
- => CalcDeltaMinutes(telemetry, begin, end);
-
- protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- if (!((previousOperation?.IdCategory == WellOperationCategory.IdRotor) ||
- (previousOperation?.IdCategory == WellOperationCategory.IdSlide)))
- return false;
-
- var point0 = telemetry[position];
- var delta = point0.WellDepth - point0.BitDepth;
- if (delta > 0.05d)
- return false;
-
- if (point0.Pressure < 15)
- return false;
-
- if (point0.BlockPosition < 3)
- return false;
-
- if (ContainsDeviationApprox(telemetry, t => t.WellDepth, position, 150, 0.0001))
- return false;
-
- return true;
- }
-
- protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- var point0 = telemetry[position];
- var delta = point0.WellDepth - point0.BitDepth;
- if ((delta > 0.03d )
- && (point0.Pressure > 15)
- && ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03))
- return IdReasonOfEnd_Custom1;
-
- return IdReasonOfEnd_NotDetected;
- }
-
- protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
- => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
- }
-
-
-}
-
+// using AsbCloudDb.Model;
+//
+// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+// {
+//
+// ///
+// /// Промывка
+// ///
+// internal class DetectorFlashing : DetectorAbstract
+// {
+// public DetectorFlashing()
+// : base(WellOperationCategory.IdFlashing)
+// { }
+//
+// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
+// => CalcDeltaMinutes(telemetry, begin, end);
+//
+// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// if (!((previousOperation?.IdCategory == WellOperationCategory.IdRotor) ||
+// (previousOperation?.IdCategory == WellOperationCategory.IdSlide)))
+// return false;
+//
+// var point0 = telemetry[position];
+// var delta = point0.WellDepth - point0.BitDepth;
+// if (delta > 0.05d)
+// return false;
+//
+// if (point0.Pressure < 15)
+// return false;
+//
+// if (point0.BlockPosition < 3)
+// return false;
+//
+// if (ContainsDeviationApprox(telemetry, t => t.WellDepth, position, 150, 0.0001))
+// return false;
+//
+// return true;
+// }
+//
+// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// var point0 = telemetry[position];
+// var delta = point0.WellDepth - point0.BitDepth;
+// if ((delta > 0.03d )
+// && (point0.Pressure > 15)
+// && ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03))
+// return IdReasonOfEnd_Custom1;
+//
+// return IdReasonOfEnd_NotDetected;
+// }
+//
+// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
+// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
+// }
+//
+//
+// }
+//
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorFlashingBeforeConnection.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorFlashingBeforeConnection.cs
index 4e447e67..ffc74129 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorFlashingBeforeConnection.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorFlashingBeforeConnection.cs
@@ -1,55 +1,55 @@
-using AsbCloudDb.Model;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-
- ///
- /// Промывка перед наращиванием
- ///
- internal class DetectorFlashingBeforeConnection : DetectorAbstract
- {
- public DetectorFlashingBeforeConnection()
- : base(WellOperationCategory.IdFlashingBeforeConnection) { }
-
- protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
- => CalcDeltaMinutes(telemetry, begin, end);
-
- protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- if (!((previousOperation?.IdCategory == WellOperationCategory.IdRotor) ||
- (previousOperation?.IdCategory == WellOperationCategory.IdSlide)))
- return false;
-
- var point0 = telemetry[position];
- var delta = point0.WellDepth - point0.BitDepth;
- if (delta > 0.05d)
- return false;
-
- if (point0.Pressure < 15)
- return false;
-
- if (point0.BlockPosition > 3)
- return false;
-
- return true;
- }
-
- protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- var point0 = telemetry[position];
- var delta = point0.WellDepth - point0.BitDepth;
- if ((delta > 0.03d )
- && (point0.Pressure > 15)
- && ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03))
- return IdReasonOfEnd_Custom1;
-
- return IdReasonOfEnd_NotDetected;
- }
-
- protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
- => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
- }
-
-
-}
-
+// using AsbCloudDb.Model;
+//
+// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+// {
+//
+// ///
+// /// Промывка перед наращиванием
+// ///
+// internal class DetectorFlashingBeforeConnection : DetectorAbstract
+// {
+// public DetectorFlashingBeforeConnection()
+// : base(WellOperationCategory.IdFlashingBeforeConnection) { }
+//
+// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
+// => CalcDeltaMinutes(telemetry, begin, end);
+//
+// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// if (!((previousOperation?.IdCategory == WellOperationCategory.IdRotor) ||
+// (previousOperation?.IdCategory == WellOperationCategory.IdSlide)))
+// return false;
+//
+// var point0 = telemetry[position];
+// var delta = point0.WellDepth - point0.BitDepth;
+// if (delta > 0.05d)
+// return false;
+//
+// if (point0.Pressure < 15)
+// return false;
+//
+// if (point0.BlockPosition > 3)
+// return false;
+//
+// return true;
+// }
+//
+// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// var point0 = telemetry[position];
+// var delta = point0.WellDepth - point0.BitDepth;
+// if ((delta > 0.03d )
+// && (point0.Pressure > 15)
+// && ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03))
+// return IdReasonOfEnd_Custom1;
+//
+// return IdReasonOfEnd_NotDetected;
+// }
+//
+// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
+// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
+// }
+//
+//
+// }
+//
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorRotor.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorRotor.cs
index 2d5ce962..9562645d 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorRotor.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorRotor.cs
@@ -1,62 +1,54 @@
-using AsbCloudDb.Model;
-using System.Linq;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-
- internal class DetectorRotor : DetectorAbstract
- {
- public DetectorRotor()
- : base(WellOperationCategory.IdRotor) { }
-
- protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- var point0 = telemetry[position];
- var delta = point0.WellDepth - point0.BitDepth;
- if (delta > 0.03d)
- return false;
-
- if (point0.Pressure < 25)
- return false;
-
- if (point0.RotorSpeed < 5)
- return false;
-
- var point1 = telemetry[position + 1];
- if (point1.WellDepth - point0.WellDepth <= 0.003)
- return false;
-
- return true;
- }
-
- protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- var point0 = telemetry[position];
- var delta = point0.WellDepth - point0.BitDepth;
- if (delta > 0.03d)
- return IdReasonOfEnd_DeltaDepthIsHi;
-
- if (point0.Pressure < 25)
- return IdReasonOfEnd_PressureIsLo;
-
- var avgRotorSpeed = CalcAvgAppr(d => d.RotorSpeed, telemetry, position, 60);
-
- if (avgRotorSpeed < 10)
- return IdReasonOfEnd_AvgRotorSpeedIsLo;
-
- if (!DeviatesFromBegin(telemetry, t => t.WellDepth, position, 150, 0.003))
- return IdReasonOfEnd_WellDepthDeviates;
-
- return IdReasonOfEnd_NotDetected;
- }
-
- protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
- => IsValidByWellDepthIncreasing(telemetry, begin, end);
-
- protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
- => CalcRop(telemetry, begin, end);
- }
-
-
-}
-
+// using AsbCloudDb.Model;
+// using System.Linq;
+//
+// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+// {
+//
+// public class DetectorRotor : DetectorAbstract
+// {
+// public DetectorRotor()
+// : base(WellOperationCategory.IdRotor) { }
+//
+// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// var point0 = telemetry[position];
+// var delta = point0.WellDepth - point0.BitDepth;
+// if (delta > 0.03d)
+// return false;
+//
+// if (point0.Pressure < 25)
+// return false;
+//
+// if (point0.RotorSpeed < 5)
+// return false;
+//
+// var point1 = telemetry[position + 1];
+// if (point1.WellDepth - point0.WellDepth <= 0.003)
+// return false;
+//
+// return true;
+// }
+//
+// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// var point0 = telemetry[position];
+// var delta = point0.WellDepth - point0.BitDepth;
+// if (delta > 0.03d)
+// return IdReasonOfEnd_DeltaDepthIsHi;
+//
+// if (point0.Pressure < 25)
+// return IdReasonOfEnd_PressureIsLo;
+//
+// return IdReasonOfEnd_NotDetected;
+// }
+//
+// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
+// => IsValidByWellDepthIncreasing(telemetry, begin, end);
+//
+// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
+// => CalcRop(telemetry, begin, end);
+// }
+//
+//
+// }
+//
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlide.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlide.cs
index 48f6fe7b..6244b4d6 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlide.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlide.cs
@@ -1,61 +1,49 @@
-using AsbCloudDb.Model;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-
- internal class DetectorSlide : DetectorAbstract
- {
- public DetectorSlide()
- : base(WellOperationCategory.IdSlide) { }
-
- protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- var point0 = telemetry[position];
- var delta = point0.WellDepth - point0.BitDepth;
- if (delta > 0.03d)
- return false;
-
- if (point0.Pressure < 25)
- return false;
-
- if (point0.RotorSpeed > 5)
- return false;
-
- var point1 = telemetry[position + 1];
- if (point1.WellDepth - point0.WellDepth <= 0.003)
- return false;
-
- return true;
- }
-
- protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- var point0 = telemetry[position];
- var delta = point0.WellDepth - point0.BitDepth;
- if (delta > 0.03d)
- return IdReasonOfEnd_DeltaDepthIsHi;
-
- if (point0.Pressure < 25)
- return IdReasonOfEnd_PressureIsLo;
-
- var avgRotorSpeed = CalcAvgAppr(d => d.RotorSpeed, telemetry, position, 60);
-
- if (avgRotorSpeed > 10)
- return IdReasonOfEnd_AvgRotorSpeedIsHi;
-
- if (!DeviatesFromBegin(telemetry, t => t.WellDepth, position, 150, 0.003))
- return IdReasonOfEnd_WellDepthDeviates;
-
- return IdReasonOfEnd_NotDetected;
- }
-
- protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
- => IsValidByWellDepthIncreasing(telemetry, begin, end);
-
- protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
- => CalcRop(telemetry, begin, end);
- }
-
-
-}
-
+// using AsbCloudDb.Model;
+//
+// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+// {
+//
+// public class DetectorSlide : DetectorAbstract
+// {
+// public DetectorSlide()
+// : base(WellOperationCategory.IdSlide) { }
+//
+// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// var point0 = telemetry[position];
+// var delta = point0.WellDepth - point0.BitDepth;
+// if (delta > 0.03d)
+// return false;
+//
+// if (point0.Pressure < 25)
+// return false;
+//
+// return true;
+// }
+//
+// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// var point0 = telemetry[position];
+// var delta = point0.WellDepth - point0.BitDepth;
+// if (delta > 0.03d)
+// return IdReasonOfEnd_DeltaDepthIsHi;
+//
+// if (point0.Pressure < 25)
+// return IdReasonOfEnd_PressureIsLo;
+//
+// if (!DeviatesFromBegin(telemetry, t => t.WellDepth, position, 150, 0.003))
+// return IdReasonOfEnd_WellDepthDeviates;
+//
+// return IdReasonOfEnd_NotDetected;
+// }
+//
+// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
+// => IsValidByWellDepthIncreasing(telemetry, begin, end);
+//
+// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
+// => CalcRop(telemetry, begin, end);
+// }
+//
+//
+// }
+//
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs
index f8883005..8be8b197 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs
@@ -1,17 +1,16 @@
-using AsbCloudDb.Model;
+using System;
+using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{
internal class DetectorSlipsTime : DetectorAbstract
{
- public DetectorSlipsTime()
- : base(WellOperationCategory.IdSlipsTime)
- { }
-
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
=> CalcDeltaMinutes(telemetry, begin, end);
+ public override Func GetIdOperation => (_, _, _) => WellOperationCategory.IdSlipsTime;
+
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
{
var point0 = telemetry[position];
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorStaticSurveying.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorStaticSurveying.cs
index f999dbd5..20d411dc 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorStaticSurveying.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorStaticSurveying.cs
@@ -1,69 +1,69 @@
-using AsbCloudDb.Model;
-using System.Linq;
-using System;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-
-
- ///
- /// Статический замер телесистемы
- ///
- internal class DetectorStaticSurveying: DetectorAbstract
- {
- public DetectorStaticSurveying()
- : base(WellOperationCategory.IdStaticSurveying) { }
-
- protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- var point0 = telemetry[position];
-
- if (point0.Pressure < 15)
- return false;
-
- var delta = point0.WellDepth - point0.BitDepth;
- if (delta > 2.5d || delta < 0.15d)
- return false;
-
- if (point0.RotorSpeed > 30)
- return false;
-
- if (ContainsDeviation(telemetry, t => t.BlockPosition, position, 120, 0.03))
- return false;
-
- if (ContainsDeviation(telemetry, t => t.Pressure, position, 60, 10))
- return false;
-
- return true;
- }
-
- protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- var point0 = telemetry[position];
-
- var delta = point0.WellDepth - point0.BitDepth;
- if (delta > 2.5d )
- return IdReasonOfEnd_DeltaDepthIsHi;
-
- if (point0.RotorSpeed > 30)
- return IdReasonOfEnd_RotorSpeedIsHi;
-
- if (RisesFromBegin(telemetry, t => t.Pressure, position, 10, 15))
- return IdReasonOfEnd_PressureIsRising;
-
- if (ContainsDeviation(telemetry, t => t.BlockPosition, position, 10, 0.05))
- return IdReasonOfEnd_BlockPositionDeviates;
-
- return IdReasonOfEnd_NotDetected;
- }
-
- protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
- => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
-
- protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
- => CalcDeltaMinutes(telemetry, begin, end);
- }
-
-
-}
-
+// using AsbCloudDb.Model;
+// using System.Linq;
+// using System;
+//
+// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+// {
+//
+//
+// ///
+// /// Статический замер телесистемы
+// ///
+// internal class DetectorStaticSurveying: DetectorAbstract
+// {
+// public DetectorStaticSurveying()
+// : base(WellOperationCategory.IdStaticSurveying) { }
+//
+// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// var point0 = telemetry[position];
+//
+// if (point0.Pressure < 15)
+// return false;
+//
+// var delta = point0.WellDepth - point0.BitDepth;
+// if (delta > 2.5d || delta < 0.15d)
+// return false;
+//
+// if (point0.RotorSpeed > 30)
+// return false;
+//
+// if (ContainsDeviation(telemetry, t => t.BlockPosition, position, 120, 0.03))
+// return false;
+//
+// if (ContainsDeviation(telemetry, t => t.Pressure, position, 60, 10))
+// return false;
+//
+// return true;
+// }
+//
+// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// var point0 = telemetry[position];
+//
+// var delta = point0.WellDepth - point0.BitDepth;
+// if (delta > 2.5d )
+// return IdReasonOfEnd_DeltaDepthIsHi;
+//
+// if (point0.RotorSpeed > 30)
+// return IdReasonOfEnd_RotorSpeedIsHi;
+//
+// if (RisesFromBegin(telemetry, t => t.Pressure, position, 10, 15))
+// return IdReasonOfEnd_PressureIsRising;
+//
+// if (ContainsDeviation(telemetry, t => t.BlockPosition, position, 10, 0.05))
+// return IdReasonOfEnd_BlockPositionDeviates;
+//
+// return IdReasonOfEnd_NotDetected;
+// }
+//
+// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
+// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
+//
+// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
+// => CalcDeltaMinutes(telemetry, begin, end);
+// }
+//
+//
+// }
+//
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs
index dde3f12e..96e11346 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs
@@ -1,65 +1,65 @@
-using AsbCloudDb.Model;
-using System.Collections.Generic;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-
- internal class DetectorTemplating : DetectorAbstract
- {
- public DetectorTemplating()
- : base(WellOperationCategory.IdTemplating) { }
-
- protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
- => CalcDeltaMinutes(telemetry, begin, end);
-
- protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- if(previousOperation?.IdCategory == WellOperationCategory.IdSlipsTime)
- return false;
-
- var point0 = telemetry[position];
- var delta = point0.WellDepth - point0.BitDepth;
- if (delta < 0.03d || delta > 30)
- return false;
-
- if (point0.Pressure < 15)
- return false;
-
- if (point0.BlockPosition > 2.5)
- return false;
-
- if (point0.RotorSpeed > 10)
- return false;
-
- if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03))
- return false;
-
- return true;
- }
-
- protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- var point0 = telemetry[position];
- var delta = point0.WellDepth - point0.BitDepth;
- if (delta < 0.03d || delta > 30)
- return IdReasonOfEnd_DeltaDepthOutOfRange;
-
- if (point0.Pressure < 15)
- return IdReasonOfEnd_PressureIsLo;
-
- if (point0.BlockPosition > 31)
- return IdReasonOfEnd_BlockPositionIsHi;
-
- if (point0.RotorSpeed > 10)
- return IdReasonOfEnd_RotorSpeedIsHi;
-
- return IdReasonOfEnd_NotDetected;
- }
-
- protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
- => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
- }
-
-
-}
-
+// using AsbCloudDb.Model;
+// using System.Collections.Generic;
+//
+// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+// {
+//
+// internal class DetectorTemplating : DetectorAbstract
+// {
+// public DetectorTemplating()
+// : base(WellOperationCategory.IdTemplating) { }
+//
+// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
+// => CalcDeltaMinutes(telemetry, begin, end);
+//
+// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// if(previousOperation?.IdCategory == WellOperationCategory.IdSlipsTime)
+// return false;
+//
+// var point0 = telemetry[position];
+// var delta = point0.WellDepth - point0.BitDepth;
+// if (delta < 0.03d || delta > 30)
+// return false;
+//
+// if (point0.Pressure < 15)
+// return false;
+//
+// if (point0.BlockPosition > 2.5)
+// return false;
+//
+// if (point0.RotorSpeed > 10)
+// return false;
+//
+// if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03))
+// return false;
+//
+// return true;
+// }
+//
+// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// var point0 = telemetry[position];
+// var delta = point0.WellDepth - point0.BitDepth;
+// if (delta < 0.03d || delta > 30)
+// return IdReasonOfEnd_DeltaDepthOutOfRange;
+//
+// if (point0.Pressure < 15)
+// return IdReasonOfEnd_PressureIsLo;
+//
+// if (point0.BlockPosition > 31)
+// return IdReasonOfEnd_BlockPositionIsHi;
+//
+// if (point0.RotorSpeed > 10)
+// return IdReasonOfEnd_RotorSpeedIsHi;
+//
+// return IdReasonOfEnd_NotDetected;
+// }
+//
+// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
+// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
+// }
+//
+//
+// }
+//
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplatingWhileDrilling.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplatingWhileDrilling.cs
index 7d48f361..656ad29e 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplatingWhileDrilling.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplatingWhileDrilling.cs
@@ -1,61 +1,61 @@
-using AsbCloudDb.Model;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-
- ///
- /// Шаблонировка при бурении
- ///
- internal class DetectorTemplatingWhileDrilling : DetectorAbstract
- {
- public DetectorTemplatingWhileDrilling()
- : base(WellOperationCategory.IdTemplatingWhileDrilling) { }
-
- protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
- => CalcDeltaMinutes(telemetry, begin, end);
-
- protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- if (previousOperation?.IdCategory != WellOperationCategory.IdFlashing)
- return false;
-
- var point0 = telemetry[position];
-
- if (point0.Pressure < 15)
- return false;
-
- if (point0.RotorSpeed < 1)
- return false;
-
- if (RisesFromBegin(telemetry, t => t.BlockPosition, position, 30, 0.5))
- return false;
-
- return true;
- }
-
- protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
- {
- var point0 = telemetry[position];
-
- if (point0.Pressure < 15)
- return IdReasonOfEnd_PressureIsLo;
-
- if (RisesFromBegin(telemetry, t=>t.WellDepth, position, 10, 0.01))
- return IdReasonOfEnd_WellDepthDeviates;
-
- var delta = point0.WellDepth - point0.BitDepth;
- if ( (delta > 0.03d )
- && (point0.Pressure > 15)
- && (!ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03)))
- return IdReasonOfEnd_Custom1;
-
- return IdReasonOfEnd_NotDetected;
- }
-
- protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
- => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
- }
-
-
-}
-
+// using AsbCloudDb.Model;
+//
+// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+// {
+//
+// ///
+// /// Шаблонировка при бурении
+// ///
+// internal class DetectorTemplatingWhileDrilling : DetectorAbstract
+// {
+// public DetectorTemplatingWhileDrilling()
+// : base(WellOperationCategory.IdTemplatingWhileDrilling) { }
+//
+// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
+// => CalcDeltaMinutes(telemetry, begin, end);
+//
+// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// if (previousOperation?.IdCategory != WellOperationCategory.IdFlashing)
+// return false;
+//
+// var point0 = telemetry[position];
+//
+// if (point0.Pressure < 15)
+// return false;
+//
+// if (point0.RotorSpeed < 1)
+// return false;
+//
+// if (RisesFromBegin(telemetry, t => t.BlockPosition, position, 30, 0.5))
+// return false;
+//
+// return true;
+// }
+//
+// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+// {
+// var point0 = telemetry[position];
+//
+// if (point0.Pressure < 15)
+// return IdReasonOfEnd_PressureIsLo;
+//
+// if (RisesFromBegin(telemetry, t=>t.WellDepth, position, 10, 0.01))
+// return IdReasonOfEnd_WellDepthDeviates;
+//
+// var delta = point0.WellDepth - point0.BitDepth;
+// if ( (delta > 0.03d )
+// && (point0.Pressure > 15)
+// && (!ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03)))
+// return IdReasonOfEnd_Custom1;
+//
+// return IdReasonOfEnd_NotDetected;
+// }
+//
+// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
+// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
+// }
+//
+//
+// }
+//
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDetectorResult.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDetectorResult.cs
index 2c7d8f09..fcab00bd 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDetectorResult.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDetectorResult.cs
@@ -3,11 +3,10 @@
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{
- class OperationDetectorResult
- {
- public int TelemetryBegin { get; set; }
- public int TelemetryEnd { get; set; }
- public DetectedOperation Operation { get; set; } = null!;
- }
-
+ public class OperationDetectorResult
+ {
+ public int TelemetryBegin { get; set; }
+ public int TelemetryEnd { get; set; }
+ public DetectedOperation Operation { get; set; } = null!;
+ }
}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md
index 21332ad4..965f271e 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md
@@ -1,22 +1,29 @@
-# Алгоритм определения бурения в роторе
-## Описание
+Метод определения бурения
-## Метод определения бурения в роторе
+Признак начала операции =
- Признак начала операции =
- ( расстояние от долота до забоя < 0.03м ) И
- ( давление > 25атм ) И
- ( глубина забоя за следующую секунду больше текущей на 0.003м ) И
- ( обороты ротора > 5 об/м );
+расстояние от долота до забоя < 0.03м И
- Признак окончания операции =
- ( расстояние от долота до забоя > 0.03м ) ИЛИ
- ( давление < 25атм ) ИЛИ
- ( среднее арифметическое оборотов ротора за 60 сек < 10 об/м ) ИЛИ
- ( глубина забоя в течении следующих 150 сек не изменяется больше чем на 0.003 );
-
-## Метод определения бурения в слайде
-Повторяет метод определения бурения в роторе, за исключением условия с оборотами ротора. Это уловие нужно инвертировать.
+давление > 25атм
-## Ключевой параметр
-МСП = разность глубины забоя на конец и начало операции / продолжительность операции.
\ No newline at end of file
+Признак окончания операции =
+
+расстояние от долота до забоя > 0.03м ИЛИ
+
+давление < 25атм
+
+Находим границы
+
+После того когда мы нашли границы, мы должны определить операцию, тогда мы смотрим на забой точки окончания операций сравниваем с забоем точками начала операций:
+
+Если они равны друг другу, то мы эту операцию дальше не обрабатываем, а выбрасываем.
+
+Если они не равны, то у нас произошло увеличение забоя, значит эта операция бурения.
+
+Дальше мы определяем как мы бурили в роторе или слайде, для этого нам необходимо рассчитать среднюю скорость(среднее арифметическое) за всю операцию бурения . Если среднее арифметическое больше константы (10 об/мин), то это бурение в роторе, если меньше, то это бурение в слайде.
+
+Если бурение в роторе, то мы считаем только дисперсию нормированных оборотов ротора(по среднему значению). (Так как это может быть бурение в слайде с осцилляцией и выглядеть как бурение в роторе):
+
+Если полученное значение меньше константы(0,2), то мы подтвердили что бурение в роторе.
+
+Если полученное значение больше константы, то это бурение в слайде с осцилляцией.
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs b/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs
index b37d009b..4673d032 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs
@@ -16,8 +16,8 @@ public class WorkOperationDetection: Work
{
private static readonly DetectorAbstract[] detectors = new DetectorAbstract[]
{
- new DetectorRotor(),
- new DetectorSlide(),
+ // new DetectorRotor(),
+ // new DetectorSlide(),
//new DetectorDevelopment(),
//new DetectorTemplating(),
new DetectorSlipsTime(),
diff --git a/AsbCloudWebApi/Controllers/SAUB/DetectedOperationController.cs b/AsbCloudWebApi/Controllers/SAUB/DetectedOperationController.cs
index 58950cba..33255f21 100644
--- a/AsbCloudWebApi/Controllers/SAUB/DetectedOperationController.cs
+++ b/AsbCloudWebApi/Controllers/SAUB/DetectedOperationController.cs
@@ -5,9 +5,10 @@ using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
-using System.Linq;
+using System.ComponentModel.DataAnnotations;
using System.Threading;
using System.Threading.Tasks;
+using AsbCloudInfrastructure.Services.DetectOperations;
using Microsoft.AspNetCore.Http;
namespace AsbCloudWebApi.Controllers.SAUB
@@ -22,11 +23,14 @@ namespace AsbCloudWebApi.Controllers.SAUB
{
private readonly IDetectedOperationService detectedOperationService;
private readonly IWellService wellService;
-
- public DetectedOperationController(IDetectedOperationService detectedOperationService, IWellService wellService)
+ private readonly DetectedOperationExportService detectedOperationExportService;
+
+ public DetectedOperationController(IDetectedOperationService detectedOperationService, IWellService wellService,
+ DetectedOperationExportService detectedOperationExportService)
{
this.detectedOperationService = detectedOperationService;
this.wellService = wellService;
+ this.detectedOperationExportService = detectedOperationExportService;
}
///
@@ -118,42 +122,23 @@ namespace AsbCloudWebApi.Controllers.SAUB
/// Создает excel файл с операциями по скважине
///
/// id скважины
- ///
- /// Токен отмены задачи
- /// Запрашиваемый файл
+ /// Идентификатор домена
+ ///
[HttpGet("export")]
[Permission]
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
- public async Task ExportAsync(int? idWell, int? idCluster, CancellationToken token)
+ public async Task ExportAsync(int idWell, [Range(1, 2)] int idDomain, CancellationToken token)
{
- if (idCluster is null && idWell is null)
- return this.ValidationBadRequest(nameof(idWell), $"One of {nameof(idWell)} or {nameof(idCluster)} mast be set.");
-
- int? idCompany = User.GetCompanyId();
+ var idCompany = User.GetCompanyId();
if (idCompany is null)
return Forbid();
-
- IEnumerable idsWells;
- if (idCluster is not null)
- {
- var companyWells = await wellService.GetAsync(new() { IdCompany = idCompany }, token);
- idsWells = companyWells.Where(w => w.IdCluster == idCluster)
- .Select(w=>w.Id);
- }
- else
- {
- if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
- idWell!.Value, token).ConfigureAwait(false))
- return Forbid();
- idsWells = new List { (int)idWell };
- }
-
- var stream = await detectedOperationService.ExportAsync(idsWells, token);
- var fileName = "operations.xlsx";
- return File(stream, fileName);
+
+ var stream = await detectedOperationExportService.ExportAsync(idWell, idDomain, token);
+
+ return File(stream, "application/octet-stream", "operations.xlsx");
}
}
}
diff --git a/ConsoleApp1/ConsoleApp1.csproj b/ConsoleApp1/ConsoleApp1.csproj
index c0c5ae85..d043fb8e 100644
--- a/ConsoleApp1/ConsoleApp1.csproj
+++ b/ConsoleApp1/ConsoleApp1.csproj
@@ -22,6 +22,10 @@
+
+
+
+
diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs
index 15f086ae..ffe1d128 100644
--- a/ConsoleApp1/Program.cs
+++ b/ConsoleApp1/Program.cs
@@ -1,24 +1,24 @@
-using System.IO;
-using System.Text.RegularExpressions;
+
using System.Threading;
using System.Threading.Tasks;
-using AsbCloudApp.Data;
-using AsbCloudApp.Services;
using AsbCloudDb.Model;
-using AsbCloudInfrastructure;
-using CliWrap;
-using Mapster;
+using ConsoleApp1.DetectedOperations;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
namespace ConsoleApp1
{
class Program
{
- static void Main(/*string[] args*/)
+ private static DbContextOptions options = new DbContextOptionsBuilder()
+ .UseNpgsql("Host=localhost;Database=postgres;Port=5433;Username=postgres;Password=root;Persist Security Info=True")
+ .Options;
+
+ static async Task Main(/*string[] args*/)
{
-
-
+ using var db = new AsbCloudDbContext(options);
+
+ await new DetectedOperationExportService(db).Export(483, CancellationToken.None);
+
}
}
}