diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
deleted file mode 100644
index 3da8d5d0..00000000
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
+++ /dev/null
@@ -1,97 +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 positionStart)
- {
- if ((telemetry.Length > positionStart + FragmentLength + StepLength) && DetectStart(telemetry, positionStart))
- {
- var skip = positionStart + StepLength;
- while (telemetry.Length > skip + FragmentLength)
- {
- if (DetectEnd(telemetry, skip))
- {
- var dateStart = telemetry[positionStart].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[positionStart].IdUser ?? -1,
- DateStart = dateStart,
- DateEnd = dateEnd,
- DepthStart = telemetry[positionStart].WellDepth ?? -1d,
- DepthEnd = telemetry[skip].WellDepth ?? -1d,
- Value = CalcValue(telemetry, positionStart, skip),
- };
-
- if (!IsValid(result))
- return null;
-
- positionStart = skip;// + FragmentLength;
- return result;
- }
-
- skip = skip + StepLength;
- }
- }
- return null;
- }
-
- ///
- /// Расчет ключевого параметра
- ///
- ///
- protected abstract double CalcValue(DetectableTelemetry[] telemetry, int positionBegin, int positionEnd);
-
- ///
- /// Определение начала операции
- ///
- ///
- ///
- ///
- protected abstract bool DetectStart(DetectableTelemetry[] telemetry, int position);
-
- ///
- /// Определение окончания операции
- ///
- ///
- ///
- ///
- protected abstract bool DetectEnd(DetectableTelemetry[] telemetry, int position);
-
- ///
- /// Валидация операции
- ///
- ///
- ///
- protected abstract bool IsValid(DetectedOperation result);
- }
-#nullable disable
-}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingBase.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingBase.cs
deleted file mode 100644
index 258bdd2e..00000000
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingBase.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using AsbCloudDb.Model;
-using System.Linq;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
- internal abstract class DetectorDrillingAbstract : DetectorAbstract
- {
- /* # РАСЧЕТ minRop
- * шаг энкодера = 0.006м;
- * 2 шага за 10 секунд не считается, так как может быть простым шумом;
- * minRop = 0.006 * 2 / 10 = 0.0012 м/сек
- * minRop > 4.32 м/ч & minRop < 6.48 м/ч (3 шага за 10 сек);
- */
- protected const double minRop = 5.4; //м/час
- protected const double minRotorSpeed = 5; //об/мин
- protected const double minPressure = 25;
- protected const double minDeltaDepth = 0.01;
-
- public DetectorDrillingAbstract(int IdCategory) : base(IdCategory)
- {
- FragmentLength = 12;
- StepLength = 3;
- }
-
- 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.Pressure < minPressure)
- return false;
-
- var fragment = telemetry[position..(position + FragmentLength)];
-
- var lineBlockPosition = new InterpolationLine(fragment.Select(d => (d.BlockPosition ?? 0d, (d.DateTime - firstItem.DateTime).TotalHours)));
- if (!lineBlockPosition.IsYDecreases(-minRop))
- return false;
-
- var lineWellDepth = new InterpolationLine(fragment.Select(d => ((d.WellDepth - firstItem.WellDepth) ?? 0d, (d.DateTime - firstItem.DateTime).TotalHours)));
- if (!lineWellDepth.IsYIncreases(minRop))
- return false;
-
- if (!ModeCondition(fragment))
- return false;
-
- return true;
- }
-
- protected override bool DetectEnd(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 true;
-
- if (firstItem.Pressure < minPressure)
- return true;
-
- var fragment = telemetry[position..(position + FragmentLength)];
- if (!ModeCondition(fragment))
- return true;
-
- return false;
- }
-
- protected abstract bool ModeCondition(DetectableTelemetry[] telemetryFragment);
-
- ///
- /// Рассчитываем МСП, м/час
- ///
- ///
- protected override double CalcValue(DetectableTelemetry[] telemetry, int positionBegin, int positionEnd)
- {
- var pBegin = telemetry[positionBegin];
- var pEnd = telemetry[positionEnd];
- var result = (double)(pEnd.WellDepth - pBegin.WellDepth) / (pEnd.DateTime - pBegin.DateTime).TotalHours;
- return result;
- }
- protected override bool IsValid(DetectedOperation result)
- => result.Value > 0;
- }
-}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingRotor.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingRotor.cs
deleted file mode 100644
index 73cf8675..00000000
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingRotor.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using AsbCloudDb.Model;
-using System.Linq;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-#nullable enable
- class DetectorDrillingRotor : DetectorDrillingAbstract
- {
- public DetectorDrillingRotor()
- : base(2){}
-
- protected override bool ModeCondition(DetectableTelemetry[] telemetryFragment)
- {
- var lineRotorSpeed = new InterpolationLine(telemetryFragment.Select(d => (d.RotorSpeed ?? 0d, (d.DateTime - telemetryFragment[0].DateTime).TotalHours)));
- return lineRotorSpeed.IsAverageYMoreThanBound(minRotorSpeed);
- }
- }
-#nullable disable
-}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingSlide.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingSlide.cs
deleted file mode 100644
index d072e5bd..00000000
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrillingSlide.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Linq;
-
-namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
-{
-#nullable enable
- class DetectorDrillingSlide : DetectorDrillingAbstract
- {
- public DetectorDrillingSlide()
- : base(3){}
-
- protected override bool ModeCondition(DetectableTelemetry[] telemetryFragment)
- {
- var lineRotorSpeed = new InterpolationLine(telemetryFragment.Select(d => (d.RotorSpeed ?? 0d, (d.DateTime - telemetryFragment[0].DateTime).TotalHours)));
- return lineRotorSpeed.IsAverageYLessThanBound(minRotorSpeed);
- }
- }
-#nullable disable
-}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs
deleted file mode 100644
index 870cd7bd..00000000
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs
+++ /dev/null
@@ -1,50 +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 double CalcValue(DetectableTelemetry[] telemetry, int positionBegin, int positionEnd)
- {
- var pBegin = telemetry[positionBegin];
- var pEnd = telemetry[positionEnd];
- var result = (pEnd.DateTime - pBegin.DateTime).TotalMinutes;
- return result;
- }
-
- protected override bool IsValid(DetectedOperation result)
- => result.Value > 0;
-
- }
-#nullable disable
-}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/FragmentDetector.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/FragmentDetector.cs
new file mode 100644
index 00000000..ca6115e9
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/FragmentDetector.cs
@@ -0,0 +1,144 @@
+using AsbCloudDb.Model;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+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 int FragmentLength { get => fragmentLength; set => fragmentLength = value; }
+ public int StepLength { get => stepLength; set => stepLength = value; }
+
+ public FragmentDetector(
+ Func detectStart,
+ IFragmentDetector detector,
+ params IFragmentDetector[] detectors)
+ {
+ this.detectStart = detectStart;
+ this.detectors = JoinDetectors(detector, detectors);
+ detectEnd = (f, i) => !detectStart(f,i);
+ }
+
+ public FragmentDetector(
+ Func detectStart,
+ Func detectEnd,
+ IFragmentDetector detector,
+ params IFragmentDetector[] detectors)
+ {
+ this.detectStart = detectStart;
+ this.detectEnd = detectEnd;
+ this.detectors = JoinDetectors(detector, detectors);
+ }
+
+ public FragmentDetector(Func detectStart, IOperationDetector operation)
+ {
+ this.detectStart = detectStart;
+ detectors = new IOperationDetector[] { operation };
+ detectEnd = (f, i) => !detectStart(f, i);
+ }
+
+ public FragmentDetector(Func detectStart, Func detectEnd, IOperationDetector operation)
+ {
+ this.detectStart = detectStart;
+ this.detectEnd = detectEnd;
+ detectors = new IOperationDetector[] { operation };
+ }
+
+ 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 && fragmentLength < telemetry.Length)
+ data = telemetry[position..(position + fragmentLength)];
+ else
+ data = telemetry;
+ var line = new InterpolationLine(data.Select(d => (yGetter(d), (d.DateTime - telemetry[0].DateTime).TotalHours)));
+ var result = interpolationValueCondition(line);
+ return result;
+ };
+ return detect;
+ }
+
+ public IFragmentDetector AddChildDetector(params IFragmentDetector[] detectors)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IDetector AddOperationDetector(IOperationDetector operation)
+ {
+ detectors = new IOperationDetector[] { operation};
+ return this;
+ }
+
+ public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetryFragment, out IEnumerable operations)
+ {
+ var positionStart = 0;
+ var operationsList = new List();
+ // поиск начала соответствия критерию
+ while (telemetryFragment.Length > positionStart + FragmentLength + stepLength)
+ {
+ if (detectStart(telemetryFragment, positionStart))
+ {
+ // Поиск окончания соответствия критерию
+ var positionEnd = positionStart + stepLength;
+ while (telemetryFragment.Length > positionEnd + FragmentLength)
+ {
+ if (detectEnd(telemetryFragment, positionEnd))
+ {
+ var innerFragment = telemetryFragment[positionStart..positionEnd];
+ var detectorEnumerator = detectors.GetEnumerator();
+ while(detectorEnumerator.MoveNext())
+ if (detectorEnumerator.Current.TryDetect(idTelemetry, innerFragment, out IEnumerable result))
+ operationsList.AddRange(result);
+
+ break;
+ }
+ positionEnd += stepLength;
+ }
+ positionStart = positionEnd;
+ }
+ else
+ {
+ positionStart += stepLength;
+ }
+ }
+ operations = operationsList;
+ return operationsList.Any();
+ }
+
+ }
+#nullable disable
+}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/IDetector.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/IDetector.cs
new file mode 100644
index 00000000..96640006
--- /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, 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..14451145
--- /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
+{
+ 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, out IEnumerable operations)
+ {
+ if(!telemetryFragment.Any() || !isValid(telemetryFragment))
+ {
+ operations = Enumerable.Empty();
+ return false;
+ }
+
+ var operation = MakeOperation(idTelemetry, telemetryFragment);
+
+ operations = new List { operation };
+
+ return true;
+ }
+
+ private DetectedOperation MakeOperation(int idTelemetry, DetectableTelemetry[] telemetryFragment)
+ {
+ var pBegin = telemetryFragment.First();
+ var pEnd = telemetryFragment.Last();
+ var 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),
+ };
+ return operation;
+ }
+
+ public OperationDetector SetIsValidDelegate(Func isValid)
+ {
+ this.isValid = isValid;
+ return this;
+ }
+
+ public OperationDetector SetCalcValueDelegate(Func calcValue)
+ {
+ this.calcValue = calcValue;
+ return this;
+ }
+ }
+}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDrilling.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/OperationDrilling.cs
new file mode 100644
index 00000000..2686339d
--- /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[] telemetryFragment) =>
+ {
+ var pBegin = telemetryFragment.First();
+ var pEnd = telemetryFragment.Last();
+ if (pBegin.WellDepth >= pEnd.WellDepth)
+ return false;
+
+ return true;
+ };
+
+ calcValue = (DetectableTelemetry[] telemetryFragment) =>
+ {
+ var pBegin = telemetryFragment.First();
+ var pEnd = telemetryFragment.Last();
+ 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..98291fec
--- /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[] telemetryFragment) =>
+ {
+ var pBegin = telemetryFragment.First();
+ var pEnd = telemetryFragment.Last();
+ if (Math.Abs((double)(pBegin.WellDepth - pEnd.WellDepth)) > 0.01)
+ return false;
+
+ return true;
+ };
+
+ calcValue = (DetectableTelemetry[] telemetryFragment) =>
+ {
+ var pBegin = telemetryFragment.First();
+ var pEnd = telemetryFragment.Last();
+ 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 16e414ae..bc22de01 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs
@@ -8,31 +8,39 @@ 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 minStepLength = 3;
+ private readonly int minFragmentLength = 6;
private readonly string connectionString;
private readonly TimeSpan period = TimeSpan.FromHours(1);
+ private static readonly Func isBitAtTheBottom = FragmentDetector.MakeInstantDelegate(d => (double)(d.WellDepth - d.BitDepth) < 0.001d);
+ 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(isBitAtTheBottom,
+ new FragmentDetector(isPressureGt25,
+ new FragmentDetector(isRotorSpeedAvgGt5, new OperationDrilling(3)),
+ new FragmentDetector(isRotorSpeedAvgLt5, new OperationDrilling(2))
+ ),
+ new FragmentDetector(isPressureLt15,
+ new FragmentDetector(isBlockPositionLt8,
+ new FragmentDetector(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,70 +136,46 @@ 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);
- var dbRequests_ = 0;
- var dbTime_ = 0d;
- var sw_ = new Stopwatch();
- var otherTime_ = 0d;
-
while (true)
{
- sw_.Restart();
var data = await query
.Where(d => d.DateTime > startDate)
.Take(take)
.ToArrayAsync(token);
- sw_.Stop();
- dbTime_ += sw_.ElapsedMilliseconds;
- dbRequests_++;
- sw_.Restart();
-
if (data.Length < minFragmentLength)
break;
- var skip = 0;
-
var isDetected = false;
- while (data.Length > skip + minFragmentLength)
+ 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 < minLengthToDetect)
continue;
- var detectedOperation = detector.DetectOrDefault(data, ref skip);
- if (detectedOperation is not null)
+ if (fragmentDetector.TryDetect(idTelemetry, data, out IEnumerable operations))
{
- isDetected1 = true;
isDetected = true;
- detectedOperation.IdTelemetry = idTelemetry;
- detectedOperations.Add(detectedOperation);
- startDate = detectedOperation.DateEnd;
+ detectedOperations.AddRange(operations);
+ startDate = operations.Last().DateEnd;
break;
}
}
-
- if (!isDetected1)
- skip += minStepLength;
}
- sw_.Stop();
- otherTime_ += sw_.ElapsedMilliseconds;
-
if (!isDetected)
{
if (data.Length < take)
break;
- var lastPartDate = data.Last().DateTime;
- startDate = startDate + (0.75 * (lastPartDate - startDate));
+ startDate = startDate.AddSeconds(0.95 * take);
}
}