DD.WellWorkover.Cloud/AsbCloudInfrastructure/Background/PeriodicWorks/WorkProcessMapDrillingCache.cs

123 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AsbCloudDb.Model;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Background.PeriodicWorks
{
internal class WorkProcessMapDrillingCache : Work
{
private int MechanicalDrillingCategoryId = 4001;
public WorkProcessMapDrillingCache() : base("Generate process map drilling cache table")
{
Timeout = TimeSpan.FromMinutes(10);
}
protected override Task Action(string id, IServiceProvider services, Action<string, double?> onProgressCallback, CancellationToken token)
{
//1 найти последнюю запись в кеш-таблице (по полям "Дата до")
//2 определяем дату с которой начинаем анализ
//3 находим автоопределнные операции по скважине, начиная с начальной даты из пункта 2
// 3.1 только те, которые связанные с бурением (idParent = 4001)
// 3.2 выбираем 500 операций
// 3.3. выбираем минимальную дату начала и максимальную дату окончания
//4 по полученным в пункте выше данным выбираем записи из telemetry_data_saub
// 4.1.выбираем те у которых (bit_depth == well_depth)
//5. для каждой операции из 3.2 находим соответствующий ей кусок телеметрии (по дате начала и окончания)
// и храним индексы этого куска в виде span
//6. кусок телеметрии, полученный в пункте 5 (span) и соответствующая ей операция направляется на разбивку диапазонов
//7/ разбивка диапазонов:
// параметры метода: массив из
using var db = services.GetRequiredService<IAsbCloudDbContext>();
var dateFrom = db.ProcessMapDrillingCache.OrderByDescending(c => c.DateTo).FirstOrDefault()?.DateTo ?? DateTimeOffset.MinValue;
//а остальные операции, которые не вошли в 500 первых?
var detectedOperations = db.DetectedOperations
.Where(o => o.DateStart > dateFrom)
.Where(o => o.OperationCategory.IdParent == MechanicalDrillingCategoryId)
.Take(500)
.ToArray();
var minDate = detectedOperations.Min(o => o.DateStart);
var maxDate = detectedOperations.Max(o => o.DateEnd);
var telemetryDataSaub = db.TelemetryDataSaub
.Where(t => t.DateTime >= minDate)
.Where(t => t.DateTime <= maxDate)
.Where(t => t.BitDepth == t.WellDepth)
.OrderBy(t => t.DateTime)
.ToArray();
var result = new List<ProcessMapDrillingCacheItem>();
foreach (var operation in detectedOperations)
{
var indexStart = 0;
var length = 0;
foreach (var telemetryDataSaubItem in telemetryDataSaub)
{
if(operation.DateStart <= telemetryDataSaubItem.DateTime && operation.DateEnd >= telemetryDataSaubItem.DateTime)
{
length++;
}
else if (length > 0)
{
var subset = telemetryDataSaub.AsSpan(indexStart, length);
var ranges = getRanges(subset, operation);
result.AddRange(ranges);
break;
}
indexStart++;
}
}
return Task.CompletedTask;
}
private List<ProcessMapDrillingCacheItem> getRanges(Span<TelemetryDataSaub> span, DetectedOperation operation)
{
var result = new List<ProcessMapDrillingCacheItem>();
var cacheItem = new ProcessMapDrillingCacheItem();
cacheItem.Elems.Add(span[0]);
result.Add(cacheItem);
for (var i=1; i<span.Length; i++)
{
var prev = span[i-1];
var current = span[i];
var isNewCacheItem = !(current.Mode == prev.Mode);
isNewCacheItem = isNewCacheItem || !(current.BlockSpeedSp == prev.BlockSpeedSp);
isNewCacheItem = isNewCacheItem || !(current.PressureIdle == prev.PressureIdle);
isNewCacheItem = isNewCacheItem || !(current.PressureSp == prev.PressureSp);
isNewCacheItem = isNewCacheItem || !(current.AxialLoadSp == prev.AxialLoadSp);
isNewCacheItem = isNewCacheItem || !(current.AxialLoadLimitMax == prev.AxialLoadLimitMax);
isNewCacheItem = isNewCacheItem || !(current.HookWeightIdle == prev.HookWeightIdle);
isNewCacheItem = isNewCacheItem || !(current.RotorTorqueIdle == prev.RotorTorqueIdle);
isNewCacheItem = isNewCacheItem || !(current.RotorTorqueSp == prev.RotorTorqueSp);
isNewCacheItem = isNewCacheItem || !(current.RotorTorqueLimitMax == prev.RotorTorqueLimitMax);
isNewCacheItem = isNewCacheItem || !(current.IdFeedRegulator == prev.IdFeedRegulator);
if (isNewCacheItem)
{
cacheItem = new ProcessMapDrillingCacheItem();
result.Add(cacheItem);
}
cacheItem.Elems.Add(current);
}
return result;
}
}
internal class ProcessMapDrillingCacheItem
{
public List<TelemetryDataSaub> Elems = new List<TelemetryDataSaub>();
}
}