diff --git a/AsbCloudApp/Repositories/ITelemetryDataCache.cs b/AsbCloudApp/Repositories/ITelemetryDataCache.cs
index bce8d328..f90f2ac4 100644
--- a/AsbCloudApp/Repositories/ITelemetryDataCache.cs
+++ b/AsbCloudApp/Repositories/ITelemetryDataCache.cs
@@ -72,5 +72,12 @@ namespace AsbCloudApp.Repositories
///
///
IEnumerable GetStat();
+
+ ///
+ /// Получить ключи телеметрии по параметрам запроса
+ ///
+ ///
+ ///
+ IEnumerable? GetIds(TelemetryDataRequest request);
}
}
\ No newline at end of file
diff --git a/AsbCloudDb/Migrations/20240131104814_Add_Table_DataSaubStat.Designer.cs b/AsbCloudDb/Migrations/20240201060511_Add_Table_DataSaubStat.Designer.cs
similarity index 99%
rename from AsbCloudDb/Migrations/20240131104814_Add_Table_DataSaubStat.Designer.cs
rename to AsbCloudDb/Migrations/20240201060511_Add_Table_DataSaubStat.Designer.cs
index 953a220c..702cb1ea 100644
--- a/AsbCloudDb/Migrations/20240131104814_Add_Table_DataSaubStat.Designer.cs
+++ b/AsbCloudDb/Migrations/20240201060511_Add_Table_DataSaubStat.Designer.cs
@@ -13,7 +13,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace AsbCloudDb.Migrations
{
[DbContext(typeof(AsbCloudDbContext))]
- [Migration("20240131104814_Add_Table_DataSaubStat")]
+ [Migration("20240201060511_Add_Table_DataSaubStat")]
partial class Add_Table_DataSaubStat
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@@ -368,11 +368,6 @@ namespace AsbCloudDb.Migrations
.HasColumnName("depth_start")
.HasComment("Глубина забоя по стволу начальная");
- b.Property("DetectedOperationCategoryId")
- .HasColumnType("integer")
- .HasColumnName("detected_operation_category_id")
- .HasComment("Название автоопределённой операции");
-
b.Property("EnabledSubsystems")
.HasColumnType("integer")
.HasColumnName("enabled_subsystems")
@@ -388,6 +383,11 @@ namespace AsbCloudDb.Migrations
.HasColumnName("has_oscillation")
.HasComment("Наличие или отсутствие осцилляции");
+ b.Property("IdCategory")
+ .HasColumnType("integer")
+ .HasColumnName("id_category")
+ .HasComment("Название автоопределённой операции");
+
b.Property("IdFeedRegulator")
.HasColumnType("smallint")
.HasColumnName("id_feed_regulator")
@@ -440,6 +440,8 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id");
+ b.HasIndex("IdCategory");
+
b.HasIndex("IdTelemetry");
b.ToTable("t_data_saub_stat");
@@ -8424,12 +8426,20 @@ namespace AsbCloudDb.Migrations
modelBuilder.Entity("AsbCloudDb.Model.DataSaubStat", b =>
{
+ b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory")
+ .WithMany()
+ .HasForeignKey("IdCategory")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry")
.WithMany()
.HasForeignKey("IdTelemetry")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
+ b.Navigation("OperationCategory");
+
b.Navigation("Telemetry");
});
diff --git a/AsbCloudDb/Migrations/20240131104814_Add_Table_DataSaubStat.cs b/AsbCloudDb/Migrations/20240201060511_Add_Table_DataSaubStat.cs
similarity index 87%
rename from AsbCloudDb/Migrations/20240131104814_Add_Table_DataSaubStat.cs
rename to AsbCloudDb/Migrations/20240201060511_Add_Table_DataSaubStat.cs
index a2b6d38f..fbe4048e 100644
--- a/AsbCloudDb/Migrations/20240131104814_Add_Table_DataSaubStat.cs
+++ b/AsbCloudDb/Migrations/20240201060511_Add_Table_DataSaubStat.cs
@@ -33,7 +33,7 @@ namespace AsbCloudDb.Migrations
rotor_torque_limit_max = table.Column(type: "double precision", nullable: true, comment: "Максимально допустимый момент"),
id_feed_regulator = table.Column(type: "smallint", nullable: true, comment: "Работа при достижении ограничения"),
rotor_speed = table.Column(type: "double precision", nullable: false, comment: "Фактическая скорость оборотов ВСП"),
- detected_operation_category_id = table.Column(type: "integer", nullable: false, comment: "Название автоопределённой операции"),
+ id_category = table.Column(type: "integer", nullable: false, comment: "Название автоопределённой операции"),
enabled_subsystems = table.Column(type: "integer", nullable: false, comment: "Флаги подсистем"),
has_oscillation = table.Column(type: "boolean", nullable: false, comment: "Наличие или отсутствие осцилляции"),
flow = table.Column(type: "double precision", nullable: false, comment: "Фактический расход"),
@@ -48,9 +48,20 @@ namespace AsbCloudDb.Migrations
principalTable: "t_telemetry",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_t_data_saub_stat_t_well_operation_category_id_category",
+ column: x => x.id_category,
+ principalTable: "t_well_operation_category",
+ principalColumn: "id",
+ onDelete: ReferentialAction.Cascade);
},
comment: "Кеш-таблица для хранения данных для РТК-отчета");
+ migrationBuilder.CreateIndex(
+ name: "IX_t_data_saub_stat_id_category",
+ table: "t_data_saub_stat",
+ column: "id_category");
+
migrationBuilder.CreateIndex(
name: "IX_t_data_saub_stat_id_telemetry",
table: "t_data_saub_stat",
diff --git a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs
index 82cd365a..eeb9ad9b 100644
--- a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs
+++ b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs
@@ -366,11 +366,6 @@ namespace AsbCloudDb.Migrations
.HasColumnName("depth_start")
.HasComment("Глубина забоя по стволу начальная");
- b.Property("DetectedOperationCategoryId")
- .HasColumnType("integer")
- .HasColumnName("detected_operation_category_id")
- .HasComment("Название автоопределённой операции");
-
b.Property("EnabledSubsystems")
.HasColumnType("integer")
.HasColumnName("enabled_subsystems")
@@ -386,6 +381,11 @@ namespace AsbCloudDb.Migrations
.HasColumnName("has_oscillation")
.HasComment("Наличие или отсутствие осцилляции");
+ b.Property("IdCategory")
+ .HasColumnType("integer")
+ .HasColumnName("id_category")
+ .HasComment("Название автоопределённой операции");
+
b.Property("IdFeedRegulator")
.HasColumnType("smallint")
.HasColumnName("id_feed_regulator")
@@ -438,6 +438,8 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id");
+ b.HasIndex("IdCategory");
+
b.HasIndex("IdTelemetry");
b.ToTable("t_data_saub_stat");
@@ -8422,12 +8424,20 @@ namespace AsbCloudDb.Migrations
modelBuilder.Entity("AsbCloudDb.Model.DataSaubStat", b =>
{
+ b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory")
+ .WithMany()
+ .HasForeignKey("IdCategory")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry")
.WithMany()
.HasForeignKey("IdTelemetry")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
+ b.Navigation("OperationCategory");
+
b.Navigation("Telemetry");
});
diff --git a/AsbCloudDb/Model/DataSaubStat.cs b/AsbCloudDb/Model/DataSaubStat.cs
index 8b22367b..8871b598 100644
--- a/AsbCloudDb/Model/DataSaubStat.cs
+++ b/AsbCloudDb/Model/DataSaubStat.cs
@@ -64,8 +64,8 @@ namespace AsbCloudDb.Model
[Column("rotor_speed"), Comment("Фактическая скорость оборотов ВСП")]
public double RotorSpeed { get; set; }
- [Column("detected_operation_category_id"), Comment("Название автоопределённой операции")]
- public int DetectedOperationCategoryId { get; set; }
+ [Column("id_category"), Comment("Название автоопределённой операции")]
+ public int IdCategory { get; set; }
[Column("enabled_subsystems"), Comment("Флаги подсистем")]
public int EnabledSubsystems { get; set; }
@@ -81,5 +81,9 @@ namespace AsbCloudDb.Model
[ForeignKey(nameof(IdTelemetry))]
public virtual Telemetry Telemetry { get; set; } = null!;
+
+ [JsonIgnore]
+ [ForeignKey(nameof(IdCategory))]
+ public virtual WellOperationCategory OperationCategory { get; set; } = null!;
}
}
diff --git a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs
index 15f3cd34..8369ffa2 100644
--- a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs
+++ b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs
@@ -1,7 +1,12 @@
-using AsbCloudDb.Model;
+using AsbCloudApp.Data.SAUB;
+using AsbCloudApp.Repositories;
+using AsbCloudApp.Requests;
+using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
+using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -14,72 +19,81 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
internal class WorkDataSaubStat : Work
{
private int MechanicalDrillingCategoryId = 4001;
+ private int Gap = 60;
public WorkDataSaubStat() : base("Generate DataSaubStat entries and save them into Db")
{
Timeout = TimeSpan.FromMinutes(10);
}
- protected override Task Action(string id, IServiceProvider services, Action onProgressCallback, CancellationToken token)
+ protected override async Task Action(string id, IServiceProvider services, Action 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();
+ var telemetryDataCache = services.GetRequiredService>();
+
+ var telemetryIds = telemetryDataCache.GetIds(new TelemetryDataRequest()
+ {
+ GeDate = DateTime.UtcNow.AddDays(-Gap)
+ });
+
+ if (telemetryIds == null || !telemetryIds.Any())
+ return;
+
var dateEnd = db.Set()
.OrderByDescending(c => c.DateEnd)
.FirstOrDefault()?.DateEnd
?? DateTimeOffset.MinValue;
- var detectedOperations = db.Set()
+ var detectedOperations = await db.Set()
.Where(o => o.DateStart > dateEnd)
.Where(o => o.OperationCategory.IdParent == MechanicalDrillingCategoryId)
+ .Where(o => telemetryIds.Contains(o.IdTelemetry))
.OrderBy(o => o.DateStart)
.Take(500)
- .ToArray();
+ .ToArrayAsync(token);
+
+ if (!detectedOperations.Any())
+ return;
var minDate = detectedOperations.FirstOrDefault()?.DateStart;
var maxDate = detectedOperations.OrderByDescending(d => d.DateEnd).FirstOrDefault()?.DateEnd;
- var telemetryDataSaub = db.Set()
+ var telemetryDataSaub = (await db.Set()
.Where(t => t.DateTime >= minDate)
.Where(t => t.DateTime <= maxDate)
.Where(t => Math.Abs(t.BitDepth - t.WellDepth) < 0.0001)
- .OrderBy(t => t.DateTime)
- .ToArray();
+ .Where(t => telemetryIds.Contains(t.IdTelemetry))
+ .ToArrayAsync(token))
+ .GroupBy(t => t.IdTelemetry)
+ .ToDictionary(g => g.Key, g => g.OrderBy(t => t.DateTime).ToArray());
+ CreateDataSaubStat(db, detectedOperations, telemetryDataSaub);
+ }
+
+ private static void CreateDataSaubStat(IAsbCloudDbContext db, DetectedOperation[] detectedOperations, Dictionary telemetryDataSaub)
+ {
var indexStart = 0;
var indexEnd = 0;
foreach (var operation in detectedOperations)
{
- indexStart = Array.FindIndex(telemetryDataSaub, indexEnd, t => t.DateTime >= operation.DateStart);
- indexEnd = Array.FindIndex(telemetryDataSaub, indexStart, t => t.DateTime > operation.DateEnd) - 1;
+ if (!telemetryDataSaub.TryGetValue(operation.IdTelemetry, out TelemetryDataSaub[]? telemetryDataSaubPart))
+ break;
+
+ indexStart = Array.FindIndex(telemetryDataSaubPart, indexEnd, t => t.DateTime >= operation.DateStart);
+ indexEnd = Array.FindIndex(telemetryDataSaubPart, indexStart, t => t.DateTime > operation.DateEnd) - 1;
if (indexStart >= 0 && indexEnd >= indexStart)
{
var length = indexEnd - indexStart;
- var subset = telemetryDataSaub.AsSpan(indexStart, length + 1);
- var result = CalcStats(operation, subset, db);
+ var subset = telemetryDataSaubPart.AsSpan(indexStart, length + 1);
+ CalcStats(operation, subset, db);
+ db.SaveChanges();
}
}
-
- return Task.CompletedTask;
}
- private int CalcStats(DetectedOperation operation, Span telemetryDataSaub, IAsbCloudDbContext db)
+ private static void CalcStats(DetectedOperation operation, Span telemetryDataSaub, IAsbCloudDbContext db)
{
var indexStart = 0;
for (var i = 1; i < telemetryDataSaub.Length; i++)
@@ -96,15 +110,14 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
db.Set().Add(dataSaubStatItem);
}
}
- return db.SaveChanges();
}
- private DataSaubStat CalcStat(DetectedOperation operation, Span span)
+ private static DataSaubStat CalcStat(DetectedOperation operation, Span span)
{
var hasOscillation = operation.ExtraData.TryGetValue(DetectorDrilling.ExtraDataKeyHasOscillation, out object? hasOscillationObject)
&& hasOscillationObject is true;
- var wavg = CalcWavg(span);
+ var aggregatedValues = CalcAggregate(span);
var processMapDrillingCacheItem = new DataSaubStat
{
DateStart = operation.DateStart,
@@ -113,33 +126,33 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
DepthEnd = operation.DepthEnd,
Speed = (operation.DepthEnd - operation.DepthStart) / ((operation.DateEnd - operation.DateStart).TotalHours),
BlockSpeedSp = span[0].BlockSpeedSp,
- Pressure = wavg.Pressure,
+ Pressure = aggregatedValues.Pressure,
PressureIdle = span[0].PressureIdle,
PressureSp = span[0].PressureSp,
- AxialLoad = wavg.AxialLoad,
+ AxialLoad = aggregatedValues.AxialLoad,
AxialLoadSp = span[0].AxialLoadSp,
AxialLoadLimitMax = span[0].AxialLoadLimitMax,
- RotorTorque = wavg.RotorTorque,
+ RotorTorque = aggregatedValues.RotorTorque,
RotorTorqueSp = span[0].RotorTorqueSp,
RotorTorqueLimitMax = span[0].RotorTorqueLimitMax,
IdFeedRegulator = span[0].IdFeedRegulator,
- RotorSpeed = wavg.RotorSpeed,
- DetectedOperationCategoryId = operation.IdCategory,
+ RotorSpeed = aggregatedValues.RotorSpeed,
+ IdCategory = operation.IdCategory,
EnabledSubsystems = operation.EnabledSubsystems,
HasOscillation = hasOscillation,
IdTelemetry = operation.IdTelemetry,
- Flow = wavg.Flow
+ Flow = aggregatedValues.Flow
};
return processMapDrillingCacheItem;
}
- private (
+ private static (
double Pressure,
double AxialLoad,
double RotorTorque,
double RotorSpeed,
double Flow
- ) CalcWavg(Span span)
+ ) CalcAggregate(Span span)
{
var sumPressure = 0.0;
var sumAxialLoad = 0.0;
@@ -154,7 +167,7 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
sumAxialLoad += weigth * span[i].AxialLoad;
sumRotorTorque += weigth * span[i].RotorTorque;
sumRotorSpeed += weigth * span[i].RotorSpeed;
- flow = span[i + 1].Flow > flow ? span[i + 1].Flow ?? 0.0 :flow;
+ flow = span[i + 1].Flow > flow ? span[i + 1].Flow ?? 0.0 : flow;
}
return (
Pressure: sumPressure / diffDepthTotal,
@@ -165,7 +178,7 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
);
}
- private bool IsNewCacheItem(TelemetryDataSaub previous, TelemetryDataSaub current)
+ private static bool IsNewCacheItem(TelemetryDataSaub previous, TelemetryDataSaub current)
{
return !(current.Mode == previous.Mode)
|| !(current.BlockSpeedSp == previous.BlockSpeedSp)
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
index 99983dd5..fef27bc3 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
@@ -324,5 +324,27 @@ namespace AsbCloudInfrastructure.Services.SAUB
return data;
}
+
+ public IEnumerable? GetIds(TelemetryDataRequest request)
+ {
+ var data = new Dictionary();
+
+ if (request.GeDate.HasValue)
+ {
+ data = caches
+ .Where(item => item.Value.LastData.Any(d => d.DateTime >= request.GeDate.Value.ToRemoteDateTime(item.Value.TimezoneHours)))
+ .ToDictionary(item => item.Key, item => item.Value);
+ }
+
+ if (request.LeDate.HasValue)
+ {
+ data = caches
+ .Where(item => item.Value.LastData.Any(d => d.DateTime <= request.LeDate.Value.ToRemoteDateTime(item.Value.TimezoneHours)))
+ .ToDictionary(item => item.Key, item => item.Value);
+ }
+
+ var telemetryIds = data.Select(item => item.Key);
+ return telemetryIds;
+ }
}
}