forked from ddrilling/AsbCloudServer
doesn't work. Wrong handle begin of operation.
This commit is contained in:
parent
85c253b82b
commit
d0386b0182
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Конструктор детектора.
|
||||
/// Словарь с IdCategory в дефолтных данных AsbCloudDbContext для таблицы WellOperationCategory
|
||||
/// </summary>
|
||||
/// <param name="IdCategory">ключ названия/описания операции из таблицы WellOperationCategory</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Расчет ключевого параметра
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
protected abstract double CalcValue(DetectableTelemetry[] telemetry, int positionBegin, int positionEnd);
|
||||
|
||||
/// <summary>
|
||||
/// Определение начала операции
|
||||
/// </summary>
|
||||
/// <param name="telemetry"></param>
|
||||
/// <param name="position"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract bool DetectStart(DetectableTelemetry[] telemetry, int position);
|
||||
|
||||
/// <summary>
|
||||
/// Определение окончания операции
|
||||
/// </summary>
|
||||
/// <param name="telemetry"></param>
|
||||
/// <param name="position"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract bool DetectEnd(DetectableTelemetry[] telemetry, int position);
|
||||
|
||||
/// <summary>
|
||||
/// Валидация операции
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract bool IsValid(DetectedOperation result);
|
||||
}
|
||||
#nullable disable
|
||||
}
|
@ -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);
|
||||
|
||||
/// <summary>
|
||||
/// Рассчитываем МСП, м/час
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
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;
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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<IDetector> detectors = Enumerable.Empty<IDetector>();
|
||||
|
||||
protected Func<DetectableTelemetry[], int, bool> detectStart;
|
||||
protected Func<DetectableTelemetry[], int, bool> detectEnd;
|
||||
|
||||
public int FragmentLength { get => fragmentLength; set => fragmentLength = value; }
|
||||
public int StepLength { get => stepLength; set => stepLength = value; }
|
||||
|
||||
public FragmentDetector(
|
||||
Func<DetectableTelemetry[], int, bool> detectStart,
|
||||
IFragmentDetector detector,
|
||||
params IFragmentDetector[] detectors)
|
||||
{
|
||||
this.detectStart = detectStart;
|
||||
this.detectors = JoinDetectors(detector, detectors);
|
||||
detectEnd = (f, i) => !detectStart(f,i);
|
||||
}
|
||||
|
||||
public FragmentDetector(
|
||||
Func<DetectableTelemetry[], int, bool> detectStart,
|
||||
Func<DetectableTelemetry[], int, bool> detectEnd,
|
||||
IFragmentDetector detector,
|
||||
params IFragmentDetector[] detectors)
|
||||
{
|
||||
this.detectStart = detectStart;
|
||||
this.detectEnd = detectEnd;
|
||||
this.detectors = JoinDetectors(detector, detectors);
|
||||
}
|
||||
|
||||
public FragmentDetector(Func<DetectableTelemetry[], int, bool> detectStart, IOperationDetector operation)
|
||||
{
|
||||
this.detectStart = detectStart;
|
||||
detectors = new IOperationDetector[] { operation };
|
||||
detectEnd = (f, i) => !detectStart(f, i);
|
||||
}
|
||||
|
||||
public FragmentDetector(Func<DetectableTelemetry[], int, bool> detectStart, Func<DetectableTelemetry[], int, bool> detectEnd, IOperationDetector operation)
|
||||
{
|
||||
this.detectStart = detectStart;
|
||||
this.detectEnd = detectEnd;
|
||||
detectors = new IOperationDetector[] { operation };
|
||||
}
|
||||
|
||||
private static IEnumerable<IFragmentDetector> 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<DetectableTelemetry[], int, bool> MakeInstantDelegate(Func<DetectableTelemetry, bool> instantValueCondition)
|
||||
{
|
||||
var detect = (DetectableTelemetry[] telemetry, int position) =>
|
||||
{
|
||||
var firstItem = telemetry[position];
|
||||
var result = instantValueCondition(firstItem);
|
||||
return result;
|
||||
};
|
||||
return detect;
|
||||
}
|
||||
|
||||
public static Func<DetectableTelemetry[], int, bool> MakeInterpolationDelegate(
|
||||
Func<DetectableTelemetry, double> yGetter,
|
||||
Func<InterpolationLine, bool> 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<DetectedOperation> operations)
|
||||
{
|
||||
var positionStart = 0;
|
||||
var operationsList = new List<DetectedOperation>();
|
||||
// поиск начала соответствия критерию
|
||||
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<DetectedOperation> result))
|
||||
operationsList.AddRange(result);
|
||||
|
||||
break;
|
||||
}
|
||||
positionEnd += stepLength;
|
||||
}
|
||||
positionStart = positionEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
positionStart += stepLength;
|
||||
}
|
||||
}
|
||||
operations = operationsList;
|
||||
return operationsList.Any();
|
||||
}
|
||||
|
||||
}
|
||||
#nullable disable
|
||||
}
|
@ -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<DetectedOperation> operations);
|
||||
}
|
||||
|
||||
internal interface IOperationDetector : IDetector
|
||||
{ }
|
||||
|
||||
internal interface IFragmentDetector: IDetector
|
||||
{ }
|
||||
}
|
@ -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<DetectableTelemetry[], bool> isValid = (_) => true;
|
||||
|
||||
protected Func<DetectableTelemetry[], double> calcValue = (_) => 0d;
|
||||
|
||||
public OperationDetector(int idOperation)
|
||||
{
|
||||
this.idOperation = idOperation;
|
||||
}
|
||||
|
||||
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetryFragment, out IEnumerable<DetectedOperation> operations)
|
||||
{
|
||||
if(!telemetryFragment.Any() || !isValid(telemetryFragment))
|
||||
{
|
||||
operations = Enumerable.Empty<DetectedOperation>();
|
||||
return false;
|
||||
}
|
||||
|
||||
var operation = MakeOperation(idTelemetry, telemetryFragment);
|
||||
|
||||
operations = new List<DetectedOperation> { 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<DetectableTelemetry[], bool> isValid)
|
||||
{
|
||||
this.isValid = isValid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OperationDetector SetCalcValueDelegate(Func<DetectableTelemetry[], double> calcValue)
|
||||
{
|
||||
this.calcValue = calcValue;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<DetectorAbstract> detectors = new List<DetectorAbstract>
|
||||
{
|
||||
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<DetectableTelemetry[], int, bool> isBitAtTheBottom = FragmentDetector.MakeInstantDelegate(d => (double)(d.WellDepth - d.BitDepth) < 0.001d);
|
||||
private static readonly Func<DetectableTelemetry[], int, bool> isPressureGt25 = FragmentDetector.MakeInstantDelegate(d => d.Pressure > 25);
|
||||
private static readonly Func<DetectableTelemetry[], int, bool> isPressureLt15 = FragmentDetector.MakeInstantDelegate(d => d.Pressure < 15);
|
||||
private static readonly Func<DetectableTelemetry[], int, bool> isBlockPositionLt8 = FragmentDetector.MakeInstantDelegate(d => d.BlockPosition < 8);
|
||||
private static readonly Func<DetectableTelemetry[], int, bool> isHookWeightLt20 = FragmentDetector.MakeInstantDelegate(d => d.HookWeight < 20);
|
||||
private static readonly Func<DetectableTelemetry[], int, bool> isRotorSpeedAvgGt5 = FragmentDetector.MakeInterpolationDelegate(d => (double)d.RotorSpeed, line => line.IsAverageYGreaterThan(5), 12);
|
||||
private static readonly Func<DetectableTelemetry[], int, bool> isRotorSpeedAvgLt5 = FragmentDetector.MakeInterpolationDelegate(d => (double)d.RotorSpeed, line => line.IsAverageYLessThan(5), 12);
|
||||
private static readonly List<IDetector> detectors = new List<IDetector>
|
||||
{
|
||||
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<DetectedOperation>(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<DetectedOperation> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user