Fixed telemetry analytics calculation logic

This commit is contained in:
KharchenkoVV 2021-09-30 16:41:00 +05:00
parent b60b84b45c
commit a589775ceb
10 changed files with 166 additions and 204 deletions

View File

@ -1,12 +0,0 @@
using AsbCloudApp.Data;
using System.Collections.Generic;
namespace AsbCloudApp.Services
{
public interface ISaubDataCache
{
TelemetryAnalysisDto CurrentAnalysis { get; set; }
IEnumerable<TelemetryDataSaubDto> GetOrCreateCache(int telemetryId);
void AddData(TelemetryDataSaubDto data);
}
}

View File

@ -23,7 +23,7 @@ namespace AsbCloudApp.Services
Task<IEnumerable<TelemetryOperationInfoDto>> GetOperationsToIntervalAsync(int idWell, Task<IEnumerable<TelemetryOperationInfoDto>> GetOperationsToIntervalAsync(int idWell,
int intervalHoursTimestamp, int workBeginTimestamp, int intervalHoursTimestamp, int workBeginTimestamp,
CancellationToken token = default); CancellationToken token = default);
void SaveAnalytics(); void CalculateAnalytics();
Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell, Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell,
CancellationToken token = default); CancellationToken token = default);
} }

View File

@ -13,6 +13,8 @@ namespace AsbCloudDevOperations
{ {
private readonly HttpClient client = new(); private readonly HttpClient client = new();
//Пример роута: "api/telemetryDataSaub/123123_";
public void TestControllerRoute(string route, CancellationToken token = default) public void TestControllerRoute(string route, CancellationToken token = default)
{ {
var host = "http://localhost:5000"; var host = "http://localhost:5000";

View File

@ -24,7 +24,6 @@ namespace AsbCloudInfrastructure
services.AddSingleton(new CacheDb()); services.AddSingleton(new CacheDb());
services.AddSingleton<ITelemetryTracker, TelemetryTracker>(); services.AddSingleton<ITelemetryTracker, TelemetryTracker>();
services.AddSingleton<IReportsBackgroundQueue, ReportsBackgroundQueue>(); services.AddSingleton<IReportsBackgroundQueue, ReportsBackgroundQueue>();
services.AddSingleton<ISaubDataCache, SaubDataCache>();
services.AddTransient<IAuthService, AuthService>(); services.AddTransient<IAuthService, AuthService>();
services.AddTransient<IWellService, WellService>(); services.AddTransient<IWellService, WellService>();

View File

@ -1,62 +1,48 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services
{ {
public class InterpolationLine public class InterpolationLine
{ {
private readonly decimal xSum; private readonly double xSum;
private readonly decimal ySum; private readonly double ySum;
private readonly decimal xySum; private readonly double xySum;
private readonly decimal x2Sum; private readonly double x2Sum;
private readonly IEnumerable<(double value, double timestamp)> rawData = new List<(double value, double timestamp)>(); private readonly int count;
public InterpolationLine(IEnumerable<(double value, double timestamp)> rawData) public InterpolationLine(IEnumerable<(double Y, double X)> rawData)
{ {
var data = rawData.Select((d) => new xSum = rawData.Sum(d => d.X);
{ ySum = rawData.Sum(d => d.Y);
X = d.timestamp, xySum = rawData.Sum(d => d.X * d.Y);
Y = d.value x2Sum = rawData.Sum(d => d.X * d.X);
}); count = rawData.Count();
xSum = (decimal)data.Sum(d => d.X);
ySum = (decimal)data.Sum(d => d.Y);
xySum = (decimal)data.Sum(d => d.X * d.Y);
x2Sum = (decimal)data.Sum(d => d.X * d.X);
this.rawData = rawData;
}
public double GetAForLinearFormula()
{
var result = (xSum * ySum - rawData.Count() * xySum) /
(xSum * xSum - rawData.Count() * x2Sum);
return (double)result;
} }
public double GetBForLinearFormula() public double A =>
{ (xSum * ySum - count * xySum) /
var result = (xSum * xySum - x2Sum * ySum) / (xSum * xSum - count * x2Sum);
(xSum * xSum - rawData.Count() * x2Sum);
return (double)result; public double B =>
} (xSum * xySum - x2Sum * ySum) /
(xSum * xSum - count * x2Sum);
public static bool IsValueNotChanges(double value,
(double upperBound, double lowerBound) bounds) =>
value < bounds.upperBound && value > bounds.lowerBound;
public static bool IsValueIncreases(double value, double bound) => public bool IsYNotChanges(double upperBound = 0d, double lowerBound = 0d) =>
value > bound; A < upperBound && A > lowerBound;
public static bool IsValueDecreases(double value, double bound) => public bool IsYIncreases(double bound = 0d) =>
value < bound; A > bound;
public static bool IsAverageLessThanBound(IEnumerable<(double Value, double TotalSeconds)> values, public bool IsYDecreases(double bound = 0d) =>
double bound) => A < bound;
(values.Sum(s => s.Value) / values.Count()) < bound;
public static bool IsAverageMoreThanBound(IEnumerable<(double Value, double TotalSeconds)> values, public bool IsAverageYLessThanBound(double bound) =>
double bound) => (ySum / count) < bound;
(values.Sum(s => s.Value) / values.Count()) >= bound;
public bool IsAverageYMoreThanBound(double bound) =>
(ySum / count) >= bound;
} }
} }

View File

@ -1,32 +0,0 @@
using AsbCloudApp.Data;
using AsbCloudApp.Services;
using System.Collections.Generic;
namespace AsbCloudInfrastructure.Services
{
public class SaubDataCache : ISaubDataCache
{
public TelemetryAnalysisDto CurrentAnalysis { get; set; }
private readonly Dictionary<int, List<TelemetryDataSaubDto>> saubData =
new Dictionary<int, List<TelemetryDataSaubDto>>();
public IEnumerable<TelemetryDataSaubDto> GetOrCreateCache(int telemetryId)
{
if (!saubData.ContainsKey(telemetryId))
saubData[telemetryId] = new List<TelemetryDataSaubDto>();
return saubData[telemetryId];
}
public void AddData(TelemetryDataSaubDto data)
{
GetOrCreateCache(data.IdTelemetry);
saubData[data.IdTelemetry].Add(data);
if (saubData[data.IdTelemetry].Count > 10)
saubData[data.IdTelemetry].RemoveAt(1);
}
}
}

View File

@ -12,27 +12,15 @@ namespace AsbCloudInfrastructure.Services
{ {
public class TelemetryAnalyticsBackgroundService : BackgroundService public class TelemetryAnalyticsBackgroundService : BackgroundService
{ {
private static readonly DbContextOptions<AsbCloudDbContext> options =
new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
.Options;
private readonly AsbCloudDbContext context = new AsbCloudDbContext(options);
private readonly CacheDb cacheDb; private readonly CacheDb cacheDb;
private readonly ISaubDataCache saubDataCache;
public TelemetryAnalyticsBackgroundService(ISaubDataCache saubDataCache, CacheDb cacheDb) public TelemetryAnalyticsBackgroundService(CacheDb cacheDb)
{ {
this.saubDataCache = saubDataCache;
this.cacheDb = cacheDb; this.cacheDb = cacheDb;
} }
protected override async Task ExecuteAsync(CancellationToken token = default) protected override async Task ExecuteAsync(CancellationToken token = default)
{ {
var telemetryService = new TelemetryService(context, cacheDb);
var analyticsService = new TelemetryAnalyticsService(context,
telemetryService, saubDataCache, cacheDb);
var timeToStartAnalysis = DateTime.Now; var timeToStartAnalysis = DateTime.Now;
while (!token.IsCancellationRequested) while (!token.IsCancellationRequested)
@ -41,9 +29,18 @@ namespace AsbCloudInfrastructure.Services
{ {
try try
{ {
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
.Options;
using var context = new AsbCloudDbContext(options);
var telemetryService = new TelemetryService(context, cacheDb);
var analyticsService = new TelemetryAnalyticsService(context,
telemetryService, cacheDb);
timeToStartAnalysis = DateTime.Now.AddHours(1); timeToStartAnalysis = DateTime.Now.AddHours(1);
await Task.Run(() => analyticsService.SaveAnalytics(), token) await Task.Run(() => analyticsService.CalculateAnalytics(), token)
.ConfigureAwait(false); .ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)

View File

@ -2,7 +2,6 @@
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.Cache; using AsbCloudInfrastructure.Services.Cache;
using Mapster;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -16,17 +15,17 @@ namespace AsbCloudInfrastructure.Services
{ {
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
private readonly ITelemetryService telemetryService; private readonly ITelemetryService telemetryService;
private readonly ISaubDataCache saubDataCache;
private readonly CacheTable<WellOperationCategory> cacheOperations; private readonly CacheTable<WellOperationCategory> cacheOperations;
private readonly TelemetryOperationDetectorService operationDetectorService; private readonly TelemetryOperationDetectorService operationDetectorService;
private readonly IEnumerable<WellOperationCategory> operations; private readonly IEnumerable<WellOperationCategory> operations;
private const int intervalHours = 12;
public TelemetryAnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService, public TelemetryAnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService,
ISaubDataCache saubDataCache, CacheDb cacheDb) CacheDb cacheDb)
{ {
this.db = db; this.db = db;
this.telemetryService = telemetryService; this.telemetryService = telemetryService;
this.saubDataCache = saubDataCache;
cacheOperations = cacheDb.GetCachedTable<WellOperationCategory>((AsbCloudDbContext)db); cacheOperations = cacheDb.GetCachedTable<WellOperationCategory>((AsbCloudDbContext)db);
operations = cacheOperations.Where(); operations = cacheOperations.Where();
operationDetectorService = new TelemetryOperationDetectorService(operations); operationDetectorService = new TelemetryOperationDetectorService(operations);
@ -231,7 +230,7 @@ namespace AsbCloudInfrastructure.Services
return groupedOperationsList; return groupedOperationsList;
} }
public void SaveAnalytics() public void CalculateAnalytics()
{ {
var allTelemetryIds = (from telemetry in db.TelemetryDataSaub var allTelemetryIds = (from telemetry in db.TelemetryDataSaub
select telemetry.IdTelemetry) select telemetry.IdTelemetry)
@ -242,47 +241,58 @@ namespace AsbCloudInfrastructure.Services
{ {
var analyzeStartDate = GetAnalyzeStartDate(idTelemetry); var analyzeStartDate = GetAnalyzeStartDate(idTelemetry);
if(analyzeStartDate != default) if (analyzeStartDate == default)
continue;
TelemetryAnalysis currentAnalysis = null;
while (TryGetDataSaubPart(idTelemetry, analyzeStartDate,
out var dataSaubPart))
{ {
while (GetDataSaubsToAnalyze(idTelemetry, analyzeStartDate).Any()) analyzeStartDate = dataSaubPart.Last().Date;
var count = dataSaubPart.Count();
var skip = 0;
var step = 10;
var take = step * 2;
for(;skip < count; skip += step)
{ {
var dataSaubsToAnalyze = GetDataSaubsToAnalyze(idTelemetry, analyzeStartDate); var analyzingSaubs = dataSaubPart.Skip(skip).Take(take);
analyzeStartDate = dataSaubsToAnalyze.Last().Date; if (analyzingSaubs.Count() <= 1)
foreach (var dataSaub in dataSaubsToAnalyze)
{ {
var dataSaubDto = dataSaub.Adapt<TelemetryDataSaubDto>(); continue;
}
saubDataCache.AddData(dataSaubDto); var dataSaub = analyzingSaubs.First();
if (saubDataCache.GetOrCreateCache(dataSaubDto.IdTelemetry).Count() > 1) var telemetryAnalysis = new TelemetryAnalysis();
telemetryAnalysis = GetDrillingAnalysis(analyzingSaubs);
if (currentAnalysis is null)
{ {
var dataSaubs = saubDataCache.GetOrCreateCache(dataSaubDto.IdTelemetry) currentAnalysis = telemetryAnalysis;
.OrderBy(d => d.Date); currentAnalysis.OperationStartDepth = dataSaub.WellDepth;
}
var telemetryAnalysisDto = GetDrillingAnalysis(dataSaubs); if (currentAnalysis.IdOperation == telemetryAnalysis.IdOperation)
if (saubDataCache.CurrentAnalysis is null)
saubDataCache.CurrentAnalysis = telemetryAnalysisDto;
if (saubDataCache.CurrentAnalysis.IdOperation == telemetryAnalysisDto.IdOperation)
{ {
saubDataCache.CurrentAnalysis.DurationSec += currentAnalysis.DurationSec += telemetryAnalysis.DurationSec;
telemetryAnalysisDto.DurationSec; currentAnalysis.OperationEndDepth = dataSaub.WellDepth;
saubDataCache.CurrentAnalysis.OperationEndDepth = dataSaubDto.WellDepth;
} }
else else
{ {
db.TelemetryAnalysis.Add(saubDataCache.CurrentAnalysis.Adapt<TelemetryAnalysis>()); db.TelemetryAnalysis.Add(currentAnalysis);
saubDataCache.CurrentAnalysis = telemetryAnalysisDto; currentAnalysis = telemetryAnalysis;
saubDataCache.CurrentAnalysis.OperationStartDepth = dataSaubDto.WellDepth; currentAnalysis.OperationStartDepth = dataSaub.WellDepth;
}
} }
} }
db.SaveChanges(); db.SaveChanges();
}
GC.Collect();
} }
} }
} }
@ -332,24 +342,36 @@ namespace AsbCloudInfrastructure.Services
? DateTimeOffset.MinValue ? DateTimeOffset.MinValue
: DateTimeOffset.FromUnixTimeSeconds(lastAnalysisUnixDate); : DateTimeOffset.FromUnixTimeSeconds(lastAnalysisUnixDate);
var firstDataSaub = (from ds in db.TelemetryDataSaub var firstDataSaub = GetFirstSaub(analyzeStartDate.DateTime, idTelemetry);
where ds.IdTelemetry == idTelemetry &&
ds.Date >= analyzeStartDate
select ds).FirstOrDefault();
var firstSaubUtcTime = firstDataSaub?.Date.ToUniversalTime() ?? default; var firstSaubUtcTime = firstDataSaub?.Date.ToUniversalTime() ?? default;
return firstSaubUtcTime; return firstSaubUtcTime;
} }
private IEnumerable<TelemetryDataSaub> GetDataSaubsToAnalyze(int idTelemetry, private bool TryGetDataSaubPart(int idTelemetry, DateTime analyzeStartDate,
DateTime analyzeStartDate) out IEnumerable<TelemetryDataSaub> dataSaubPart)
{
var query = (from ds in db.TelemetryDataSaub
where ds.IdTelemetry == idTelemetry
&& ds.Date > analyzeStartDate
orderby ds.Date
select ds)
.Take(12 * 60* 60)
.AsNoTracking();
dataSaubPart = query.ToList();
return dataSaubPart.Any();
}
private TelemetryDataSaub GetFirstSaub(DateTime analyzeStartDate, int idTelemetry)
{ {
return (from ds in db.TelemetryDataSaub return (from ds in db.TelemetryDataSaub
where ds.IdTelemetry == idTelemetry where ds.IdTelemetry == idTelemetry
&& ds.Date > analyzeStartDate && ds.Date > analyzeStartDate.AddHours(intervalHours)
&& ds.Date < analyzeStartDate.AddHours(12) orderby ds.Date
select ds).ToList(); select ds).FirstOrDefault();
} }
private static IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> DivideOperationsByIntervalLength( private static IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> DivideOperationsByIntervalLength(
@ -449,64 +471,66 @@ namespace AsbCloudInfrastructure.Services
return groupedOperationsList; return groupedOperationsList;
} }
private TelemetryAnalysisDto GetDrillingAnalysis(IEnumerable<TelemetryDataSaubDto> dataSaubBases) private TelemetryAnalysis GetDrillingAnalysis(IEnumerable<TelemetryDataSaub> dataSaubBases)
{ {
var lastSaubDate = dataSaubBases.Last().Date; var lastSaubDate = dataSaubBases.Last().Date;
var saubWellDepths = dataSaubBases.Where(sw => sw.WellDepth is not null) var saubWellDepths = dataSaubBases.Where(sw => sw.WellDepth is not null)
.Select(s => (Value: (double)s.WellDepth, .Select(s => (Y: (double)s.WellDepth,
(s.Date - dataSaubBases.First().Date).TotalSeconds)); X: (s.Date - dataSaubBases.First().Date).TotalSeconds));
var saubBitDepths = dataSaubBases.Where(sw => sw.BitDepth is not null) var saubBitDepths = dataSaubBases.Where(sw => sw.BitDepth is not null)
.Select(s => (Value: (double)s.BitDepth, .Select(s => (Y: (double)s.BitDepth,
(s.Date - dataSaubBases.First().Date).TotalSeconds)); X: (s.Date - dataSaubBases.First().Date).TotalSeconds));
var saubBlockPositions = dataSaubBases.Where(sw => sw.BlockPosition is not null) var saubBlockPositions = dataSaubBases.Where(sw => sw.BlockPosition is not null)
.Select(s => (Value: (double)s.BlockPosition, .Select(s => (Y: (double)s.BlockPosition,
(s.Date - dataSaubBases.First().Date).TotalSeconds)); X: (s.Date - dataSaubBases.First().Date).TotalSeconds));
var saubRotorSpeeds = dataSaubBases.Where(sw => sw.RotorSpeed is not null) var saubRotorSpeeds = dataSaubBases.Where(sw => sw.RotorSpeed is not null)
.Select(s => (Value: (double)s.RotorSpeed, .Select(s => (Y: (double)s.RotorSpeed,
(s.Date - dataSaubBases.First().Date).TotalSeconds)); X: (s.Date - dataSaubBases.First().Date).TotalSeconds));
var saubPressures = dataSaubBases.Where(sw => sw.Pressure is not null) var saubPressures = dataSaubBases.Where(sw => sw.Pressure is not null)
.Select(s => (Value: (double)s.Pressure, .Select(s => (Y: (double)s.Pressure,
(s.Date - dataSaubBases.First().Date).TotalSeconds)); X: (s.Date - dataSaubBases.First().Date).TotalSeconds));
var saubHookWeights = dataSaubBases.Where(sw => sw.HookWeight is not null) var saubHookWeights = dataSaubBases.Where(sw => sw.HookWeight is not null)
.Select(s => (Value: (double)s.HookWeight, .Select(s => (Y: (double)s.HookWeight,
(s.Date - dataSaubBases.First().Date).TotalSeconds)); X: (s.Date - dataSaubBases.First().Date).TotalSeconds));
var wellDepthChangingIndex = new InterpolationLine(saubWellDepths).GetAForLinearFormula(); var wellDepthLine = new InterpolationLine(saubWellDepths);
var bitPositionChangingIndex = new InterpolationLine(saubBitDepths).GetAForLinearFormula(); var bitPositionLine = new InterpolationLine(saubBitDepths);
var blockPositionChangingIndex = new InterpolationLine(saubBlockPositions).GetAForLinearFormula(); var blockPositionLine = new InterpolationLine(saubBlockPositions);
var rotorSpeedChangingIndex = new InterpolationLine(saubRotorSpeeds).GetAForLinearFormula(); var rotorSpeedLine = new InterpolationLine(saubRotorSpeeds);
var pressureChangingIndex = new InterpolationLine(saubPressures).GetAForLinearFormula(); var pressureLine = new InterpolationLine(saubPressures);
var hookWeightChangingIndex = new InterpolationLine(saubHookWeights).GetAForLinearFormula(); var hookWeightLine = new InterpolationLine(saubHookWeights);
var IsBlockRising = InterpolationLine.IsValueDecreases(blockPositionChangingIndex, -0.0001); var IsBlockRising = blockPositionLine.IsYDecreases(-0.0001);
var IsBlockGoesDown = InterpolationLine.IsValueIncreases(blockPositionChangingIndex, 0.0001); var IsBlockGoesDown = blockPositionLine.IsYIncreases(0.0001);
var IsBlockStandsStill = InterpolationLine.IsValueNotChanges(blockPositionChangingIndex, (0.0001, -0.0001)); var IsBlockStandsStill = blockPositionLine.IsYNotChanges(0.0001, -0.0001);
var drillingAnalysis = new TelemetryAnalysisDto var drillingAnalysis = new TelemetryAnalysis
{ {
IdTelemetry = dataSaubBases.First().IdTelemetry, IdTelemetry = dataSaubBases.First().IdTelemetry,
UnixDate = (long)(lastSaubDate - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds, UnixDate = (long)(lastSaubDate - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds,
DurationSec = (int)(dataSaubBases.Last().Date - dataSaubBases.ElementAt(dataSaubBases.Count() - 2).Date).TotalSeconds, DurationSec = (int)(dataSaubBases.Last().Date -
dataSaubBases.ElementAt(dataSaubBases.Count() - 2).Date).TotalSeconds,
OperationStartDepth = null, OperationStartDepth = null,
OperationEndDepth = null, OperationEndDepth = null,
IsWellDepthDecreasing = InterpolationLine.IsValueDecreases(wellDepthChangingIndex, -0.0001), IsWellDepthDecreasing = wellDepthLine.IsYDecreases(-0.0001),
IsWellDepthIncreasing = InterpolationLine.IsValueIncreases(wellDepthChangingIndex, 0.0001), IsWellDepthIncreasing = wellDepthLine.IsYIncreases( 0.0001),
IsBitPositionDecreasing = InterpolationLine.IsValueDecreases(bitPositionChangingIndex, -0.0001), IsBitPositionDecreasing = bitPositionLine.IsYDecreases(-0.0001),
IsBitPositionIncreasing = InterpolationLine.IsValueIncreases(bitPositionChangingIndex, 0.0001), IsBitPositionIncreasing = bitPositionLine.IsYIncreases(0.0001),
IsBitPositionLt20 = InterpolationLine.IsAverageLessThanBound(saubBitDepths, 20), IsBitPositionLt20 = bitPositionLine.IsAverageYLessThanBound(20),
IsBlockPositionDecreasing = InterpolationLine.IsValueDecreases(blockPositionChangingIndex, -0.0001), IsBlockPositionDecreasing = blockPositionLine.IsYDecreases(-0.0001),
IsBlockPositionIncreasing = InterpolationLine.IsValueIncreases(blockPositionChangingIndex, 0.0001), IsBlockPositionIncreasing = blockPositionLine.IsYIncreases(0.0001),
IsRotorSpeedLt3 = InterpolationLine.IsAverageLessThanBound(saubRotorSpeeds, 3), IsRotorSpeedLt3 = rotorSpeedLine.IsAverageYLessThanBound(3),
IsRotorSpeedGt3 = InterpolationLine.IsAverageMoreThanBound(saubRotorSpeeds, 3), IsRotorSpeedGt3 = rotorSpeedLine.IsAverageYMoreThanBound(3),
IsPressureLt20 = InterpolationLine.IsAverageLessThanBound(saubPressures, 20), IsPressureLt20 = pressureLine.IsAverageYLessThanBound(20),
IsPressureGt20 = InterpolationLine.IsAverageMoreThanBound(saubPressures, 20), IsPressureGt20 = pressureLine.IsAverageYMoreThanBound(20),
IsHookWeightNotChanges = InterpolationLine.IsValueNotChanges(hookWeightChangingIndex, (0.0001, -0.0001)), IsHookWeightNotChanges = hookWeightLine.IsYNotChanges(0.0001, -0.0001),
IsHookWeightLt3 = InterpolationLine.IsAverageLessThanBound(saubHookWeights, 3), IsHookWeightLt3 = hookWeightLine.IsAverageYLessThanBound(3),
IdOperation = 1 IdOperation = 1
}; };
drillingAnalysis.IdOperation = operationDetectorService.DetectOperation(drillingAnalysis).Id; drillingAnalysis.IdOperation =
operationDetectorService.DetectOperation(drillingAnalysis).Id;
return drillingAnalysis; return drillingAnalysis;
} }

View File

@ -1,5 +1,4 @@
using AsbCloudApp.Data; using AsbCloudDb.Model;
using AsbCloudDb.Model;
using System; using System;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services
@ -8,6 +7,6 @@ namespace AsbCloudInfrastructure.Services
{ {
public int Order { get; set; } public int Order { get; set; }
public WellOperationCategory Operation { get; set; } public WellOperationCategory Operation { get; set; }
public Func<TelemetryAnalysisDto, bool> Detect { get; set; } public Func<TelemetryAnalysis, bool> Detect { get; set; }
} }
} }

View File

@ -19,8 +19,7 @@ namespace AsbCloudInfrastructure.Services
Operation = operations.FirstOrDefault(o => o.Name.Equals("На поверхности")), Operation = operations.FirstOrDefault(o => o.Name.Equals("На поверхности")),
Detect = (data) => Detect = (data) =>
{ {
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing return data.IsBitPositionLt20 && data.IsHookWeightLt3;
&& data.IsBitPositionLt20 && data.IsHookWeightLt3;
} }
}, },
new TelemetryOperationDetector new TelemetryOperationDetector
@ -42,7 +41,7 @@ namespace AsbCloudInfrastructure.Services
Detect = (data) => Detect = (data) =>
{ {
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing && return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
data.IsBitPositionDecreasing && data.IsBlockPositionDecreasing && data.IsBitPositionDecreasing && data.IsBlockPositionIncreasing &&
data.IsRotorSpeedGt3 && data.IsPressureGt20; data.IsRotorSpeedGt3 && data.IsPressureGt20;
} }
}, },
@ -53,7 +52,7 @@ namespace AsbCloudInfrastructure.Services
Detect = (data) => Detect = (data) =>
{ {
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing && return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
data.IsBitPositionIncreasing && data.IsBitPositionIncreasing && data.IsBitPositionIncreasing && data.IsBlockPositionDecreasing &&
data.IsRotorSpeedGt3 && data.IsPressureGt20; data.IsRotorSpeedGt3 && data.IsPressureGt20;
} }
}, },
@ -64,7 +63,7 @@ namespace AsbCloudInfrastructure.Services
Detect = (data) => Detect = (data) =>
{ {
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing && return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
data.IsBitPositionDecreasing && data.IsBitPositionDecreasing && data.IsBitPositionDecreasing && data.IsBlockPositionIncreasing &&
data.IsRotorSpeedLt3 && data.IsPressureGt20; data.IsRotorSpeedLt3 && data.IsPressureGt20;
} }
}, },
@ -75,7 +74,7 @@ namespace AsbCloudInfrastructure.Services
Detect = (data) => Detect = (data) =>
{ {
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing && return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
data.IsBitPositionIncreasing && data.IsBlockPositionIncreasing && data.IsBitPositionIncreasing && data.IsBlockPositionDecreasing &&
data.IsRotorSpeedLt3 && data.IsPressureGt20; data.IsRotorSpeedLt3 && data.IsPressureGt20;
} }
}, },
@ -86,7 +85,7 @@ namespace AsbCloudInfrastructure.Services
Detect = (data) => Detect = (data) =>
{ {
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing && return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
data.IsBitPositionIncreasing && data.IsBlockPositionIncreasing && data.IsBitPositionIncreasing && data.IsBlockPositionDecreasing &&
data.IsRotorSpeedLt3 && data.IsPressureLt20; data.IsRotorSpeedLt3 && data.IsPressureLt20;
} }
}, },
@ -97,7 +96,7 @@ namespace AsbCloudInfrastructure.Services
Detect = (data) => Detect = (data) =>
{ {
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing && return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
data.IsBitPositionIncreasing && data.IsBlockPositionIncreasing && data.IsBitPositionIncreasing && data.IsBlockPositionDecreasing &&
data.IsRotorSpeedGt3 && data.IsPressureLt20; data.IsRotorSpeedGt3 && data.IsPressureLt20;
} }
}, },
@ -108,7 +107,7 @@ namespace AsbCloudInfrastructure.Services
Detect = (data) => Detect = (data) =>
{ {
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing && return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
data.IsBitPositionDecreasing && data.IsBlockPositionDecreasing && data.IsBitPositionDecreasing && data.IsBlockPositionIncreasing &&
data.IsRotorSpeedLt3 && data.IsPressureLt20; data.IsRotorSpeedLt3 && data.IsPressureLt20;
} }
}, },
@ -119,7 +118,7 @@ namespace AsbCloudInfrastructure.Services
Detect = (data) => Detect = (data) =>
{ {
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing && return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
data.IsBitPositionDecreasing && data.IsBlockPositionDecreasing && data.IsBitPositionDecreasing && data.IsBlockPositionIncreasing &&
data.IsRotorSpeedGt3 && data.IsPressureLt20; data.IsRotorSpeedGt3 && data.IsPressureLt20;
} }
}, },
@ -180,7 +179,7 @@ namespace AsbCloudInfrastructure.Services
}; };
} }
public WellOperationCategory DetectOperation(TelemetryAnalysisDto data) => public WellOperationCategory DetectOperation(TelemetryAnalysis data) =>
detectors.OrderBy(d => d.Order).First(o => o.Detect(data)).Operation detectors.OrderBy(d => d.Order).First(o => o.Detect(data)).Operation
?? new WellOperationCategory { Id = 1, Name = "Невозможно определить операцию" }; ?? new WellOperationCategory { Id = 1, Name = "Невозможно определить операцию" };
} }