forked from ddrilling/AsbCloudServer
Правки
1. Дополнения шаблона для отладки 1.2 Добавлен комментарии 2. Вернул определение операции удержание в клиньях
This commit is contained in:
parent
1a237f7050
commit
a435dce308
Binary file not shown.
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
@ -14,7 +15,11 @@ namespace AsbCloudInfrastructure.Services.DetectOperations;
|
|||||||
|
|
||||||
public class DetectedOperationExportService
|
public class DetectedOperationExportService
|
||||||
{
|
{
|
||||||
private readonly DetectorAbstract[] detectors = { new DetectorDrilling() };
|
private readonly DetectorAbstract[] detectors =
|
||||||
|
{
|
||||||
|
new DetectorDrilling(),
|
||||||
|
new DetectorSlipsTime()
|
||||||
|
};
|
||||||
|
|
||||||
private readonly IDictionary<int, string> domains = new Dictionary<int, string>
|
private readonly IDictionary<int, string> domains = new Dictionary<int, string>
|
||||||
{
|
{
|
||||||
@ -38,6 +43,7 @@ public class DetectedOperationExportService
|
|||||||
private const int columnDeltaDepth = 7;
|
private const int columnDeltaDepth = 7;
|
||||||
private const int columnDepth = 8;
|
private const int columnDepth = 8;
|
||||||
private const int columnIdReasonOfEnd = 9;
|
private const int columnIdReasonOfEnd = 9;
|
||||||
|
private const int columnComment = 10;
|
||||||
|
|
||||||
private readonly IAsbCloudDbContext dbContext;
|
private readonly IAsbCloudDbContext dbContext;
|
||||||
|
|
||||||
@ -65,14 +71,14 @@ public class DetectedOperationExportService
|
|||||||
return await GenerateExcelFileStreamAsync(well, idDomain, operations, cancellationToken);
|
return await GenerateExcelFileStreamAsync(well, idDomain, operations, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Stream> GenerateExcelFileStreamAsync(Well well, int idDomain, IEnumerable<DetectedOperation> detectedOperations,
|
private async Task<Stream> GenerateExcelFileStreamAsync(Well well, int idDomain, IEnumerable<OperationDetectorResult> operationDetectorResults,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken);
|
using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken);
|
||||||
|
|
||||||
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
|
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();
|
MemoryStream memoryStream = new MemoryStream();
|
||||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
workbook.SaveAs(memoryStream, new SaveOptions { });
|
||||||
@ -80,22 +86,23 @@ public class DetectedOperationExportService
|
|||||||
return memoryStream;
|
return memoryStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AddToWorkbookAsync(XLWorkbook workbook, Well well, int idDomain, IEnumerable<DetectedOperation> detectedOperations,
|
private async Task AddToWorkbookAsync(XLWorkbook workbook, Well well, int idDomain, IEnumerable<OperationDetectorResult> operationDetectorResults,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
const string sheetName = "Операции";
|
const string sheetName = "Операции";
|
||||||
|
|
||||||
if (!detectedOperations.Any())
|
if (!operationDetectorResults.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName)
|
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName)
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа {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);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AddToSheetAsync(IXLWorksheet sheet, Well well, int idDomain, IList<DetectedOperation> detectedOperations,
|
private async Task AddToSheetAsync(IXLWorksheet sheet, Well well, int idDomain, IList<OperationDetectorResult> operationDetectorResults,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var wellOperationCategories = await dbContext.WellOperationCategories.ToListAsync(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(cellDepositName).Value = well.Cluster.Deposit.Caption;
|
||||||
sheet.Cell(cellClusterName).Value = well.Cluster.Caption;
|
sheet.Cell(cellClusterName).Value = well.Cluster.Caption;
|
||||||
sheet.Cell(cellWellName).Value = well.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 < operationDetectorResults.Count; i++)
|
||||||
|
|
||||||
for (int i = 0; i < detectedOperations.Count; i++)
|
|
||||||
{
|
{
|
||||||
var dateStart = detectedOperations[i].DateStart.ToOffset(timeZoneWell);
|
var detectedOperations = operationDetectorResults.Select(o => o.Operation).ToArray();
|
||||||
var dateEnd = detectedOperations[i].DateEnd.ToOffset(timeZoneWell);
|
|
||||||
|
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);
|
var row = sheet.Row(5 + i + headerRowsCount);
|
||||||
|
|
||||||
@ -137,9 +144,11 @@ public class DetectedOperationExportService
|
|||||||
row.Cell(columnDateStart).Value = dateStart;
|
row.Cell(columnDateStart).Value = dateStart;
|
||||||
row.Cell(columnDateStart).SetHyperlink(new XLHyperlink(link));
|
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
|
? detectedOperations[i].DepthStart - detectedOperations[i - 1].DepthEnd
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
|
row.Cell(columnComment).Value = CreateComment(operationDetectorResults[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,8 +167,32 @@ public class DetectedOperationExportService
|
|||||||
|
|
||||||
return memoryStream;
|
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<IEnumerable<DetectedOperation>> DetectOperationsAsync(int idTelemetry, DateTimeOffset begin,
|
var stringBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
stringBuilder.AppendLine($"Средняя скорость оборотов ротора: {avgRotorSpeed}");
|
||||||
|
stringBuilder.AppendLine($"Нормированные обороты ротора: {despersion}");
|
||||||
|
|
||||||
|
return stringBuilder.ToString();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<IEnumerable<OperationDetectorResult>> DetectOperationsAsync(int idTelemetry, DateTimeOffset begin,
|
||||||
CancellationToken token)
|
CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = dbContext.TelemetryDataSaub
|
var query = dbContext.TelemetryDataSaub
|
||||||
@ -180,7 +213,7 @@ public class DetectedOperationExportService
|
|||||||
.OrderBy(d => d.DateTime);
|
.OrderBy(d => d.DateTime);
|
||||||
|
|
||||||
var startDate = begin;
|
var startDate = begin;
|
||||||
var detectedOperations = new List<DetectedOperation>(8);
|
var detectedOperationResults = new List<OperationDetectorResult>(8);
|
||||||
DetectedOperation? lastDetectedOperation = null;
|
DetectedOperation? lastDetectedOperation = null;
|
||||||
const int minOperationLength = 5;
|
const int minOperationLength = 5;
|
||||||
const int maxDetectorsInterpolationFrameLength = 30;
|
const int maxDetectorsInterpolationFrameLength = 30;
|
||||||
@ -205,8 +238,8 @@ public class DetectedOperationExportService
|
|||||||
if (!detector.TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out var result))
|
if (!detector.TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out var result))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
detectedOperations.Add(result!.Operation);
|
detectedOperationResults.Add(result!);
|
||||||
lastDetectedOperation = result.Operation;
|
lastDetectedOperation = result!.Operation;
|
||||||
isDetected = true;
|
isDetected = true;
|
||||||
positionBegin = result.TelemetryEnd;
|
positionBegin = result.TelemetryEnd;
|
||||||
break;
|
break;
|
||||||
@ -221,6 +254,6 @@ public class DetectedOperationExportService
|
|||||||
startDate = data[positionEnd].DateTime;
|
startDate = data[positionEnd].DateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
return detectedOperations;
|
return detectedOperationResults;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
|
|
||||||
@ -8,6 +9,9 @@ public class DetectorDrilling : DetectorAbstract
|
|||||||
{
|
{
|
||||||
protected override Func<DetectableTelemetry[], int, int, int> GetIdOperation => DefineDrillingOperation;
|
protected override Func<DetectableTelemetry[], int, int, int> 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)
|
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
{
|
||||||
var point0 = telemetry[position];
|
var point0 = telemetry[position];
|
||||||
@ -42,7 +46,7 @@ public class DetectorDrilling : DetectorAbstract
|
|||||||
operationDetectorResult.Operation.IdReasonOfEnd is IdReasonOfEnd_DeltaDepthIsHi or IdReasonOfEnd_PressureIsLo &&
|
operationDetectorResult.Operation.IdReasonOfEnd is IdReasonOfEnd_DeltaDepthIsHi or IdReasonOfEnd_PressureIsLo &&
|
||||||
Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01;
|
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;
|
const int idSlideWithOscillation = 12000;
|
||||||
|
|
||||||
@ -61,12 +65,14 @@ public class DetectorDrilling : DetectorAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed);
|
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)
|
if (avgRotorSpeed < 5)
|
||||||
return WellOperationCategory.IdSlide;
|
return WellOperationCategory.IdSlide;
|
||||||
|
|
||||||
var despersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed/avgRotorSpeed - 1, 2));
|
|
||||||
|
|
||||||
return despersion < 0.2d ? WellOperationCategory.IdRotor : idSlideWithOscillation;
|
return despersion < 0.2d ? WellOperationCategory.IdRotor : idSlideWithOscillation;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,39 +1,35 @@
|
|||||||
// using System;
|
using System;
|
||||||
// using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
//
|
|
||||||
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
// {
|
|
||||||
//
|
public class DetectorSlipsTime : DetectorAbstract
|
||||||
// internal class DetectorSlipsTime : DetectorAbstract
|
{
|
||||||
// {
|
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
=> CalcDeltaMinutes(telemetry, begin, end);
|
||||||
// => CalcDeltaMinutes(telemetry, begin, end);
|
|
||||||
//
|
protected override Func<DetectableTelemetry[], int, int, int> GetIdOperation => (_, _, _) => WellOperationCategory.IdSlipsTime;
|
||||||
// public override Func<DetectableTelemetry[], int, int, int> GetIdOperation => (_, _, _) => WellOperationCategory.IdSlipsTime;
|
|
||||||
//
|
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
{
|
||||||
// {
|
var point0 = telemetry[position];
|
||||||
// var point0 = telemetry[position];
|
var delta = point0.WellDepth - point0.BitDepth;
|
||||||
// var delta = point0.WellDepth - point0.BitDepth;
|
if (delta > 2.5d)
|
||||||
// if (delta > 2.5d)
|
return false;
|
||||||
// return false;
|
|
||||||
//
|
if (point0.Pressure > 15)
|
||||||
// if (point0.Pressure > 15)
|
return false;
|
||||||
// return false;
|
|
||||||
//
|
if (point0.BlockPosition > 8)
|
||||||
// if (point0.BlockPosition > 8)
|
return false;
|
||||||
// return false;
|
|
||||||
//
|
if (point0.HookWeight > 20)
|
||||||
// if (point0.HookWeight > 20)
|
return false;
|
||||||
// return false;
|
|
||||||
//
|
return true;
|
||||||
// return true;
|
}
|
||||||
// }
|
|
||||||
//
|
protected override bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
|
||||||
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01;
|
||||||
// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
}
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
|
@ -16,7 +16,8 @@ public class WorkOperationDetection: Work
|
|||||||
{
|
{
|
||||||
private static readonly DetectorAbstract[] detectors = new DetectorAbstract[]
|
private static readonly DetectorAbstract[] detectors = new DetectorAbstract[]
|
||||||
{
|
{
|
||||||
new DetectorDrilling()
|
new DetectorDrilling(),
|
||||||
|
new DetectorSlipsTime()
|
||||||
// new DetectorRotor(),
|
// new DetectorRotor(),
|
||||||
// new DetectorSlide(),
|
// new DetectorSlide(),
|
||||||
//new DetectorDevelopment(),
|
//new DetectorDevelopment(),
|
||||||
|
Loading…
Reference in New Issue
Block a user