forked from ddrilling/AsbCloudServer
Remove legacy telemetry analysis, except db model
This commit is contained in:
parent
be8287f041
commit
579b5f26da
@ -1,26 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data
|
|
||||||
{
|
|
||||||
public class TelemetryAnalysisDto : IId
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public int IdTelemetry { get; set; }
|
|
||||||
public int IdOperation { get; set; }
|
|
||||||
public long UnixDate { get; set; }
|
|
||||||
public int DurationSec { get; set; }
|
|
||||||
public double? OperationStartDepth { get; set; }
|
|
||||||
public double? OperationEndDepth { get; set; }
|
|
||||||
public bool IsWellDepthIncreasing { get; set; }
|
|
||||||
public bool IsWellDepthDecreasing { get; set; }
|
|
||||||
public bool IsBitPositionIncreasing { get; set; }
|
|
||||||
public bool IsBitPositionDecreasing { get; set; }
|
|
||||||
public bool IsBitPositionLt20 { get; set; }
|
|
||||||
public bool IsBlockPositionIncreasing { get; set; }
|
|
||||||
public bool IsBlockPositionDecreasing { get; set; }
|
|
||||||
public bool IsRotorSpeedLt3 { get; set; }
|
|
||||||
public bool IsRotorSpeedGt3 { get; set; }
|
|
||||||
public bool IsPressureLt20 { get; set; }
|
|
||||||
public bool IsPressureGt20 { get; set; }
|
|
||||||
public bool IsHookWeightNotChanges { get; set; }
|
|
||||||
public bool IsHookWeightLt3 { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data
|
|
||||||
{
|
|
||||||
public class TelemetryOperationDetailsDto
|
|
||||||
{
|
|
||||||
public string OperationName { get; set; }
|
|
||||||
public int DurationSec { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Data
|
|
||||||
{
|
|
||||||
public class TelemetryOperationDto : IId
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string Name { get; set; }
|
|
||||||
public DateTime BeginDate { get; set; }
|
|
||||||
public DateTime EndDate { get; set; }
|
|
||||||
public double StartWellDepth { get; set; }
|
|
||||||
public double EndWellDepth { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data
|
|
||||||
{
|
|
||||||
public class TelemetryOperationDurationDto
|
|
||||||
{
|
|
||||||
public string OperationName { get; set; }
|
|
||||||
public double Duration { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Data
|
|
||||||
{
|
|
||||||
public class TelemetryOperationInfoDto
|
|
||||||
{
|
|
||||||
public DateTime IntervalBegin { get; set; }
|
|
||||||
public IList<TelemetryOperationDetailsDto> Operations { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Data
|
|
||||||
{
|
|
||||||
public class WellDepthToDayDto
|
|
||||||
{
|
|
||||||
public double WellDepth { get; set; }
|
|
||||||
public double BitDepth { get; set; }
|
|
||||||
public DateTime Date { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Data
|
|
||||||
{
|
|
||||||
public class WellDepthToIntervalDto
|
|
||||||
{
|
|
||||||
public DateTime IntervalStartDate { get; set; }
|
|
||||||
public double IntervalDepthProgress { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Services
|
|
||||||
{
|
|
||||||
public interface ITelemetryAnalyticsService
|
|
||||||
{
|
|
||||||
Task<PaginationContainer<TelemetryOperationDto>> GetOperationsByWellAsync(int idWell,
|
|
||||||
IEnumerable<int> categoryids = default, DateTime begin = default,
|
|
||||||
DateTime end = default, int skip = 0, int take = 32,
|
|
||||||
CancellationToken token = default);
|
|
||||||
Task<IEnumerable<WellDepthToDayDto>> GetWellDepthToDayAsync(int idWell,
|
|
||||||
CancellationToken token = default);
|
|
||||||
Task<IEnumerable<WellDepthToIntervalDto>> GetWellDepthToIntervalAsync(int idWell,
|
|
||||||
int intervalHoursTimestamp, int shiftStartSec,
|
|
||||||
CancellationToken token = default);
|
|
||||||
Task<IEnumerable<TelemetryOperationDurationDto>> GetOperationsSummaryAsync(int idWell,
|
|
||||||
DateTime begin = default, DateTime end = default,
|
|
||||||
CancellationToken token = default);
|
|
||||||
Task<IEnumerable<TelemetryOperationInfoDto>> GetOperationsToIntervalAsync(int idWell,
|
|
||||||
int intervalHoursTimestamp, int workBeginTimestamp,
|
|
||||||
CancellationToken token = default);
|
|
||||||
Task AnalyzeAndSaveTelemetriesAsync(CancellationToken token = default);
|
|
||||||
Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell,
|
|
||||||
CancellationToken token = default);
|
|
||||||
}
|
|
||||||
}
|
|
@ -61,7 +61,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdDeposit");
|
b.HasIndex("IdDeposit");
|
||||||
|
|
||||||
b.ToTable("t_cluster");
|
b.ToTable("t_cluster", (string)null);
|
||||||
|
|
||||||
b.HasComment("Кусты");
|
b.HasComment("Кусты");
|
||||||
});
|
});
|
||||||
@ -90,7 +90,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdCompanyType");
|
b.HasIndex("IdCompanyType");
|
||||||
|
|
||||||
b.ToTable("t_company");
|
b.ToTable("t_company", (string)null);
|
||||||
|
|
||||||
b.HasData(
|
b.HasData(
|
||||||
new
|
new
|
||||||
@ -117,7 +117,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("t_company_type");
|
b.ToTable("t_company_type", (string)null);
|
||||||
|
|
||||||
b.HasData(
|
b.HasData(
|
||||||
new
|
new
|
||||||
@ -166,7 +166,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("t_deposit");
|
b.ToTable("t_deposit", (string)null);
|
||||||
|
|
||||||
b.HasComment("Месторождение");
|
b.HasComment("Месторождение");
|
||||||
});
|
});
|
||||||
@ -220,7 +220,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdTelemetry");
|
b.HasIndex("IdTelemetry");
|
||||||
|
|
||||||
b.ToTable("t_detected_operation");
|
b.ToTable("t_detected_operation", (string)null);
|
||||||
|
|
||||||
b.HasComment("автоматически определенные операции по телеметрии");
|
b.HasComment("автоматически определенные операции по телеметрии");
|
||||||
});
|
});
|
||||||
@ -315,7 +315,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdWellOperationCategory");
|
b.HasIndex("IdWellOperationCategory");
|
||||||
|
|
||||||
b.ToTable("t_drill_flow_chart");
|
b.ToTable("t_drill_flow_chart", (string)null);
|
||||||
|
|
||||||
b.HasComment("Параметры коридоров бурения (диапазоны параметров бурения)");
|
b.HasComment("Параметры коридоров бурения (диапазоны параметров бурения)");
|
||||||
});
|
});
|
||||||
@ -344,7 +344,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
b.HasIndex("IdWell", "IdFileCategory")
|
b.HasIndex("IdWell", "IdFileCategory")
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("t_drilling_program_part");
|
b.ToTable("t_drilling_program_part", (string)null);
|
||||||
|
|
||||||
b.HasComment("части программ бурения");
|
b.HasComment("части программ бурения");
|
||||||
});
|
});
|
||||||
@ -459,7 +459,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdWellSectionType");
|
b.HasIndex("IdWellSectionType");
|
||||||
|
|
||||||
b.ToTable("t_drill_params");
|
b.ToTable("t_drill_params", (string)null);
|
||||||
|
|
||||||
b.HasComment("Режим бурения в секции (диапазоны параметров бурения)");
|
b.HasComment("Режим бурения в секции (диапазоны параметров бурения)");
|
||||||
});
|
});
|
||||||
@ -485,7 +485,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("t_file_category");
|
b.ToTable("t_file_category", (string)null);
|
||||||
|
|
||||||
b.HasComment("Категории файлов");
|
b.HasComment("Категории файлов");
|
||||||
|
|
||||||
@ -659,7 +659,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdWell");
|
b.HasIndex("IdWell");
|
||||||
|
|
||||||
b.ToTable("t_file_info");
|
b.ToTable("t_file_info", (string)null);
|
||||||
|
|
||||||
b.HasComment("Файлы всех категорий");
|
b.HasComment("Файлы всех категорий");
|
||||||
});
|
});
|
||||||
@ -710,7 +710,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdUser");
|
b.HasIndex("IdUser");
|
||||||
|
|
||||||
b.ToTable("t_file_mark");
|
b.ToTable("t_file_mark", (string)null);
|
||||||
|
|
||||||
b.HasComment("Действия с файлами.");
|
b.HasComment("Действия с файлами.");
|
||||||
});
|
});
|
||||||
@ -755,7 +755,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdWell");
|
b.HasIndex("IdWell");
|
||||||
|
|
||||||
b.ToTable("t_measure");
|
b.ToTable("t_measure", (string)null);
|
||||||
|
|
||||||
b.HasComment("Таблица c данными для вкладки 'Последние данные'");
|
b.HasComment("Таблица c данными для вкладки 'Последние данные'");
|
||||||
});
|
});
|
||||||
@ -781,7 +781,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("t_measure_category");
|
b.ToTable("t_measure_category", (string)null);
|
||||||
|
|
||||||
b.HasComment("Категория последних данных");
|
b.HasComment("Категория последних данных");
|
||||||
|
|
||||||
@ -829,7 +829,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("t_permission");
|
b.ToTable("t_permission", (string)null);
|
||||||
|
|
||||||
b.HasComment("Разрешения на доступ к данным");
|
b.HasComment("Разрешения на доступ к данным");
|
||||||
|
|
||||||
@ -1432,7 +1432,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdWell");
|
b.HasIndex("IdWell");
|
||||||
|
|
||||||
b.ToTable("t_relation_company_well");
|
b.ToTable("t_relation_company_well", (string)null);
|
||||||
|
|
||||||
b.HasComment("отношение скважин и компаний");
|
b.HasComment("отношение скважин и компаний");
|
||||||
});
|
});
|
||||||
@ -1457,7 +1457,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdDrillingProgramPart");
|
b.HasIndex("IdDrillingProgramPart");
|
||||||
|
|
||||||
b.ToTable("t_relation_user_drilling_program_part");
|
b.ToTable("t_relation_user_drilling_program_part", (string)null);
|
||||||
|
|
||||||
b.HasComment("Отношение пользователей и частей ПБ");
|
b.HasComment("Отношение пользователей и частей ПБ");
|
||||||
});
|
});
|
||||||
@ -1476,7 +1476,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdPermission");
|
b.HasIndex("IdPermission");
|
||||||
|
|
||||||
b.ToTable("t_relation_user_role_permission");
|
b.ToTable("t_relation_user_role_permission", (string)null);
|
||||||
|
|
||||||
b.HasComment("Отношение ролей пользователей и разрешений доступа");
|
b.HasComment("Отношение ролей пользователей и разрешений доступа");
|
||||||
|
|
||||||
@ -2058,7 +2058,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdInclude");
|
b.HasIndex("IdInclude");
|
||||||
|
|
||||||
b.ToTable("t_relation_user_role_user_role");
|
b.ToTable("t_relation_user_role_user_role", (string)null);
|
||||||
|
|
||||||
b.HasComment("Отношение ролей к ролям");
|
b.HasComment("Отношение ролей к ролям");
|
||||||
|
|
||||||
@ -2349,7 +2349,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdUserRole");
|
b.HasIndex("IdUserRole");
|
||||||
|
|
||||||
b.ToTable("t_relation_user_user_role");
|
b.ToTable("t_relation_user_user_role", (string)null);
|
||||||
|
|
||||||
b.HasComment("Отношение пользователей и ролей");
|
b.HasComment("Отношение пользователей и ролей");
|
||||||
|
|
||||||
@ -2405,7 +2405,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdWell");
|
b.HasIndex("IdWell");
|
||||||
|
|
||||||
b.ToTable("t_report_property");
|
b.ToTable("t_report_property", (string)null);
|
||||||
|
|
||||||
b.HasComment("Отчеты с данными по буровым");
|
b.HasComment("Отчеты с данными по буровым");
|
||||||
});
|
});
|
||||||
@ -2459,7 +2459,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdWell");
|
b.HasIndex("IdWell");
|
||||||
|
|
||||||
b.ToTable("t_setpoints_rquest");
|
b.ToTable("t_setpoints_rquest", (string)null);
|
||||||
|
|
||||||
b.HasComment("Запросы на изменение уставок панели оператора");
|
b.HasComment("Запросы на изменение уставок панели оператора");
|
||||||
});
|
});
|
||||||
@ -2492,7 +2492,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex(new[] { "RemoteUid" }, "t_telemetry_remote_uid_index");
|
b.HasIndex(new[] { "RemoteUid" }, "t_telemetry_remote_uid_index");
|
||||||
|
|
||||||
b.ToTable("t_telemetry");
|
b.ToTable("t_telemetry", (string)null);
|
||||||
|
|
||||||
b.HasComment("таблица привязки телеметрии от комплектов к конкретной скважине.");
|
b.HasComment("таблица привязки телеметрии от комплектов к конкретной скважине.");
|
||||||
});
|
});
|
||||||
@ -2605,7 +2605,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdTelemetry");
|
b.HasIndex("IdTelemetry");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_analysis");
|
b.ToTable("t_telemetry_analysis", (string)null);
|
||||||
|
|
||||||
b.HasComment("События на скважине");
|
b.HasComment("События на скважине");
|
||||||
});
|
});
|
||||||
@ -2808,7 +2808,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("IdTelemetry", "DateTime");
|
b.HasKey("IdTelemetry", "DateTime");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_data_saub");
|
b.ToTable("t_telemetry_data_saub", (string)null);
|
||||||
|
|
||||||
b.HasComment("набор основных данных по SAUB");
|
b.HasComment("набор основных данных по SAUB");
|
||||||
});
|
});
|
||||||
@ -3120,7 +3120,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("IdTelemetry", "DateTime");
|
b.HasKey("IdTelemetry", "DateTime");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_data_spin");
|
b.ToTable("t_telemetry_data_spin", (string)null);
|
||||||
|
|
||||||
b.HasComment("набор основных данных по SpinMaster");
|
b.HasComment("набор основных данных по SpinMaster");
|
||||||
});
|
});
|
||||||
@ -3145,7 +3145,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("IdTelemetry", "IdEvent");
|
b.HasKey("IdTelemetry", "IdEvent");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_event");
|
b.ToTable("t_telemetry_event", (string)null);
|
||||||
|
|
||||||
b.HasComment("Справочник событий. События формируют сообщения. Разделено по версиям посылок от телеметрии.");
|
b.HasComment("Справочник событий. События формируют сообщения. Разделено по версиям посылок от телеметрии.");
|
||||||
});
|
});
|
||||||
@ -3205,7 +3205,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdTelemetry");
|
b.HasIndex("IdTelemetry");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_message");
|
b.ToTable("t_telemetry_message", (string)null);
|
||||||
|
|
||||||
b.HasComment("Сообщения на буровых");
|
b.HasComment("Сообщения на буровых");
|
||||||
});
|
});
|
||||||
@ -3241,7 +3241,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("IdTelemetry", "IdUser");
|
b.HasKey("IdTelemetry", "IdUser");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_user");
|
b.ToTable("t_telemetry_user", (string)null);
|
||||||
|
|
||||||
b.HasComment("Пользователи панели САУБ. Для сообщений.");
|
b.HasComment("Пользователи панели САУБ. Для сообщений.");
|
||||||
});
|
});
|
||||||
@ -3318,7 +3318,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
b.HasIndex("Login")
|
b.HasIndex("Login")
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("t_user");
|
b.ToTable("t_user", (string)null);
|
||||||
|
|
||||||
b.HasComment("Пользователи облака");
|
b.HasComment("Пользователи облака");
|
||||||
|
|
||||||
@ -3355,7 +3355,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("t_user_role");
|
b.ToTable("t_user_role", (string)null);
|
||||||
|
|
||||||
b.HasComment("Роли пользователей в системе");
|
b.HasComment("Роли пользователей в системе");
|
||||||
|
|
||||||
@ -3727,7 +3727,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdWellType");
|
b.HasIndex("IdWellType");
|
||||||
|
|
||||||
b.ToTable("t_well");
|
b.ToTable("t_well", (string)null);
|
||||||
|
|
||||||
b.HasComment("скважины");
|
b.HasComment("скважины");
|
||||||
});
|
});
|
||||||
@ -3755,7 +3755,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdWellSrc");
|
b.HasIndex("IdWellSrc");
|
||||||
|
|
||||||
b.ToTable("t_well_composite");
|
b.ToTable("t_well_composite", (string)null);
|
||||||
|
|
||||||
b.HasComment("Композитная скважина");
|
b.HasComment("Композитная скважина");
|
||||||
});
|
});
|
||||||
@ -3831,7 +3831,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("IdWellSectionType");
|
b.HasIndex("IdWellSectionType");
|
||||||
|
|
||||||
b.ToTable("t_well_operation");
|
b.ToTable("t_well_operation", (string)null);
|
||||||
|
|
||||||
b.HasComment("Данные по операциям на скважине");
|
b.HasComment("Данные по операциям на скважине");
|
||||||
});
|
});
|
||||||
@ -3857,7 +3857,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("t_well_operation_category");
|
b.ToTable("t_well_operation_category", (string)null);
|
||||||
|
|
||||||
b.HasComment("Справочник операций на скважине");
|
b.HasComment("Справочник операций на скважине");
|
||||||
|
|
||||||
@ -4289,7 +4289,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("t_well_section_type");
|
b.ToTable("t_well_section_type", (string)null);
|
||||||
|
|
||||||
b.HasComment("конструкция секции скважины");
|
b.HasComment("конструкция секции скважины");
|
||||||
|
|
||||||
@ -4463,7 +4463,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("t_well_type");
|
b.ToTable("t_well_type", (string)null);
|
||||||
|
|
||||||
b.HasComment("конструкция скважины");
|
b.HasComment("конструкция скважины");
|
||||||
|
|
||||||
@ -4520,7 +4520,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasKey("IdTelemetry", "DateTime");
|
b.HasKey("IdTelemetry", "DateTime");
|
||||||
|
|
||||||
b.ToTable("RecordBase");
|
b.ToTable("RecordBase", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b =>
|
||||||
@ -4684,7 +4684,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("TelemetryId");
|
b.HasIndex("TelemetryId");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_wits_1");
|
b.ToTable("t_telemetry_wits_1", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b =>
|
||||||
@ -4772,7 +4772,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("TelemetryId");
|
b.HasIndex("TelemetryId");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_wits_50");
|
b.ToTable("t_telemetry_wits_50", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b =>
|
||||||
@ -4824,7 +4824,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("TelemetryId");
|
b.HasIndex("TelemetryId");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_wits_60");
|
b.ToTable("t_telemetry_wits_60", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b =>
|
||||||
@ -4880,7 +4880,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("TelemetryId");
|
b.HasIndex("TelemetryId");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_wits_61");
|
b.ToTable("t_telemetry_wits_61", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b =>
|
||||||
@ -4968,7 +4968,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("TelemetryId");
|
b.HasIndex("TelemetryId");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_wits_7");
|
b.ToTable("t_telemetry_wits_7", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b =>
|
||||||
@ -5172,7 +5172,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
b.HasIndex("TelemetryId");
|
b.HasIndex("TelemetryId");
|
||||||
|
|
||||||
b.ToTable("t_telemetry_wits_8");
|
b.ToTable("t_telemetry_wits_8", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.Cluster", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.Cluster", b =>
|
||||||
|
@ -3,7 +3,6 @@ using AsbCloudApp.Data.SAUB;
|
|||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using AsbCloudInfrastructure.Services;
|
using AsbCloudInfrastructure.Services;
|
||||||
using AsbCloudInfrastructure.Services.Analysis;
|
|
||||||
using AsbCloudInfrastructure.Services.Cache;
|
using AsbCloudInfrastructure.Services.Cache;
|
||||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
using AsbCloudInfrastructure.Services.DrillingProgram;
|
using AsbCloudInfrastructure.Services.DrillingProgram;
|
||||||
@ -75,7 +74,6 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IOperationsStatService, OperationsStatService>();
|
services.AddTransient<IOperationsStatService, OperationsStatService>();
|
||||||
services.AddTransient<IReportService, ReportService>();
|
services.AddTransient<IReportService, ReportService>();
|
||||||
services.AddTransient<ISetpointsService, SetpointsService>();
|
services.AddTransient<ISetpointsService, SetpointsService>();
|
||||||
services.AddTransient<ITelemetryAnalyticsService, TelemetryAnalyticsService>();
|
|
||||||
services.AddTransient<ITelemetryService, TelemetryService>();
|
services.AddTransient<ITelemetryService, TelemetryService>();
|
||||||
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
|
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
|
||||||
services.AddTransient<ITimezoneService, TimezoneService>();
|
services.AddTransient<ITimezoneService, TimezoneService>();
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Analysis
|
|
||||||
{
|
|
||||||
class DataSaubAnalyse
|
|
||||||
{
|
|
||||||
public int IdTelemetry { get; internal set; }
|
|
||||||
public DateTimeOffset Date { get; internal set; }
|
|
||||||
public double WellDepth { get; internal set; }
|
|
||||||
public double BitDepth { get; internal set; }
|
|
||||||
public double BlockPosition { get; internal set; }
|
|
||||||
public double RotorSpeed { get; internal set; }
|
|
||||||
public double Pressure { get; internal set; }
|
|
||||||
public double HookWeight { get; internal set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Analysis
|
|
||||||
{
|
|
||||||
public class InterpolationLine
|
|
||||||
{
|
|
||||||
private readonly double xSum;
|
|
||||||
private readonly double ySum;
|
|
||||||
private readonly double xySum;
|
|
||||||
private readonly double x2Sum;
|
|
||||||
private readonly int count;
|
|
||||||
|
|
||||||
public InterpolationLine(IEnumerable<(double Y, double X)> rawData)
|
|
||||||
{
|
|
||||||
var iterator = rawData.GetEnumerator();
|
|
||||||
while (iterator.MoveNext())
|
|
||||||
{
|
|
||||||
xSum += iterator.Current.X;
|
|
||||||
ySum += iterator.Current.Y;
|
|
||||||
xySum += iterator.Current.X * iterator.Current.Y;
|
|
||||||
x2Sum += iterator.Current.X * iterator.Current.X;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double A =>
|
|
||||||
(xSum * ySum - count * xySum) /
|
|
||||||
(xSum * xSum - count * x2Sum);
|
|
||||||
|
|
||||||
public double B =>
|
|
||||||
(xSum * xySum - x2Sum * ySum) /
|
|
||||||
(xSum * xSum - count * x2Sum);
|
|
||||||
|
|
||||||
public bool IsYNotChanges(double upperBound = 0d, double lowerBound = 0d) =>
|
|
||||||
A < upperBound && A > lowerBound;
|
|
||||||
|
|
||||||
public bool IsYIncreases(double bound = 0d) =>
|
|
||||||
A > bound;
|
|
||||||
|
|
||||||
public bool IsYDecreases(double bound = 0d) =>
|
|
||||||
A < bound;
|
|
||||||
|
|
||||||
public bool IsAverageYLessThanBound(double bound) =>
|
|
||||||
(ySum / count) < bound;
|
|
||||||
|
|
||||||
public bool IsAverageYMoreThanBound(double bound) =>
|
|
||||||
(ySum / count) >= bound;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
using AsbCloudApp.Services;
|
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using AsbCloudInfrastructure.Services.Cache;
|
|
||||||
using AsbCloudInfrastructure.Services.SAUB;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Analysis
|
|
||||||
{
|
|
||||||
public class TelemetryAnalyticsBackgroundService : BackgroundService
|
|
||||||
{
|
|
||||||
private readonly CacheDb cacheDb;
|
|
||||||
private readonly ITelemetryTracker telemetryTracker;
|
|
||||||
private readonly string connectionString;
|
|
||||||
private readonly TimeSpan period = TimeSpan.FromHours(1);
|
|
||||||
|
|
||||||
public TelemetryAnalyticsBackgroundService(CacheDb cacheDb, ITelemetryTracker telemetryTracker, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
this.cacheDb = cacheDb;
|
|
||||||
this.telemetryTracker = telemetryTracker;
|
|
||||||
connectionString = configuration.GetConnectionString("DefaultConnection");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task ExecuteAsync(CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var timeToStartAnalysis = DateTime.Now;
|
|
||||||
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
|
|
||||||
.UseNpgsql(connectionString)
|
|
||||||
.Options;
|
|
||||||
|
|
||||||
while (!token.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
if (DateTime.Now > timeToStartAnalysis)
|
|
||||||
{
|
|
||||||
timeToStartAnalysis = DateTime.Now + period;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using var context = new AsbCloudDbContext(options);
|
|
||||||
var timezoneService = new TimezoneService();
|
|
||||||
var telemetryService = new TelemetryService(context, telemetryTracker, timezoneService, cacheDb);
|
|
||||||
var analyticsService = new TelemetryAnalyticsService(context,
|
|
||||||
telemetryService, cacheDb);
|
|
||||||
|
|
||||||
await analyticsService.AnalyzeAndSaveTelemetriesAsync(token).ConfigureAwait(false);
|
|
||||||
context.Dispose();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Trace.TraceError(ex.Message);
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
GC.Collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
var ms = (int)(timeToStartAnalysis - DateTime.Now).TotalMilliseconds;
|
|
||||||
ms = ms > 100 ? ms : 100;
|
|
||||||
await Task.Delay(ms, token).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task StopAsync(CancellationToken token)
|
|
||||||
{
|
|
||||||
await base.StopAsync(token).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,533 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using AsbCloudInfrastructure.Services.Cache;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Analysis
|
|
||||||
{
|
|
||||||
public class TelemetryAnalyticsService : ITelemetryAnalyticsService
|
|
||||||
{
|
|
||||||
private readonly IAsbCloudDbContext db;
|
|
||||||
private readonly ITelemetryService telemetryService;
|
|
||||||
private readonly CacheTable<WellOperationCategory> cacheOperations;
|
|
||||||
private readonly TelemetryOperationDetectorService operationDetectorService;
|
|
||||||
private readonly IEnumerable<WellOperationCategory> operations;
|
|
||||||
|
|
||||||
private const int countOfRecordsForInterpolation = 12 * 60 * 60;
|
|
||||||
|
|
||||||
public TelemetryAnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService,
|
|
||||||
CacheDb cacheDb)
|
|
||||||
{
|
|
||||||
this.db = db;
|
|
||||||
this.telemetryService = telemetryService;
|
|
||||||
cacheOperations = cacheDb.GetCachedTable<WellOperationCategory>((AsbCloudDbContext)db);
|
|
||||||
operations = cacheOperations.Where();
|
|
||||||
operationDetectorService = new TelemetryOperationDetectorService(operations);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<WellDepthToDayDto>> GetWellDepthToDayAsync(int idWell, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell);
|
|
||||||
|
|
||||||
if (idTelemetry is null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var timezone = telemetryService.GetTimezone((int)idTelemetry);
|
|
||||||
var depthToTimeData = (from d in db.TelemetryDataSaub
|
|
||||||
where d.IdTelemetry == idTelemetry
|
|
||||||
select new
|
|
||||||
{
|
|
||||||
d.WellDepth,
|
|
||||||
d.BitDepth,
|
|
||||||
d.DateTime
|
|
||||||
});
|
|
||||||
|
|
||||||
var m = (int)Math.Round(1d * depthToTimeData.Count() / 2048);
|
|
||||||
|
|
||||||
if (m > 1)
|
|
||||||
depthToTimeData = depthToTimeData.Where((d, i) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % m == 0);
|
|
||||||
|
|
||||||
return await depthToTimeData.Select(d => new WellDepthToDayDto
|
|
||||||
{
|
|
||||||
WellDepth = d.WellDepth ?? 0.0,
|
|
||||||
BitDepth = d.BitDepth ?? 0.0,
|
|
||||||
Date = d.DateTime.ToRemoteDateTime(timezone.Hours),
|
|
||||||
}).AsNoTracking().ToListAsync(token).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<WellDepthToIntervalDto>> GetWellDepthToIntervalAsync(int idWell,
|
|
||||||
int intervalSeconds, int shiftStartSec, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
intervalSeconds = intervalSeconds == 0 ? 86400 : intervalSeconds;
|
|
||||||
|
|
||||||
var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell);
|
|
||||||
|
|
||||||
if (telemetryId is null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var timezone = telemetryService.GetTimezone((int)telemetryId);
|
|
||||||
|
|
||||||
var drillingPeriodsInfo = await db.TelemetryDataSaub
|
|
||||||
.Where(t => t.IdTelemetry == telemetryId)
|
|
||||||
.GroupBy(t => Math.Floor((((t.DateTime.DayOfYear * 24 + t.DateTime.Hour) * 60 + t.DateTime.Minute) * 60 + t.DateTime.Second + timezone.Hours - shiftStartSec) / intervalSeconds))
|
|
||||||
.Select(g => new
|
|
||||||
{
|
|
||||||
WellDepthMin = g.Min(t => t.WellDepth),
|
|
||||||
WellDepthMax = g.Max(t => t.WellDepth),
|
|
||||||
DateMin = g.Min(t => t.DateTime),
|
|
||||||
DateMax = g.Max(t => t.DateTime),
|
|
||||||
})
|
|
||||||
.OrderBy(g => g.DateMin)
|
|
||||||
.ToListAsync(token);
|
|
||||||
|
|
||||||
var wellDepthToIntervalData = drillingPeriodsInfo.Select(d => new WellDepthToIntervalDto
|
|
||||||
{
|
|
||||||
IntervalStartDate = d.DateMin.ToRemoteDateTime(timezone.Hours),
|
|
||||||
IntervalDepthProgress = (d.WellDepthMax - d.WellDepthMin) ?? 0.0
|
|
||||||
// / (d.DateMax - d.DateMin).TotalHours,
|
|
||||||
}).OrderBy(d => d.IntervalStartDate).ToList();
|
|
||||||
|
|
||||||
return wellDepthToIntervalData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<PaginationContainer<TelemetryOperationDto>> GetOperationsByWellAsync(int idWell,
|
|
||||||
IEnumerable<int> categoryIds = default, DateTime begin = default,
|
|
||||||
DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell);
|
|
||||||
|
|
||||||
if (telemetryId is null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var operations = from a in db.TelemetryAnalysis.Include(t => t.Operation)
|
|
||||||
where a.IdTelemetry == telemetryId
|
|
||||||
select a;
|
|
||||||
|
|
||||||
if ((categoryIds != default) && (categoryIds.Any()))
|
|
||||||
operations = operations.Where(o => categoryIds.Contains(o.IdOperation));
|
|
||||||
|
|
||||||
var result = new PaginationContainer<TelemetryOperationDto>
|
|
||||||
{
|
|
||||||
Skip = skip,
|
|
||||||
Take = take
|
|
||||||
};
|
|
||||||
|
|
||||||
operations = operations.OrderBy(o => o.UnixDate);
|
|
||||||
|
|
||||||
if (begin != default)
|
|
||||||
{
|
|
||||||
var unixBegin = (begin - new DateTime(1970, 1, 1)).TotalSeconds;
|
|
||||||
operations = operations.Where(o => o.UnixDate >= unixBegin);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end != default)
|
|
||||||
{
|
|
||||||
var unixEnd = (end - new DateTime(1970, 1, 1)).TotalSeconds;
|
|
||||||
operations = operations.Where(m => (m.UnixDate + m.DurationSec) <= unixEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Count = await operations.CountAsync(token).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (skip > 0)
|
|
||||||
operations = operations.Skip(skip);
|
|
||||||
|
|
||||||
var operationsList = await operations.Take(take)
|
|
||||||
.AsNoTracking()
|
|
||||||
.ToListAsync(token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (operationsList.Count == 0)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
foreach (var operation in operations)
|
|
||||||
{
|
|
||||||
var operationDto = new TelemetryOperationDto
|
|
||||||
{
|
|
||||||
Id = operation.Id,
|
|
||||||
Name = operation.Operation.Name,
|
|
||||||
BeginDate = DateTimeOffset.FromUnixTimeSeconds(operation.UnixDate).DateTime,
|
|
||||||
EndDate = DateTimeOffset.FromUnixTimeSeconds(operation.UnixDate + operation.DurationSec).DateTime,
|
|
||||||
StartWellDepth = operation.OperationStartDepth ?? 0.0,
|
|
||||||
EndWellDepth = operation.OperationEndDepth ?? 0.0
|
|
||||||
};
|
|
||||||
|
|
||||||
result.Items.Add(operationDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<TelemetryOperationDurationDto>> GetOperationsSummaryAsync(int idWell,
|
|
||||||
DateTime begin = default, DateTime end = default, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell);
|
|
||||||
|
|
||||||
if (telemetryId is null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var unixBegin = begin == default
|
|
||||||
? 0
|
|
||||||
: (begin - new DateTime(1970, 1, 1)).TotalSeconds;
|
|
||||||
var unixEnd = end == default
|
|
||||||
? (DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds
|
|
||||||
: (end - new DateTime(1970, 1, 1)).TotalSeconds;
|
|
||||||
|
|
||||||
return await (from a in db.TelemetryAnalysis
|
|
||||||
where a.IdTelemetry == telemetryId &&
|
|
||||||
a.UnixDate > unixBegin && a.UnixDate < unixEnd
|
|
||||||
join o in db.WellOperationCategories on a.IdOperation equals o.Id
|
|
||||||
group a by new { a.IdOperation, o.Name } into g
|
|
||||||
select new TelemetryOperationDurationDto
|
|
||||||
{
|
|
||||||
OperationName = g.Key.Name,
|
|
||||||
Duration = g.Where(g => g.DurationSec > 0)
|
|
||||||
.Sum(a => a.DurationSec)
|
|
||||||
}).AsNoTracking().ToListAsync(token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method is not finished (only half done). It returns not correct Dtos.
|
|
||||||
public async Task<IEnumerable<TelemetryOperationInfoDto>> GetOperationsToIntervalAsync(int idWell,
|
|
||||||
int intervalSeconds, int workBeginSeconds, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
intervalSeconds = intervalSeconds == 0 ? 86400 : intervalSeconds;
|
|
||||||
|
|
||||||
var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell);
|
|
||||||
|
|
||||||
if (telemetryId is null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var timezone = telemetryService.GetTimezone((int)telemetryId);
|
|
||||||
|
|
||||||
// Get'n'Group all operations only by start date and by name (if there were several operations in interval).
|
|
||||||
// Without dividing these operations duration by given interval
|
|
||||||
var ops = await (from a in db.TelemetryAnalysis
|
|
||||||
where a.IdTelemetry == telemetryId
|
|
||||||
join o in db.WellOperationCategories on a.IdOperation equals o.Id
|
|
||||||
group a by new
|
|
||||||
{
|
|
||||||
Interval = Math.Floor((a.UnixDate - workBeginSeconds + timezone.Hours) / intervalSeconds),
|
|
||||||
o.Name
|
|
||||||
} into g
|
|
||||||
select new
|
|
||||||
{
|
|
||||||
IntervalStart = g.Min(d => d.UnixDate),
|
|
||||||
OperationName = g.Key.Name,
|
|
||||||
OperationDuration = g.Sum(an => an.DurationSec)
|
|
||||||
}).AsNoTracking()
|
|
||||||
.OrderBy(op => op.IntervalStart)
|
|
||||||
.ToListAsync(token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
var groupedOperationsList = new List<TelemetryOperationInfoDto>();
|
|
||||||
|
|
||||||
if (operations is not null && operations.Any())
|
|
||||||
{
|
|
||||||
var operations = ops.Select(o => (o.IntervalStart, o.OperationName, o.OperationDuration));
|
|
||||||
|
|
||||||
var splittedOperationsByInterval = DivideOperationsByIntervalLength(operations, intervalSeconds); // divides good
|
|
||||||
|
|
||||||
groupedOperationsList = UniteOperationsInDto(splittedOperationsByInterval, intervalSeconds, timezone.Hours).ToList(); // unites not good
|
|
||||||
}
|
|
||||||
|
|
||||||
return groupedOperationsList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task AnalyzeAndSaveTelemetriesAsync(CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var allTelemetryIds = await db.Telemetries.Select(t => t.Id).ToListAsync(token).ConfigureAwait(false);
|
|
||||||
|
|
||||||
foreach (var idTelemetry in allTelemetryIds)
|
|
||||||
{
|
|
||||||
var analyzeStartDate = await GetLastAnalysisDateAsync(idTelemetry, token).ConfigureAwait(false);
|
|
||||||
await AnalyseAndSaveTelemetryAsync(idTelemetry, analyzeStartDate, token).ConfigureAwait(false);
|
|
||||||
GC.Collect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task AnalyseAndSaveTelemetryAsync(int idTelemetry, DateTimeOffset analyzeStartDate, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
const int step = 10;
|
|
||||||
const int take = step * 2;
|
|
||||||
|
|
||||||
TelemetryAnalysis currentAnalysis = null;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
var dataSaubPart = await GetDataSaubPartOrDefaultAsync(idTelemetry, analyzeStartDate, token).ConfigureAwait(false);
|
|
||||||
if (dataSaubPart is null)
|
|
||||||
break;
|
|
||||||
|
|
||||||
var count = dataSaubPart.Count;
|
|
||||||
var skip = 0;
|
|
||||||
|
|
||||||
if (step > count)
|
|
||||||
break;
|
|
||||||
|
|
||||||
analyzeStartDate = dataSaubPart.Last().Date;
|
|
||||||
for (; (skip + step) < count; skip += step)
|
|
||||||
{
|
|
||||||
var dataSaubPartOfPart = dataSaubPart.Skip(skip).Take(take);
|
|
||||||
var telemetryAnalysis = GetDrillingAnalysis(dataSaubPartOfPart);
|
|
||||||
|
|
||||||
if (currentAnalysis is not null)
|
|
||||||
{
|
|
||||||
if (currentAnalysis.IdOperation == telemetryAnalysis.IdOperation)
|
|
||||||
currentAnalysis.DurationSec += telemetryAnalysis.DurationSec;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
currentAnalysis.OperationEndDepth = dataSaubPartOfPart.LastOrDefault()?.WellDepth;
|
|
||||||
db.TelemetryAnalysis.Add(currentAnalysis);
|
|
||||||
currentAnalysis = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentAnalysis is null)
|
|
||||||
{
|
|
||||||
currentAnalysis = telemetryAnalysis;
|
|
||||||
currentAnalysis.OperationStartDepth = dataSaubPartOfPart.FirstOrDefault()?.WellDepth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await db.SaveChangesAsync(token).ConfigureAwait(false);
|
|
||||||
GC.Collect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell);
|
|
||||||
|
|
||||||
if (idTelemetry is null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var timezone = telemetryService.GetTimezone((int)idTelemetry);
|
|
||||||
|
|
||||||
var datesRange = await (from d in db.TelemetryAnalysis
|
|
||||||
where d.IdTelemetry == idTelemetry
|
|
||||||
select d.UnixDate).DefaultIfEmpty()
|
|
||||||
.GroupBy(g => true)
|
|
||||||
.AsNoTracking()
|
|
||||||
.Select(g => new
|
|
||||||
{
|
|
||||||
From = g.Min(),
|
|
||||||
To = g.Max()
|
|
||||||
}).OrderBy(gr => gr.From)
|
|
||||||
.FirstOrDefaultAsync(token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
var result = new DatesRangeDto
|
|
||||||
{
|
|
||||||
From = DateTimeOffset.FromUnixTimeSeconds(datesRange.From).ToRemoteDateTime(timezone.Hours),
|
|
||||||
To = (datesRange.To == default
|
|
||||||
? DateTime.MaxValue
|
|
||||||
: DateTimeOffset.FromUnixTimeSeconds(datesRange.To)).ToRemoteDateTime(timezone.Hours),
|
|
||||||
};
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<DateTime> GetLastAnalysisDateAsync(int idTelemetry, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var lastAnalysisInDb = await (from analysis in db.TelemetryAnalysis
|
|
||||||
where analysis.IdTelemetry == idTelemetry
|
|
||||||
orderby analysis.UnixDate
|
|
||||||
select analysis)
|
|
||||||
.LastOrDefaultAsync(token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
DateTime lastAnalysisDate = new DateTime(0, DateTimeKind.Utc);
|
|
||||||
|
|
||||||
if (lastAnalysisInDb is not null)
|
|
||||||
lastAnalysisDate = DateTime.UnixEpoch.AddSeconds(lastAnalysisInDb.DurationSec + lastAnalysisInDb.UnixDate);
|
|
||||||
|
|
||||||
return lastAnalysisDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Task<List<DataSaubAnalyse>> GetDataSaubPartOrDefaultAsync(int idTelemetry, DateTimeOffset analyzeStartDate, CancellationToken token) =>
|
|
||||||
db.TelemetryDataSaub
|
|
||||||
.Where(d =>
|
|
||||||
d.IdTelemetry == idTelemetry &&
|
|
||||||
d.DateTime > analyzeStartDate &&
|
|
||||||
d.BitDepth != null &&
|
|
||||||
d.BlockPosition != null &&
|
|
||||||
d.HookWeight != null &&
|
|
||||||
d.Pressure != null &&
|
|
||||||
d.RotorSpeed != null &&
|
|
||||||
d.WellDepth != null
|
|
||||||
)
|
|
||||||
.OrderBy(d => d.DateTime)
|
|
||||||
.Take(countOfRecordsForInterpolation)
|
|
||||||
.Select(d => new DataSaubAnalyse
|
|
||||||
{
|
|
||||||
IdTelemetry = d.IdTelemetry,
|
|
||||||
Date = d.DateTime,
|
|
||||||
BitDepth = d.BitDepth ?? 0,
|
|
||||||
BlockPosition = d.BlockPosition ?? 0,
|
|
||||||
HookWeight = d.HookWeight ?? 0,
|
|
||||||
Pressure = d.Pressure ?? 0,
|
|
||||||
RotorSpeed = d.RotorSpeed ?? 0,
|
|
||||||
WellDepth = d.WellDepth ?? 0,
|
|
||||||
})
|
|
||||||
.ToListAsync(token);
|
|
||||||
|
|
||||||
private static IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> DivideOperationsByIntervalLength(
|
|
||||||
IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> operations, int intervalSeconds)
|
|
||||||
{
|
|
||||||
var splittedOperationsByInterval = new List<(long IntervalStart, string OperationName, int OperationDuration)>();
|
|
||||||
|
|
||||||
var operationDurationTimeCounter = 0;
|
|
||||||
|
|
||||||
foreach (var (IntervalStart, OperationName, OperationDuration) in operations)
|
|
||||||
{
|
|
||||||
if (OperationDuration < (intervalSeconds - operationDurationTimeCounter))
|
|
||||||
{
|
|
||||||
splittedOperationsByInterval.Add((IntervalStart, OperationName, OperationDuration));
|
|
||||||
operationDurationTimeCounter += OperationDuration;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // if operation duration overflows current interval it should be divided into 2 or more parts for this and next intervals
|
|
||||||
var remainingIntervalTime = intervalSeconds - operationDurationTimeCounter;
|
|
||||||
splittedOperationsByInterval.Add((IntervalStart, OperationName, remainingIntervalTime)); // first part of long operation
|
|
||||||
|
|
||||||
var operationDurationAfterDividing = OperationDuration - remainingIntervalTime; // second part of long operation. Can be less or more than interval
|
|
||||||
|
|
||||||
// If operation duration even after dividing is still more than interval,
|
|
||||||
// it should be divided several times to several intervals.
|
|
||||||
if (operationDurationAfterDividing > intervalSeconds)
|
|
||||||
{
|
|
||||||
var counter = 0;
|
|
||||||
var updatedIntervalStartTime = IntervalStart + remainingIntervalTime;
|
|
||||||
|
|
||||||
while (operationDurationAfterDividing > intervalSeconds)
|
|
||||||
{
|
|
||||||
splittedOperationsByInterval.Add((updatedIntervalStartTime + intervalSeconds * counter, OperationName, intervalSeconds));
|
|
||||||
operationDurationAfterDividing -= intervalSeconds;
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
splittedOperationsByInterval.Add((updatedIntervalStartTime + operationDurationAfterDividing, OperationName, operationDurationAfterDividing));
|
|
||||||
|
|
||||||
operationDurationTimeCounter = operationDurationAfterDividing;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
splittedOperationsByInterval.Add((IntervalStart, OperationName, operationDurationAfterDividing));
|
|
||||||
operationDurationTimeCounter = operationDurationAfterDividing;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return splittedOperationsByInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<TelemetryOperationInfoDto> UniteOperationsInDto(
|
|
||||||
IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> operations, int intervalSeconds, double timezoneOffset)
|
|
||||||
{
|
|
||||||
var groupedOperationsList = new List<TelemetryOperationInfoDto>();
|
|
||||||
|
|
||||||
var groupedOperationsObj = new TelemetryOperationInfoDto
|
|
||||||
{
|
|
||||||
IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(operations.First().IntervalStart)
|
|
||||||
.ToRemoteDateTime(timezoneOffset),
|
|
||||||
Operations = new List<TelemetryOperationDetailsDto>()
|
|
||||||
};
|
|
||||||
|
|
||||||
var intervalEndDate = operations.First().IntervalStart + intervalSeconds;
|
|
||||||
|
|
||||||
foreach (var (IntervalStart, OperationName, OperationDuration) in operations)
|
|
||||||
{
|
|
||||||
if (IntervalStart < intervalEndDate)
|
|
||||||
{
|
|
||||||
groupedOperationsObj.Operations.Add(new TelemetryOperationDetailsDto
|
|
||||||
{
|
|
||||||
OperationName = OperationName,
|
|
||||||
DurationSec = OperationDuration
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
groupedOperationsList.Add(groupedOperationsObj);
|
|
||||||
|
|
||||||
intervalEndDate = IntervalStart + intervalSeconds;
|
|
||||||
groupedOperationsObj = new TelemetryOperationInfoDto
|
|
||||||
{
|
|
||||||
IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(IntervalStart)
|
|
||||||
.ToRemoteDateTime(timezoneOffset),
|
|
||||||
Operations = new List<TelemetryOperationDetailsDto>()
|
|
||||||
};
|
|
||||||
|
|
||||||
groupedOperationsObj.Operations.Add(new TelemetryOperationDetailsDto
|
|
||||||
{
|
|
||||||
OperationName = OperationName,
|
|
||||||
DurationSec = OperationDuration
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
groupedOperationsList.Add(groupedOperationsObj);
|
|
||||||
|
|
||||||
return groupedOperationsList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TelemetryAnalysis GetDrillingAnalysis(IEnumerable<DataSaubAnalyse> dataSaubPartOfPart)
|
|
||||||
{
|
|
||||||
var dataSaubFirst = dataSaubPartOfPart.First();
|
|
||||||
var dataSaubLast = dataSaubPartOfPart.Last();
|
|
||||||
|
|
||||||
var saubWellDepths = dataSaubPartOfPart.Select(s => (Y: (double)s.WellDepth,
|
|
||||||
X: (s.Date - dataSaubFirst.Date).TotalSeconds));
|
|
||||||
var saubBitDepths = dataSaubPartOfPart.Select(s => (Y: (double)s.BitDepth,
|
|
||||||
X: (s.Date - dataSaubFirst.Date).TotalSeconds));
|
|
||||||
var saubBlockPositions = dataSaubPartOfPart.Select(s => (Y: (double)s.BlockPosition,
|
|
||||||
X: (s.Date - dataSaubFirst.Date).TotalSeconds));
|
|
||||||
var saubRotorSpeeds = dataSaubPartOfPart.Select(s => (Y: (double)s.RotorSpeed,
|
|
||||||
X: (s.Date - dataSaubFirst.Date).TotalSeconds));
|
|
||||||
var saubPressures = dataSaubPartOfPart.Select(s => (Y: (double)s.Pressure,
|
|
||||||
X: (s.Date - dataSaubFirst.Date).TotalSeconds));
|
|
||||||
var saubHookWeights = dataSaubPartOfPart.Select(s => (Y: (double)s.HookWeight,
|
|
||||||
X: (s.Date - dataSaubFirst.Date).TotalSeconds));
|
|
||||||
|
|
||||||
var wellDepthLine = new InterpolationLine(saubWellDepths);
|
|
||||||
var bitPositionLine = new InterpolationLine(saubBitDepths);
|
|
||||||
var blockPositionLine = new InterpolationLine(saubBlockPositions);
|
|
||||||
var rotorSpeedLine = new InterpolationLine(saubRotorSpeeds);
|
|
||||||
var pressureLine = new InterpolationLine(saubPressures);
|
|
||||||
var hookWeightLine = new InterpolationLine(saubHookWeights);
|
|
||||||
|
|
||||||
var drillingAnalysis = new TelemetryAnalysis
|
|
||||||
{
|
|
||||||
IdTelemetry = dataSaubFirst.IdTelemetry,
|
|
||||||
UnixDate = (long)(dataSaubFirst.Date - DateTime.UnixEpoch).TotalSeconds,
|
|
||||||
DurationSec = (int)(dataSaubLast.Date - dataSaubFirst.Date).TotalSeconds,
|
|
||||||
OperationStartDepth = null,
|
|
||||||
OperationEndDepth = null,
|
|
||||||
IsWellDepthDecreasing = wellDepthLine.IsYDecreases(-0.0001),
|
|
||||||
IsWellDepthIncreasing = wellDepthLine.IsYIncreases(0.0001),
|
|
||||||
IsBitPositionDecreasing = bitPositionLine.IsYDecreases(-0.0001),
|
|
||||||
IsBitPositionIncreasing = bitPositionLine.IsYIncreases(0.0001),
|
|
||||||
IsBitPositionLt20 = bitPositionLine.IsAverageYLessThanBound(20),
|
|
||||||
IsBlockPositionDecreasing = blockPositionLine.IsYDecreases(-0.0001),
|
|
||||||
IsBlockPositionIncreasing = blockPositionLine.IsYIncreases(0.0001),
|
|
||||||
IsRotorSpeedLt5 = rotorSpeedLine.IsAverageYLessThanBound(5),
|
|
||||||
IsRotorSpeedGt5 = rotorSpeedLine.IsAverageYMoreThanBound(5),
|
|
||||||
IsPressureLt20 = pressureLine.IsAverageYLessThanBound(20),
|
|
||||||
IsPressureGt20 = pressureLine.IsAverageYMoreThanBound(20),
|
|
||||||
IsHookWeightNotChanges = hookWeightLine.IsYNotChanges(0.0001, -0.0001),
|
|
||||||
IsHookWeightLt3 = hookWeightLine.IsAverageYLessThanBound(3),
|
|
||||||
IdOperation = default,
|
|
||||||
};
|
|
||||||
|
|
||||||
drillingAnalysis.IdOperation =
|
|
||||||
operationDetectorService.DetectOperation(drillingAnalysis).Id;
|
|
||||||
|
|
||||||
return drillingAnalysis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
using AsbCloudDb.Model;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Analysis
|
|
||||||
{
|
|
||||||
class TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
public int Order { get; set; }
|
|
||||||
public WellOperationCategory Operation { get; set; }
|
|
||||||
public Func<TelemetryAnalysis, bool> Detect { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,205 +0,0 @@
|
|||||||
using AsbCloudDb.Model;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Analysis
|
|
||||||
{
|
|
||||||
class TelemetryOperationDetectorService
|
|
||||||
{
|
|
||||||
private readonly IEnumerable<TelemetryOperationDetector> detectors;
|
|
||||||
|
|
||||||
public TelemetryOperationDetectorService(IEnumerable<WellOperationCategory> operations)
|
|
||||||
{
|
|
||||||
detectors = new List<TelemetryOperationDetector>()
|
|
||||||
{
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 1,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Роторное бурение")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return data.IsWellDepthIncreasing && data.IsBitPositionIncreasing &&
|
|
||||||
data.IsBlockPositionIncreasing && data.IsRotorSpeedGt5;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 2,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Слайдирование")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return data.IsWellDepthIncreasing && data.IsBitPositionIncreasing &&
|
|
||||||
data.IsBlockPositionIncreasing && data.IsRotorSpeedLt5;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 3,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("На поверхности")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return data.IsBitPositionLt20 && data.IsHookWeightLt3;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 4,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Удержание в клиньях")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
!data.IsBitPositionIncreasing && !data.IsBitPositionDecreasing &&
|
|
||||||
data.IsBlockPositionDecreasing && !data.IsBlockPositionIncreasing &&
|
|
||||||
data.IsHookWeightLt3;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 5,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Подъем с проработкой")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
data.IsBitPositionDecreasing && data.IsBlockPositionIncreasing &&
|
|
||||||
data.IsRotorSpeedGt5 && data.IsPressureGt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 6,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Спуск с проработкой")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
data.IsBitPositionIncreasing && data.IsBlockPositionDecreasing &&
|
|
||||||
data.IsRotorSpeedGt5 && data.IsPressureGt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 7,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Подъем с промывкой")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
data.IsBitPositionDecreasing && data.IsBlockPositionIncreasing &&
|
|
||||||
data.IsRotorSpeedLt5 && data.IsPressureGt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 8,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Спуск с промывкой")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
data.IsBitPositionIncreasing && data.IsBlockPositionDecreasing &&
|
|
||||||
data.IsRotorSpeedLt5 && data.IsPressureGt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 9,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Спуск в скважину")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
data.IsBitPositionIncreasing && data.IsBlockPositionDecreasing &&
|
|
||||||
data.IsRotorSpeedLt5 && data.IsPressureLt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 10,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Спуск с вращением")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
data.IsBitPositionIncreasing && data.IsBlockPositionDecreasing &&
|
|
||||||
data.IsRotorSpeedGt5 && data.IsPressureLt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 11,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Подъем из скважины")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
data.IsBitPositionDecreasing && data.IsBlockPositionIncreasing &&
|
|
||||||
data.IsRotorSpeedLt5 && data.IsPressureLt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 12,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Подъем с вращением")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
data.IsBitPositionDecreasing && data.IsBlockPositionIncreasing &&
|
|
||||||
data.IsRotorSpeedGt5 && data.IsPressureLt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 13,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Промывка в покое")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
!data.IsBitPositionDecreasing && !data.IsBitPositionIncreasing &&
|
|
||||||
!data.IsBlockPositionDecreasing && !data.IsBlockPositionIncreasing &&
|
|
||||||
data.IsRotorSpeedLt5 && data.IsPressureGt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 14,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Промывка с вращением")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
!data.IsBitPositionDecreasing && !data.IsBitPositionIncreasing &&
|
|
||||||
!data.IsBlockPositionDecreasing && !data.IsBlockPositionIncreasing &&
|
|
||||||
data.IsRotorSpeedGt5 && data.IsPressureGt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 15,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Неподвижное состояние")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
!data.IsBitPositionDecreasing && !data.IsBitPositionIncreasing &&
|
|
||||||
!data.IsBlockPositionDecreasing && !data.IsBlockPositionIncreasing &&
|
|
||||||
data.IsRotorSpeedLt5 && data.IsPressureLt20 && data.IsHookWeightNotChanges;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 16,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Вращение без циркуляции")),
|
|
||||||
Detect = (data) =>
|
|
||||||
{
|
|
||||||
return !data.IsWellDepthDecreasing && !data.IsWellDepthIncreasing &&
|
|
||||||
!data.IsBitPositionDecreasing && !data.IsBitPositionIncreasing &&
|
|
||||||
!data.IsBlockPositionDecreasing && !data.IsBlockPositionIncreasing &&
|
|
||||||
data.IsRotorSpeedGt5 && data.IsPressureLt20;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new TelemetryOperationDetector
|
|
||||||
{
|
|
||||||
Order = 17,
|
|
||||||
Operation = operations.FirstOrDefault(o => o.Name.Equals("Невозможно определить операцию")),
|
|
||||||
Detect = (data) => true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public WellOperationCategory DetectOperation(TelemetryAnalysis data) =>
|
|
||||||
detectors.OrderBy(d => d.Order).First(o => o.Detect(data)).Operation
|
|
||||||
?? new WellOperationCategory { Id = 1, Name = "Невозможно определить операцию" };
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,205 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Controllers.SAUB
|
|
||||||
{
|
|
||||||
[Route("api/well/{idWell}/telemetryAnalytics")]
|
|
||||||
[ApiController]
|
|
||||||
[Authorize]
|
|
||||||
public class TelemetryAnalyticsController : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly ITelemetryAnalyticsService analyticsService;
|
|
||||||
private readonly IWellService wellService;
|
|
||||||
|
|
||||||
public TelemetryAnalyticsController(ITelemetryAnalyticsService analyticsService, IWellService wellService)
|
|
||||||
{
|
|
||||||
this.analyticsService = analyticsService;
|
|
||||||
this.wellService = wellService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Возвращает список операций на скважине за все время
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell">id скважины</param>
|
|
||||||
/// <param name="categoryIds">список категорий</param>
|
|
||||||
/// <param name="begin">дата начала</param>
|
|
||||||
/// <param name="end">окончание</param>
|
|
||||||
/// <param name="skip">для пагинации кол-во записей пропустить</param>
|
|
||||||
/// <param name="take">для пагинации кол-во записей </param>
|
|
||||||
/// <param name="token"> Токен отмены задачи </param>
|
|
||||||
/// <returns>Список операций на скважине за все время</returns>
|
|
||||||
[HttpGet]
|
|
||||||
[Route("operationsByWell")]
|
|
||||||
[Permission]
|
|
||||||
[ProducesResponseType(typeof(PaginationContainer<TelemetryOperationDto>), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetOperationsByWellAsync(int idWell, int skip = 0, int take = 32,
|
|
||||||
[FromQuery] IEnumerable<int> categoryIds = default, DateTime begin = default, DateTime end = default,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
int? idCompany = User.GetCompanyId();
|
|
||||||
|
|
||||||
if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
|
||||||
idWell, token).ConfigureAwait(false))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var analytics = await analyticsService.GetOperationsByWellAsync(idWell, categoryIds, begin, end, skip, take, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (analytics is null || analytics.Count == 0)
|
|
||||||
return NoContent();
|
|
||||||
|
|
||||||
return Ok(analytics);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Возвращает данные по скважине "глубина-день"
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell">id скважины</param>
|
|
||||||
/// <param name="token">Токен отмены задачи</param>
|
|
||||||
/// <returns>Коллекцию данных по скважине "глубина-день"</returns>
|
|
||||||
[HttpGet]
|
|
||||||
[Route("wellDepthToDay")]
|
|
||||||
[Permission]
|
|
||||||
[ProducesResponseType(typeof(IEnumerable<WellDepthToDayDto>), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetWellDepthToDayAsync(int idWell,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
int? idCompany = User.GetCompanyId();
|
|
||||||
|
|
||||||
if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
|
||||||
idWell, token).ConfigureAwait(false))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var wellDepthToDayData = await analyticsService.GetWellDepthToDayAsync(idWell, token)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (wellDepthToDayData is null || !wellDepthToDayData.Any())
|
|
||||||
return NoContent();
|
|
||||||
|
|
||||||
return Ok(wellDepthToDayData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Возвращает данные по глубине скважины за период
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell">id скважины</param>
|
|
||||||
/// <param name="intervalSeconds">количество секунд в необходимом интервале времени</param>
|
|
||||||
/// <param name="shiftStartSec">количество секунд в времени начала смены</param>
|
|
||||||
/// <param name="token">Токен отмены задачи</param>
|
|
||||||
/// <returns>Коллекцию данных по глубине скважины за период</returns>
|
|
||||||
[HttpGet]
|
|
||||||
[Route("wellDepthToInterval")]
|
|
||||||
[Permission]
|
|
||||||
[ProducesResponseType(typeof(IEnumerable<WellDepthToIntervalDto>), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetWellDepthToIntervalAsync(int idWell,
|
|
||||||
int intervalSeconds, int shiftStartSec, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
int? idCompany = User.GetCompanyId();
|
|
||||||
|
|
||||||
if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
|
||||||
idWell, token).ConfigureAwait(false))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var wellDepthToIntervalData = await analyticsService.GetWellDepthToIntervalAsync(idWell,
|
|
||||||
intervalSeconds, shiftStartSec, token).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (wellDepthToIntervalData is null || !wellDepthToIntervalData.Any())
|
|
||||||
return NoContent();
|
|
||||||
|
|
||||||
return Ok(wellDepthToIntervalData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Возвращает данные по операциям на скважине "операции-время"
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell">id скважины</param>
|
|
||||||
/// <param name="begin">дата начала интервала</param>
|
|
||||||
/// <param name="end">дата окончания интервала</param>
|
|
||||||
/// <param name="token">Токен отмены задачи</param>
|
|
||||||
/// <returns>Коллекцию операций на скважине</returns>
|
|
||||||
[HttpGet]
|
|
||||||
[Route("operationsSummary")]
|
|
||||||
[Permission]
|
|
||||||
[ProducesResponseType(typeof(IEnumerable<TelemetryOperationDurationDto>), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetOperationsSummaryAsync(int idWell, DateTime begin = default,
|
|
||||||
DateTime end = default, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
int? idCompany = User.GetCompanyId();
|
|
||||||
|
|
||||||
if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
|
||||||
idWell, token).ConfigureAwait(false))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var analytics = await analyticsService.GetOperationsSummaryAsync(idWell,
|
|
||||||
begin, end, token).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (analytics is null || !analytics.Any())
|
|
||||||
return NoContent();
|
|
||||||
|
|
||||||
return Ok(analytics);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Возвращает детальные данные по операциям на скважине за период
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell">id скважины</param>
|
|
||||||
/// <param name="intervalSeconds">количество секунд в необходимом интервале времени</param>
|
|
||||||
/// <param name="workBeginSeconds">количество секунд в времени начала смены</param>
|
|
||||||
/// <param name="token">Токен отмены задачи</param>
|
|
||||||
/// <returns>Коллекцию операций на скважине</returns>
|
|
||||||
[HttpGet]
|
|
||||||
[Route("operationsToInterval")]
|
|
||||||
[Permission]
|
|
||||||
[ProducesResponseType(typeof(IEnumerable<TelemetryOperationDurationDto>), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetOperationsToIntervalAsync(int idWell,
|
|
||||||
int intervalSeconds, int workBeginSeconds, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
int? idCompany = User.GetCompanyId();
|
|
||||||
|
|
||||||
if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
|
||||||
idWell, token).ConfigureAwait(false))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var analytics = await analyticsService.GetOperationsToIntervalAsync(idWell,
|
|
||||||
intervalSeconds, workBeginSeconds, token).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (analytics is null || !analytics.Any())
|
|
||||||
return NoContent();
|
|
||||||
|
|
||||||
return Ok(analytics);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Возвращает даты первой и последней операций на скважине
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell">id скважины</param>
|
|
||||||
/// <param name="token">Токен для отмены задачи</param>
|
|
||||||
/// <returns>Даты самой первой и самой последней операций на скважине</returns>
|
|
||||||
[HttpGet]
|
|
||||||
[Route("datesRange")]
|
|
||||||
[Permission]
|
|
||||||
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetOperationsDateRangeAsync(int idWell, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
int? idCompany = User.GetCompanyId();
|
|
||||||
|
|
||||||
if (idCompany is null)
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
|
||||||
idWell, token).ConfigureAwait(false))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var wellOperationsDatesRange = await analyticsService.GetOperationsDateRangeAsync(idWell, token).ConfigureAwait(false);
|
|
||||||
|
|
||||||
return Ok(wellOperationsDatesRange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user