diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx b/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx index 1c366050..bfde3933 100644 Binary files a/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx and b/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx differ diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs index cfb115f0..dab037d5 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Text; using System.Threading; using System.Threading.Tasks; using AsbCloudInfrastructure.Services.DetectOperations.Detectors; @@ -14,7 +15,11 @@ namespace AsbCloudInfrastructure.Services.DetectOperations; public class DetectedOperationExportService { - private readonly DetectorAbstract[] detectors = { new DetectorDrilling() }; + private readonly DetectorAbstract[] detectors = + { + new DetectorDrilling(), + new DetectorSlipsTime() + }; private readonly IDictionary domains = new Dictionary { @@ -38,6 +43,7 @@ public class DetectedOperationExportService private const int columnDeltaDepth = 7; private const int columnDepth = 8; private const int columnIdReasonOfEnd = 9; + private const int columnComment = 10; private readonly IAsbCloudDbContext dbContext; @@ -65,14 +71,14 @@ public class DetectedOperationExportService return await GenerateExcelFileStreamAsync(well, idDomain, operations, cancellationToken); } - private async Task GenerateExcelFileStreamAsync(Well well, int idDomain, IEnumerable detectedOperations, + private async Task GenerateExcelFileStreamAsync(Well well, int idDomain, IEnumerable operationDetectorResults, CancellationToken cancellationToken) { using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken); using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled); - await AddToWorkbookAsync(workbook, well, idDomain, detectedOperations, cancellationToken); + await AddToWorkbookAsync(workbook, well, idDomain, operationDetectorResults, cancellationToken); MemoryStream memoryStream = new MemoryStream(); workbook.SaveAs(memoryStream, new SaveOptions { }); @@ -80,22 +86,23 @@ public class DetectedOperationExportService return memoryStream; } - private async Task AddToWorkbookAsync(XLWorkbook workbook, Well well, int idDomain, IEnumerable detectedOperations, + private async Task AddToWorkbookAsync(XLWorkbook workbook, Well well, int idDomain, IEnumerable operationDetectorResults, CancellationToken cancellationToken) { const string sheetName = "Операции"; - if (!detectedOperations.Any()) + if (!operationDetectorResults.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(), + await AddToSheetAsync(sheet, well, idDomain, operationDetectorResults + .OrderBy(x => x.Operation.DateStart).ThenBy(x => x.Operation.DepthStart).ToArray(), cancellationToken); } - private async Task AddToSheetAsync(IXLWorksheet sheet, Well well, int idDomain, IList detectedOperations, + private async Task AddToSheetAsync(IXLWorksheet sheet, Well well, int idDomain, IList operationDetectorResults, CancellationToken cancellationToken) { var wellOperationCategories = await dbContext.WellOperationCategories.ToListAsync(cancellationToken); @@ -103,14 +110,14 @@ public class DetectedOperationExportService 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); + sheet.Cell(cellDeltaDate).Value = operationDetectorResults.Max(o => o.Operation.DateEnd) - operationDetectorResults.Min(o => o.Operation.DateStart); - var timeZoneWell = TimeSpan.FromHours(well.Timezone.Hours); - - for (int i = 0; i < detectedOperations.Count; i++) + for (int i = 0; i < operationDetectorResults.Count; i++) { - var dateStart = detectedOperations[i].DateStart.ToOffset(timeZoneWell); - var dateEnd = detectedOperations[i].DateEnd.ToOffset(timeZoneWell); + var detectedOperations = operationDetectorResults.Select(o => o.Operation).ToArray(); + + var dateStart = detectedOperations[i].DateStart.ToRemoteDateTime(well.Timezone.Hours); + var dateEnd = detectedOperations[i].DateEnd.ToRemoteDateTime(well.Timezone.Hours); var row = sheet.Row(5 + i + headerRowsCount); @@ -137,9 +144,11 @@ public class DetectedOperationExportService row.Cell(columnDateStart).Value = dateStart; row.Cell(columnDateStart).SetHyperlink(new XLHyperlink(link)); - row.Cell(columnDeltaDepth).Value = i > 0 && i + 1 < detectedOperations.Count + row.Cell(columnDeltaDepth).Value = i > 0 && i + 1 < detectedOperations.Length ? detectedOperations[i].DepthStart - detectedOperations[i - 1].DepthEnd : 0; + + row.Cell(columnComment).Value = CreateComment(operationDetectorResults[i]); } } @@ -158,8 +167,32 @@ public class DetectedOperationExportService return memoryStream; } + + private string? CreateComment(OperationDetectorResult operationDetectorResult) + { + switch (operationDetectorResult.Operation.IdCategory) + { + case 12000: + case 5002: + case 5003: + { + var detectorDrilling = detectors.FirstOrDefault(d => d is DetectorDrilling) as DetectorDrilling; + var avgRotorSpeed = Math.Round(detectorDrilling.AvgRotorSpeedDict[(operationDetectorResult.TelemetryBegin, operationDetectorResult.TelemetryEnd)], 2); + var despersion = Math.Round(detectorDrilling.DespersionDict[(operationDetectorResult.TelemetryBegin, operationDetectorResult.TelemetryEnd)], 2); - private async Task> DetectOperationsAsync(int idTelemetry, DateTimeOffset begin, + var stringBuilder = new StringBuilder(); + + stringBuilder.AppendLine($"Средняя скорость оборотов ротора: {avgRotorSpeed}"); + stringBuilder.AppendLine($"Нормированные обороты ротора: {despersion}"); + + return stringBuilder.ToString(); + } + default: + return null; + } + } + + private async Task> DetectOperationsAsync(int idTelemetry, DateTimeOffset begin, CancellationToken token) { var query = dbContext.TelemetryDataSaub @@ -180,7 +213,7 @@ public class DetectedOperationExportService .OrderBy(d => d.DateTime); var startDate = begin; - var detectedOperations = new List(8); + var detectedOperationResults = new List(8); DetectedOperation? lastDetectedOperation = null; const int minOperationLength = 5; const int maxDetectorsInterpolationFrameLength = 30; @@ -205,8 +238,8 @@ public class DetectedOperationExportService if (!detector.TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out var result)) continue; - detectedOperations.Add(result!.Operation); - lastDetectedOperation = result.Operation; + detectedOperationResults.Add(result!); + lastDetectedOperation = result!.Operation; isDetected = true; positionBegin = result.TelemetryEnd; break; @@ -221,6 +254,6 @@ public class DetectedOperationExportService startDate = data[positionEnd].DateTime; } - return detectedOperations; + return detectedOperationResults; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs index ac1954f9..cc8b7353 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using AsbCloudDb.Model; @@ -8,6 +9,9 @@ public class DetectorDrilling : DetectorAbstract { protected override Func GetIdOperation => DefineDrillingOperation; + public IDictionary<(int, int), float> AvgRotorSpeedDict { get; } = new Dictionary<(int, int), float>(); + public IDictionary<(int, int), double> DespersionDict { get; } = new Dictionary<(int, int), double>(); + protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) { var point0 = telemetry[position]; @@ -42,7 +46,7 @@ public class DetectorDrilling : DetectorAbstract operationDetectorResult.Operation.IdReasonOfEnd is IdReasonOfEnd_DeltaDepthIsHi or IdReasonOfEnd_PressureIsLo && Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01; - private static int DefineDrillingOperation(DetectableTelemetry[] telemetry, int begin, int end) + private int DefineDrillingOperation(DetectableTelemetry[] telemetry, int begin, int end) { const int idSlideWithOscillation = 12000; @@ -61,12 +65,14 @@ public class DetectorDrilling : DetectorAbstract } var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed); - + var despersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed/avgRotorSpeed - 1, 2)); + + AvgRotorSpeedDict.Add((begin, end), avgRotorSpeed); + DespersionDict.Add((begin, end), despersion); + if (avgRotorSpeed < 5) return WellOperationCategory.IdSlide; - var despersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed/avgRotorSpeed - 1, 2)); - return despersion < 0.2d ? WellOperationCategory.IdRotor : idSlideWithOscillation; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs index 187aee33..7ca25fe5 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs @@ -1,39 +1,35 @@ -// using System; -// using AsbCloudDb.Model; -// -// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors -// { -// -// internal class DetectorSlipsTime : DetectorAbstract -// { -// 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]; -// var delta = point0.WellDepth - point0.BitDepth; -// if (delta > 2.5d) -// return false; -// -// if (point0.Pressure > 15) -// return false; -// -// if (point0.BlockPosition > 8) -// return false; -// -// if (point0.HookWeight > 20) -// return false; -// -// return true; -// } -// -// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end) -// => IsValidByWellDepthDoesNotChange(telemetry, begin, end); -// } -// -// -// } -// +using System; +using AsbCloudDb.Model; + +namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors; + +public class DetectorSlipsTime : DetectorAbstract +{ + protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end) + => CalcDeltaMinutes(telemetry, begin, end); + + protected override Func GetIdOperation => (_, _, _) => WellOperationCategory.IdSlipsTime; + + protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) + { + var point0 = telemetry[position]; + var delta = point0.WellDepth - point0.BitDepth; + if (delta > 2.5d) + return false; + + if (point0.Pressure > 15) + return false; + + if (point0.BlockPosition > 8) + return false; + + if (point0.HookWeight > 20) + return false; + + return true; + } + + protected override bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) => + Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01; +} + diff --git a/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs b/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs index fd762b09..43815670 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs @@ -16,7 +16,8 @@ public class WorkOperationDetection: Work { private static readonly DetectorAbstract[] detectors = new DetectorAbstract[] { - new DetectorDrilling() + new DetectorDrilling(), + new DetectorSlipsTime() // new DetectorRotor(), // new DetectorSlide(), //new DetectorDevelopment(),