forked from ddrilling/AsbCloudServer
Fixed telemetry analytics calculation logic
This commit is contained in:
parent
b60b84b45c
commit
a589775ceb
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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";
|
||||||
|
@ -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>();
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 = "Невозможно определить операцию" };
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user