forked from ddrilling/AsbCloudServer
Merge pull request 'Создание страницы "Качество". Первый этап' (#333) from feature/#79219300-drilling-quality into dev
Reviewed-on: https://test.digitaldrilling.ru:8443/DDrilling/AsbCloudServer/pulls/333
This commit is contained in:
commit
a385f3c6ce
49
AsbCloudApp/Data/SaubStat/DataSaubStatDrillingQualityDto.cs
Normal file
49
AsbCloudApp/Data/SaubStat/DataSaubStatDrillingQualityDto.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data;
|
||||
|
||||
/// <summary>
|
||||
/// dto для хранения данных статистики качества бурения
|
||||
/// </summary>
|
||||
public class DataSaubStatDrillingQualityDto : IId, IDataSaubStatDto
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата и время начала
|
||||
/// </summary>
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата и время окончания
|
||||
/// </summary>
|
||||
public DateTimeOffset DateEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина забоя по стволу начальная
|
||||
/// </summary>
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина забоя по стволу конечная
|
||||
/// </summary>
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Качественная проходка
|
||||
/// </summary>
|
||||
public double DepthDrillingQuality { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Флаг
|
||||
/// </summary>
|
||||
public int IdFeedRegulator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ключ телеметрии
|
||||
/// </summary>
|
||||
public int IdTelemetry { get; set; }
|
||||
}
|
@ -6,7 +6,7 @@ namespace AsbCloudApp.Data;
|
||||
/// <summary>
|
||||
/// dto для хранения данных статистики сауб
|
||||
/// </summary>
|
||||
public class DataSaubStatDto:IId
|
||||
public class DataSaubStatDto : IId, IDataSaubStatDto
|
||||
{
|
||||
/// <summary>
|
||||
///
|
34
AsbCloudApp/Data/SaubStat/IDataSaubStatDto.cs
Normal file
34
AsbCloudApp/Data/SaubStat/IDataSaubStatDto.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Dto для работы с данными dataSaubStat
|
||||
/// </summary>
|
||||
public interface IDataSaubStatDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Дата и время начала
|
||||
/// </summary>
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата и время окончания
|
||||
/// </summary>
|
||||
public DateTimeOffset DateEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина забоя по стволу начальная
|
||||
/// </summary>
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина забоя по стволу конечная
|
||||
/// </summary>
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ключ телеметрии
|
||||
/// </summary>
|
||||
public int IdTelemetry { get; set; }
|
||||
}
|
@ -8,19 +8,20 @@ using System.Threading.Tasks;
|
||||
namespace AsbCloudApp.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Репозиторий работы с данными из таблицы t_data_daub_stat
|
||||
/// Репозиторий работы с данными, реализующими интерфейс IDataSaubStatDto
|
||||
/// </summary>
|
||||
public interface IDataSaubStatRepository : ITelemetryDataEditorService
|
||||
public interface IDataSaubStatRepository<TDto> : ITelemetryDataEditorService
|
||||
where TDto : IDataSaubStatDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Получение записей по ключу телеметрии
|
||||
/// Получение записей по ключам телеметрий
|
||||
/// </summary>
|
||||
/// <param name="idTelemetry">ключ телеметрии</param>
|
||||
/// <param name="idsTelemetries">ключи телеметрий</param>
|
||||
/// <param name="geDate">начальная дата</param>
|
||||
/// <param name="leDate">конечная дата</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<DataSaubStatDto>> GetAsync(int idTelemetry, DateTimeOffset geDate, DateTimeOffset leDate, CancellationToken token);
|
||||
Task<IEnumerable<TDto>> GetAsync(IEnumerable<int> idsTelemetries, DateTimeOffset geDate, DateTimeOffset leDate, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение последних по дате окончания бурения записей в разрезе телеметрий
|
||||
@ -28,13 +29,13 @@ public interface IDataSaubStatRepository : ITelemetryDataEditorService
|
||||
/// <param name="idTelemetries">ключи телеметрий</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<DataSaubStatDto>> GetLastsAsync(int[] idTelemetries, CancellationToken token);
|
||||
Task<IEnumerable<TDto>> GetLastsAsync(int[] idTelemetries, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Вставка записей статистики
|
||||
/// Вставка записей
|
||||
/// </summary>
|
||||
/// <param name="dataSaubStats"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> InsertRangeAsync(IEnumerable<DataSaubStatDto> dataSaubStats, CancellationToken token);
|
||||
Task<int> InsertRangeAsync(IEnumerable<TDto> dataSaubStats, CancellationToken token);
|
||||
}
|
||||
|
27
AsbCloudApp/Requests/DrillingQualityRequest.cs
Normal file
27
AsbCloudApp/Requests/DrillingQualityRequest.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Запрос на получение записей качества бурения
|
||||
/// </summary>
|
||||
public class DrillingQualityRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// идентификаторы скважин
|
||||
/// </summary>
|
||||
[Required]
|
||||
public IEnumerable<int> IdsWell { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Больше или равно дате
|
||||
/// </summary>
|
||||
public DateTimeOffset GeDate { get; set; } = DateTimeOffset.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// Меньше или равно дате
|
||||
/// </summary>
|
||||
public DateTimeOffset LeDate { get; set; } = DateTimeOffset.MaxValue;
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Requests;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Сервис записи данных в таблицу t_data_saub_stat_drilling_quality, которая используется для построения РТК-отчета
|
||||
/// </summary>
|
||||
public interface IDataSaubStatDrillingQualityService
|
||||
{
|
||||
/// <summary>
|
||||
/// Расчет статистики DataSaubStatDrillingQuality и сохранение её в бд
|
||||
/// </summary>
|
||||
/// <param name="lastDaysFilter">
|
||||
/// Количество дней за которые должны были приходить данные, чтобы телеметрия попала в обработку.
|
||||
/// </param>
|
||||
/// <param name="onProgressCallback"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task CreateStatAsync(int lastDaysFilter, Action<string, double?> onProgressCallback, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Расчет статистики DataSaubStatDrillingQuality
|
||||
/// </summary>
|
||||
/// <param name="idTelemetry"></param>
|
||||
/// <param name="geDate"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<DataSaubStatDrillingQualityDto>> CreateStatDrillingQualityForTelemetry(
|
||||
int idTelemetry,
|
||||
DateTimeOffset geDate,
|
||||
CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение записей DrillingQualityDto по параметрам
|
||||
/// </summary>
|
||||
/// <param name="request">параметры запроса</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<DrillingQualityDto>> GetStatAsync(DrillingQualityRequest request, CancellationToken token);
|
||||
}
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||
namespace AsbCloudApp.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Сервис записи данных в таблицу DataSaubStat, которая используется для построения РТК-отчета
|
||||
/// Сервис записи данных в таблицу t_data_saub_stat, которая используется для построения РТК-отчета
|
||||
/// </summary>
|
||||
public interface IDataSaubStatService
|
||||
{
|
12464
AsbCloudDb/Migrations/20241004110355_Add_Table_DataSaubStatDrillingQuality.Designer.cs
generated
Normal file
12464
AsbCloudDb/Migrations/20241004110355_Add_Table_DataSaubStatDrillingQuality.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Add_Table_DataSaubStatDrillingQuality : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "t_data_saub_stat_drilling_quality",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
id_telemetry = table.Column<int>(type: "integer", nullable: false, comment: "Ключ телеметрии"),
|
||||
date_start = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата и время начала"),
|
||||
date_end = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата и время окончания"),
|
||||
depth_start = table.Column<double>(type: "double precision", nullable: false, comment: "Глубина забоя по стволу начальная"),
|
||||
depth_end = table.Column<double>(type: "double precision", nullable: false, comment: "Глубина забоя по стволу конечная"),
|
||||
id_feed_regulator = table.Column<int>(type: "integer", nullable: false, comment: "Флаг"),
|
||||
depth_drilling_quality = table.Column<double>(type: "double precision", nullable: false, comment: "Качественная проходка")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_t_data_saub_stat_drilling_quality", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_data_saub_stat_drilling_quality_t_telemetry_id_telemetry",
|
||||
column: x => x.id_telemetry,
|
||||
principalTable: "t_telemetry",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
},
|
||||
comment: "Кеш-таблица для хранения данных для построения страницы \"Качество\"");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_data_saub_stat_drilling_quality_id_telemetry",
|
||||
table: "t_data_saub_stat_drilling_quality",
|
||||
column: "id_telemetry");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "t_data_saub_stat_drilling_quality");
|
||||
}
|
||||
}
|
||||
}
|
@ -451,6 +451,60 @@ namespace AsbCloudDb.Migrations
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DataSaubStatDrillingQuality", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTimeOffset>("DateEnd")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date_end")
|
||||
.HasComment("Дата и время окончания");
|
||||
|
||||
b.Property<DateTimeOffset>("DateStart")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date_start")
|
||||
.HasComment("Дата и время начала");
|
||||
|
||||
b.Property<double>("DepthDrillingQuality")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("depth_drilling_quality")
|
||||
.HasComment("Качественная проходка");
|
||||
|
||||
b.Property<double>("DepthEnd")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("depth_end")
|
||||
.HasComment("Глубина забоя по стволу конечная");
|
||||
|
||||
b.Property<double>("DepthStart")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("depth_start")
|
||||
.HasComment("Глубина забоя по стволу начальная");
|
||||
|
||||
b.Property<int>("IdFeedRegulator")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_feed_regulator")
|
||||
.HasComment("Флаг");
|
||||
|
||||
b.Property<int>("IdTelemetry")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_telemetry")
|
||||
.HasComment("Ключ телеметрии");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdTelemetry");
|
||||
|
||||
b.ToTable("t_data_saub_stat_drilling_quality", t =>
|
||||
{
|
||||
t.HasComment("Кеш-таблица для хранения данных для построения страницы \"Качество\"");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Deposit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -10720,6 +10774,17 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("Telemetry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DataSaubStatDrillingQuality", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdTelemetry")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Telemetry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DetectedOperation", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory")
|
||||
|
@ -110,6 +110,7 @@ namespace AsbCloudDb.Model
|
||||
public DbSet<DrillTest> DrillTests => Set<DrillTest>();
|
||||
|
||||
public DbSet<DataSaubStat> DataSaubStat => Set<DataSaubStat>();
|
||||
public DbSet<DataSaubStatDrillingQuality> DataSaubStatDrillingQuality => Set<DataSaubStatDrillingQuality>();
|
||||
public AsbCloudDbContext() : base()
|
||||
{
|
||||
Interlocked.Increment(ref referenceCount);
|
||||
|
@ -81,6 +81,7 @@ namespace AsbCloudDb.Model
|
||||
DbSet<TrajectoryFact> TrajectoriesFact { get; }
|
||||
DbSet<WellSectionPlan> WellSectionsPlan { get; }
|
||||
DbSet<DataSaubStat> DataSaubStat { get; }
|
||||
DbSet<DataSaubStatDrillingQuality> DataSaubStatDrillingQuality { get; }
|
||||
DatabaseFacade Database { get; }
|
||||
DbSet<ProcessMapPlanRotor> ProcessMapPlanRotor { get; }
|
||||
DbSet<ProcessMapPlanSlide> ProcessMapPlanSlide { get; }
|
||||
|
@ -7,7 +7,7 @@ using System.Text.Json.Serialization;
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
[Table("t_data_saub_stat"), Comment("Кеш-таблица для хранения данных для РТК-отчета")]
|
||||
public class DataSaubStat : IId
|
||||
public class DataSaubStat : IId, IDataSaubStat
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
40
AsbCloudDb/Model/SaubStat/DataSaubStatDrillingQuality.cs
Normal file
40
AsbCloudDb/Model/SaubStat/DataSaubStatDrillingQuality.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
[Table("t_data_saub_stat_drilling_quality"), Comment("Кеш-таблица для хранения данных для построения страницы \"Качество\"")]
|
||||
public class DataSaubStatDrillingQuality : IId, IDataSaubStat
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("id_telemetry"), Comment("Ключ телеметрии")]
|
||||
public int IdTelemetry { get; set; }
|
||||
|
||||
[Column("date_start", TypeName = "timestamp with time zone"), Comment("Дата и время начала")]
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
|
||||
[Column("date_end", TypeName = "timestamp with time zone"), Comment("Дата и время окончания")]
|
||||
public DateTimeOffset DateEnd { get; set; }
|
||||
|
||||
[Column("depth_start"), Comment("Глубина забоя по стволу начальная")]
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
[Column("depth_end"), Comment("Глубина забоя по стволу конечная")]
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
[Column("id_feed_regulator"), Comment("Флаг")]
|
||||
public int IdFeedRegulator { get; set; }
|
||||
|
||||
[Column("depth_drilling_quality"), Comment("Качественная проходка")]
|
||||
public double DepthDrillingQuality { get; set; }
|
||||
|
||||
[ForeignKey(nameof(IdTelemetry))]
|
||||
public virtual Telemetry Telemetry { get; set; } = null!;
|
||||
|
||||
}
|
||||
}
|
9
AsbCloudDb/Model/SaubStat/IDataSaubStat.cs
Normal file
9
AsbCloudDb/Model/SaubStat/IDataSaubStat.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudDb.Model;
|
||||
public interface IDataSaubStat
|
||||
{
|
||||
public int IdTelemetry { get; set; }
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
public DateTimeOffset DateEnd { get; set; }
|
||||
}
|
@ -7,16 +7,29 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Services\DataSaubStat\test1.csv" />
|
||||
<None Remove="Services\DataSaubStat\test1_result.csv" />
|
||||
<None Remove="Services\DataSaubStat\test2.csv" />
|
||||
<None Remove="Services\DataSaubStat\test2_result.csv" />
|
||||
<None Remove="Services\DataSaubStat\test3.csv" />
|
||||
<None Remove="Services\DataSaubStat\test3_result.csv" />
|
||||
<None Remove="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
||||
<None Remove="Services\Trajectory\Templates\TrajectoryFactManualTemplate.xlsx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Services\DataSaubStat\test1.csv" />
|
||||
<EmbeddedResource Include="Services\DataSaubStat\test1_result.csv" />
|
||||
<EmbeddedResource Include="Services\DataSaubStat\test2.csv" />
|
||||
<EmbeddedResource Include="Services\DataSaubStat\test2_result.csv" />
|
||||
<EmbeddedResource Include="Services\DataSaubStat\test3.csv" />
|
||||
<EmbeddedResource Include="Services\DataSaubStat\test3_result.csv" />
|
||||
<EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryFactManualTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryPlanTemplate.xlsx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CsvHelper" Version="33.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.6" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
|
||||
<PackageReference Include="NSubstitute" Version="5.1.0" />
|
||||
|
46
AsbCloudInfrastructure.Tests/CsvMockHelper.cs
Normal file
46
AsbCloudInfrastructure.Tests/CsvMockHelper.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using AsbCloudApp.Exceptions;
|
||||
using CsvHelper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace AsbCloudInfrastructure.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Хелпер, который помогает получать мок-данные из csv файла
|
||||
/// </summary>
|
||||
public static class CsvMockHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// метод получения данных из файла
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="path">путь до файла</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentInvalidException"></exception>
|
||||
public static IEnumerable<T> Get<T>(string path)
|
||||
{
|
||||
var resourceName = Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceNames()
|
||||
.Where(r => r.Contains(path))
|
||||
.FirstOrDefault();
|
||||
|
||||
if (String.IsNullOrEmpty(resourceName))
|
||||
throw new ArgumentInvalidException(nameof(path), "Файл с mock-данными не найден");
|
||||
|
||||
using var stream = Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream(resourceName)!;
|
||||
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
|
||||
{
|
||||
var dataSaubMaps = csv.GetRecords<T>().ToArray();
|
||||
return dataSaubMaps;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
using CsvHelper.Configuration.Attributes;
|
||||
|
||||
namespace AsbCloudInfrastructure.Tests.MapData
|
||||
{
|
||||
public class DataSaubStatDrillingQualityDtoMap
|
||||
{
|
||||
[Name("id_telemetry")]
|
||||
public int IdTelemetry { get; set; }
|
||||
|
||||
[Name("depth_start")]
|
||||
public float DepthStart { get; set; }
|
||||
|
||||
[Name("depth_end")]
|
||||
public float DepthEnd { get; set; }
|
||||
|
||||
[Name("depth_drilling_quality")]
|
||||
public float DepthDrillingQuality { get; set; }
|
||||
|
||||
[Name("id_feed_regulator")]
|
||||
public short? IdFeedRegulator { get; set; }
|
||||
}
|
||||
}
|
47
AsbCloudInfrastructure.Tests/MapData/TelemetryDataSaubMap.cs
Normal file
47
AsbCloudInfrastructure.Tests/MapData/TelemetryDataSaubMap.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using CsvHelper.Configuration.Attributes;
|
||||
using System;
|
||||
|
||||
namespace AsbCloudInfrastructure.Tests.MapData
|
||||
{
|
||||
public class TelemetryDataSaubMap
|
||||
{
|
||||
[Name("id_telemetry")]
|
||||
public int IdTelemetry { get; set; }
|
||||
|
||||
[Name("date")]
|
||||
public DateTime DateTime { get; set; }
|
||||
|
||||
[Name("well_depth")]
|
||||
public float WellDepth { get; set; }
|
||||
|
||||
[Name("bit_depth")]
|
||||
public float BitDepth { get; set; }
|
||||
|
||||
[Name("block_speed")]
|
||||
public float? BlockSpeed { get; set; }
|
||||
|
||||
[Name("block_speed_sp")]
|
||||
public float? BlockSpeedSp { get; set; }
|
||||
|
||||
[Name("pressure")]
|
||||
public float Pressure { get; set; }
|
||||
|
||||
[Name("pressure_sp")]
|
||||
public float? PressureSp { get; set; }
|
||||
|
||||
[Name("axial_load")]
|
||||
public float AxialLoad { get; set; }
|
||||
|
||||
[Name("axial_load_sp")]
|
||||
public float? AxialLoadSp { get; set; }
|
||||
|
||||
[Name("rotor_torque")]
|
||||
public float RotorTorque { get; set; }
|
||||
|
||||
[Name("rotor_torque_sp")]
|
||||
public float? RotorTorqueSp { get; set; }
|
||||
|
||||
[Name("id_feed_regulator")]
|
||||
public short? IdFeedRegulator { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudInfrastructure.Services;
|
||||
using AsbCloudInfrastructure.Tests.MapData;
|
||||
using CsvHelper;
|
||||
using Mapster;
|
||||
using NSubstitute;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudInfrastructure.Tests.Services;
|
||||
|
||||
public class DataSaubStatDtillingQualityServiceTest
|
||||
{
|
||||
private readonly IDataSaubStatRepository<DataSaubStatDrillingQualityDto> dataSaubStatRepositoryMock = Substitute.For<IDataSaubStatRepository<DataSaubStatDrillingQualityDto>>();
|
||||
private readonly ITelemetryDataCache<TelemetryDataSaubDto> telemetryDataCacheMock = Substitute.For<ITelemetryDataCache<TelemetryDataSaubDto>>();
|
||||
private readonly ITelemetryDataSaubService dataSaubServiceMock = Substitute.For<ITelemetryDataSaubService>();
|
||||
private readonly ITelemetryService telemetryServiceMock = Substitute.For<ITelemetryService>();
|
||||
|
||||
private DataSaubStatDrillingQualityService dataSaubStatService;
|
||||
|
||||
public DataSaubStatDtillingQualityServiceTest()
|
||||
{
|
||||
dataSaubStatService = new DataSaubStatDrillingQualityService(
|
||||
dataSaubStatRepositoryMock,
|
||||
telemetryDataCacheMock,
|
||||
dataSaubServiceMock,
|
||||
telemetryServiceMock);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("DataSaubStat.test3.csv", "DataSaubStat.test3_result.csv")]
|
||||
[InlineData("DataSaubStat.test2.csv", "DataSaubStat.test2_result.csv")]
|
||||
[InlineData("DataSaubStat.test1.csv", "DataSaubStat.test1_result.csv")]
|
||||
public async Task Create_DataSaubStatDrillingQuality_From_CSVFile_ShouldReturn_Success(
|
||||
string pathMockData,
|
||||
string pathResult
|
||||
)
|
||||
{
|
||||
var mockData = CsvMockHelper.Get<TelemetryDataSaubMap>(pathMockData);
|
||||
var dtoMockData = mockData.Select(x => x.Adapt<TelemetryDataSaubDto>()).ToArray();
|
||||
|
||||
dataSaubServiceMock
|
||||
.Get(Arg.Any<int>(), Arg.Any<bool>(), Arg.Any<DateTimeOffset>(), Arg.Any<DateTimeOffset>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.Returns(dtoMockData);
|
||||
|
||||
//act
|
||||
var actualData = await dataSaubStatService.CreateStatDrillingQualityForTelemetry(1, DateTimeOffset.UnixEpoch, CancellationToken.None);
|
||||
|
||||
var mockDataResult = CsvMockHelper.Get<DataSaubStatDrillingQualityDtoMap>(pathResult);
|
||||
var expectedData = mockDataResult.Select(x => x.Adapt<DataSaubStatDrillingQualityDto>()).ToArray();
|
||||
|
||||
//assert
|
||||
var actual = actualData
|
||||
.OrderBy(d => d.IdFeedRegulator)
|
||||
.ToArray();
|
||||
|
||||
var expected = expectedData
|
||||
.OrderBy(d => d.IdFeedRegulator)
|
||||
.ToArray();
|
||||
|
||||
Assert.Equal(expected.Count(), actual.Count());
|
||||
|
||||
for (var i = 0; i < actual.Count(); i++)
|
||||
{
|
||||
var expectedItem = expected[i];
|
||||
var actualItem = actual[i];
|
||||
|
||||
Assert.True(Math.Abs(expectedItem.DepthStart - actualItem.DepthStart) < 0.000001);
|
||||
Assert.True(Math.Abs(expectedItem.DepthEnd - actualItem.DepthEnd) < 0.000001);
|
||||
Assert.True(Math.Abs(expectedItem.DepthDrillingQuality - actualItem.DepthDrillingQuality) < 0.000001);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudInfrastructure.Tests.Services;
|
||||
namespace AsbCloudInfrastructure.Tests.Services.DataSaubStat;
|
||||
|
||||
public class DataSaubStatServiceTest
|
||||
{
|
||||
private readonly int Gap = 5;
|
||||
private readonly IDataSaubStatRepository dataSaubStatRepositoryMock = Substitute.For<IDataSaubStatRepository>();
|
||||
private readonly IDataSaubStatRepository<DataSaubStatDto> dataSaubStatRepositoryMock = Substitute.For<IDataSaubStatRepository<DataSaubStatDto>>();
|
||||
private readonly ITelemetryDataCache<TelemetryDataSaubDto> telemetryDataCacheMock = Substitute.For<ITelemetryDataCache<TelemetryDataSaubDto>>();
|
||||
private readonly IDetectedOperationRepository detectedOperationRepositoryMock = Substitute.For<IDetectedOperationRepository>();
|
||||
private readonly ITelemetryDataSaubService dataSaubServiceMock = Substitute.For<ITelemetryDataSaubService>();
|
21
AsbCloudInfrastructure.Tests/Services/DataSaubStat/test1.csv
Normal file
21
AsbCloudInfrastructure.Tests/Services/DataSaubStat/test1.csv
Normal file
@ -0,0 +1,21 @@
|
||||
"id_telemetry","date","well_depth","bit_depth","block_speed","block_speed_sp","pressure","pressure_sp","axial_load","axial_load_sp","rotor_torque","rotor_torque_sp","id_feed_regulator"
|
||||
618,2023-02-24 06:52:03.000 +0500,303.545989990234,64.1760025024414,45.00,50.00,3.71015930175781,52.00,2.8034496307373,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,313.545989990234,63.5940017700195,46.00,50.00,3.69481015205383,52.00,2.04865455627441,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,323.545989990234,63.0130004882813,47.00,50.00,3.7329523563385,52.00,2.90703392028809,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,333.545989990234,62.4309997558594,48.00,50.00,3.70306921005249,52.00,2.17815017700195,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,343.545989990234,61.8499984741211,49.00,50.00,3.69618034362793,52.00,2.45234489440918,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,353.545989990234,61.2560005187988,50.00,50.00,3.72630000114441,52.00,3.2121467590332,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,363.545989990234,60.6679992675781,51.00,50.00,3.70950126647949,52.00,2.8408260345459,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,373.545989990234,60.0870018005371,52.00,50.00,3.73658561706543,52.00,1.16445922851563,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,383.545989990234,59.4939994812012,53.00,50.00,3.68171286582947,52.00,2.30134773254395,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,393.545989990234,58.9070014953613,54.00,50.00,3.72104644775391,52.00,1.91220664978027,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,403.545989990234,58.3199996948242,55.00,50.00,3.75041079521179,52.00,1.29618453979492,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,413.545989990234,57.7270011901856,56.00,50.00,3.71274995803833,52.00,2.0904655456543,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,423.545989990234,57.1389999389648,57.00,50.00,3.73990893363953,52.00,2.42434310913086,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,433.545989990234,56.5460014343262,58.00,50.00,3.7690634727478,52.00,2.07949066162109,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,443.545989990234,55.9589996337891,59.00,50.00,3.7951807975769,52.00,1.98602676391602,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,453.545989990234,55.3660011291504,60.00,50.00,3.84931874275208,52.00,2.41486930847168,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,463.545989990234,54.7719993591309,61.00,50.00,3.91031193733215,52.00,2.98539924621582,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,473.545989990234,54.1790008544922,62.00,50.00,3.95907807350159,52.00,2.65116500854492,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,483.545989990234,53.5919990539551,63.00,50.00,3.98743534088135,52.00,1.92432594299316,8.00,0.00,23.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,493.545989990234,53.0050010681152,64.00,50.00,4.02055215835571,52.00,2.56299781799316,8.00,0.00,23.00,1
|
|
@ -0,0 +1,2 @@
|
||||
"id_telemetry","depth_start","depth_end","id_feed_regulator","depth_drilling_quality"
|
||||
618,303.545989990234,493.545989990234,1,50.00
|
|
32
AsbCloudInfrastructure.Tests/Services/DataSaubStat/test2.csv
Normal file
32
AsbCloudInfrastructure.Tests/Services/DataSaubStat/test2.csv
Normal file
@ -0,0 +1,32 @@
|
||||
"id_telemetry","date","well_depth","bit_depth","block_speed","block_speed_sp","pressure","pressure_sp","axial_load","axial_load_sp","rotor_torque","rotor_torque_sp","id_feed_regulator"
|
||||
618,2023-02-24 06:52:03.000 +0500,205.00,204.00,100.00,80.00,80.00,105.00,0.00,10.00,10.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,205.00,204.99,90.00,80.00,70.00,105.00,0.00,10.00,10.00,13.00,0
|
||||
618,2023-02-24 06:52:03.000 +0500,205.00,205.00,80.00,80.00,150.00,105.00,3.00,10.00,10.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,207.00,207.00,70.00,80.00,57.00,105.00,4.00,10.00,10.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,210.00,210.00,78.00,80.00,62.00,105.00,8.00,10.00,10.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,210.00,209.00,82.00,80.00,93.00,105.00,0.00,10.00,10.00,13.00,0
|
||||
618,2023-02-24 06:52:03.000 +0500,210.00,209.77,81.00,80.00,32.00,105.00,0.30,10.00,10.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,210.00,210.00,90.00,80.00,66.00,70.00,7.00,10.00,11.00,13.00,2
|
||||
618,2023-02-24 06:52:03.000 +0500,213.00,213.00,90.00,80.00,33.00,70.00,6.00,10.00,12.00,13.00,2
|
||||
618,2023-02-24 06:52:03.000 +0500,216.00,216.00,30.00,80.00,74.00,70.00,5.00,10.00,12.00,13.00,2
|
||||
618,2023-02-24 06:52:03.000 +0500,219.00,219.00,5.00,80.00,35.00,70.00,7.00,10.00,12.50,13.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,222.00,222.00,90.00,80.00,99.00,70.00,2.00,10.00,13.60,13.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,222.00,221.00,33.00,80.00,20.00,70.00,0.00,10.00,13.00,13.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,222.00,222.00,100.00,100.00,96.00,70.00,4.00,10.00,12.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,225.00,225.00,106.00,100.00,78.00,70.00,5.00,10.00,11.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,228.00,228.00,102.00,100.00,77.00,70.00,6.00,10.00,12.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,231.00,231.00,98.00,100.00,85.00,70.00,8.00,12.00,11.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,234.00,234.00,200.00,100.00,32.00,70.00,5.00,12.00,10.00,15.00,0
|
||||
618,2023-02-24 06:52:03.000 +0500,237.00,237.00,200.00,100.00,88.00,70.00,9.00,12.00,10.00,15.00,0
|
||||
618,2023-02-24 06:52:03.000 +0500,240.00,240.00,94.00,100.00,63.00,70.00,6.00,12.00,11.00,15.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,240.00,233.00,96.00,100.00,66.00,70.00,0.00,12.00,10.00,15.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,240.00,240.00,82.00,80.00,92.00,105.00,0.50,12.00,11.00,15.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,243.00,243.00,12.00,80.00,100.00,105.00,11.50,12.00,12.00,15.00,3
|
||||
618,2023-02-24 06:52:03.000 +0500,246.00,246.00,15.00,80.00,92.00,105.00,11.00,12.00,11.00,15.00,3
|
||||
618,2023-02-24 06:52:03.000 +0500,249.00,249.00,36.00,80.00,90.00,105.00,12.00,12.00,14.00,15.00,3
|
||||
618,2023-02-24 06:52:03.000 +0500,252.00,252.00,55.00,80.00,60.00,105.00,12.50,12.00,13.00,15.00,3
|
||||
618,2023-02-24 06:52:03.000 +0500,255.00,255.00,78.00,80.00,90.00,105.00,12.00,12.00,14.00,15.00,3
|
||||
618,2023-02-24 06:52:03.000 +0500,258.00,258.00,33.00,80.00,80.00,105.00,10.00,12.00,14.70,15.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,261.00,261.00,54.00,80.00,70.00,105.00,10.00,12.00,18.00,15.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,262.00,262.00,55.00,80.00,90.00,105.00,10.00,12.00,13.00,15.00,0
|
||||
618,2023-02-24 06:52:03.000 +0500,262.00,261.00,57.00,80.00,90.00,105.00,0.00,12.00,10.00,15.00,0
|
|
@ -0,0 +1,8 @@
|
||||
"id_telemetry","depth_start","depth_end","id_feed_regulator","depth_drilling_quality"
|
||||
618,205.00,210.00,1,2.00
|
||||
618,210.00,219.00,2,6.00
|
||||
618,219.00,222.00,4,3.00
|
||||
618,222.00,234.00,1,9.00
|
||||
618,240.00,243.00,1,3.00
|
||||
618,243.00,258.00,3,12.00
|
||||
618,258.00,262.00,4,3.00
|
|
33
AsbCloudInfrastructure.Tests/Services/DataSaubStat/test3.csv
Normal file
33
AsbCloudInfrastructure.Tests/Services/DataSaubStat/test3.csv
Normal file
@ -0,0 +1,33 @@
|
||||
"id_telemetry","date","well_depth","bit_depth","block_speed","block_speed_sp","pressure","pressure_sp","axial_load","axial_load_sp","rotor_torque","rotor_torque_sp","id_feed_regulator"
|
||||
618,2023-02-24 06:52:03.000 +0500,326.00,325.00,100.00,80.00,80.00,105.00,0.00,10.00,10.00,13.00,0
|
||||
618,2023-02-24 06:52:03.000 +0500,326.00,325.99,90.00,80.00,70.00,105.00,0.00,10.00,10.00,13.00,0
|
||||
618,2023-02-24 06:52:03.000 +0500,326.00,326.00,87.00,90.00,150.00,105.00,3.00,10.00,10.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,328.00,328.00,70.00,80.00,57.00,105.00,4.00,10.00,10.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,331.00,331.00,92.00,90.00,62.00,105.00,8.00,10.00,10.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,331.00,330.00,82.00,80.00,93.00,105.00,0.00,10.00,10.00,13.00,0
|
||||
618,2023-02-24 06:52:03.000 +0500,331.00,330.77,81.00,80.00,32.00,105.00,9.90,10.00,10.00,13.00,3
|
||||
618,2023-02-24 06:52:03.000 +0500,331.00,331.00,90.00,80.00,66.00,70.00,7.00,10.00,11.00,13.00,3
|
||||
618,2023-02-24 06:52:03.000 +0500,334.00,334.00,90.00,80.00,33.00,70.00,10.30,10.00,12.00,13.00,3
|
||||
618,2023-02-24 06:52:03.000 +0500,337.00,337.00,79.00,80.00,74.00,70.00,5.00,10.00,12.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,340.00,340.00,83.00,80.00,35.00,70.00,7.00,10.00,12.50,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,343.00,343.00,90.00,80.00,99.00,70.00,2.00,10.00,13.60,13.00,2
|
||||
618,2023-02-24 06:52:03.000 +0500,343.00,342.00,33.00,80.00,20.00,70.00,0.00,10.00,13.00,13.00,2
|
||||
618,2023-02-24 06:52:03.000 +0500,343.00,343.00,100.00,100.00,96.00,70.00,4.00,10.00,12.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,346.00,346.00,106.00,100.00,78.00,70.00,5.00,10.00,11.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,349.00,349.00,102.00,100.00,77.00,70.00,6.00,10.00,12.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,352.00,352.00,98.00,100.00,85.00,70.00,8.00,12.00,11.00,13.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,355.00,355.00,200.00,100.00,69.00,70.00,5.00,12.00,10.00,15.00,2
|
||||
618,2023-02-24 06:52:03.000 +0500,358.00,358.00,200.00,100.00,72.00,70.00,9.00,12.00,10.00,15.00,2
|
||||
618,2023-02-24 06:52:03.000 +0500,361.00,361.00,94.00,100.00,63.00,70.00,6.00,12.00,11.00,15.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,361.00,354.00,96.00,100.00,66.00,70.00,0.00,12.00,15.00,15.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,361.00,361.00,82.00,80.00,92.00,105.00,0.50,12.00,15.20,15.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,364.00,364.00,12.00,80.00,100.00,105.00,11.50,12.00,14.50,15.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,367.00,367.00,15.00,80.00,92.00,105.00,11.00,12.00,11.00,15.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,370.00,370.00,81.00,80.00,90.00,105.00,12.00,12.00,14.00,15.00,1
|
||||
618,2023-02-24 06:52:03.000 +0500,373.00,373.00,55.00,80.00,60.00,105.00,12.50,12.00,13.00,15.00,3
|
||||
618,2023-02-24 06:52:03.000 +0500,376.00,376.00,78.00,80.00,90.00,105.00,12.00,12.00,14.00,15.00,3
|
||||
618,2023-02-24 06:52:03.000 +0500,379.00,379.00,33.00,80.00,80.00,105.00,10.00,12.00,14.70,15.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,382.00,382.00,54.00,80.00,70.00,105.00,10.00,12.00,18.00,15.00,4
|
||||
618,2023-02-24 06:52:03.000 +0500,383.00,383.00,55.00,80.00,90.00,105.00,10.00,12.00,13.00,15.00,0
|
||||
618,2023-02-24 06:52:03.000 +0500,383.00,382.00,57.00,80.00,90.00,105.00,0.00,12.00,10.00,15.00,0
|
||||
|
|
@ -0,0 +1,10 @@
|
||||
"id_telemetry","depth_start","depth_end","id_feed_regulator","depth_drilling_quality"
|
||||
618,326.00,331.00,1,2.00
|
||||
618,331.00,337.00,3,3.00
|
||||
618,337.00,343.00,1,6.00
|
||||
618,343.00,355.00,1,9.00
|
||||
618,355.00,361.00,2,6.00
|
||||
618,361.00,370.00,4,6.00
|
||||
618,370.00,373.00,1,3.00
|
||||
618,373.00,379.00,3,6.00
|
||||
618,379.00,383.00,4,3.00
|
|
@ -1,22 +1,13 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Background.PeriodicWorks;
|
||||
|
||||
/// <summary>
|
||||
/// задача по добавлению данных в таблицу DataSaubStat, которая используется для построения РТК-отчета
|
||||
/// задача по добавлению данных в таблицу t_data_saub_stat, которая используется для построения РТК-отчета
|
||||
/// </summary>
|
||||
internal class WorkDataSaubStat : Work
|
||||
{
|
||||
@ -31,7 +22,7 @@ internal class WorkDataSaubStat : Work
|
||||
{
|
||||
var dataSaubStatService = services.GetRequiredService<IDataSaubStatService>();
|
||||
|
||||
if (dataSaubStatService != null )
|
||||
if (dataSaubStatService != null)
|
||||
await dataSaubStatService.CreateStatAsync(Gap, onProgressCallback, token);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Background.PeriodicWorks;
|
||||
|
||||
/// <summary>
|
||||
/// задача по добавлению данных в таблицу t_data_saub_stat_drilling_quality,
|
||||
/// которая используется для построения страницы "Качество"
|
||||
/// </summary>
|
||||
internal class WorkDataSaubStatDrillingQuality : Work
|
||||
{
|
||||
private int Gap = 60;
|
||||
|
||||
public WorkDataSaubStatDrillingQuality() : base("Generate DataSaubStatDrillingQuality entries and save them into Db")
|
||||
{
|
||||
Timeout = TimeSpan.FromMinutes(10);
|
||||
}
|
||||
|
||||
protected override async Task Action(string id, IServiceProvider services, Action<string, double?> onProgressCallback, CancellationToken token)
|
||||
{
|
||||
var dataSaubStatService = services.GetRequiredService<IDataSaubStatDrillingQualityService>();
|
||||
|
||||
if (dataSaubStatService != null)
|
||||
await dataSaubStatService.CreateStatAsync(Gap, onProgressCallback, token);
|
||||
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Services.DailyReport;
|
||||
using AsbCloudApp.Services.Notifications;
|
||||
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
||||
using AsbCloudApp.Services.WellReport;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
@ -41,14 +42,13 @@ using AsbCloudInfrastructure.Services.Trajectory.Parser;
|
||||
using AsbCloudInfrastructure.Services.WellOperations.Factories;
|
||||
using AsbCloudInfrastructure.Services.WellOperationService;
|
||||
using AsbCloudInfrastructure.Services.WellOperationService.WellOperationService;
|
||||
using AsbCloudInfrastructure.Services.WellReport;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using AsbCloudApp.Services.WellReport;
|
||||
using AsbCloudInfrastructure.Services.WellReport;
|
||||
|
||||
namespace AsbCloudInfrastructure;
|
||||
|
||||
@ -318,8 +318,10 @@ public static class DependencyInjection
|
||||
services.AddTransient<WellInfoService>();
|
||||
services.AddTransient<IHelpPageService, HelpPageService>();
|
||||
services.AddTransient<IScheduleReportService, ScheduleReportService>();
|
||||
services.AddTransient<IDataSaubStatRepository, DataSaubStatRepository>();
|
||||
services.AddTransient<IDataSaubStatRepository<DataSaubStatDto>, DataSaubStatRepository<DataSaubStat, DataSaubStatDto>>();
|
||||
services.AddTransient<IDataSaubStatRepository<DataSaubStatDrillingQualityDto>, DataSaubStatRepository<DataSaubStatDrillingQuality, DataSaubStatDrillingQualityDto>>();
|
||||
services.AddTransient<IDataSaubStatService, DataSaubStatService>();
|
||||
services.AddTransient<IDataSaubStatDrillingQualityService, DataSaubStatDrillingQualityService>();
|
||||
services.AddTransient<IWellOperationService, WellOperationService>();
|
||||
|
||||
services.AddTransient<
|
||||
|
@ -1,5 +1,4 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
@ -12,8 +11,9 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Repository;
|
||||
|
||||
public class DataSaubStatRepository : IDataSaubStatRepository
|
||||
public class DataSaubStatRepository<TEntity, TDto> : IDataSaubStatRepository<TDto>
|
||||
where TDto : AsbCloudApp.Data.IDataSaubStatDto
|
||||
where TEntity : class, AsbCloudDb.Model.IDataSaubStat
|
||||
{
|
||||
private readonly IAsbCloudDbContext db;
|
||||
private readonly ITelemetryService telemetryService;
|
||||
@ -22,16 +22,15 @@ public class DataSaubStatRepository : IDataSaubStatRepository
|
||||
{
|
||||
db = dbContext;
|
||||
this.telemetryService = telemetryService;
|
||||
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<DataSaubStatDto>> GetLastsAsync(int[] idTelemetries, CancellationToken token)
|
||||
public async Task<IEnumerable<TDto>> GetLastsAsync(int[] idTelemetries, CancellationToken token)
|
||||
{
|
||||
var timeZoneOffsets = idTelemetries
|
||||
.Distinct()
|
||||
.ToDictionary(idTelemetry => idTelemetry, idTelemetry => TimeSpan.FromHours(telemetryService.GetTimezone(idTelemetry).Hours));
|
||||
|
||||
var stats = await db.Set<DataSaubStat>()
|
||||
var stats = await db.Set<TEntity>()
|
||||
.Where(s => idTelemetries.Contains(s.IdTelemetry))
|
||||
.GroupBy(s => s.IdTelemetry, (key, group) => group.OrderByDescending(el => el.DateEnd).First())
|
||||
.ToArrayAsync(token);
|
||||
@ -41,51 +40,60 @@ public class DataSaubStatRepository : IDataSaubStatRepository
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<DataSaubStatDto>> GetAsync(int idTelemetry, DateTimeOffset geDate, DateTimeOffset leDate, CancellationToken token)
|
||||
public async Task<IEnumerable<TDto>> GetAsync(IEnumerable<int> idsTelemetries, DateTimeOffset geDate, DateTimeOffset leDate, CancellationToken token)
|
||||
{
|
||||
//todo
|
||||
var timeSpanDict = new Dictionary<int, TimeSpan>();
|
||||
|
||||
idsTelemetries = idsTelemetries.Distinct();
|
||||
foreach (var idTelemetry in idsTelemetries)
|
||||
{
|
||||
var timeSpan = TimeSpan.FromHours(telemetryService.GetTimezone(idTelemetry).Hours);
|
||||
timeSpanDict.Add(idTelemetry, timeSpan);
|
||||
}
|
||||
|
||||
var geDateUtc = geDate.ToUniversalTime();
|
||||
var leDateUtc = leDate.ToUniversalTime();
|
||||
|
||||
var stats = await db.Set<DataSaubStat>()
|
||||
.Where(s => s.IdTelemetry == idTelemetry)
|
||||
var stats = await db.Set<TEntity>()
|
||||
.Where(s => idsTelemetries.Contains(s.IdTelemetry))
|
||||
.Where(s => s.DateStart >= geDateUtc)
|
||||
.Where(s => s.DateEnd <= leDateUtc)
|
||||
.ToArrayAsync(token);
|
||||
|
||||
var result = stats.Select(s => ConvertToDto(s, timeSpan));
|
||||
var result = stats.Select(s => ConvertToDto(s, timeSpanDict[s.IdTelemetry]));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> InsertRangeAsync(IEnumerable<DataSaubStatDto> dataSaubStats, CancellationToken token)
|
||||
public async Task<int> InsertRangeAsync(IEnumerable<TDto> dataSaubStats, CancellationToken token)
|
||||
{
|
||||
var entities = dataSaubStats.Select(data => ConvertToEntity(data));
|
||||
db.Set<DataSaubStat>().AddRange(entities);
|
||||
db.Set<TEntity>().AddRange(entities);
|
||||
return await db.SaveChangesAsync(token);
|
||||
}
|
||||
|
||||
private static DataSaubStatDto ConvertToDto(DataSaubStat entity, TimeSpan timeSpan)
|
||||
private static TDto ConvertToDto(TEntity entity, TimeSpan timeSpan)
|
||||
{
|
||||
var dto = entity.Adapt<DataSaubStatDto>();
|
||||
var dto = entity.Adapt<TDto>();
|
||||
dto.DateStart = dto.DateStart.ToOffset(timeSpan);
|
||||
dto.DateEnd = dto.DateEnd.ToOffset(timeSpan);
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
private static DataSaubStat ConvertToEntity(DataSaubStatDto dto)
|
||||
private static TEntity ConvertToEntity(TDto dto)
|
||||
{
|
||||
var entity = dto.Adapt<DataSaubStat>();
|
||||
var entity = dto.Adapt<TEntity>();
|
||||
entity.DateStart = dto.DateStart.ToUniversalTime();
|
||||
entity.DateEnd = dto.DateEnd.ToUniversalTime();
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private IQueryable<DataSaubStat> BuildQuery(TelemetryPartDeleteRequest request)
|
||||
private IQueryable<TEntity> BuildQuery(TelemetryPartDeleteRequest request)
|
||||
{
|
||||
var query = db.Set<DataSaubStat>()
|
||||
var query = db.Set<TEntity>()
|
||||
.Where(o => o.IdTelemetry == request.IdTelemetry);
|
||||
|
||||
if (request.LeDate is not null)
|
||||
@ -106,7 +114,7 @@ public class DataSaubStatRepository : IDataSaubStatRepository
|
||||
public async Task<int> DeleteAsync(TelemetryPartDeleteRequest request, CancellationToken token)
|
||||
{
|
||||
var query = BuildQuery(request);
|
||||
db.Set<DataSaubStat>().RemoveRange(query);
|
||||
db.Set<TEntity>().RemoveRange(query);
|
||||
return await db.SaveChangesAsync(token);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,230 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services;
|
||||
|
||||
|
||||
public class DataSaubStatDrillingQualityService : IDataSaubStatDrillingQualityService
|
||||
{
|
||||
private IDataSaubStatRepository<DataSaubStatDrillingQualityDto> dataSaubStatDrillingQualityRepository;
|
||||
private ITelemetryDataSaubService dataSaubService;
|
||||
private ITelemetryDataCache<TelemetryDataSaubDto> telemetryDataCache;
|
||||
private ITelemetryService telemetryService;
|
||||
|
||||
private static int IdFeedRegulatorRop = 1;
|
||||
private static int IdFeedRegulatorPressureDelta = 2;
|
||||
private static int IdFeedRegulatorAxialLoad = 3;
|
||||
private static int IdFeedRegulatorTorque = 4;
|
||||
|
||||
public Dictionary<int, Predicate<TelemetryDataSaubDto>> QualitySettingsForFeedRegulators { get; }
|
||||
|
||||
public DataSaubStatDrillingQualityService(
|
||||
IDataSaubStatRepository<DataSaubStatDrillingQualityDto> dataSaubStatDrillingQualityRepository,
|
||||
ITelemetryDataCache<TelemetryDataSaubDto> telemetryDataCache,
|
||||
ITelemetryDataSaubService dataSaubService,
|
||||
ITelemetryService telemetryService)
|
||||
{
|
||||
this.dataSaubStatDrillingQualityRepository = dataSaubStatDrillingQualityRepository;
|
||||
this.dataSaubService = dataSaubService;
|
||||
this.telemetryDataCache = telemetryDataCache;
|
||||
this.telemetryService = telemetryService;
|
||||
|
||||
Predicate<TelemetryDataSaubDto> hasQualityWithIdFeedRegulator1 = (TelemetryDataSaubDto spanItem)
|
||||
=> (spanItem.BlockSpeed >= spanItem.BlockSpeedSp * 0.95
|
||||
&& spanItem.BlockSpeed <= spanItem.BlockSpeedSp * 1.05);
|
||||
|
||||
Predicate<TelemetryDataSaubDto> hasQualityWithIdFeedRegulator2 = (TelemetryDataSaubDto spanItem)
|
||||
=> (spanItem.Pressure >= (spanItem.PressureSp) - 5
|
||||
&& spanItem.Pressure <= (spanItem.PressureSp) + 5);
|
||||
|
||||
Predicate<TelemetryDataSaubDto> hasQualityWithIdFeedRegulator3 = (TelemetryDataSaubDto spanItem)
|
||||
=> (spanItem.AxialLoad >= (spanItem.AxialLoadSp - 0.5)
|
||||
&& spanItem.AxialLoad <= (spanItem.AxialLoadSp + 0.5));
|
||||
|
||||
Predicate<TelemetryDataSaubDto> hasQualityWithIdFeedRegulator4 = (TelemetryDataSaubDto spanItem)
|
||||
=> (spanItem.RotorTorque >= (spanItem.RotorTorqueSp - 0.5)
|
||||
&& spanItem.RotorTorque <= (spanItem.RotorTorqueSp + 0.5));
|
||||
|
||||
QualitySettingsForFeedRegulators = new Dictionary<int, Predicate<TelemetryDataSaubDto>>() {
|
||||
{ IdFeedRegulatorRop, hasQualityWithIdFeedRegulator1 },
|
||||
{ IdFeedRegulatorPressureDelta, hasQualityWithIdFeedRegulator2 },
|
||||
{ IdFeedRegulatorAxialLoad, hasQualityWithIdFeedRegulator3 },
|
||||
{ IdFeedRegulatorTorque, hasQualityWithIdFeedRegulator4 },
|
||||
};
|
||||
}
|
||||
|
||||
public async Task CreateStatAsync(int lastDaysFilter, Action<string, double?> onProgressCallback, CancellationToken token)
|
||||
{
|
||||
var cacheRequest = new TelemetryDataRequest()
|
||||
{
|
||||
GeDate = DateTime.UtcNow.AddDays(-lastDaysFilter)
|
||||
};
|
||||
var idTelemetries = telemetryDataCache.GetIds(cacheRequest).ToArray();
|
||||
|
||||
if (!idTelemetries.Any())
|
||||
return;
|
||||
|
||||
var stats = await dataSaubStatDrillingQualityRepository.GetLastsAsync(idTelemetries, token);
|
||||
|
||||
for (var i = 0; i < idTelemetries.Length; i++)
|
||||
{
|
||||
var idTelemetry = idTelemetries[i];
|
||||
var lastDate = stats.FirstOrDefault(s => s.IdTelemetry == idTelemetry)?.DateEnd.ToUniversalTime() ?? DateTimeOffset.UnixEpoch;
|
||||
var result = await CreateStatDrillingQualityForTelemetry(idTelemetry, lastDate, token);
|
||||
|
||||
var statsCount = result.Count();
|
||||
if (result.Any())
|
||||
statsCount = await dataSaubStatDrillingQualityRepository.InsertRangeAsync(result, token);
|
||||
|
||||
if (onProgressCallback != null)
|
||||
onProgressCallback($"Calculate stat for telemetry: {idTelemetry}; from {lastDate}; results count: {statsCount};", 1d * i / idTelemetries.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<DataSaubStatDrillingQualityDto>> CreateStatDrillingQualityForTelemetry(
|
||||
int idTelemetry,
|
||||
DateTimeOffset geDate,
|
||||
CancellationToken token)
|
||||
{
|
||||
var leDate = DateTimeOffset.UtcNow;
|
||||
var result = new List<DataSaubStatDrillingQualityDto>();
|
||||
|
||||
var dataSaub = await dataSaubService.Get(idTelemetry, true, geDate, leDate, 100_000, token);
|
||||
|
||||
if (!dataSaub.Any())
|
||||
return result;
|
||||
|
||||
if (dataSaub is not TelemetryDataSaubDto[] dataSaubArray)
|
||||
dataSaubArray = dataSaub.ToArray();
|
||||
|
||||
foreach (var item in QualitySettingsForFeedRegulators)
|
||||
{
|
||||
var data = CreateDataSaubStatDrillingQuality(item.Key, item.Value, dataSaubArray);
|
||||
result.AddRange(data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IEnumerable<DataSaubStatDrillingQualityDto> CreateDataSaubStatDrillingQuality(
|
||||
int idFeedRegulator,
|
||||
Predicate<TelemetryDataSaubDto> checkQuality,
|
||||
TelemetryDataSaubDto[] dataSaub)
|
||||
{
|
||||
var result = new List<DataSaubStatDrillingQualityDto>();
|
||||
|
||||
var indexStart = 0;
|
||||
var indexEnd = 0;
|
||||
|
||||
while (indexEnd < dataSaub.Count() - 1)
|
||||
{
|
||||
indexStart = Array.FindIndex(dataSaub, indexEnd, t => t.IdFeedRegulator == idFeedRegulator);
|
||||
if (indexStart < 0)
|
||||
break;
|
||||
|
||||
indexEnd = FindIndexEnd(indexStart, idFeedRegulator, dataSaub);
|
||||
|
||||
var length = indexEnd - indexStart + 1;
|
||||
var subset = dataSaub.AsSpan(indexStart, length);
|
||||
|
||||
if ((subset[^1].WellDepth - subset[0].WellDepth) < 0.15)
|
||||
continue; // мелкие выборки не учитываем.
|
||||
|
||||
var stats = CalcStatsDrillingQuality(idFeedRegulator, subset, checkQuality);
|
||||
result.Add(stats);
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int FindIndexEnd(int indexStart, int idFeedRegulator, TelemetryDataSaubDto[] dataSaub)
|
||||
{
|
||||
var indexEnd = indexStart + 1;
|
||||
for (var i = indexStart + 1; i < dataSaub.Count(); i++)
|
||||
{
|
||||
if (dataSaub[i].WellDepth >= dataSaub[i - 1].WellDepth)
|
||||
{
|
||||
indexEnd = i;
|
||||
}
|
||||
if (dataSaub[i].IdFeedRegulator != idFeedRegulator)
|
||||
break;
|
||||
}
|
||||
return indexEnd;
|
||||
}
|
||||
|
||||
private static DataSaubStatDrillingQualityDto CalcStatsDrillingQuality(
|
||||
int idFeedRegulator,
|
||||
Span<TelemetryDataSaubDto> dataSaub,
|
||||
Predicate<TelemetryDataSaubDto> predicate
|
||||
)
|
||||
{
|
||||
var result = new DataSaubStatDrillingQualityDto();
|
||||
result.IdTelemetry = dataSaub[0].IdTelemetry;
|
||||
result.IdFeedRegulator = idFeedRegulator;
|
||||
result.DepthStart = dataSaub[0].WellDepth;
|
||||
result.DepthEnd = dataSaub[^1].WellDepth;
|
||||
result.DateStart = dataSaub[0].DateTime;
|
||||
result.DateEnd = dataSaub[^1].DateTime;
|
||||
|
||||
var depthDrillingQuality = 0.0;
|
||||
for (var i = 0; i < dataSaub.Length - 1; i++)
|
||||
{
|
||||
if (predicate(dataSaub[i]))
|
||||
{
|
||||
depthDrillingQuality += dataSaub[i + 1].WellDepth - dataSaub[i].WellDepth;
|
||||
}
|
||||
}
|
||||
result.DepthDrillingQuality = depthDrillingQuality;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<DrillingQualityDto>> GetStatAsync(DrillingQualityRequest request, CancellationToken token)
|
||||
{
|
||||
var telemetries = telemetryService.GetOrDefaultTelemetriesByIdsWells(request.IdsWell);
|
||||
var idsTelemetriesWithIdWell = telemetries
|
||||
.Where(t => t.IdWell.HasValue)
|
||||
.ToDictionary(t => t.Id, t => t.IdWell!.Value);
|
||||
|
||||
var dataSaubStatDrillingQuality = await dataSaubStatDrillingQualityRepository.GetAsync(idsTelemetriesWithIdWell.Keys, request.GeDate, request.LeDate, token);
|
||||
|
||||
var dtosGroupedByIdTelemetries = dataSaubStatDrillingQuality
|
||||
.GroupBy(s => new { s.IdTelemetry, s.IdFeedRegulator })
|
||||
.Select(stat => new
|
||||
{
|
||||
IdFeedRegulator = stat.Key.IdFeedRegulator,
|
||||
IdTelemetry = stat.Key.IdTelemetry,
|
||||
Kpd = (stat.Sum(s => s.DepthDrillingQuality) / stat.Sum(s => s.DepthEnd - s.DepthStart)) * 100,
|
||||
})
|
||||
.GroupBy(stat => stat.IdTelemetry);
|
||||
|
||||
var result = new List<DrillingQualityDto>();
|
||||
foreach (var dtos in dtosGroupedByIdTelemetries)
|
||||
{
|
||||
var kpdValuesByIdFeedRegulator = dtos
|
||||
.GroupBy(d => d.IdFeedRegulator)
|
||||
.ToDictionary(d => d.Key, d => d.FirstOrDefault()!.Kpd);
|
||||
|
||||
var item = new DrillingQualityDto()
|
||||
{
|
||||
IdWell = idsTelemetriesWithIdWell[dtos.Key],
|
||||
KpdAxialLoad = kpdValuesByIdFeedRegulator.GetValueOrDefault(IdFeedRegulatorAxialLoad),
|
||||
KpdPressureDelta = kpdValuesByIdFeedRegulator.GetValueOrDefault(IdFeedRegulatorPressureDelta),
|
||||
KpdRop = kpdValuesByIdFeedRegulator.GetValueOrDefault(IdFeedRegulatorRop),
|
||||
KpdTorque = kpdValuesByIdFeedRegulator.GetValueOrDefault(IdFeedRegulatorTorque)
|
||||
};
|
||||
|
||||
result.Add(item);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -16,13 +16,13 @@ namespace AsbCloudInfrastructure.Services;
|
||||
|
||||
public class DataSaubStatService : IDataSaubStatService
|
||||
{
|
||||
private IDataSaubStatRepository dataSaubStatRepository;
|
||||
private IDataSaubStatRepository<DataSaubStatDto> dataSaubStatRepository;
|
||||
private ITelemetryDataCache<TelemetryDataSaubDto> telemetryDataCache;
|
||||
private ITelemetryDataSaubService dataSaubService;
|
||||
private IDetectedOperationRepository detectedOperationRepository;
|
||||
|
||||
public DataSaubStatService(
|
||||
IDataSaubStatRepository dataSaubStatRepository,
|
||||
IDataSaubStatRepository<DataSaubStatDto> dataSaubStatRepository,
|
||||
ITelemetryDataCache<TelemetryDataSaubDto> telemetryDataCache,
|
||||
ITelemetryDataSaubService dataSaubService,
|
||||
IDetectedOperationRepository detectedOperationRepository)
|
||||
@ -51,7 +51,7 @@ public class DataSaubStatService : IDataSaubStatService
|
||||
var idTelemetry = idTelemetries[i];
|
||||
var lastDate = stats.FirstOrDefault(s => s.IdTelemetry == idTelemetry)?.DateEnd.ToUniversalTime() ?? DateTimeOffset.UnixEpoch;
|
||||
var statsCount = await CreateStatForTelemetryFromDate(idTelemetry, lastDate, token);
|
||||
if(onProgressCallback != null)
|
||||
if (onProgressCallback != null)
|
||||
onProgressCallback($"Calculate stat for telemetry: {idTelemetry}; from {lastDate}; results count: {statsCount};", 1d * i / idTelemetries.Length);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public class ProcessMapReportDrillingService : IProcessMapReportDrillingService
|
||||
private readonly IWellService wellService;
|
||||
private readonly IChangeLogRepository<ProcessMapPlanRotorDto, ProcessMapPlanBaseRequestWithWell> processMapPlanRotorRepository;
|
||||
private readonly IChangeLogRepository<ProcessMapPlanSlideDto, ProcessMapPlanBaseRequestWithWell> processMapPlanSlideRepository;
|
||||
private readonly IDataSaubStatRepository dataSaubStatRepository;
|
||||
private readonly IDataSaubStatRepository<DataSaubStatDto> dataSaubStatRepository;
|
||||
private readonly IWellOperationRepository wellOperationRepository;
|
||||
private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
|
||||
private readonly IWellOperationService wellOperationService;
|
||||
@ -31,7 +31,7 @@ public class ProcessMapReportDrillingService : IProcessMapReportDrillingService
|
||||
public ProcessMapReportDrillingService(IWellService wellService,
|
||||
IChangeLogRepository<ProcessMapPlanRotorDto, ProcessMapPlanBaseRequestWithWell> processMapPlanRotorRepository,
|
||||
IChangeLogRepository<ProcessMapPlanSlideDto, ProcessMapPlanBaseRequestWithWell> processMapPlanSlideRepository,
|
||||
IDataSaubStatRepository dataSaubStatRepository,
|
||||
IDataSaubStatRepository<DataSaubStatDto> dataSaubStatRepository,
|
||||
IWellOperationRepository wellOperationRepository,
|
||||
IWellOperationCategoryRepository wellOperationCategoryRepository,
|
||||
IWellOperationService wellOperationService
|
||||
@ -88,7 +88,7 @@ public class ProcessMapReportDrillingService : IProcessMapReportDrillingService
|
||||
var geDate = wellOperations.Min(p => p.DateStart);
|
||||
var leDate = wellOperations.Max(p => (p.DateStart.AddHours(p.DurationHours)));
|
||||
var dataSaubStats =
|
||||
(await dataSaubStatRepository.GetAsync(well.IdTelemetry.Value, geDate, leDate, token)).ToArray();
|
||||
(await dataSaubStatRepository.GetAsync([well.IdTelemetry.Value], geDate, leDate, token)).ToArray();
|
||||
|
||||
if (!dataSaubStats.Any())
|
||||
return Enumerable.Empty<ProcessMapReportDataSaubStatDto>();
|
||||
|
@ -49,6 +49,8 @@ public class CsvSerializer<T>
|
||||
HandleRow(props.Select(p => CsvSerializer<T>.Escape(Fromat(p.GetValue(item)))));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private string Fromat(object? obj)
|
||||
{
|
||||
if (obj is double objDouble)
|
||||
|
@ -1,3 +1,4 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Data.WITS;
|
||||
using AsbCloudApp.Repositories;
|
||||
@ -35,7 +36,8 @@ public class TelemetryDataEditorService : ITelemetryDataEditorService
|
||||
public TelemetryDataEditorService(
|
||||
ITelemetryDataSaubService dataSaubService,
|
||||
ITelemetryDataService<TelemetryDataSpinDto> dataSpinService,
|
||||
IDataSaubStatRepository dataSaubStatRepository,
|
||||
IDataSaubStatRepository<DataSaubStatDto> dataSaubStatRepository,
|
||||
IDataSaubStatRepository<DataSaubStatDrillingQualityDto> dataSaubStatDrillingQualityRepository,
|
||||
IMessageRepository messageRepository,
|
||||
IDrillTestRepository drillTestRepository,
|
||||
ILimitingParameterRepository limitingParameterRepository,
|
||||
@ -54,6 +56,7 @@ public class TelemetryDataEditorService : ITelemetryDataEditorService
|
||||
dataSaubService,
|
||||
dataSpinService,
|
||||
dataSaubStatRepository,
|
||||
dataSaubStatDrillingQualityRepository,
|
||||
messageRepository,
|
||||
drillTestRepository,
|
||||
limitingParameterRepository,
|
||||
|
@ -33,6 +33,7 @@ public class Startup
|
||||
backgroundWorker.Add<WellInfoService.WorkWellInfoUpdate>(TimeSpan.FromMinutes(30));
|
||||
backgroundWorker.Add<WorkOperationDetection>(TimeSpan.FromMinutes(0));
|
||||
backgroundWorker.Add<WorkDataSaubStat>(TimeSpan.FromMinutes(0));
|
||||
backgroundWorker.Add<WorkDataSaubStatDrillingQuality>(TimeSpan.FromMinutes(0));
|
||||
backgroundWorker.Add<WorkLimitingParameterCalc>(TimeSpan.FromMinutes(0));
|
||||
backgroundWorker.Add(MakeMemoryMonitoringWork(), TimeSpan.FromMinutes(0));
|
||||
|
||||
|
@ -10,12 +10,12 @@ namespace AsbCloudWebApi.IntegrationTests.Repository;
|
||||
|
||||
public class DataSaubStatRepositoryTest : BaseIntegrationTest
|
||||
{
|
||||
private readonly IDataSaubStatRepository dataSaubStatRepository;
|
||||
private readonly IDataSaubStatRepository<DataSaubStatDto> dataSaubStatRepository;
|
||||
|
||||
public DataSaubStatRepositoryTest(WebAppFactoryFixture factory)
|
||||
: base(factory)
|
||||
{
|
||||
dataSaubStatRepository = scope.ServiceProvider.GetRequiredService<IDataSaubStatRepository>();
|
||||
dataSaubStatRepository = scope.ServiceProvider.GetRequiredService<IDataSaubStatRepository<DataSaubStatDto>>();
|
||||
dbContext.CleanupDbSet<DataSaubStat>();
|
||||
}
|
||||
|
||||
|
43
AsbCloudWebApi/Controllers/DrillingQualityController.cs
Normal file
43
AsbCloudWebApi/Controllers/DrillingQualityController.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Контроллер для построения страницы "Качество"
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class DrillingQualityController : ControllerBase
|
||||
{
|
||||
private readonly IDataSaubStatDrillingQualityService dataSaubStatDrillingQualityService;
|
||||
|
||||
public DrillingQualityController(IDataSaubStatDrillingQualityService dataSaubStatDrillingQualityService)
|
||||
{
|
||||
this.dataSaubStatDrillingQualityService = dataSaubStatDrillingQualityService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает данные для страницы "Качество"
|
||||
/// </summary>
|
||||
/// <param name="request">Параметры запроса</param>
|
||||
/// <param name="token"> Токен отмены задачи </param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("drillingQuality")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(IEnumerable<DrillingQualityDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetDataSaubStatDrillingQualityAsync(
|
||||
[FromQuery] DrillingQualityRequest request, CancellationToken token)
|
||||
{
|
||||
var result = await dataSaubStatDrillingQualityService.GetStatAsync(request, token);
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user