diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
deleted file mode 100644
index 0924849a..00000000
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-using AsbCloudDb.Model;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations
-{
-
-#nullable enable
-
- abstract class DetectorAbstract
- {
- public int StepLength { get; set; } = 3;
- public int FragmentLength { get; set; } = 6;
- public int IdCategory { get; }
-
- // TODO: assert MaxDurationSeconds and MinDurationSeconds
- public double MaxDurationSeconds { get; } = 24 * 60 * 60;
- public double MinDurationSeconds { get; } = 3;
-
- ///
- /// Конструктор детектора.
- /// Словарь с IdCategory в дефолтных данных AsbCloudDbContext для таблицы WellOperationCategory
- ///
- /// ключ названия/описания операции из таблицы WellOperationCategory
- public DetectorAbstract(int IdCategory)
- {
- this.IdCategory = IdCategory;
- }
-
- public virtual DetectedOperation? DetectOrDefault(DetectableTelemetry[] telemetry, ref int position)
- {
- if ((telemetry.Length > position + FragmentLength + StepLength) && DetectStart(telemetry, position))
- {
- var skip = position + StepLength;
- while (telemetry.Length > skip + FragmentLength)
- {
- if (DetectEnd(telemetry, skip))
- {
- var dateStart = telemetry[position].DateTime;
- var dateEnd = telemetry[skip].DateTime;
- var durationSec = (dateEnd - dateStart).TotalSeconds;
- if (durationSec < MinDurationSeconds || durationSec > MaxDurationSeconds)
- return null;
-
- var result = new DetectedOperation
- {
- IdCategory = IdCategory,
- IdUsersAtStart = telemetry[position].IdUser ?? -1,
- DateStart = dateStart,
- DateEnd = dateEnd,
- DepthStart = telemetry[position].WellDepth ?? -1d,
- DepthEnd = telemetry[skip].WellDepth ?? -1d,
- };
- CalcValue(ref result);
- position = skip + FragmentLength;
- return result;
- }
-
- skip = skip + StepLength;
- }
- }
- return null;
- }
-
- protected abstract void CalcValue(ref DetectedOperation result);
-
- protected abstract bool DetectStart(DetectableTelemetry[] telemetry, int position);
-
- protected abstract bool DetectEnd(DetectableTelemetry[] telemetry, int position);
-
- }
-#nullable disable
-}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingRotor.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingRotor.cs
deleted file mode 100644
index 6810a05b..00000000
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingRotor.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using AsbCloudDb.Model;
-using System.Linq;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-#nullable enable
- class DetectorDrillingRotor : DetectorAbstract
- {
- const double minRop = 5; //м/час
- const double minRotorSpeed = 5; //об/мин
- const double ticksPerHour = 60 * 60 * 10_000_000d;
- const double minPressure = 25;
- const double minDeltaDepth = 0.02;
-
- public DetectorDrillingRotor() : base(2)
- {
- FragmentLength = 15;
- StepLength = 10;
- }
-
- protected override bool DetectStart(DetectableTelemetry[] telemetry, int position)
- {
- var firstItem = telemetry[position];
- var deltaDepth = firstItem.WellDepth - firstItem.BitDepth;
- if (deltaDepth is not null &&
- System.Math.Abs((float)deltaDepth) > minDeltaDepth)
- return false;
-
- if(firstItem.RotorSpeed > minRotorSpeed)
- return false;
-
- if (firstItem.Pressure < minPressure)
- return false;
-
- var fragment = telemetry[position..(position + FragmentLength)];
-
- var lineBlockPosition = new InterpolationLine(fragment.Select(d => (d.BlockPosition ?? 0d, d.DateTime.Ticks / ticksPerHour)));
- if (!lineBlockPosition.IsYDecreases(minRop))
- return false;
-
- var lineWellDepth = new InterpolationLine(fragment.Select(d => (d.WellDepth ?? 0d, d.DateTime.Ticks / ticksPerHour)));
- if (!lineWellDepth.IsYIncreases(minRop))
- return false;
-
- return true;
- }
-
- protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position)
- => !DetectStart(telemetry, position);
-
- ///
- /// Рассчитываем МСП, м/час
- ///
- ///
- protected override void CalcValue(ref DetectedOperation result)
- {
- result.Value = (result.DepthEnd - result.DepthStart) / (result.DateEnd - result.DateStart).TotalHours;
- }
- }
-#nullable disable
-}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingSlide.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingSlide.cs
deleted file mode 100644
index 89f20ae6..00000000
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingSlide.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using AsbCloudDb.Model;
-using System.Linq;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-#nullable enable
- class DetectorDrillingSlide : DetectorAbstract
- {
- const double minRop = 5; //м/час
- const double minRotorSpeed = 5; //об/мин
- const double ticksPerHour = 60 * 60 * 10_000_000d;
- const double minPressure = 25;
- const double minDeltaDepth = 0.02;
-
- public DetectorDrillingSlide() : base(3)
- {
- FragmentLength = 10;
- }
-
- protected override bool DetectStart(DetectableTelemetry[] telemetry, int position)
- {
- var firstItem = telemetry[position];
- var deltaDepth = firstItem.WellDepth - firstItem.BitDepth;
- if (deltaDepth is not null &&
- System.Math.Abs((float)deltaDepth) > minDeltaDepth)
- return false;
-
- if(firstItem.RotorSpeed < minRotorSpeed)
- return false;
-
- if (firstItem.Pressure < minPressure)
- return false;
-
- var fragment = telemetry[position..(position + FragmentLength)];
-
- var lineBlockPosition = new InterpolationLine(fragment.Select(d => (d.BlockPosition ?? 0d, d.DateTime.Ticks / ticksPerHour)));
- if (!lineBlockPosition.IsYDecreases(minRop))
- return false;
-
- var lineWellDepth = new InterpolationLine(fragment.Select(d => (d.WellDepth ?? 0d, d.DateTime.Ticks / ticksPerHour)));
- if (!lineWellDepth.IsYIncreases(minRop))
- return false;
-
- return true;
- }
-
- protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position)
- => !DetectStart(telemetry, position);
-
- ///
- /// Рассчитываем МСП, м/час
- ///
- ///
- protected override void CalcValue(ref DetectedOperation result)
- {
- result.Value = (result.DepthEnd - result.DepthStart) / (result.DateEnd - result.DateStart).TotalHours;
- }
- }
-#nullable disable
-}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs
deleted file mode 100644
index ba8b70c6..00000000
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using AsbCloudDb.Model;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-#nullable enable
- class DetectorSlipsTime : DetectorAbstract
- {
- public DetectorSlipsTime() : base(14) { }
- public double HookWeightSP { get; set; } = 20;
- public double PressureSP { get; set; } = 15;
- public double PosisionSP { get; set; } = 8;
- public double DeltaWellDepthMax { get; set; } = 2.5;
-
- protected override bool DetectStart(DetectableTelemetry[] telemetry, int position)
- {
- var item = telemetry[position];
-
- var result =
- item.HookWeight < HookWeightSP &&
- item.Pressure < PressureSP &&
- item.BlockPosition < PosisionSP &&
- (item.WellDepth - item.BitDepth) < DeltaWellDepthMax;
-
- return result;
- }
-
- protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position)
- {
- var item = telemetry[position];
-
- var result = item.Pressure > PressureSP &&
- item.BlockPosition > PosisionSP;
-
- return result;
- }
-
- protected override void CalcValue(ref DetectedOperation result)
- {
- result.Value = result.DurationMinutes;
- }
- }
-#nullable disable
-}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/FragmentDetector.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/FragmentDetector.cs
new file mode 100644
index 00000000..17f8b9dc
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/FragmentDetector.cs
@@ -0,0 +1,162 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+
+namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+{
+#nullable enable
+ internal class FragmentDetector : IFragmentDetector
+ {
+ private int fragmentLength = 12;
+ private int stepLength = 3;
+ protected IEnumerable detectors = Enumerable.Empty();
+
+ protected Func detectStart;
+ protected Func detectEnd;
+
+ public string Name { get; set; }
+
+ public int FragmentLength { get => fragmentLength; set => fragmentLength = value; }
+ public int StepLength { get => stepLength; set => stepLength = value; }
+
+ public FragmentDetector(
+ string name,
+ Func detectStart,
+ IFragmentDetector detector,
+ params IFragmentDetector[] detectors)
+ {
+ this.detectStart = detectStart;
+ this.detectors = JoinDetectors(detector, detectors);
+ detectEnd = (f, i) => !detectStart(f, i);
+ Name = name;
+ }
+ public FragmentDetector(
+ string name,
+ Func detectStart,
+ Func detectEnd,
+ IFragmentDetector detector,
+ params IFragmentDetector[] detectors)
+ {
+ this.detectStart = detectStart;
+ this.detectEnd = detectEnd;
+ this.detectors = JoinDetectors(detector, detectors);
+ Name = name;
+ }
+
+ public FragmentDetector(
+ string name,
+ Func detectStart,
+ IOperationDetector operation)
+ {
+ this.detectStart = detectStart;
+ detectors = new IOperationDetector[] { operation };
+ detectEnd = (f, i) => !detectStart(f, i);
+ Name = name;
+ }
+
+ public FragmentDetector(
+ string name,
+ Func detectStart,
+ Func detectEnd,
+ IOperationDetector operation)
+ {
+ this.detectStart = detectStart;
+ this.detectEnd = detectEnd;
+ detectors = new IOperationDetector[] { operation };
+ Name = name;
+ }
+
+ private static IEnumerable JoinDetectors(IFragmentDetector detector, params IFragmentDetector[] detectors)
+ {
+ var joined = new IFragmentDetector[1 + detectors.Length];
+ joined[0] = detector;
+ if (detectors.Length > 0)
+ detectors.CopyTo(joined, 1);
+ return joined;
+ }
+
+ public static Func MakeInstantDelegate(
+ Func instantValueCondition
+ )
+ {
+ var detect = (DetectableTelemetry[] telemetry, int position) =>
+ {
+ var firstItem = telemetry[position];
+ var result = instantValueCondition(firstItem);
+ return result;
+ };
+ return detect;
+ }
+
+ public static Func MakeInterpolationDelegate(
+ Func yGetter,
+ Func interpolationValueCondition,
+ int fragmentLength)
+ {
+ var detect = (DetectableTelemetry[] telemetry, int position) =>
+ {
+ DetectableTelemetry[] data;
+ if (fragmentLength > 0 && (position + fragmentLength) < telemetry.Length)
+ data = telemetry[position..(position + fragmentLength)];
+ else
+ data = telemetry[position..];
+ var line = new InterpolationLine(data.Select(d => (yGetter(d), (d.DateTime - telemetry[0].DateTime).TotalHours)));
+ var result = interpolationValueCondition(line);
+ return result;
+ };
+ return detect;
+ }
+
+ public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, out IEnumerable results)
+ {
+ List? totaltResultList = null;
+ var positionBegin = begin;
+ // Поиск начала соответствия критерию начала операции
+ while (end > positionBegin + fragmentLength + stepLength)
+ {
+ if (detectStart(telemetry, positionBegin))
+ {
+ // Поиск окончания соответствия критерию
+ var positionEnd = positionBegin;
+ while (positionEnd < end)
+ {
+ positionEnd += stepLength;
+ if ((positionEnd > end))
+ positionEnd = end;
+
+ if ((positionEnd == end) || detectEnd(telemetry, positionEnd))
+ {
+ totaltResultList = totaltResultList ?? new List();
+ var detectorsEnumerator = detectors.GetEnumerator();
+ while (detectorsEnumerator.MoveNext())
+ if (detectorsEnumerator.Current.TryDetect(idTelemetry, telemetry, positionBegin, positionEnd, out IEnumerable innerResult))
+ totaltResultList.AddRange(innerResult);
+
+ break;
+ }
+ }
+ positionBegin = positionEnd;
+ }
+ else
+ {
+ positionBegin += stepLength;
+ }
+ }
+
+ if(totaltResultList?.Any() == true)
+ {
+ results = totaltResultList!;
+ return true;
+ }
+ else
+ {
+ results = Enumerable.Empty();
+ return false;
+ }
+ }
+ public override string ToString()
+ => $"frame detector {Name}";
+ }
+#nullable disable
+}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/IDetector.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/IDetector.cs
new file mode 100644
index 00000000..f08ff2a9
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/IDetector.cs
@@ -0,0 +1,17 @@
+using AsbCloudDb.Model;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+{
+ internal interface IDetector
+ {
+ bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetryFragment, int begin, int end, out IEnumerable operations);
+ }
+
+ internal interface IOperationDetector : IDetector
+ { }
+
+ internal interface IFragmentDetector: IDetector
+ { }
+}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDetector.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDetector.cs
new file mode 100644
index 00000000..07cfb4a4
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDetector.cs
@@ -0,0 +1,66 @@
+using AsbCloudDb.Model;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+{
+ class OperationDetectorResult
+ {
+ public int TelemetryBegin { get; set; }
+ public int TelemetryEnd { get; set; }
+ public DetectedOperation Operation { get; set; }
+ }
+
+ internal class OperationDetector : IOperationDetector
+ {
+ private readonly int idOperation;
+
+ protected Func isValid = (_,_,_) => true;
+
+ protected Func calcValue = (_, _, _) => 0d;
+
+ public OperationDetector(int idOperation)
+ {
+ this.idOperation = idOperation;
+ }
+
+ public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetryFragment, int begin, int end, out IEnumerable operations)
+ {
+ if(!telemetryFragment.Any() || !isValid(telemetryFragment, begin, end))
+ {
+ operations = Enumerable.Empty();
+ return false;
+ }
+
+ var operation = MakeOperation(idTelemetry, telemetryFragment, begin, end);
+
+ operations = new List { operation };
+
+ return true;
+ }
+
+ private OperationDetectorResult MakeOperation(int idTelemetry, DetectableTelemetry[] telemetryFragment, int begin, int end)
+ {
+ var pBegin = telemetryFragment[begin];
+ var pEnd = telemetryFragment[end];
+ var result = new OperationDetectorResult
+ {
+ TelemetryBegin = begin,
+ TelemetryEnd = end,
+ Operation = new DetectedOperation
+ {
+ IdTelemetry = idTelemetry,
+ IdCategory = idOperation,
+ IdUsersAtStart = pBegin.IdUser ?? -1,
+ DateStart = pBegin.DateTime,
+ DateEnd = pEnd.DateTime,
+ DepthStart = (double)pBegin.WellDepth,
+ DepthEnd = (double)pEnd.WellDepth,
+ Value = calcValue(telemetryFragment, begin, end),
+ },
+ };
+ return result;
+ }
+ }
+}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDrilling.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDrilling.cs
new file mode 100644
index 00000000..32dc9201
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDrilling.cs
@@ -0,0 +1,30 @@
+using System.Linq;
+
+namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+{
+
+ internal class OperationDrilling : OperationDetector
+ {
+ public OperationDrilling(int idOperation)
+ :base(idOperation)
+ {
+ isValid = (DetectableTelemetry[] fragment, int begin, int end) =>
+ {
+ var pBegin = fragment[begin];
+ var pEnd = fragment[end];
+ if (pBegin.WellDepth >= pEnd.WellDepth)
+ return false;
+
+ return true;
+ };
+
+ calcValue = (DetectableTelemetry[] fragment, int begin, int end) =>
+ {
+ var pBegin = fragment[begin];
+ var pEnd = fragment[end];
+ var result = (double)(pEnd.WellDepth - pBegin.WellDepth) / (pEnd.DateTime - pBegin.DateTime).TotalHours;
+ return result;
+ };
+ }
+ }
+}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationSlipsTime.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationSlipsTime.cs
new file mode 100644
index 00000000..be2968a3
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationSlipsTime.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Linq;
+
+namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
+{
+ internal class OperationSlipsTime : OperationDetector
+ {
+ public OperationSlipsTime()
+ : base(14)
+ {
+ isValid = (DetectableTelemetry[] fragment, int begin, int end) =>
+ {
+ var pBegin = fragment[begin];
+ var pEnd = fragment[end];
+ if (Math.Abs((double)(pBegin.WellDepth - pEnd.WellDepth)) > 0.01)
+ return false;
+
+ return true;
+ };
+
+ calcValue = (DetectableTelemetry[] fragment, int begin, int end) =>
+ {
+ var pBegin = fragment[begin];
+ var pEnd = fragment[end];
+ var result = (pEnd.DateTime - pBegin.DateTime).TotalHours;
+ return result;
+ };
+ }
+ }
+}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/readme.md b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/readme.md
new file mode 100644
index 00000000..5f282702
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/readme.md
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/InterpolationLine.cs b/AsbCloudInfrastructure/Services/DetectOperations/InterpolationLine.cs
index e7ab4fec..1dc99547 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/InterpolationLine.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/InterpolationLine.cs
@@ -46,10 +46,10 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
public bool IsYDecreases(double bound = 0d) =>
A < bound;
- public bool IsAverageYLessThanBound(double bound) =>
+ public bool IsAverageYLessThan(double bound) =>
(ySum / count) < bound;
- public bool IsAverageYMoreThanBound(double bound) =>
+ public bool IsAverageYGreaterThan(double bound) =>
(ySum / count) >= bound;
}
}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs b/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs
index e4a6867b..8302bc96 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs
@@ -8,31 +8,48 @@ using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
namespace AsbCloudInfrastructure.Services.DetectOperations
{
public class OperationDetectionBackgroundService : BackgroundService
{
- private readonly IEnumerable detectors = new List
- {
- new Detectors.DetectorSlipsTime(),
- new Detectors.DetectorDrillingRotor(),
- new Detectors.DetectorDrillingSlide(),
- };
-
- private readonly int minStepLength;
- private readonly int minFragmentLength;
+ private readonly int stepLength = 3;
+ private readonly int fragmentLength = 6;
private readonly string connectionString;
private readonly TimeSpan period = TimeSpan.FromHours(1);
+ private static readonly Func isBitLt0_03mToBottom = FragmentDetector.MakeInstantDelegate(d =>
+ (double)(d.WellDepth - d.BitDepth) < 0.03d);
+ private static readonly Func isBitLt2_5mToBottom = FragmentDetector.MakeInstantDelegate(d =>
+ (double)(d.WellDepth - d.BitDepth) < 2.5d);
+ private static readonly Func isPressureGt25 = FragmentDetector.MakeInstantDelegate(d =>
+ d.Pressure > 25);
+ private static readonly Func isPressureLt15 = FragmentDetector.MakeInstantDelegate(d =>
+ d.Pressure < 15);
+ private static readonly Func isBlockPositionLt8 = FragmentDetector.MakeInstantDelegate(d =>
+ d.BlockPosition < 8);
+ private static readonly Func isHookWeightLt20 = FragmentDetector.MakeInstantDelegate(d =>
+ d.HookWeight < 20);
+ private static readonly Func isRotorSpeedAvgGt5 = FragmentDetector.MakeInterpolationDelegate(d => (double)d.RotorSpeed, line =>
+ line.IsAverageYGreaterThan(5), 12);
+ private static readonly Func isRotorSpeedAvgLt5 = FragmentDetector.MakeInterpolationDelegate(d => (double)d.RotorSpeed, line =>
+ line.IsAverageYLessThan(5), 12);
+
+ private static readonly List detectors = new List
+ {
+ new FragmentDetector("isBitLt2_5mToBottom", isBitLt2_5mToBottom,
+ new FragmentDetector("isBitLt0_03mToBottom", isBitLt0_03mToBottom,
+ new FragmentDetector("isPressureGt25", isPressureGt25,
+ new FragmentDetector("isRotorSpeedAvgGt5", isRotorSpeedAvgGt5, new OperationDrilling(2)),
+ new FragmentDetector("isRotorSpeedAvgLt5", isRotorSpeedAvgLt5, new OperationDrilling(3)))),
+ new FragmentDetector("isPressureLt15", isPressureLt15,
+ new FragmentDetector("isBlockPositionLt8", isBlockPositionLt8,
+ new FragmentDetector("isHookWeightLt20", isHookWeightLt20, new OperationSlipsTime())))),
+ };
+
public OperationDetectionBackgroundService(IConfiguration configuration)
{
- minStepLength = detectors.Min(d => d.StepLength);
- minStepLength = minStepLength > 0 ? minStepLength : 3;
-
- minFragmentLength = detectors.Min(d => d.FragmentLength);
- minFragmentLength = minFragmentLength > 0 ? minFragmentLength : 6;
-
connectionString = configuration.GetConnectionString("DefaultConnection");
}
@@ -128,7 +145,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
})
.OrderBy(d => d.DateTime);
- var take = 4 * 86_400;
+ var take = 4 * 86_400; // 4 дня
var startDate = begin;
var detectedOperations = new List(8);
@@ -139,47 +156,42 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
.Take(take)
.ToArrayAsync(token);
- if (data.Length < minFragmentLength)
+ if (data.Length < 2 * fragmentLength + stepLength)
break;
- var skip = 0;
-
var isDetected = false;
-
- while (data.Length > skip + minFragmentLength)
+ var positionBegin = 0;
+ var positionEnd = data.Length - fragmentLength;
+
+ foreach (var detector in detectors)
{
- var isDetected1 = false;
-
- foreach (var detector in detectors)
+ if (detector is FragmentDetector fragmentDetector)
{
- if (data.Length < skip + detector.StepLength + detector.FragmentLength)
+ var minLengthToDetect = fragmentDetector.StepLength + fragmentDetector.FragmentLength;
+ if (data.Length < positionBegin + minLengthToDetect)
continue;
- var detectedOperation = detector.DetectOrDefault(data, ref skip);
- if (detectedOperation is not null)
+ if (fragmentDetector.TryDetect(idTelemetry, data, positionBegin, positionEnd, out IEnumerable results))
{
- isDetected1 = true;
isDetected = true;
- detectedOperation.IdTelemetry = idTelemetry;
- detectedOperations.Add(detectedOperation);
- startDate = detectedOperation.DateEnd;
+ var operations = results.Select(r => r.Operation);
+ detectedOperations.AddRange(operations);
+ positionBegin = results.Max(r=>r.TelemetryEnd) + 1;
break;
}
}
-
- if (!isDetected1)
- skip += minStepLength;
}
- if (!isDetected)
+ if (isDetected)
{
- var i = skip - minFragmentLength;
- i = i > data.Length
- ? data.Length - minStepLength
- : i;
- i = i < minFragmentLength
- ? minFragmentLength
- : i;
+ startDate = detectedOperations.Max(o => o.DateEnd);
+ }
+ else
+ {
+ int i = positionEnd - (int)(data.Length * 0.8);
+ if (i < 0)
+ break;
+
startDate = data[i].DateTime;
}
}
diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs
index c4f6f029..0e85aa5f 100644
--- a/ConsoleApp1/Program.cs
+++ b/ConsoleApp1/Program.cs
@@ -12,6 +12,26 @@ namespace ConsoleApp1
// use ServiceFactory to make services
static void Main(/*string[] args*/)
{
+ System.Collections.Generic.List<(double, double)> data = new() {
+ (22.52400016784668, 17715023.435277779) ,
+ (22.52400016784668, 17715023.435555555) ,
+ (22.52400016784668, 17715023.435833335) ,
+ (22.52400016784668, 17715023.436111111) ,
+ (22.547000885009766, 17715023.436388887) ,
+ (22.833000183105469, 17715023.436666667) ,
+ (23.063999176025391, 17715023.436944444) ,
+ (23.298999786376953, 17715023.437222224) ,
+ (23.5310001373291, 17715023.4375) ,
+ (23.763999938964844, 17715023.437777776) ,
+ (23.993999481201172, 17715023.438055556) ,
+ (24.229999542236328, 17715023.438333333) ,
+ (24.459999084472656, 17715023.438611113) ,
+ (24.694999694824219, 17715023.438888889) ,
+ (24.926000595092773, 17715023.439166665) ,
+ };
+
+ var il = new AsbCloudInfrastructure.Services.DetectOperations.InterpolationLine(data);
+
Console.WriteLine("hit keyboard to start");
Console.ReadLine();
diff --git a/ConsoleApp1/Properties/launchSettings.json b/ConsoleApp1/Properties/launchSettings.json
deleted file mode 100644
index 33504c94..00000000
--- a/ConsoleApp1/Properties/launchSettings.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "profiles": {
- "WSL": {
- "commandName": "WSL2",
- "distributionName": ""
- }
- }
-}
\ No newline at end of file