forked from ddrilling/AsbCloudServer
Merge branch 'dev' into feature/daily_report
# Conflicts: # AsbCloudInfrastructure/DependencyInjection.cs
This commit is contained in:
commit
76b6f7e843
@ -34,16 +34,14 @@ namespace AsbCloudApp.Data.User
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Email
|
/// Email
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
|
||||||
[RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "Некорректный email")]
|
[RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "Некорректный email")]
|
||||||
public string Email { get; set; } = null!;
|
public string? Email { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Phone
|
/// Phone
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
|
||||||
[RegularExpression(@"^(?:\+7|8)\s?(?:\(\d{3}\)|\d{3})\s?\d{3}-?\d{2}-?\d{2}$", ErrorMessage = "Некорректный номер телефона")]
|
[RegularExpression(@"^(?:\+7|8)\s?(?:\(\d{3}\)|\d{3})\s?\d{3}-?\d{2}-?\d{2}$", ErrorMessage = "Некорректный номер телефона")]
|
||||||
public string Phone { get; set; } = null!;
|
public string? Phone { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Должность
|
/// Должность
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.DetectedOperation;
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -62,13 +60,5 @@ namespace AsbCloudApp.Services
|
|||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<DetectedOperationStatDto>?> GetOperationsStatAsync(DetectedOperationRequest request, CancellationToken token);
|
Task<IEnumerable<DetectedOperationStatDto>?> GetOperationsStatAsync(DetectedOperationRequest request, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Выгрузка в Excel
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idsWells"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<Stream> ExportAsync(IEnumerable<int> idsWells, CancellationToken token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8892
AsbCloudDb/Migrations/20231110094226_UpdateTable_t_contact_Set_Email_and_Phone_Nullable.Designer.cs
generated
Normal file
8892
AsbCloudDb/Migrations/20231110094226_UpdateTable_t_contact_Set_Email_and_Phone_Nullable.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Migrations
|
||||||
|
{
|
||||||
|
public partial class UpdateTable_t_contact_Set_Email_and_Phone_Nullable : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "phone",
|
||||||
|
table: "t_contact",
|
||||||
|
type: "character varying(50)",
|
||||||
|
maxLength: 50,
|
||||||
|
nullable: true,
|
||||||
|
comment: "номер телефона",
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "character varying(50)",
|
||||||
|
oldMaxLength: 50,
|
||||||
|
oldComment: "номер телефона");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "email",
|
||||||
|
table: "t_contact",
|
||||||
|
type: "character varying(255)",
|
||||||
|
maxLength: 255,
|
||||||
|
nullable: true,
|
||||||
|
comment: "email",
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "character varying(255)",
|
||||||
|
oldMaxLength: 255,
|
||||||
|
oldComment: "email");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "phone",
|
||||||
|
table: "t_contact",
|
||||||
|
type: "character varying(50)",
|
||||||
|
maxLength: 50,
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "",
|
||||||
|
comment: "номер телефона",
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "character varying(50)",
|
||||||
|
oldMaxLength: 50,
|
||||||
|
oldNullable: true,
|
||||||
|
oldComment: "номер телефона");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "email",
|
||||||
|
table: "t_contact",
|
||||||
|
type: "character varying(255)",
|
||||||
|
maxLength: 255,
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "",
|
||||||
|
comment: "email",
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "character varying(255)",
|
||||||
|
oldMaxLength: 255,
|
||||||
|
oldNullable: true,
|
||||||
|
oldComment: "email");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -214,7 +214,6 @@ namespace AsbCloudDb.Migrations
|
|||||||
.HasComment("компания");
|
.HasComment("компания");
|
||||||
|
|
||||||
b.Property<string>("Email")
|
b.Property<string>("Email")
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(255)
|
.HasMaxLength(255)
|
||||||
.HasColumnType("character varying(255)")
|
.HasColumnType("character varying(255)")
|
||||||
.HasColumnName("email")
|
.HasColumnName("email")
|
||||||
@ -240,7 +239,6 @@ namespace AsbCloudDb.Migrations
|
|||||||
.HasComment("ключ скважины");
|
.HasComment("ключ скважины");
|
||||||
|
|
||||||
b.Property<string>("Phone")
|
b.Property<string>("Phone")
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
.HasMaxLength(50)
|
||||||
.HasColumnType("character varying(50)")
|
.HasColumnType("character varying(50)")
|
||||||
.HasColumnName("phone")
|
.HasColumnName("phone")
|
||||||
|
@ -26,11 +26,11 @@ namespace AsbCloudDb.Model
|
|||||||
|
|
||||||
[Column("email"), Comment("email")]
|
[Column("email"), Comment("email")]
|
||||||
[StringLength(255)]
|
[StringLength(255)]
|
||||||
public string Email { get; set; } = string.Empty;
|
public string? Email { get; set; }
|
||||||
|
|
||||||
[Column("phone"), Comment("номер телефона")]
|
[Column("phone"), Comment("номер телефона")]
|
||||||
[StringLength(50)]
|
[StringLength(50)]
|
||||||
public string Phone { get; set; } = string.Empty;
|
public string? Phone { get; set; }
|
||||||
|
|
||||||
[Column("position"), Comment("должность")]
|
[Column("position"), Comment("должность")]
|
||||||
[StringLength(255)]
|
[StringLength(255)]
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Services\DetectOperations\DetectOperations.xlsx" />
|
||||||
<EmbeddedResource Include="Services\DailyReport\DailyReportTemplate.xlsx" />
|
<EmbeddedResource Include="Services\DailyReport\DailyReportTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\DrillTestReport\DrillTestReportTemplate.xlsx" />
|
<EmbeddedResource Include="Services\DrillTestReport\DrillTestReportTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
<EmbeddedResource Include="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
||||||
using AsbCloudApp.Data.DrillTestReport;
|
using AsbCloudApp.Data.DrillTestReport;
|
||||||
using AsbCloudApp.Data.Manuals;
|
using AsbCloudApp.Data.Manuals;
|
||||||
using AsbCloudApp.Data.ProcessMaps;
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
@ -7,6 +8,7 @@ using AsbCloudApp.Data.Subsystems;
|
|||||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudApp.Services.AutoGeneratedDailyReports;
|
||||||
using AsbCloudApp.Services.Notifications;
|
using AsbCloudApp.Services.Notifications;
|
||||||
using AsbCloudApp.Services.ProcessMaps;
|
using AsbCloudApp.Services.ProcessMaps;
|
||||||
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
||||||
@ -177,14 +179,16 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddMemoryCache();
|
services.AddMemoryCache();
|
||||||
services.AddScoped<IAsbCloudDbContext>(provider => provider.GetRequiredService<AsbCloudDbContext>());
|
services.AddScoped<IAsbCloudDbContext>(provider => provider.GetRequiredService<AsbCloudDbContext>());
|
||||||
|
|
||||||
services.AddSingleton(new WitsInfoService());
|
services.AddSingleton(new WitsInfoService());
|
||||||
services.AddSingleton<ITelemetryDataCache<TelemetryDataSaubDto>>(provider => TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(provider));
|
services.AddSingleton<ITelemetryDataCache<TelemetryDataSaubDto>>(provider =>
|
||||||
services.AddSingleton<ITelemetryDataCache<TelemetryDataSpinDto>>(provider => TelemetryDataCache<TelemetryDataSpinDto>.GetInstance<TelemetryDataSpin>(provider));
|
TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(provider));
|
||||||
services.AddSingleton<IRequerstTrackerService, RequestTrackerService>();
|
services.AddSingleton<ITelemetryDataCache<TelemetryDataSpinDto>>(provider =>
|
||||||
services.AddSingleton<PeriodicBackgroundWorker>();
|
TelemetryDataCache<TelemetryDataSpinDto>.GetInstance<TelemetryDataSpin>(provider));
|
||||||
services.AddSingleton<BackgroundWorker>();
|
services.AddSingleton<IRequerstTrackerService, RequestTrackerService>();
|
||||||
services.AddSingleton<NotificationBackgroundWorker>();
|
services.AddSingleton<PeriodicBackgroundWorker>();
|
||||||
services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration));
|
services.AddSingleton<BackgroundWorker>();
|
||||||
|
services.AddSingleton<NotificationBackgroundWorker>();
|
||||||
|
services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration));
|
||||||
|
|
||||||
services.AddTransient<IAuthService, AuthService>();
|
services.AddTransient<IAuthService, AuthService>();
|
||||||
services.AddTransient<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>, ProcessMapPlanRepository<ProcessMapPlanWellDrillingDto, ProcessMapWellDrilling>>();
|
services.AddTransient<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>, ProcessMapPlanRepository<ProcessMapPlanWellDrillingDto, ProcessMapWellDrilling>>();
|
||||||
@ -206,6 +210,7 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IProcessMapReportWellDrillingExportService, ProcessMapReportWellDrillingExportService>();
|
services.AddTransient<IProcessMapReportWellDrillingExportService, ProcessMapReportWellDrillingExportService>();
|
||||||
services.AddTransient<IPlannedTrajectoryImportService, PlannedTrajectoryImportService>();
|
services.AddTransient<IPlannedTrajectoryImportService, PlannedTrajectoryImportService>();
|
||||||
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
||||||
|
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||||
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
||||||
services.AddTransient<ISubsystemOperationTimeService, SubsystemOperationTimeService>();
|
services.AddTransient<ISubsystemOperationTimeService, SubsystemOperationTimeService>();
|
||||||
services.AddTransient<IScheduleRepository, ScheduleRepository>();
|
services.AddTransient<IScheduleRepository, ScheduleRepository>();
|
||||||
@ -291,7 +296,7 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto, AsbCloudDb.Model.WITS.Record50>>();
|
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto, AsbCloudDb.Model.WITS.Record50>>();
|
||||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto, AsbCloudDb.Model.WITS.Record60>>();
|
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto, AsbCloudDb.Model.WITS.Record60>>();
|
||||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto, AsbCloudDb.Model.WITS.Record61>>();
|
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto, AsbCloudDb.Model.WITS.Record61>>();
|
||||||
|
|
||||||
services.AddTransient<IDrillTestReportService, DrillTestReportService>();
|
services.AddTransient<IDrillTestReportService, DrillTestReportService>();
|
||||||
services.AddTransient<IReportMakerService<DrillTestReportDataDto>, DrillTestReportMakerService>();
|
services.AddTransient<IReportMakerService<DrillTestReportDataDto>, DrillTestReportMakerService>();
|
||||||
|
|
||||||
@ -308,6 +313,8 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IWellOperationExcelParser<WellOperationImportDefaultOptionsDto>, WellOperationDefaultExcelParser>();
|
services.AddTransient<IWellOperationExcelParser<WellOperationImportDefaultOptionsDto>, WellOperationDefaultExcelParser>();
|
||||||
services.AddTransient<IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto>, WellOperationGazpromKhantosExcelParser>();
|
services.AddTransient<IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto>, WellOperationGazpromKhantosExcelParser>();
|
||||||
|
|
||||||
|
services.AddTransient<DetectedOperationExportService>();
|
||||||
|
|
||||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||||
services.AddTransient<IDailyReportRepository, DailyReportRepository>();
|
services.AddTransient<IDailyReportRepository, DailyReportRepository>();
|
||||||
services.AddTransient<IDailyReportExportService, DailyReportExportService>();
|
services.AddTransient<IDailyReportExportService, DailyReportExportService>();
|
||||||
|
Binary file not shown.
@ -1,120 +1,224 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudDb.Model;
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using ClosedXML.Excel;
|
using ClosedXML.Excel;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations
|
namespace AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
|
|
||||||
|
public class DetectedOperationExportService
|
||||||
{
|
{
|
||||||
|
private readonly DetectorAbstract[] detectors = { new DetectorDrilling(), new DetectorSlipsTime() };
|
||||||
|
|
||||||
internal class DetectedOperationExportService
|
private readonly IDictionary<int, string> domains = new Dictionary<int, string>
|
||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext db;
|
{ 1, "https://cloud.digitaldrilling.ru" },
|
||||||
private readonly IWellService wellService;
|
{ 2, "https://cloud.autodrilling.ru" }
|
||||||
|
};
|
||||||
|
|
||||||
public DetectedOperationExportService(IAsbCloudDbContext db, IWellService wellService)
|
private const int headerRowsCount = 1;
|
||||||
{
|
|
||||||
this.db = db;
|
|
||||||
this.wellService = wellService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Stream> ExportAsync(IEnumerable<int> idsWells, CancellationToken token)
|
private const string cellDepositName = "B1";
|
||||||
{
|
private const string cellClusterName = "B2";
|
||||||
using var workbook = new XLWorkbook(XLEventTracking.Disabled);
|
private const string cellWellName = "B3";
|
||||||
|
private const string cellDeltaDate = "H2";
|
||||||
|
|
||||||
await AddSheetsAsync(workbook, idsWells, token);
|
private const int columnOperationName = 1;
|
||||||
|
private const int columnDateStart = 2;
|
||||||
|
private const int columnDateEnd = 3;
|
||||||
|
private const int columnDuration = 4;
|
||||||
|
private const int columnDepthStart = 5;
|
||||||
|
private const int columnDepthEnd = 6;
|
||||||
|
private const int columnDeltaDepth = 7;
|
||||||
|
private const int columnDepth = 8;
|
||||||
|
private const int columnIdReasonOfEnd = 9;
|
||||||
|
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
private readonly IAsbCloudDbContext dbContext;
|
||||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
return memoryStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task AddSheetsAsync(XLWorkbook workbook, IEnumerable<int> idsWells, CancellationToken token)
|
public DetectedOperationExportService(IAsbCloudDbContext dbContext)
|
||||||
{
|
{
|
||||||
if(!idsWells.Any())
|
this.dbContext = dbContext;
|
||||||
return;
|
}
|
||||||
|
|
||||||
var wells = idsWells.Select(i => wellService.GetOrDefault(i))
|
public async Task<Stream> ExportAsync(int idWell, int idDomain, CancellationToken cancellationToken)
|
||||||
.Where(w => w is not null && w.IdTelemetry is not null)
|
{
|
||||||
.Select(w => w!);
|
var well = await dbContext.Wells
|
||||||
|
.Include(w => w.Cluster)
|
||||||
|
.ThenInclude(c => c.Deposit)
|
||||||
|
.SingleOrDefaultAsync(w => w.Id == idWell, cancellationToken);
|
||||||
|
|
||||||
if (!wells.Any())
|
if (well is null)
|
||||||
return;
|
throw new ArgumentNullException(nameof(well));
|
||||||
|
|
||||||
var idsTelemetries = wells.Select(w => w.IdTelemetry);
|
if (!well.IdTelemetry.HasValue)
|
||||||
if (!idsTelemetries.Any())
|
throw new ArgumentNullException(nameof(well));
|
||||||
return;
|
|
||||||
|
|
||||||
var operations = await db.DetectedOperations
|
var operations = await DetectOperationsAsync(well.IdTelemetry.Value, new DateTime(2023, 10, 14)
|
||||||
.Include(o => o.OperationCategory)
|
.ToUtcDateTimeOffset(well.Timezone.Hours), cancellationToken);
|
||||||
.AsNoTracking()
|
|
||||||
.Where(o => idsTelemetries.Contains(o.IdTelemetry))
|
|
||||||
.OrderBy(o => o.IdTelemetry)
|
|
||||||
.ThenBy(o => o.DateStart)
|
|
||||||
.ToListAsync(token);
|
|
||||||
|
|
||||||
var groups = operations.GroupBy(o => o.IdTelemetry);
|
return await GenerateExcelFileStreamAsync(well, idDomain, operations, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var well in wells)
|
private async Task<Stream> GenerateExcelFileStreamAsync(Well well, int idDomain, IEnumerable<DetectedOperation> detectedOperations,
|
||||||
{
|
CancellationToken cancellationToken)
|
||||||
var ops = groups.FirstOrDefault(g => g.Key == well.IdTelemetry)
|
{
|
||||||
?.ToList();
|
using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken);
|
||||||
|
|
||||||
if(ops?.Any() != true)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var sheetName = $"{well.Cluster}_{well.Caption}"
|
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
|
||||||
.Replace('.','_');
|
|
||||||
|
|
||||||
var sheet = workbook.AddWorksheet(sheetName);
|
await AddToWorkbookAsync(workbook, well, idDomain, detectedOperations, cancellationToken);
|
||||||
AddHeader(sheet);
|
|
||||||
const int headerHeight = 1;
|
|
||||||
for(var i = 0; i< ops.Count; i++ )
|
|
||||||
AddRow(sheet, ops[i], well, i + 1 + headerHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddHeader(IXLWorksheet sheet)
|
MemoryStream memoryStream = new MemoryStream();
|
||||||
{
|
workbook.SaveAs(memoryStream, new SaveOptions { });
|
||||||
var rowNumber = 1;
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
sheet.Cell(rowNumber, 1).Value = "Name";
|
return memoryStream;
|
||||||
sheet.Column(1).Width = 34;
|
}
|
||||||
|
|
||||||
sheet.Cell(rowNumber, 2).Value = "DateStart";
|
|
||||||
sheet.Column(2).Width = 17;
|
|
||||||
|
|
||||||
sheet.Cell(rowNumber, 3).Value = "DateEnd";
|
|
||||||
sheet.Column(3).Width = 17;
|
|
||||||
|
|
||||||
sheet.Cell(rowNumber, 4).Value = "DepthStart";
|
|
||||||
sheet.Column(4).Width = 9;
|
|
||||||
|
|
||||||
sheet.Cell(rowNumber, 5).Value = "DepthEnd";
|
|
||||||
sheet.Column(5).Width = 9;
|
|
||||||
|
|
||||||
sheet.Cell(rowNumber, 6).Value = "KeyValue";
|
|
||||||
sheet.Column(6).Width = 9;
|
|
||||||
|
|
||||||
sheet.SheetView.FreezeRows(rowNumber);
|
private async Task AddToWorkbookAsync(XLWorkbook workbook, Well well, int idDomain, IEnumerable<DetectedOperation> detectedOperations,
|
||||||
}
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
const string sheetName = "Операции";
|
||||||
|
|
||||||
private static void AddRow(IXLWorksheet sheet, DetectedOperation operation, WellDto well, int rowNumber)
|
if (!detectedOperations.Any())
|
||||||
{
|
return;
|
||||||
var timezoneoffsetHours = well.Timezone.Hours;
|
|
||||||
sheet.Cell(rowNumber, 1).Value = operation.OperationCategory.Name;
|
|
||||||
sheet.Cell(rowNumber, 2).Value = operation.DateStart.ToRemoteDateTime(timezoneoffsetHours);
|
|
||||||
sheet.Cell(rowNumber, 3).Value = operation.DateEnd.ToRemoteDateTime(timezoneoffsetHours);
|
|
||||||
sheet.Cell(rowNumber, 4).Value = operation.DepthStart;
|
|
||||||
sheet.Cell(rowNumber, 5).Value = operation.DepthEnd;
|
|
||||||
sheet.Cell(rowNumber, 6).Value = operation.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName)
|
||||||
|
?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}.");
|
||||||
|
|
||||||
|
await AddToSheetAsync(sheet, well, idDomain, detectedOperations.OrderBy(x => x.DateStart).ThenBy(x => x.DepthStart).ToArray(),
|
||||||
|
cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task AddToSheetAsync(IXLWorksheet sheet, Well well, int idDomain, IList<DetectedOperation> detectedOperations,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var wellOperationCategories = await dbContext.WellOperationCategories.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
|
sheet.Cell(cellDepositName).Value = well.Cluster.Deposit.Caption;
|
||||||
|
sheet.Cell(cellClusterName).Value = well.Cluster.Caption;
|
||||||
|
sheet.Cell(cellWellName).Value = well.Caption;
|
||||||
|
sheet.Cell(cellDeltaDate).Value = detectedOperations.Max(o => o.DateEnd) - detectedOperations.Min(o => o.DateStart);
|
||||||
|
|
||||||
|
var timeZoneWell = TimeSpan.FromHours(well.Timezone.Hours);
|
||||||
|
|
||||||
|
for (int i = 0; i < detectedOperations.Count; i++)
|
||||||
|
{
|
||||||
|
var dateStart = detectedOperations[i].DateStart.ToOffset(timeZoneWell);
|
||||||
|
var dateEnd = detectedOperations[i].DateEnd.ToOffset(timeZoneWell);
|
||||||
|
|
||||||
|
var row = sheet.Row(5 + i + headerRowsCount);
|
||||||
|
|
||||||
|
row.Cell(columnOperationName).Value = detectedOperations[i].IdCategory == 12000
|
||||||
|
? "Бурение в слайде с осцилляцией"
|
||||||
|
: wellOperationCategories.Single(o => o.Id == detectedOperations[i].IdCategory).Name;
|
||||||
|
row.Cell(columnDateEnd).Value = dateEnd;
|
||||||
|
row.Cell(columnDuration).Value = (dateEnd - dateStart).TotalMinutes;
|
||||||
|
row.Cell(columnDepthStart).Value = detectedOperations[i].DepthStart;
|
||||||
|
row.Cell(columnDepthEnd).Value = detectedOperations[i].DepthEnd;
|
||||||
|
row.Cell(columnDepth).Value = detectedOperations[i].DepthEnd - detectedOperations[i].DepthStart;
|
||||||
|
row.Cell(columnIdReasonOfEnd).Value = detectedOperations[i].IdReasonOfEnd;
|
||||||
|
|
||||||
|
var link =
|
||||||
|
$"{domains[idDomain]}/well/{well.Id}/telemetry/monitoring?end={Uri.EscapeDataString(dateStart.AddSeconds(3544).ToString("yyyy-MM-ddTHH:mm:ss.fff"))}&range=3600";
|
||||||
|
|
||||||
|
row.Cell(columnDateStart).Value = dateStart;
|
||||||
|
row.Cell(columnDateStart).SetHyperlink(new XLHyperlink(link));
|
||||||
|
|
||||||
|
row.Cell(columnDeltaDepth).Value = i > 0 && i + 1 < detectedOperations.Count
|
||||||
|
? detectedOperations[i].DepthStart - detectedOperations[i - 1].DepthEnd
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Stream> GetExcelTemplateStreamAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
string resourceName = Assembly.GetExecutingAssembly()
|
||||||
|
.GetManifestResourceNames()
|
||||||
|
.FirstOrDefault(n => n.EndsWith("DetectOperations.xlsx"))!;
|
||||||
|
|
||||||
|
using var stream = Assembly.GetExecutingAssembly()
|
||||||
|
.GetManifestResourceStream(resourceName)!;
|
||||||
|
|
||||||
|
var memoryStream = new MemoryStream();
|
||||||
|
await stream.CopyToAsync(memoryStream, cancellationToken);
|
||||||
|
memoryStream.Position = 0;
|
||||||
|
|
||||||
|
return memoryStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<IEnumerable<DetectedOperation>> DetectOperationsAsync(int idTelemetry, DateTimeOffset begin,
|
||||||
|
CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = dbContext.TelemetryDataSaub
|
||||||
|
.AsNoTracking()
|
||||||
|
.Where(d => d.IdTelemetry == idTelemetry)
|
||||||
|
.Where(d => d.BlockPosition >= 0)
|
||||||
|
.Select(d => new DetectableTelemetry
|
||||||
|
{
|
||||||
|
DateTime = d.DateTime,
|
||||||
|
IdUser = d.IdUser,
|
||||||
|
WellDepth = d.WellDepth,
|
||||||
|
Pressure = d.Pressure,
|
||||||
|
HookWeight = d.HookWeight,
|
||||||
|
BlockPosition = d.BlockPosition,
|
||||||
|
BitDepth = d.BitDepth,
|
||||||
|
RotorSpeed = d.RotorSpeed,
|
||||||
|
})
|
||||||
|
.OrderBy(d => d.DateTime);
|
||||||
|
|
||||||
|
var startDate = begin;
|
||||||
|
var detectedOperations = new List<DetectedOperation>(8);
|
||||||
|
DetectedOperation? lastDetectedOperation = null;
|
||||||
|
const int minOperationLength = 5;
|
||||||
|
const int maxDetectorsInterpolationFrameLength = 30;
|
||||||
|
const int gap = maxDetectorsInterpolationFrameLength + minOperationLength;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var data = await query
|
||||||
|
.Where(d => d.DateTime > startDate)
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
|
if (data.Length < gap)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var isDetected = false;
|
||||||
|
var positionBegin = 0;
|
||||||
|
var positionEnd = data.Length - gap;
|
||||||
|
var step = 10;
|
||||||
|
while (positionEnd > positionBegin)
|
||||||
|
{
|
||||||
|
step++;
|
||||||
|
foreach (var detector in detectors)
|
||||||
|
{
|
||||||
|
if (!detector.TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out var result))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
detectedOperations.Add(result!.Operation);
|
||||||
|
lastDetectedOperation = result.Operation;
|
||||||
|
isDetected = true;
|
||||||
|
step = 1;
|
||||||
|
positionBegin = result.TelemetryEnd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (step > 20)
|
||||||
|
step = 10;
|
||||||
|
positionBegin += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDetected)
|
||||||
|
startDate = lastDetectedOperation!.DateEnd;
|
||||||
|
else
|
||||||
|
startDate = data[positionEnd].DateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return detectedOperations;
|
||||||
|
}
|
||||||
|
}
|
@ -6,9 +6,7 @@ using AsbCloudDb;
|
|||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -333,13 +331,6 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
|
|||||||
.ToArrayAsync(token);
|
.ToArrayAsync(token);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Stream> ExportAsync(IEnumerable<int> idsWells, CancellationToken token)
|
|
||||||
{
|
|
||||||
var exportService = new DetectedOperationExportService(db, wellService);
|
|
||||||
return exportService.ExportAsync(idsWells, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,8 @@ using System.Linq;
|
|||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
{
|
||||||
|
|
||||||
internal abstract class DetectorAbstract
|
internal abstract class DetectorAbstract
|
||||||
{
|
{
|
||||||
private readonly int idOperation;
|
|
||||||
private readonly int stepLength = 3;
|
private readonly int stepLength = 3;
|
||||||
|
|
||||||
protected const int IdReasonOfEnd_NotDetected = 0;
|
protected const int IdReasonOfEnd_NotDetected = 0;
|
||||||
@ -32,33 +31,39 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
protected const int IdReasonOfEnd_BlockPositionIsHi = 501;
|
protected const int IdReasonOfEnd_BlockPositionIsHi = 501;
|
||||||
protected const int IdReasonOfEnd_BlockPositionDeviates = 502;
|
protected const int IdReasonOfEnd_BlockPositionDeviates = 502;
|
||||||
|
|
||||||
protected const int IdReasonOfEnd_Custom1 = 10_000;
|
protected const int IdReasonOfEnd_Drilling = 600;
|
||||||
|
|
||||||
protected DetectorAbstract(int idOperation)
|
protected const int IdReasonOfEnd_Custom1 = 10_000;
|
||||||
{
|
|
||||||
this.idOperation = idOperation;
|
public abstract Func<DetectableTelemetry[], int, int, int> GetIdOperation { get; }
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperation? previousOperation, out OperationDetectorResult? result)
|
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperation? previousOperation, out OperationDetectorResult? result)
|
||||||
{
|
{
|
||||||
// Проверка соответствия критерию начала операции
|
// Проверка соответствия критерию начала операции
|
||||||
if (DetectBegin(telemetry, begin, previousOperation))
|
if (DetectBegin(telemetry, begin, previousOperation))
|
||||||
{
|
{
|
||||||
// Поиск окончания соответствия критерию
|
// Поиск окончания соответствия критерию
|
||||||
|
int idReasonOfEnd = 0;
|
||||||
var positionEnd = begin;
|
var positionEnd = begin;
|
||||||
while (positionEnd < end)
|
while (positionEnd < end)
|
||||||
{
|
{
|
||||||
positionEnd += stepLength;
|
positionEnd += stepLength;
|
||||||
if ((positionEnd > end))
|
if (positionEnd > end)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
var idReasonOfEnd = DetectEnd(telemetry, positionEnd, previousOperation);
|
idReasonOfEnd = DetectEnd(telemetry, positionEnd, previousOperation);
|
||||||
if (idReasonOfEnd != IdReasonOfEnd_NotDetected)
|
|
||||||
{
|
if(idReasonOfEnd is IdReasonOfEnd_DeltaDepthIsHi or IdReasonOfEnd_PressureIsLo &&
|
||||||
result = MakeOperation(idTelemetry, telemetry, begin, positionEnd, idReasonOfEnd);
|
!IsValidByWellDepthDoesNotChange(telemetry, begin, positionEnd))
|
||||||
return true;
|
break;
|
||||||
}
|
|
||||||
|
if (idReasonOfEnd != IdReasonOfEnd_NotDetected)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = null;
|
||||||
|
result = MakeOperation(idTelemetry, telemetry, begin, positionEnd, idReasonOfEnd);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
result = null;
|
result = null;
|
||||||
return false;
|
return false;
|
||||||
@ -81,7 +86,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
Operation = new DetectedOperation
|
Operation = new DetectedOperation
|
||||||
{
|
{
|
||||||
IdTelemetry = idTelemetry,
|
IdTelemetry = idTelemetry,
|
||||||
IdCategory = idOperation,
|
IdCategory = GetIdOperation.Invoke(telemetry, begin, end),
|
||||||
IdUsersAtStart = pBegin.IdUser ?? -1,
|
IdUsersAtStart = pBegin.IdUser ?? -1,
|
||||||
DateStart = pBegin.DateTime,
|
DateStart = pBegin.DateTime,
|
||||||
DateEnd = pEnd.DateTime,
|
DateEnd = pEnd.DateTime,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using AsbCloudDb.Model;
|
using System;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
{
|
||||||
@ -7,12 +8,12 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
/// Проработка перед наращиванием
|
/// Проработка перед наращиванием
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class DetectorDevelopment : DetectorAbstract
|
internal class DetectorDevelopment : DetectorAbstract
|
||||||
{
|
{
|
||||||
public DetectorDevelopment()
|
|
||||||
: base(WellOperationCategory.IdDevelopment) { }
|
|
||||||
|
|
||||||
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> CalcDeltaMinutes(telemetry, begin, end);
|
=> CalcDeltaMinutes(telemetry, begin, end);
|
||||||
|
|
||||||
|
public override Func<DetectableTelemetry[], int, int, int> GetIdOperation => (_, _, _)
|
||||||
|
=> WellOperationCategory.IdDevelopment;
|
||||||
|
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
|
|
||||||
|
internal class DetectorDrilling : DetectorAbstract
|
||||||
|
{
|
||||||
|
public override Func<DetectableTelemetry[], int, int, int> GetIdOperation => DefineDrillingOperation;
|
||||||
|
|
||||||
|
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
|
{
|
||||||
|
var point0 = telemetry[position];
|
||||||
|
var delta = point0.WellDepth - point0.BitDepth;
|
||||||
|
if (delta > 0.03d)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (point0.Pressure < 25)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (point0.RotorSpeed < 5)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
|
{
|
||||||
|
var point0 = telemetry[position];
|
||||||
|
var delta = point0.WellDepth - point0.BitDepth;
|
||||||
|
|
||||||
|
if (delta > 0.03d)
|
||||||
|
return IdReasonOfEnd_DeltaDepthIsHi;
|
||||||
|
|
||||||
|
if (point0.Pressure < 25)
|
||||||
|
return IdReasonOfEnd_PressureIsLo;
|
||||||
|
|
||||||
|
return IdReasonOfEnd_NotDetected;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
|
=> IsValidByWellDepthIncreasing(telemetry, begin, end);
|
||||||
|
|
||||||
|
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
|
=> CalcRop(telemetry, begin, end);
|
||||||
|
|
||||||
|
private static int DefineDrillingOperation(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
|
{
|
||||||
|
const int idSlideWithOscillation = 12000;
|
||||||
|
|
||||||
|
var telemetryRange = telemetry[begin.. end];
|
||||||
|
|
||||||
|
var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed);
|
||||||
|
|
||||||
|
if (avgRotorSpeed < 10)
|
||||||
|
return WellOperationCategory.IdSlide;
|
||||||
|
|
||||||
|
var despersion = telemetryRange
|
||||||
|
.Average(t => Math.Pow((t.RotorSpeed - avgRotorSpeed) / avgRotorSpeed, 2));
|
||||||
|
|
||||||
|
return despersion < 0.2d ? WellOperationCategory.IdRotor : idSlideWithOscillation;
|
||||||
|
}
|
||||||
|
}
|
@ -1,59 +1,59 @@
|
|||||||
using AsbCloudDb.Model;
|
// using AsbCloudDb.Model;
|
||||||
|
//
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
// {
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Промывка
|
// /// Промывка
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
internal class DetectorFlashing : DetectorAbstract
|
// internal class DetectorFlashing : DetectorAbstract
|
||||||
{
|
// {
|
||||||
public DetectorFlashing()
|
// public DetectorFlashing()
|
||||||
: base(WellOperationCategory.IdFlashing)
|
// : base(WellOperationCategory.IdFlashing)
|
||||||
{ }
|
// { }
|
||||||
|
//
|
||||||
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> CalcDeltaMinutes(telemetry, begin, end);
|
// => CalcDeltaMinutes(telemetry, begin, end);
|
||||||
|
//
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
if (!((previousOperation?.IdCategory == WellOperationCategory.IdRotor) ||
|
// if (!((previousOperation?.IdCategory == WellOperationCategory.IdRotor) ||
|
||||||
(previousOperation?.IdCategory == WellOperationCategory.IdSlide)))
|
// (previousOperation?.IdCategory == WellOperationCategory.IdSlide)))
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if (delta > 0.05d)
|
// if (delta > 0.05d)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.Pressure < 15)
|
// if (point0.Pressure < 15)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.BlockPosition < 3)
|
// if (point0.BlockPosition < 3)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (ContainsDeviationApprox(telemetry, t => t.WellDepth, position, 150, 0.0001))
|
// if (ContainsDeviationApprox(telemetry, t => t.WellDepth, position, 150, 0.0001))
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if ((delta > 0.03d )
|
// if ((delta > 0.03d )
|
||||||
&& (point0.Pressure > 15)
|
// && (point0.Pressure > 15)
|
||||||
&& ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03))
|
// && ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03))
|
||||||
return IdReasonOfEnd_Custom1;
|
// return IdReasonOfEnd_Custom1;
|
||||||
|
//
|
||||||
return IdReasonOfEnd_NotDetected;
|
// return IdReasonOfEnd_NotDetected;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
@ -1,55 +1,55 @@
|
|||||||
using AsbCloudDb.Model;
|
// using AsbCloudDb.Model;
|
||||||
|
//
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
// {
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Промывка перед наращиванием
|
// /// Промывка перед наращиванием
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
internal class DetectorFlashingBeforeConnection : DetectorAbstract
|
// internal class DetectorFlashingBeforeConnection : DetectorAbstract
|
||||||
{
|
// {
|
||||||
public DetectorFlashingBeforeConnection()
|
// public DetectorFlashingBeforeConnection()
|
||||||
: base(WellOperationCategory.IdFlashingBeforeConnection) { }
|
// : base(WellOperationCategory.IdFlashingBeforeConnection) { }
|
||||||
|
//
|
||||||
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> CalcDeltaMinutes(telemetry, begin, end);
|
// => CalcDeltaMinutes(telemetry, begin, end);
|
||||||
|
//
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
if (!((previousOperation?.IdCategory == WellOperationCategory.IdRotor) ||
|
// if (!((previousOperation?.IdCategory == WellOperationCategory.IdRotor) ||
|
||||||
(previousOperation?.IdCategory == WellOperationCategory.IdSlide)))
|
// (previousOperation?.IdCategory == WellOperationCategory.IdSlide)))
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if (delta > 0.05d)
|
// if (delta > 0.05d)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.Pressure < 15)
|
// if (point0.Pressure < 15)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.BlockPosition > 3)
|
// if (point0.BlockPosition > 3)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if ((delta > 0.03d )
|
// if ((delta > 0.03d )
|
||||||
&& (point0.Pressure > 15)
|
// && (point0.Pressure > 15)
|
||||||
&& ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03))
|
// && ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03))
|
||||||
return IdReasonOfEnd_Custom1;
|
// return IdReasonOfEnd_Custom1;
|
||||||
|
//
|
||||||
return IdReasonOfEnd_NotDetected;
|
// return IdReasonOfEnd_NotDetected;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
@ -1,62 +1,54 @@
|
|||||||
using AsbCloudDb.Model;
|
// using AsbCloudDb.Model;
|
||||||
using System.Linq;
|
// using System.Linq;
|
||||||
|
//
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
// {
|
||||||
|
//
|
||||||
internal class DetectorRotor : DetectorAbstract
|
// public class DetectorRotor : DetectorAbstract
|
||||||
{
|
// {
|
||||||
public DetectorRotor()
|
// public DetectorRotor()
|
||||||
: base(WellOperationCategory.IdRotor) { }
|
// : base(WellOperationCategory.IdRotor) { }
|
||||||
|
//
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if (delta > 0.03d)
|
// if (delta > 0.03d)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.Pressure < 25)
|
// if (point0.Pressure < 25)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.RotorSpeed < 5)
|
// if (point0.RotorSpeed < 5)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
var point1 = telemetry[position + 1];
|
// var point1 = telemetry[position + 1];
|
||||||
if (point1.WellDepth - point0.WellDepth <= 0.003)
|
// if (point1.WellDepth - point0.WellDepth <= 0.003)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if (delta > 0.03d)
|
// if (delta > 0.03d)
|
||||||
return IdReasonOfEnd_DeltaDepthIsHi;
|
// return IdReasonOfEnd_DeltaDepthIsHi;
|
||||||
|
//
|
||||||
if (point0.Pressure < 25)
|
// if (point0.Pressure < 25)
|
||||||
return IdReasonOfEnd_PressureIsLo;
|
// return IdReasonOfEnd_PressureIsLo;
|
||||||
|
//
|
||||||
var avgRotorSpeed = CalcAvgAppr(d => d.RotorSpeed, telemetry, position, 60);
|
// return IdReasonOfEnd_NotDetected;
|
||||||
|
// }
|
||||||
if (avgRotorSpeed < 10)
|
//
|
||||||
return IdReasonOfEnd_AvgRotorSpeedIsLo;
|
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
|
// => IsValidByWellDepthIncreasing(telemetry, begin, end);
|
||||||
if (!DeviatesFromBegin(telemetry, t => t.WellDepth, position, 150, 0.003))
|
//
|
||||||
return IdReasonOfEnd_WellDepthDeviates;
|
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
|
// => CalcRop(telemetry, begin, end);
|
||||||
return IdReasonOfEnd_NotDetected;
|
// }
|
||||||
}
|
//
|
||||||
|
//
|
||||||
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
// }
|
||||||
=> IsValidByWellDepthIncreasing(telemetry, begin, end);
|
//
|
||||||
|
|
||||||
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
|
||||||
=> CalcRop(telemetry, begin, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,61 +1,49 @@
|
|||||||
using AsbCloudDb.Model;
|
// using AsbCloudDb.Model;
|
||||||
|
//
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
// {
|
||||||
|
//
|
||||||
internal class DetectorSlide : DetectorAbstract
|
// public class DetectorSlide : DetectorAbstract
|
||||||
{
|
// {
|
||||||
public DetectorSlide()
|
// public DetectorSlide()
|
||||||
: base(WellOperationCategory.IdSlide) { }
|
// : base(WellOperationCategory.IdSlide) { }
|
||||||
|
//
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if (delta > 0.03d)
|
// if (delta > 0.03d)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.Pressure < 25)
|
// if (point0.Pressure < 25)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.RotorSpeed > 5)
|
// return true;
|
||||||
return false;
|
// }
|
||||||
|
//
|
||||||
var point1 = telemetry[position + 1];
|
// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
if (point1.WellDepth - point0.WellDepth <= 0.003)
|
// {
|
||||||
return false;
|
// var point0 = telemetry[position];
|
||||||
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
return true;
|
// if (delta > 0.03d)
|
||||||
}
|
// return IdReasonOfEnd_DeltaDepthIsHi;
|
||||||
|
//
|
||||||
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// if (point0.Pressure < 25)
|
||||||
{
|
// return IdReasonOfEnd_PressureIsLo;
|
||||||
var point0 = telemetry[position];
|
//
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// if (!DeviatesFromBegin(telemetry, t => t.WellDepth, position, 150, 0.003))
|
||||||
if (delta > 0.03d)
|
// return IdReasonOfEnd_WellDepthDeviates;
|
||||||
return IdReasonOfEnd_DeltaDepthIsHi;
|
//
|
||||||
|
// return IdReasonOfEnd_NotDetected;
|
||||||
if (point0.Pressure < 25)
|
// }
|
||||||
return IdReasonOfEnd_PressureIsLo;
|
//
|
||||||
|
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
var avgRotorSpeed = CalcAvgAppr(d => d.RotorSpeed, telemetry, position, 60);
|
// => IsValidByWellDepthIncreasing(telemetry, begin, end);
|
||||||
|
//
|
||||||
if (avgRotorSpeed > 10)
|
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
return IdReasonOfEnd_AvgRotorSpeedIsHi;
|
// => CalcRop(telemetry, begin, end);
|
||||||
|
// }
|
||||||
if (!DeviatesFromBegin(telemetry, t => t.WellDepth, position, 150, 0.003))
|
//
|
||||||
return IdReasonOfEnd_WellDepthDeviates;
|
//
|
||||||
|
// }
|
||||||
return IdReasonOfEnd_NotDetected;
|
//
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
|
||||||
=> IsValidByWellDepthIncreasing(telemetry, begin, end);
|
|
||||||
|
|
||||||
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
|
||||||
=> CalcRop(telemetry, begin, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
using AsbCloudDb.Model;
|
using System;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
{
|
||||||
|
|
||||||
internal class DetectorSlipsTime : DetectorAbstract
|
internal class DetectorSlipsTime : DetectorAbstract
|
||||||
{
|
{
|
||||||
public DetectorSlipsTime()
|
|
||||||
: base(WellOperationCategory.IdSlipsTime)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> CalcDeltaMinutes(telemetry, begin, end);
|
=> CalcDeltaMinutes(telemetry, begin, end);
|
||||||
|
|
||||||
|
public override Func<DetectableTelemetry[], int, int, int> GetIdOperation => (_, _, _) => WellOperationCategory.IdSlipsTime;
|
||||||
|
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
{
|
||||||
var point0 = telemetry[position];
|
var point0 = telemetry[position];
|
||||||
|
@ -1,69 +1,69 @@
|
|||||||
using AsbCloudDb.Model;
|
// using AsbCloudDb.Model;
|
||||||
using System.Linq;
|
// using System.Linq;
|
||||||
using System;
|
// using System;
|
||||||
|
//
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
// {
|
||||||
|
//
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Статический замер телесистемы
|
// /// Статический замер телесистемы
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
internal class DetectorStaticSurveying: DetectorAbstract
|
// internal class DetectorStaticSurveying: DetectorAbstract
|
||||||
{
|
// {
|
||||||
public DetectorStaticSurveying()
|
// public DetectorStaticSurveying()
|
||||||
: base(WellOperationCategory.IdStaticSurveying) { }
|
// : base(WellOperationCategory.IdStaticSurveying) { }
|
||||||
|
//
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
|
//
|
||||||
if (point0.Pressure < 15)
|
// if (point0.Pressure < 15)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if (delta > 2.5d || delta < 0.15d)
|
// if (delta > 2.5d || delta < 0.15d)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.RotorSpeed > 30)
|
// if (point0.RotorSpeed > 30)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (ContainsDeviation(telemetry, t => t.BlockPosition, position, 120, 0.03))
|
// if (ContainsDeviation(telemetry, t => t.BlockPosition, position, 120, 0.03))
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (ContainsDeviation(telemetry, t => t.Pressure, position, 60, 10))
|
// if (ContainsDeviation(telemetry, t => t.Pressure, position, 60, 10))
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
|
//
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if (delta > 2.5d )
|
// if (delta > 2.5d )
|
||||||
return IdReasonOfEnd_DeltaDepthIsHi;
|
// return IdReasonOfEnd_DeltaDepthIsHi;
|
||||||
|
//
|
||||||
if (point0.RotorSpeed > 30)
|
// if (point0.RotorSpeed > 30)
|
||||||
return IdReasonOfEnd_RotorSpeedIsHi;
|
// return IdReasonOfEnd_RotorSpeedIsHi;
|
||||||
|
//
|
||||||
if (RisesFromBegin(telemetry, t => t.Pressure, position, 10, 15))
|
// if (RisesFromBegin(telemetry, t => t.Pressure, position, 10, 15))
|
||||||
return IdReasonOfEnd_PressureIsRising;
|
// return IdReasonOfEnd_PressureIsRising;
|
||||||
|
//
|
||||||
if (ContainsDeviation(telemetry, t => t.BlockPosition, position, 10, 0.05))
|
// if (ContainsDeviation(telemetry, t => t.BlockPosition, position, 10, 0.05))
|
||||||
return IdReasonOfEnd_BlockPositionDeviates;
|
// return IdReasonOfEnd_BlockPositionDeviates;
|
||||||
|
//
|
||||||
return IdReasonOfEnd_NotDetected;
|
// return IdReasonOfEnd_NotDetected;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
||||||
|
//
|
||||||
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> CalcDeltaMinutes(telemetry, begin, end);
|
// => CalcDeltaMinutes(telemetry, begin, end);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
@ -1,65 +1,65 @@
|
|||||||
using AsbCloudDb.Model;
|
// using AsbCloudDb.Model;
|
||||||
using System.Collections.Generic;
|
// using System.Collections.Generic;
|
||||||
|
//
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
// {
|
||||||
|
//
|
||||||
internal class DetectorTemplating : DetectorAbstract
|
// internal class DetectorTemplating : DetectorAbstract
|
||||||
{
|
// {
|
||||||
public DetectorTemplating()
|
// public DetectorTemplating()
|
||||||
: base(WellOperationCategory.IdTemplating) { }
|
// : base(WellOperationCategory.IdTemplating) { }
|
||||||
|
//
|
||||||
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> CalcDeltaMinutes(telemetry, begin, end);
|
// => CalcDeltaMinutes(telemetry, begin, end);
|
||||||
|
//
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
if(previousOperation?.IdCategory == WellOperationCategory.IdSlipsTime)
|
// if(previousOperation?.IdCategory == WellOperationCategory.IdSlipsTime)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if (delta < 0.03d || delta > 30)
|
// if (delta < 0.03d || delta > 30)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.Pressure < 15)
|
// if (point0.Pressure < 15)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.BlockPosition > 2.5)
|
// if (point0.BlockPosition > 2.5)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.RotorSpeed > 10)
|
// if (point0.RotorSpeed > 10)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03))
|
// if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03))
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if (delta < 0.03d || delta > 30)
|
// if (delta < 0.03d || delta > 30)
|
||||||
return IdReasonOfEnd_DeltaDepthOutOfRange;
|
// return IdReasonOfEnd_DeltaDepthOutOfRange;
|
||||||
|
//
|
||||||
if (point0.Pressure < 15)
|
// if (point0.Pressure < 15)
|
||||||
return IdReasonOfEnd_PressureIsLo;
|
// return IdReasonOfEnd_PressureIsLo;
|
||||||
|
//
|
||||||
if (point0.BlockPosition > 31)
|
// if (point0.BlockPosition > 31)
|
||||||
return IdReasonOfEnd_BlockPositionIsHi;
|
// return IdReasonOfEnd_BlockPositionIsHi;
|
||||||
|
//
|
||||||
if (point0.RotorSpeed > 10)
|
// if (point0.RotorSpeed > 10)
|
||||||
return IdReasonOfEnd_RotorSpeedIsHi;
|
// return IdReasonOfEnd_RotorSpeedIsHi;
|
||||||
|
//
|
||||||
return IdReasonOfEnd_NotDetected;
|
// return IdReasonOfEnd_NotDetected;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
@ -1,61 +1,61 @@
|
|||||||
using AsbCloudDb.Model;
|
// using AsbCloudDb.Model;
|
||||||
|
//
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
// {
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Шаблонировка при бурении
|
// /// Шаблонировка при бурении
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
internal class DetectorTemplatingWhileDrilling : DetectorAbstract
|
// internal class DetectorTemplatingWhileDrilling : DetectorAbstract
|
||||||
{
|
// {
|
||||||
public DetectorTemplatingWhileDrilling()
|
// public DetectorTemplatingWhileDrilling()
|
||||||
: base(WellOperationCategory.IdTemplatingWhileDrilling) { }
|
// : base(WellOperationCategory.IdTemplatingWhileDrilling) { }
|
||||||
|
//
|
||||||
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> CalcDeltaMinutes(telemetry, begin, end);
|
// => CalcDeltaMinutes(telemetry, begin, end);
|
||||||
|
//
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
if (previousOperation?.IdCategory != WellOperationCategory.IdFlashing)
|
// if (previousOperation?.IdCategory != WellOperationCategory.IdFlashing)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
|
//
|
||||||
if (point0.Pressure < 15)
|
// if (point0.Pressure < 15)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (point0.RotorSpeed < 1)
|
// if (point0.RotorSpeed < 1)
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
if (RisesFromBegin(telemetry, t => t.BlockPosition, position, 30, 0.5))
|
// if (RisesFromBegin(telemetry, t => t.BlockPosition, position, 30, 0.5))
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
// protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
// {
|
||||||
var point0 = telemetry[position];
|
// var point0 = telemetry[position];
|
||||||
|
//
|
||||||
if (point0.Pressure < 15)
|
// if (point0.Pressure < 15)
|
||||||
return IdReasonOfEnd_PressureIsLo;
|
// return IdReasonOfEnd_PressureIsLo;
|
||||||
|
//
|
||||||
if (RisesFromBegin(telemetry, t=>t.WellDepth, position, 10, 0.01))
|
// if (RisesFromBegin(telemetry, t=>t.WellDepth, position, 10, 0.01))
|
||||||
return IdReasonOfEnd_WellDepthDeviates;
|
// return IdReasonOfEnd_WellDepthDeviates;
|
||||||
|
//
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
// var delta = point0.WellDepth - point0.BitDepth;
|
||||||
if ( (delta > 0.03d )
|
// if ( (delta > 0.03d )
|
||||||
&& (point0.Pressure > 15)
|
// && (point0.Pressure > 15)
|
||||||
&& (!ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03)))
|
// && (!ContainsDeviationApprox(telemetry, t=>t.BlockPosition, position, 60, 0.03)))
|
||||||
return IdReasonOfEnd_Custom1;
|
// return IdReasonOfEnd_Custom1;
|
||||||
|
//
|
||||||
return IdReasonOfEnd_NotDetected;
|
// return IdReasonOfEnd_NotDetected;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
// => IsValidByWellDepthDoesNotChange(telemetry, begin, end);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
@ -3,11 +3,10 @@
|
|||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
{
|
||||||
|
|
||||||
class OperationDetectorResult
|
public class OperationDetectorResult
|
||||||
{
|
{
|
||||||
public int TelemetryBegin { get; set; }
|
public int TelemetryBegin { get; set; }
|
||||||
public int TelemetryEnd { get; set; }
|
public int TelemetryEnd { get; set; }
|
||||||
public DetectedOperation Operation { get; set; } = null!;
|
public DetectedOperation Operation { get; set; } = null!;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,29 @@
|
|||||||
# Алгоритм определения бурения в роторе
|
Метод определения бурения
|
||||||
## Описание
|
|
||||||
|
|
||||||
## Метод определения бурения в роторе
|
Признак начала операции =
|
||||||
|
|
||||||
Признак начала операции =
|
расстояние от долота до забоя < 0.03м И
|
||||||
( расстояние от долота до забоя < 0.03м ) И
|
|
||||||
( давление > 25атм ) И
|
|
||||||
( глубина забоя за следующую секунду больше текущей на 0.003м ) И
|
|
||||||
( обороты ротора > 5 об/м );
|
|
||||||
|
|
||||||
Признак окончания операции =
|
давление > 25атм
|
||||||
( расстояние от долота до забоя > 0.03м ) ИЛИ
|
|
||||||
( давление < 25атм ) ИЛИ
|
|
||||||
( среднее арифметическое оборотов ротора за 60 сек < 10 об/м ) ИЛИ
|
|
||||||
( глубина забоя в течении следующих 150 сек не изменяется больше чем на 0.003 );
|
|
||||||
|
|
||||||
## Метод определения бурения в слайде
|
|
||||||
Повторяет метод определения бурения в роторе, за исключением условия с оборотами ротора. Это уловие нужно инвертировать.
|
|
||||||
|
|
||||||
## Ключевой параметр
|
Признак окончания операции =
|
||||||
МСП = разность глубины забоя на конец и начало операции / продолжительность операции.
|
|
||||||
|
расстояние от долота до забоя > 0.03м ИЛИ
|
||||||
|
|
||||||
|
давление < 25атм
|
||||||
|
|
||||||
|
Находим границы
|
||||||
|
|
||||||
|
После того когда мы нашли границы, мы должны определить операцию, тогда мы смотрим на забой точки окончания операций сравниваем с забоем точками начала операций:
|
||||||
|
|
||||||
|
Если они равны друг другу, то мы эту операцию дальше не обрабатываем, а выбрасываем.
|
||||||
|
|
||||||
|
Если они не равны, то у нас произошло увеличение забоя, значит эта операция бурения.
|
||||||
|
|
||||||
|
Дальше мы определяем как мы бурили в роторе или слайде, для этого нам необходимо рассчитать среднюю скорость(среднее арифметическое) за всю операцию бурения . Если среднее арифметическое больше константы (10 об/мин), то это бурение в роторе, если меньше, то это бурение в слайде.
|
||||||
|
|
||||||
|
Если бурение в роторе, то мы считаем только дисперсию нормированных оборотов ротора(по среднему значению). (Так как это может быть бурение в слайде с осцилляцией и выглядеть как бурение в роторе):
|
||||||
|
|
||||||
|
Если полученное значение меньше константы(0,2), то мы подтвердили что бурение в роторе.
|
||||||
|
|
||||||
|
Если полученное значение больше константы, то это бурение в слайде с осцилляцией.
|
@ -16,8 +16,8 @@ public class WorkOperationDetection: Work
|
|||||||
{
|
{
|
||||||
private static readonly DetectorAbstract[] detectors = new DetectorAbstract[]
|
private static readonly DetectorAbstract[] detectors = new DetectorAbstract[]
|
||||||
{
|
{
|
||||||
new DetectorRotor(),
|
// new DetectorRotor(),
|
||||||
new DetectorSlide(),
|
// new DetectorSlide(),
|
||||||
//new DetectorDevelopment(),
|
//new DetectorDevelopment(),
|
||||||
//new DetectorTemplating(),
|
//new DetectorTemplating(),
|
||||||
new DetectorSlipsTime(),
|
new DetectorSlipsTime(),
|
||||||
|
@ -133,6 +133,7 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
[HttpGet("datesRange")]
|
[HttpGet("datesRange")]
|
||||||
[Permission]
|
[Permission]
|
||||||
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
|
||||||
|
[ProducesResponseType((int)System.Net.HttpStatusCode.NoContent)]
|
||||||
public async Task<IActionResult> GetReportsDateRangeAsync(int idWell, CancellationToken token)
|
public async Task<IActionResult> GetReportsDateRangeAsync(int idWell, CancellationToken token)
|
||||||
{
|
{
|
||||||
int? idCompany = User.GetCompanyId();
|
int? idCompany = User.GetCompanyId();
|
||||||
@ -146,6 +147,9 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
|
|
||||||
var wellReportsDatesRange = reportService.GetDatesRangeOrDefault(idWell);
|
var wellReportsDatesRange = reportService.GetDatesRangeOrDefault(idWell);
|
||||||
|
|
||||||
|
if (wellReportsDatesRange is null)
|
||||||
|
return NoContent();
|
||||||
|
|
||||||
return Ok(wellReportsDatesRange);
|
return Ok(wellReportsDatesRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,10 @@ using AsbCloudApp.Services;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Controllers.SAUB
|
namespace AsbCloudWebApi.Controllers.SAUB
|
||||||
@ -22,11 +23,14 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
|||||||
{
|
{
|
||||||
private readonly IDetectedOperationService detectedOperationService;
|
private readonly IDetectedOperationService detectedOperationService;
|
||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
|
private readonly DetectedOperationExportService detectedOperationExportService;
|
||||||
public DetectedOperationController(IDetectedOperationService detectedOperationService, IWellService wellService)
|
|
||||||
|
public DetectedOperationController(IDetectedOperationService detectedOperationService, IWellService wellService,
|
||||||
|
DetectedOperationExportService detectedOperationExportService)
|
||||||
{
|
{
|
||||||
this.detectedOperationService = detectedOperationService;
|
this.detectedOperationService = detectedOperationService;
|
||||||
this.wellService = wellService;
|
this.wellService = wellService;
|
||||||
|
this.detectedOperationExportService = detectedOperationExportService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -118,42 +122,23 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
|||||||
/// Создает excel файл с операциями по скважине
|
/// Создает excel файл с операциями по скважине
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idWell">id скважины</param>
|
/// <param name="idWell">id скважины</param>
|
||||||
/// <param name="idCluster"></param>
|
/// <param name="idDomain">Идентификатор домена</param>
|
||||||
/// <param name="token"> Токен отмены задачи </param>
|
/// <param name="token"></param>
|
||||||
/// <returns>Запрашиваемый файл</returns>
|
|
||||||
[HttpGet("export")]
|
[HttpGet("export")]
|
||||||
[Permission]
|
[Permission]
|
||||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
|
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
|
[ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
|
||||||
public async Task<IActionResult> ExportAsync(int? idWell, int? idCluster, CancellationToken token)
|
public async Task<IActionResult> ExportAsync(int idWell, [Range(1, 2)] int idDomain, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (idCluster is null && idWell is null)
|
var idCompany = User.GetCompanyId();
|
||||||
return this.ValidationBadRequest(nameof(idWell), $"One of {nameof(idWell)} or {nameof(idCluster)} mast be set.");
|
|
||||||
|
|
||||||
int? idCompany = User.GetCompanyId();
|
|
||||||
|
|
||||||
if (idCompany is null)
|
if (idCompany is null)
|
||||||
return Forbid();
|
return Forbid();
|
||||||
|
|
||||||
IEnumerable<int> idsWells;
|
var stream = await detectedOperationExportService.ExportAsync(idWell, idDomain, token);
|
||||||
if (idCluster is not null)
|
|
||||||
{
|
return File(stream, "application/octet-stream", "operations.xlsx");
|
||||||
var companyWells = await wellService.GetAsync(new() { IdCompany = idCompany }, token);
|
|
||||||
idsWells = companyWells.Where(w => w.IdCluster == idCluster)
|
|
||||||
.Select(w=>w.Id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
|
||||||
idWell!.Value, token).ConfigureAwait(false))
|
|
||||||
return Forbid();
|
|
||||||
idsWells = new List<int> { (int)idWell };
|
|
||||||
}
|
|
||||||
|
|
||||||
var stream = await detectedOperationService.ExportAsync(idsWells, token);
|
|
||||||
var fileName = "operations.xlsx";
|
|
||||||
return File(stream, fileName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,7 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
|||||||
[HttpGet("{idWell}/dateRange")]
|
[HttpGet("{idWell}/dateRange")]
|
||||||
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
|
||||||
[ProducesResponseType((int)System.Net.HttpStatusCode.NotFound)]
|
[ProducesResponseType((int)System.Net.HttpStatusCode.NotFound)]
|
||||||
|
[ProducesResponseType((int)System.Net.HttpStatusCode.NoContent)]
|
||||||
public virtual async Task<ActionResult<DatesRangeDto?>> GetRangeAsync(
|
public virtual async Task<ActionResult<DatesRangeDto?>> GetRangeAsync(
|
||||||
[FromRoute] int idWell,
|
[FromRoute] int idWell,
|
||||||
[Required] DateTimeOffset geDate,
|
[Required] DateTimeOffset geDate,
|
||||||
@ -158,6 +159,9 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
|||||||
|
|
||||||
var content = await telemetryDataService.GetRangeAsync(idWell, geDate, leDate, token);
|
var content = await telemetryDataService.GetRangeAsync(idWell, geDate, leDate, token);
|
||||||
|
|
||||||
|
if (content is null)
|
||||||
|
return NoContent();
|
||||||
|
|
||||||
return Ok(content);
|
return Ok(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +175,7 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
|||||||
[Permission]
|
[Permission]
|
||||||
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
|
||||||
[ProducesResponseType((int)System.Net.HttpStatusCode.NotFound)]
|
[ProducesResponseType((int)System.Net.HttpStatusCode.NotFound)]
|
||||||
|
[ProducesResponseType((int)System.Net.HttpStatusCode.NoContent)]
|
||||||
public virtual async Task<ActionResult<DatesRangeDto?>> GetDataDatesRangeAsync(int idWell,
|
public virtual async Task<ActionResult<DatesRangeDto?>> GetDataDatesRangeAsync(int idWell,
|
||||||
CancellationToken token)
|
CancellationToken token)
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="DetectedOperations\Files\Operations.xlsx" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
using System.IO;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using AsbCloudInfrastructure;
|
using ConsoleApp1.DetectedOperations;
|
||||||
using CliWrap;
|
|
||||||
using Mapster;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace ConsoleApp1
|
namespace ConsoleApp1
|
||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
static void Main(/*string[] args*/)
|
private static DbContextOptions<AsbCloudDbContext> options = new DbContextOptionsBuilder<AsbCloudDbContext>()
|
||||||
|
.UseNpgsql("Host=localhost;Database=postgres;Port=5433;Username=postgres;Password=root;Persist Security Info=True")
|
||||||
|
.Options;
|
||||||
|
|
||||||
|
static async Task Main(/*string[] args*/)
|
||||||
{
|
{
|
||||||
|
using var db = new AsbCloudDbContext(options);
|
||||||
|
|
||||||
|
await new DetectedOperationExportService(db).Export(483, CancellationToken.None);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user