forked from ddrilling/AsbCloudServer
Rename processMaps to processMapPlan, processMapReport, processMapReportMaker.
This commit is contained in:
parent
4766a8ee8a
commit
9b794311c4
@ -47,16 +47,6 @@ namespace AsbCloudApp.Data.SAUB
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public float PressureIdle { get; set; }
|
public float PressureIdle { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// задание давления для роторного режима
|
|
||||||
/// </summary>
|
|
||||||
public float PressureSpRotor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// задание давления для режима слайда
|
|
||||||
/// </summary>
|
|
||||||
public float PressureSpSlide { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ограничение макс перепада давления
|
/// ограничение макс перепада давления
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -108,13 +98,13 @@ namespace AsbCloudApp.Data.SAUB
|
|||||||
public float BlockSpeedSp { get; set; }
|
public float BlockSpeedSp { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Талевый блок. Задание скорости для роторного бурения
|
/// Режим САУБ
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float BlockSpeedSpRotor { get; set; }
|
public short Mode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Талевый блок. Задание скорости для режима слайда
|
/// Текущий критерий бурения
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float BlockSpeedSpSlide { get; set; }
|
public short? IdFeedRegulator { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace AsbCloudApp.Repositories
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// РТК
|
/// РТК
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IProcessMapRepository : IRepositoryWellRelated<ProcessMapPlanDto>
|
public interface IProcessMapPlanRepository : IRepositoryWellRelated<ProcessMapPlanDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить параметры бурения начиная с даты.
|
/// Получить параметры бурения начиная с даты.
|
||||||
|
@ -7,7 +7,7 @@ namespace AsbCloudApp.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Сервис формирования РТК.
|
/// Сервис формирования РТК.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IProcessMapReportService
|
public interface IProcessMapReportMakerService
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Сформировать.
|
/// Сформировать.
|
@ -8,7 +8,7 @@ namespace AsbCloudApp.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Сервис формирования РТК
|
/// Сервис формирования РТК
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IProcessMapService
|
public interface IProcessMapReportService
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение моделей РТК
|
/// Получение моделей РТК
|
||||||
|
@ -107,7 +107,7 @@ namespace AsbCloudInfrastructure
|
|||||||
|
|
||||||
services.AddTransient<IAuthService, AuthService>();
|
services.AddTransient<IAuthService, AuthService>();
|
||||||
services.AddTransient<IDepositRepository, DepositRepository>();
|
services.AddTransient<IDepositRepository, DepositRepository>();
|
||||||
services.AddTransient<IProcessMapRepository, ProcessMapRepository>();
|
services.AddTransient<IProcessMapPlanRepository, ProcessMapRepository>();
|
||||||
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
|
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
|
||||||
services.AddTransient<IEventService, EventService>();
|
services.AddTransient<IEventService, EventService>();
|
||||||
services.AddTransient<FileService>();
|
services.AddTransient<FileService>();
|
||||||
@ -133,8 +133,8 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IWellFinalDocumentsService, WellFinalDocumentsService>();
|
services.AddTransient<IWellFinalDocumentsService, WellFinalDocumentsService>();
|
||||||
services.AddTransient<IFileCategoryService, FileCategoryService>();
|
services.AddTransient<IFileCategoryService, FileCategoryService>();
|
||||||
services.AddTransient<ILimitingParameterService, LimitingParameterService>();
|
services.AddTransient<ILimitingParameterService, LimitingParameterService>();
|
||||||
|
services.AddTransient<IProcessMapReportMakerService, ProcessMapReportMakerService>();
|
||||||
services.AddTransient<IProcessMapReportService, ProcessMapReportService>();
|
services.AddTransient<IProcessMapReportService, ProcessMapReportService>();
|
||||||
services.AddTransient<IProcessMapService, ProcessMapService>();
|
|
||||||
services.AddTransient<ITrajectoryVisualizationService, TrajectoryVisualizationService>();
|
services.AddTransient<ITrajectoryVisualizationService, TrajectoryVisualizationService>();
|
||||||
|
|
||||||
// admin crud services:
|
// admin crud services:
|
||||||
|
@ -4,10 +4,8 @@ using AsbCloudApp.Repositories;
|
|||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using DocumentFormat.OpenXml.Spreadsheet;
|
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Org.BouncyCastle.Asn1.Ocsp;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -19,7 +17,7 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
{
|
{
|
||||||
#nullable enable
|
#nullable enable
|
||||||
public class ProcessMapRepository : CrudWellRelatedRepositoryBase<ProcessMapPlanDto, ProcessMap>,
|
public class ProcessMapRepository : CrudWellRelatedRepositoryBase<ProcessMapPlanDto, ProcessMap>,
|
||||||
IProcessMapRepository
|
IProcessMapPlanRepository
|
||||||
{
|
{
|
||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
public class WellCompositeRepository : IWellCompositeRepository
|
public class WellCompositeRepository : IWellCompositeRepository
|
||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext db;
|
private readonly IAsbCloudDbContext db;
|
||||||
private readonly IProcessMapRepository processMapRepository;
|
private readonly IProcessMapPlanRepository processMapRepository;
|
||||||
|
|
||||||
public WellCompositeRepository(IAsbCloudDbContext db, IProcessMapRepository processMapRepository)
|
public WellCompositeRepository(IAsbCloudDbContext db, IProcessMapPlanRepository processMapRepository)
|
||||||
{
|
{
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.processMapRepository = processMapRepository;
|
this.processMapRepository = processMapRepository;
|
||||||
|
@ -0,0 +1,216 @@
|
|||||||
|
using AsbCloudApp.Data.ProcessMap;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
using ClosedXML.Excel;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Services.ProcessMap
|
||||||
|
{
|
||||||
|
#nullable enable
|
||||||
|
public class ProcessMapReportMakerService : IProcessMapReportMakerService
|
||||||
|
{
|
||||||
|
const int firstColumn = 2;
|
||||||
|
const int lastColumn = 61;
|
||||||
|
|
||||||
|
const int headerRowsCount = 8;
|
||||||
|
|
||||||
|
private readonly IProcessMapReportService processMapService;
|
||||||
|
|
||||||
|
public ProcessMapReportMakerService(IProcessMapReportService processMapService)
|
||||||
|
{
|
||||||
|
this.processMapService = processMapService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Stream> MakeReportAsync(int idWell, CancellationToken token)
|
||||||
|
{
|
||||||
|
var stream = GetExcelTemplateStream();
|
||||||
|
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
||||||
|
|
||||||
|
var data = await processMapService.GetProcessMapAsync(idWell, token);
|
||||||
|
|
||||||
|
FillProcessMapToWorkbook(workbook, data);
|
||||||
|
|
||||||
|
MemoryStream memoryStream = new MemoryStream();
|
||||||
|
workbook.SaveAs(memoryStream, new SaveOptions { });
|
||||||
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
return memoryStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapReportDto> data)
|
||||||
|
{
|
||||||
|
var sheet = workbook.Worksheets.FirstOrDefault();
|
||||||
|
if (sheet is null)
|
||||||
|
return;
|
||||||
|
var dataBySections = data.GroupBy(p => p.IdWellSectionType);
|
||||||
|
FillSheet(sheet, dataBySections);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FillSheet(IXLWorksheet sheet, IEnumerable<IGrouping<int, ProcessMapReportDto>> dataBySections)
|
||||||
|
{
|
||||||
|
var startRow = headerRowsCount + 1;
|
||||||
|
foreach (var sectionData in dataBySections)
|
||||||
|
{
|
||||||
|
if(sectionData.Any())
|
||||||
|
startRow = FillSection(sheet, sectionData, startRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FillSection(IXLWorksheet sheet, IGrouping<int, ProcessMapReportDto> sectionData, int row)
|
||||||
|
{
|
||||||
|
var rowStart = row;
|
||||||
|
|
||||||
|
var sectionName = sectionData.FirstOrDefault()?.WellSectionTypeName
|
||||||
|
?? sectionData.Key.ToString();
|
||||||
|
|
||||||
|
sheet.Range(row, firstColumn, row, lastColumn)
|
||||||
|
.Merge()
|
||||||
|
.FirstCell()
|
||||||
|
.SetVal(sectionName)
|
||||||
|
.Style
|
||||||
|
.Fill.SetBackgroundColor(XLColor.LightGray);
|
||||||
|
|
||||||
|
row++;
|
||||||
|
|
||||||
|
foreach (var interval in sectionData)
|
||||||
|
row = FillIntervalData(sheet, interval, row);
|
||||||
|
|
||||||
|
var sectionStyle = sheet.Range(rowStart, firstColumn, row - 1, lastColumn).Style;
|
||||||
|
SetBorders(sectionStyle);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FillIntervalData(IXLWorksheet sheet, ProcessMapReportDto interval, int row)
|
||||||
|
{
|
||||||
|
const int columnDepth = firstColumn + 1;
|
||||||
|
const int columnDate = firstColumn + 2;
|
||||||
|
const int columnRopTime = firstColumn + 3;
|
||||||
|
const int columnMode = firstColumn + 4;
|
||||||
|
|
||||||
|
int rowRotor = row;
|
||||||
|
int rowSlide = row + 1;
|
||||||
|
|
||||||
|
sheet.Range(rowRotor, firstColumn, rowSlide, firstColumn)
|
||||||
|
.Merge();
|
||||||
|
|
||||||
|
sheet.Range(rowRotor, columnDepth, rowSlide, columnDepth)
|
||||||
|
.Merge().FirstCell()
|
||||||
|
.SetVal(interval.DepthStart, "0.0");
|
||||||
|
|
||||||
|
sheet.Range(rowRotor, columnDate, rowSlide, columnDate)
|
||||||
|
.Merge().FirstCell()
|
||||||
|
.SetVal(interval.DateStart);
|
||||||
|
|
||||||
|
sheet.Range(rowRotor, columnRopTime, rowSlide, columnRopTime)
|
||||||
|
.Merge().FirstCell()
|
||||||
|
.SetVal(interval.MechDrillingHours);
|
||||||
|
|
||||||
|
//row = FillIntervalModeData(sheet, "Ротор", interval.Rotor, columnMode, row);
|
||||||
|
//row = FillIntervalModeData(sheet, "Слайд", interval.Slide, columnMode, row);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
//private static int FillIntervalModeData(IXLWorksheet sheet, string modeName, ProcessMapReportRowDto modeData, int column, int row)
|
||||||
|
//{
|
||||||
|
// int columnDeltaDepth = column + 1;
|
||||||
|
// int columnPressure = columnDeltaDepth + 1;
|
||||||
|
// int columnLoad = columnPressure + 5;
|
||||||
|
// int columnTorque = columnLoad + 5;
|
||||||
|
// int columnSpeed = columnTorque + 5;
|
||||||
|
// int columnUsagePlan = columnSpeed + 5;
|
||||||
|
// int columnUsageFact = columnUsagePlan + 1;
|
||||||
|
// int columnRop = columnUsageFact + 12;
|
||||||
|
|
||||||
|
// sheet.Cell(row, column)
|
||||||
|
// .SetVal(modeName);
|
||||||
|
|
||||||
|
// sheet.Cell(row, columnDeltaDepth)
|
||||||
|
// .SetVal(modeData.DeltaDepth);
|
||||||
|
|
||||||
|
// FillIntervalModeDataParam(sheet, modeData.PressureDiff, columnPressure, row);
|
||||||
|
// FillIntervalModeDataParam(sheet, modeData.AxialLoad, columnLoad, row);
|
||||||
|
// FillIntervalModeDataParam(sheet, modeData.TopDriveTorque, columnTorque, row);
|
||||||
|
// FillIntervalModeDataSpeed(sheet, modeData.SpeedLimit, columnSpeed, row);
|
||||||
|
|
||||||
|
// sheet.Cell(row, columnUsagePlan)
|
||||||
|
// .SetVal(100);
|
||||||
|
|
||||||
|
// sheet.Cell(row, columnUsageFact)
|
||||||
|
// .SetVal(modeData.Usage);
|
||||||
|
|
||||||
|
// sheet.Cell(row, columnRop)
|
||||||
|
// .SetVal(modeData.Rop);
|
||||||
|
|
||||||
|
// return row + 1;
|
||||||
|
//}
|
||||||
|
|
||||||
|
private static void FillIntervalModeDataParam(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row)
|
||||||
|
{
|
||||||
|
const int columnOffsetSpPlan = 0;
|
||||||
|
const int columnOffsetSpFact = 1;
|
||||||
|
const int columnOffsetFact = 2;
|
||||||
|
const int columnOffsetLimit = 3;
|
||||||
|
const int columnOffsetPercent = 4;
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetSpPlan)
|
||||||
|
.SetVal(dataParam.SetpointPlan);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetSpFact)
|
||||||
|
.SetVal(dataParam.SetpointFact);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetFact)
|
||||||
|
.SetVal(dataParam.Fact);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetLimit)
|
||||||
|
.SetVal(dataParam.Limit);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetPercent)
|
||||||
|
.SetVal(dataParam.PercDrillingBySetpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FillIntervalModeDataSpeed(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row)
|
||||||
|
{
|
||||||
|
const int columnOffsetSpPlan = 0;
|
||||||
|
const int columnOffsetSpFact = 1;
|
||||||
|
const int columnOffsetFact = 2;
|
||||||
|
const int columnOffsetLimit = 3;
|
||||||
|
const int columnOffsetPercent = 4;
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetSpPlan)
|
||||||
|
.SetVal(dataParam.SetpointPlan);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetSpFact)
|
||||||
|
.SetVal(dataParam.SetpointFact);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetFact)
|
||||||
|
.SetVal(dataParam.Fact);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetLimit)
|
||||||
|
.SetVal(dataParam.Limit);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetPercent)
|
||||||
|
.SetVal(dataParam.PercDrillingBySetpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream GetExcelTemplateStream()
|
||||||
|
{
|
||||||
|
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
||||||
|
.GetManifestResourceStream("AsbCloudInfrastructure.Services.ProcessMap.ProcessMapReportTemplate.xlsx");
|
||||||
|
return stream!;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IXLStyle SetBorders(IXLStyle style)
|
||||||
|
{
|
||||||
|
style.Border.RightBorder = XLBorderStyleValues.Thin ;
|
||||||
|
style.Border.LeftBorder = XLBorderStyleValues.Thin;
|
||||||
|
style.Border.TopBorder = XLBorderStyleValues.Thin ;
|
||||||
|
style.Border.BottomBorder = XLBorderStyleValues.Thin ;
|
||||||
|
style.Border.InsideBorder = XLBorderStyleValues.Thin ;
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#nullable disable
|
||||||
|
}
|
@ -1,8 +1,15 @@
|
|||||||
using AsbCloudApp.Data.ProcessMap;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.ProcessMap;
|
||||||
|
using AsbCloudApp.Data.SAUB;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using ClosedXML.Excel;
|
using AsbCloudApp.Services.Subsystems;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudApp.Data.Subsystems;
|
||||||
|
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;
|
||||||
@ -10,207 +17,86 @@ using System.Threading.Tasks;
|
|||||||
namespace AsbCloudInfrastructure.Services.ProcessMap
|
namespace AsbCloudInfrastructure.Services.ProcessMap
|
||||||
{
|
{
|
||||||
#nullable enable
|
#nullable enable
|
||||||
public class ProcessMapReportService : IProcessMapReportService
|
public partial class ProcessMapReportService : IProcessMapReportService
|
||||||
{
|
{
|
||||||
const int firstColumn = 2;
|
private readonly IWellService wellService;
|
||||||
const int lastColumn = 61;
|
private readonly IWellOperationRepository wellOperationRepository;
|
||||||
|
private readonly IProcessMapPlanRepository processMapPlanRepository;
|
||||||
|
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
||||||
|
private readonly ILimitingParameterRepository limitingParameterRepository;
|
||||||
|
private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
|
||||||
|
|
||||||
const int headerRowsCount = 8;
|
public ProcessMapReportService(
|
||||||
|
IWellService wellService,
|
||||||
private readonly IProcessMapService processMapService;
|
IWellOperationRepository wellOperationService,
|
||||||
|
IProcessMapPlanRepository processMapPlanRepository,
|
||||||
public ProcessMapReportService(IProcessMapService processMapService)
|
ITelemetryDataSaubService telemetryDataSaubService,
|
||||||
|
ILimitingParameterRepository limitingParameterRepository,
|
||||||
|
ISubsystemOperationTimeService subsystemOperationTimeService)
|
||||||
{
|
{
|
||||||
this.processMapService = processMapService;
|
this.wellService = wellService;
|
||||||
|
this.wellOperationRepository = wellOperationService;
|
||||||
|
this.processMapPlanRepository = processMapPlanRepository;
|
||||||
|
this.telemetryDataSaubService = telemetryDataSaubService;
|
||||||
|
this.limitingParameterRepository = limitingParameterRepository;
|
||||||
|
this.subsystemOperationTimeService = subsystemOperationTimeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Stream> MakeReportAsync(int idWell, CancellationToken token)
|
/// <inheritdoc/>
|
||||||
|
public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapAsync(int idWell, CancellationToken token)
|
||||||
{
|
{
|
||||||
var stream = GetExcelTemplateStream();
|
var well = wellService.GetOrDefault(idWell)
|
||||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
?? throw new ArgumentInvalidException("idWell not found", nameof(idWell));
|
||||||
|
|
||||||
var data = await processMapService.GetProcessMapAsync(idWell, token);
|
var idTelemetry = well.IdTelemetry
|
||||||
|
?? throw new ArgumentInvalidException("telemetry by well not found", nameof(idWell));
|
||||||
|
|
||||||
FillProcessMapToWorkbook(workbook, data);
|
var processMapPlan = await processMapPlanRepository.GetByIdWellAsync(idWell, token);
|
||||||
|
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
if(!processMapPlan.Any())
|
||||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
return Enumerable.Empty<ProcessMapReportDto>();
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
return memoryStream;
|
var telemetryDataStat = await telemetryDataSaubService.GetTelemetryDataStatAsync(idTelemetry, token);
|
||||||
|
|
||||||
|
var result = CalcByIntervals(processMapPlan, telemetryDataStat);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapReportDto> data)
|
private IEnumerable<ProcessMapReportDto> CalcByIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan, IEnumerable<TelemetryDataSaubStatDto> telemetryDataStat)
|
||||||
{
|
{
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault();
|
var result = new List<ProcessMapReportDto>(processMapPlan.Count() * 4);
|
||||||
if (sheet is null)
|
var intervals = GetProcessMapIntervals(processMapPlan);
|
||||||
return;
|
|
||||||
var dataBySections = data.GroupBy(p => p.IdWellSectionType);
|
|
||||||
FillSheet(sheet, dataBySections);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void FillSheet(IXLWorksheet sheet, IEnumerable<IGrouping<int, ProcessMapReportDto>> dataBySections)
|
|
||||||
{
|
|
||||||
var startRow = headerRowsCount + 1;
|
|
||||||
foreach (var sectionData in dataBySections)
|
|
||||||
{
|
|
||||||
if(sectionData.Any())
|
|
||||||
startRow = FillSection(sheet, sectionData, startRow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int FillSection(IXLWorksheet sheet, IGrouping<int, ProcessMapReportDto> sectionData, int row)
|
|
||||||
{
|
|
||||||
var rowStart = row;
|
|
||||||
|
|
||||||
var sectionName = sectionData.FirstOrDefault()?.WellSectionTypeName
|
|
||||||
?? sectionData.Key.ToString();
|
|
||||||
|
|
||||||
sheet.Range(row, firstColumn, row, lastColumn)
|
|
||||||
.Merge()
|
|
||||||
.FirstCell()
|
|
||||||
.SetVal(sectionName)
|
|
||||||
.Style
|
|
||||||
.Fill.SetBackgroundColor(XLColor.LightGray);
|
|
||||||
|
|
||||||
row++;
|
|
||||||
|
|
||||||
foreach (var interval in sectionData)
|
|
||||||
row = FillIntervalData(sheet, interval, row);
|
|
||||||
|
|
||||||
var sectionStyle = sheet.Range(rowStart, firstColumn, row - 1, lastColumn).Style;
|
|
||||||
SetBorders(sectionStyle);
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int FillIntervalData(IXLWorksheet sheet, ProcessMapReportDto interval, int row)
|
|
||||||
{
|
|
||||||
const int columnDepth = firstColumn + 1;
|
|
||||||
const int columnDate = firstColumn + 2;
|
|
||||||
const int columnRopTime = firstColumn + 3;
|
|
||||||
const int columnMode = firstColumn + 4;
|
|
||||||
|
|
||||||
int rowRotor = row;
|
|
||||||
int rowSlide = row + 1;
|
|
||||||
|
|
||||||
sheet.Range(rowRotor, firstColumn, rowSlide, firstColumn)
|
|
||||||
.Merge();
|
|
||||||
|
|
||||||
sheet.Range(rowRotor, columnDepth, rowSlide, columnDepth)
|
|
||||||
.Merge().FirstCell()
|
|
||||||
.SetVal(interval.DepthStart, "0.0");
|
|
||||||
|
|
||||||
sheet.Range(rowRotor, columnDate, rowSlide, columnDate)
|
|
||||||
.Merge().FirstCell()
|
|
||||||
.SetVal(interval.DateStart);
|
|
||||||
|
|
||||||
sheet.Range(rowRotor, columnRopTime, rowSlide, columnRopTime)
|
|
||||||
.Merge().FirstCell()
|
|
||||||
.SetVal(interval.MechDrillingHours);
|
|
||||||
|
|
||||||
//row = FillIntervalModeData(sheet, "Ротор", interval.Rotor, columnMode, row);
|
|
||||||
//row = FillIntervalModeData(sheet, "Слайд", interval.Slide, columnMode, row);
|
|
||||||
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
//private static int FillIntervalModeData(IXLWorksheet sheet, string modeName, ProcessMapReportRowDto modeData, int column, int row)
|
|
||||||
//{
|
|
||||||
// int columnDeltaDepth = column + 1;
|
|
||||||
// int columnPressure = columnDeltaDepth + 1;
|
|
||||||
// int columnLoad = columnPressure + 5;
|
|
||||||
// int columnTorque = columnLoad + 5;
|
|
||||||
// int columnSpeed = columnTorque + 5;
|
|
||||||
// int columnUsagePlan = columnSpeed + 5;
|
|
||||||
// int columnUsageFact = columnUsagePlan + 1;
|
|
||||||
// int columnRop = columnUsageFact + 12;
|
|
||||||
|
|
||||||
// sheet.Cell(row, column)
|
|
||||||
// .SetVal(modeName);
|
|
||||||
|
|
||||||
// sheet.Cell(row, columnDeltaDepth)
|
|
||||||
// .SetVal(modeData.DeltaDepth);
|
|
||||||
|
|
||||||
// FillIntervalModeDataParam(sheet, modeData.PressureDiff, columnPressure, row);
|
|
||||||
// FillIntervalModeDataParam(sheet, modeData.AxialLoad, columnLoad, row);
|
|
||||||
// FillIntervalModeDataParam(sheet, modeData.TopDriveTorque, columnTorque, row);
|
|
||||||
// FillIntervalModeDataSpeed(sheet, modeData.SpeedLimit, columnSpeed, row);
|
|
||||||
|
|
||||||
// sheet.Cell(row, columnUsagePlan)
|
|
||||||
// .SetVal(100);
|
|
||||||
|
|
||||||
// sheet.Cell(row, columnUsageFact)
|
|
||||||
// .SetVal(modeData.Usage);
|
|
||||||
|
|
||||||
// sheet.Cell(row, columnRop)
|
|
||||||
// .SetVal(modeData.Rop);
|
|
||||||
|
|
||||||
// return row + 1;
|
|
||||||
//}
|
|
||||||
|
|
||||||
private static void FillIntervalModeDataParam(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row)
|
|
||||||
{
|
|
||||||
const int columnOffsetSpPlan = 0;
|
|
||||||
const int columnOffsetSpFact = 1;
|
|
||||||
const int columnOffsetFact = 2;
|
|
||||||
const int columnOffsetLimit = 3;
|
|
||||||
const int columnOffsetPercent = 4;
|
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetSpPlan)
|
|
||||||
.SetVal(dataParam.SetpointPlan);
|
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetSpFact)
|
return result;
|
||||||
.SetVal(dataParam.SetpointFact);
|
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetFact)
|
|
||||||
.SetVal(dataParam.Fact);
|
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetLimit)
|
|
||||||
.SetVal(dataParam.Limit);
|
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetPercent)
|
|
||||||
.SetVal(dataParam.PercDrillingBySetpoint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void FillIntervalModeDataSpeed(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row)
|
private IEnumerable<(double, double)> GetProcessMapIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan)
|
||||||
{
|
{
|
||||||
const int columnOffsetSpPlan = 0;
|
|
||||||
const int columnOffsetSpFact = 1;
|
return Enumerable.Empty<(double, double)>();
|
||||||
const int columnOffsetFact = 2;
|
|
||||||
const int columnOffsetLimit = 3;
|
|
||||||
const int columnOffsetPercent = 4;
|
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetSpPlan)
|
|
||||||
.SetVal(dataParam.SetpointPlan);
|
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetSpFact)
|
|
||||||
.SetVal(dataParam.SetpointFact);
|
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetFact)
|
|
||||||
.SetVal(dataParam.Fact);
|
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetLimit)
|
|
||||||
.SetVal(dataParam.Limit);
|
|
||||||
|
|
||||||
sheet.Cell(row, column + columnOffsetPercent)
|
|
||||||
.SetVal(dataParam.PercDrillingBySetpoint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream GetExcelTemplateStream()
|
private static DateTime GetInterpolatedDate(WellOperationDto operation, double depth)
|
||||||
{
|
{
|
||||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
var ratio = (depth - operation.DepthStart) / (operation.DepthEnd - operation.DepthStart);
|
||||||
.GetManifestResourceStream("AsbCloudInfrastructure.Services.ProcessMap.ProcessMapReportTemplate.xlsx");
|
var deltaHours = operation.DurationHours * ratio;
|
||||||
return stream!;
|
var interpolatedDate = operation.DateStart + TimeSpan.FromHours(deltaHours);
|
||||||
|
return interpolatedDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IXLStyle SetBorders(IXLStyle style)
|
private static IEnumerable<(double min, double max)> SplitByIntervals(double min, double max)
|
||||||
{
|
{
|
||||||
style.Border.RightBorder = XLBorderStyleValues.Thin ;
|
const double step = 100;
|
||||||
style.Border.LeftBorder = XLBorderStyleValues.Thin;
|
var iMin = min;
|
||||||
style.Border.TopBorder = XLBorderStyleValues.Thin ;
|
var iMax = (1 + (int)(min / step)) * step;
|
||||||
style.Border.BottomBorder = XLBorderStyleValues.Thin ;
|
for (; iMax < max; iMax += step)
|
||||||
style.Border.InsideBorder = XLBorderStyleValues.Thin ;
|
{
|
||||||
return style;
|
yield return (iMin, iMax);
|
||||||
|
iMin = iMax;
|
||||||
|
}
|
||||||
|
yield return (iMin, max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#nullable disable
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
@ -1,348 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Data.ProcessMap;
|
|
||||||
using AsbCloudApp.Data.SAUB;
|
|
||||||
using AsbCloudApp.Exceptions;
|
|
||||||
using AsbCloudApp.Repositories;
|
|
||||||
using AsbCloudApp.Requests;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using AsbCloudApp.Services.Subsystems;
|
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using AsbCloudApp.Data.Subsystems;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AsbCloudInfrastructure.Services.Subsystems;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.ProcessMap
|
|
||||||
{
|
|
||||||
#nullable enable
|
|
||||||
public partial class ProcessMapService : IProcessMapService
|
|
||||||
{
|
|
||||||
private readonly IWellService wellService;
|
|
||||||
private readonly IWellOperationRepository wellOperationRepository;
|
|
||||||
private readonly IProcessMapRepository processMapRepository;
|
|
||||||
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
|
||||||
private readonly ILimitingParameterRepository limitingParameterRepository;
|
|
||||||
private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
|
|
||||||
|
|
||||||
public ProcessMapService(
|
|
||||||
IWellService wellService,
|
|
||||||
IWellOperationRepository wellOperationService,
|
|
||||||
IProcessMapRepository processMapRepository,
|
|
||||||
ITelemetryDataSaubService telemetryDataSaubService,
|
|
||||||
ILimitingParameterRepository limitingParameterRepository,
|
|
||||||
ISubsystemOperationTimeService subsystemOperationTimeService)
|
|
||||||
{
|
|
||||||
this.wellService = wellService;
|
|
||||||
this.wellOperationRepository = wellOperationService;
|
|
||||||
this.processMapRepository = processMapRepository;
|
|
||||||
this.telemetryDataSaubService = telemetryDataSaubService;
|
|
||||||
this.limitingParameterRepository = limitingParameterRepository;
|
|
||||||
this.subsystemOperationTimeService = subsystemOperationTimeService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapAsync(int idWell, CancellationToken token)
|
|
||||||
{
|
|
||||||
var well = wellService.GetOrDefault(idWell)
|
|
||||||
?? throw new ArgumentInvalidException("idWell not found", nameof(idWell));
|
|
||||||
var idTelemetry = well.IdTelemetry
|
|
||||||
?? throw new ArgumentInvalidException("telemetry by well not found", nameof(idWell));
|
|
||||||
|
|
||||||
var processMap = (await processMapRepository.GetByIdWellAsync(idWell, token))!;
|
|
||||||
var factDrillingOperations = await GetFactDrillingOperationsAsync(idWell, token);
|
|
||||||
var telemetryDataStat = await telemetryDataSaubService.GetTelemetryDataStatAsync(idTelemetry, token);
|
|
||||||
var limitingParameters = await limitingParameterRepository.GetLimitingParametersAsync(new(), well, token);
|
|
||||||
var subsystemsOperationTime = await GetOperationTimeAsync(idWell, token);
|
|
||||||
|
|
||||||
var result = factDrillingOperations
|
|
||||||
.GroupBy(o => o.IdWellSectionType)
|
|
||||||
.SelectMany(sectionOperations =>
|
|
||||||
{
|
|
||||||
var sectionProcessMap = processMap.Where(p => p.IdWellSectionType == sectionOperations.Key);
|
|
||||||
return HandleSection(sectionOperations, sectionProcessMap, telemetryDataStat, limitingParameters, subsystemsOperationTime!);
|
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Task<IEnumerable<SubsystemOperationTimeDto>?> GetOperationTimeAsync(int idWell, CancellationToken token)
|
|
||||||
{
|
|
||||||
var request = new SubsystemOperationTimeRequest
|
|
||||||
{
|
|
||||||
IdWell = idWell,
|
|
||||||
IdsSubsystems = new int[] { SubsystemOperationTimeService.IdSubsystemAKB, SubsystemOperationTimeService.IdSubsystemSpin },
|
|
||||||
};
|
|
||||||
return subsystemOperationTimeService.GetOperationTimeAsync(request, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<IEnumerable<WellOperationDto>> GetFactDrillingOperationsAsync(int idWell, CancellationToken token)
|
|
||||||
{
|
|
||||||
var operationsRequest = new WellOperationRequest
|
|
||||||
{
|
|
||||||
IdWell = idWell,
|
|
||||||
OperationCategoryIds = WellOperationCategory.MechanicalDrillingSubIds,
|
|
||||||
OperationType = WellOperation.IdOperationTypeFact,
|
|
||||||
SortFields = new[] { nameof(WellOperation.DateStart) }
|
|
||||||
};
|
|
||||||
|
|
||||||
var allFactDrillingOperations = await wellOperationRepository.GetAsync(operationsRequest, token);
|
|
||||||
var factDrillingOperations = allFactDrillingOperations.Where(o => o.DepthEnd > o.DepthStart);
|
|
||||||
return factDrillingOperations;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<ProcessMapReportDto> HandleSection(
|
|
||||||
IEnumerable<WellOperationDto> sectionOperations,
|
|
||||||
IEnumerable<ProcessMapPlanDto> sectionProcessMap,
|
|
||||||
IEnumerable<TelemetryDataSaubStatDto> telemetryDataStat,
|
|
||||||
IEnumerable<LimitingParameterDataDto> limitingParameters,
|
|
||||||
IEnumerable<SubsystemOperationTimeDto> subsystemsOperationTime)
|
|
||||||
{
|
|
||||||
var minDepth = sectionOperations.Min(o => o.DepthStart);
|
|
||||||
var maxDepth = sectionOperations.Max(o => o.DepthEnd);
|
|
||||||
|
|
||||||
var depthIntervals = SplitByIntervals(minDepth, maxDepth).ToArray();
|
|
||||||
var result = new ProcessMapReportDto[depthIntervals.Length];
|
|
||||||
|
|
||||||
for (var i = 0; i < depthIntervals.Length; i++ )
|
|
||||||
result[i] = MakeProcessMapReportDto(depthIntervals[i], sectionOperations, sectionProcessMap, telemetryDataStat, limitingParameters, subsystemsOperationTime);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ProcessMapReportDto MakeProcessMapReportDto(
|
|
||||||
(double min, double max) depthInterval,
|
|
||||||
IEnumerable<WellOperationDto> sectionOperations,
|
|
||||||
IEnumerable<ProcessMapPlanDto> sectionProcessMap,
|
|
||||||
IEnumerable<TelemetryDataSaubStatDto> telemetryDataStat,
|
|
||||||
IEnumerable<LimitingParameterDataDto> limitingParameters,
|
|
||||||
IEnumerable<SubsystemOperationTimeDto> subsystemsOperationTime)
|
|
||||||
{
|
|
||||||
var dto = new ProcessMapReportDto{
|
|
||||||
DepthStart = depthInterval.min
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: trim items by detpth intervals. Use linear interpolation.
|
|
||||||
var intervalOperations = sectionOperations.Where(o => o.DepthEnd >= depthInterval.min && o.DepthStart <= depthInterval.max);
|
|
||||||
var intervalProcessMap = sectionProcessMap.Where(map => map.DepthEnd >= depthInterval.min && map.DepthStart <= depthInterval.max);
|
|
||||||
var intervalTelemetryDataStat = CalcIntervalTelemetryDataStat(depthInterval, telemetryDataStat);
|
|
||||||
var intervalLimitingParametrs = limitingParameters.Where(l => l.DepthEnd >= depthInterval.min && l.DepthStart <= depthInterval.max);
|
|
||||||
var intervalSubsystemsOperationTime = subsystemsOperationTime.Where(o => o.DepthEnd >= depthInterval.min && o.DepthStart <= depthInterval.max);
|
|
||||||
|
|
||||||
var firstIntervalOperation = intervalOperations.FirstOrDefault();
|
|
||||||
if (firstIntervalOperation is not null)
|
|
||||||
{
|
|
||||||
dto.DateStart = GetInterpolatedDate(firstIntervalOperation, depthInterval.min);
|
|
||||||
dto.IdWell = firstIntervalOperation.IdWell;
|
|
||||||
dto.IdWellSectionType = firstIntervalOperation.IdWellSectionType;
|
|
||||||
dto.WellSectionTypeName = firstIntervalOperation.WellSectionTypeName ?? string.Empty;
|
|
||||||
dto.MechDrillingHours = CalcHours(depthInterval, intervalOperations);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Разделить интервальные коллекции на ротор и слайд. Пока нет готовой методики.
|
|
||||||
var slideOperations = intervalOperations.Where(o => o.IdCategory == WellOperationCategory.IdSlide);
|
|
||||||
var rotorOperations = intervalOperations.Where(o => o.IdCategory == WellOperationCategory.IdRotor);
|
|
||||||
|
|
||||||
//dto.Slide = CalcDrillModeStat(depthInterval, slideOperations, intervalProcessMap, intervalTelemetryDataStat, intervalLimitingParametrs, intervalSubsystemsOperationTime);
|
|
||||||
//dto.Rotor = CalcDrillModeStat(depthInterval, rotorOperations, intervalProcessMap, intervalTelemetryDataStat, intervalLimitingParametrs, intervalSubsystemsOperationTime);
|
|
||||||
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TelemetryDataSaubStatDto? CalcIntervalTelemetryDataStat((double min, double max) depthInterval, IEnumerable<TelemetryDataSaubStatDto> telemetryDataStat)
|
|
||||||
{
|
|
||||||
TelemetryDataSaubStatDto[] data = telemetryDataStat
|
|
||||||
.Where(d => d.WellDepthMin <= depthInterval.max && d.WellDepthMax >= depthInterval.min)
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
if (!data.Any())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (data.Length == 1)
|
|
||||||
return data.First();
|
|
||||||
|
|
||||||
var result = new TelemetryDataSaubStatDto
|
|
||||||
{
|
|
||||||
WellDepthMin = data.Min(d => d.WellDepthMin),
|
|
||||||
WellDepthMax = data.Max(d => d.WellDepthMax),
|
|
||||||
DateMin = data.Min(d => d.DateMin),
|
|
||||||
DateMax = data.Max(d => d.DateMax),
|
|
||||||
};
|
|
||||||
|
|
||||||
var intervalDeltaDepth = result.WellDepthMax - result.WellDepthMin;
|
|
||||||
|
|
||||||
foreach (var item in data)
|
|
||||||
{
|
|
||||||
var itemWeight = (item.WellDepthMax - item.WellDepthMin) / intervalDeltaDepth;
|
|
||||||
|
|
||||||
result.Pressure += item.Pressure * itemWeight;
|
|
||||||
result.PressureSp += item.PressureSp * itemWeight;
|
|
||||||
result.PressureSpRotor += item.PressureSpSlide * itemWeight;
|
|
||||||
result.PressureIdle += item.PressureIdle * itemWeight;
|
|
||||||
result.PressureDelta += item.PressureDelta * itemWeight;
|
|
||||||
|
|
||||||
result.AxialLoad += item.AxialLoad * itemWeight;
|
|
||||||
result.AxialLoadSp += item.AxialLoadSp * itemWeight;
|
|
||||||
result.AxialLoadLimitMax += item.AxialLoadLimitMax * itemWeight;
|
|
||||||
|
|
||||||
result.RotorTorque += item.RotorTorque * itemWeight;
|
|
||||||
result.RotorTorqueSp += item.RotorTorqueSp * itemWeight;
|
|
||||||
result.RotorTorqueLimitMax += item.RotorTorqueLimitMax * itemWeight;
|
|
||||||
|
|
||||||
result.BlockSpeed += item.BlockSpeed * itemWeight;
|
|
||||||
result.BlockSpeedSp += item.BlockSpeedSp * itemWeight;
|
|
||||||
result.BlockSpeedSpRotor += item.BlockSpeedSpRotor * itemWeight;
|
|
||||||
result.BlockSpeedSpSlide += item.BlockSpeedSpSlide * itemWeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//private static ProcessMapReportRowDto CalcDrillModeStat(
|
|
||||||
// (double min, double max) depthInterval,
|
|
||||||
// IEnumerable<WellOperationDto> intervalModeOperations,
|
|
||||||
// IEnumerable<ProcessMapDto> intervalProcessMap,
|
|
||||||
// TelemetryDataSaubStatDto? telemetryDataStat,
|
|
||||||
// IEnumerable<LimitingParameterDataDto> intervalLimitingParametrs,
|
|
||||||
// IEnumerable<SubsystemOperationTimeDto> intervalSubsystemsOperationTime)
|
|
||||||
//{
|
|
||||||
// var dto = new ProcessMapReportRowDto();
|
|
||||||
// if (intervalModeOperations.Any())
|
|
||||||
// {
|
|
||||||
// var deltaDepth = CalcDeltaDepth(depthInterval, intervalModeOperations);
|
|
||||||
// dto.DeltaDepth = deltaDepth;
|
|
||||||
// dto.Rop = deltaDepth / CalcHours(depthInterval, intervalModeOperations);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if (intervalProcessMap.Any())
|
|
||||||
// {
|
|
||||||
// var processMapFirst = intervalProcessMap.First();
|
|
||||||
// dto.PressureDiff.SetpointPlan = processMapFirst.Pressure.Plan;
|
|
||||||
// dto.AxialLoad.SetpointPlan = processMapFirst.AxialLoad.Plan;
|
|
||||||
// dto.TopDriveTorque.SetpointPlan = processMapFirst.TopDriveTorque.Plan;
|
|
||||||
// //dto.SpeedLimit.SetpointPlan = null;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (telemetryDataStat is not null)
|
|
||||||
// {
|
|
||||||
// dto.PressureDiff.SetpointFact = telemetryDataStat.PressureSp;
|
|
||||||
// dto.PressureDiff.Fact = telemetryDataStat.PressureDelta;
|
|
||||||
// dto.PressureDiff.Limit = telemetryDataStat.PressureDeltaLimitMax;
|
|
||||||
|
|
||||||
// dto.AxialLoad.SetpointFact = telemetryDataStat.AxialLoadSp;
|
|
||||||
// dto.AxialLoad.Fact = telemetryDataStat.AxialLoad;
|
|
||||||
// dto.AxialLoad.Limit = telemetryDataStat.AxialLoadLimitMax;
|
|
||||||
|
|
||||||
// dto.TopDriveTorque.SetpointFact = telemetryDataStat.RotorTorqueSp;
|
|
||||||
// dto.TopDriveTorque.Fact = telemetryDataStat.RotorTorque;
|
|
||||||
// dto.TopDriveTorque.Limit = telemetryDataStat.RotorTorqueLimitMax;
|
|
||||||
|
|
||||||
// dto.SpeedLimit.SetpointFact = telemetryDataStat.BlockSpeedSp;
|
|
||||||
// dto.SpeedLimit.Fact = telemetryDataStat.BlockSpeed;
|
|
||||||
// //dto.SpeedLimit.Limit = mull;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if(intervalLimitingParametrs.Any())
|
|
||||||
// {
|
|
||||||
// const int idLimParamRop = 1;
|
|
||||||
// const int idLimParamPressure = 2;
|
|
||||||
// const int idLimParamAxialLoad = 3;
|
|
||||||
// const int idLimParamTorque = 4;
|
|
||||||
|
|
||||||
// var intervalLimitingParametrsStat = intervalLimitingParametrs
|
|
||||||
// .GroupBy(p => p.IdFeedRegulator)
|
|
||||||
// .Select(g => new
|
|
||||||
// {
|
|
||||||
// IdLimParam = g.Key,
|
|
||||||
// SumDepth = g.Sum(p => p.DepthEnd - p.DepthStart),
|
|
||||||
// });
|
|
||||||
|
|
||||||
// var totalDepth = intervalLimitingParametrsStat
|
|
||||||
// .Sum(s => s.SumDepth);
|
|
||||||
|
|
||||||
// if (totalDepth > 0)
|
|
||||||
// {
|
|
||||||
// dto.AxialLoad.PercDrillingSetpoint = intervalLimitingParametrsStat
|
|
||||||
// .FirstOrDefault(s => s.IdLimParam == idLimParamAxialLoad)?.SumDepth / totalDepth;
|
|
||||||
|
|
||||||
// dto.PressureDiff.PercDrillingSetpoint = intervalLimitingParametrsStat
|
|
||||||
// .FirstOrDefault(s => s.IdLimParam == idLimParamPressure)?.SumDepth / totalDepth;
|
|
||||||
|
|
||||||
// dto.TopDriveTorque.PercDrillingSetpoint = intervalLimitingParametrsStat
|
|
||||||
// .FirstOrDefault(s => s.IdLimParam == idLimParamTorque)?.SumDepth / totalDepth;
|
|
||||||
|
|
||||||
// dto.SpeedLimit.PercDrillingSetpoint = intervalLimitingParametrsStat
|
|
||||||
// .FirstOrDefault(s => s.IdLimParam == idLimParamRop)?.SumDepth / totalDepth;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (intervalSubsystemsOperationTime.Any() && dto.DeltaDepth > 0)
|
|
||||||
// {
|
|
||||||
// dto.Usage = intervalSubsystemsOperationTime.Sum(t => t.DepthEnd - t.DepthStart) / dto.DeltaDepth.Value;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return dto;
|
|
||||||
//}
|
|
||||||
|
|
||||||
private static double CalcDeltaDepth((double min, double max) depthInterval, IEnumerable<WellOperationDto> intervalOperations)
|
|
||||||
{
|
|
||||||
var ddepth = 0d;
|
|
||||||
foreach (var operation in intervalOperations)
|
|
||||||
{
|
|
||||||
var depthStart = operation.DepthStart > depthInterval.min
|
|
||||||
? operation.DepthStart
|
|
||||||
: depthInterval.min;
|
|
||||||
|
|
||||||
var depthEnd = operation.DepthEnd < depthInterval.max
|
|
||||||
? operation.DepthEnd
|
|
||||||
: depthInterval.max;
|
|
||||||
|
|
||||||
ddepth += (depthEnd - depthEnd);
|
|
||||||
}
|
|
||||||
return ddepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double CalcHours((double min, double max) depthInterval, IEnumerable<WellOperationDto> intervalOperations)
|
|
||||||
{
|
|
||||||
var hours = 0d;
|
|
||||||
foreach (var operation in intervalOperations)
|
|
||||||
{
|
|
||||||
var dateStart = operation.DepthStart > depthInterval.min
|
|
||||||
? operation.DateStart
|
|
||||||
: GetInterpolatedDate(operation, depthInterval.min);
|
|
||||||
|
|
||||||
var dateEnd = operation.DepthEnd < depthInterval.max
|
|
||||||
? operation.DateStart + TimeSpan.FromHours(operation.DurationHours)
|
|
||||||
: GetInterpolatedDate(operation, depthInterval.max);
|
|
||||||
|
|
||||||
hours += (dateEnd - dateStart).TotalHours;
|
|
||||||
}
|
|
||||||
return hours;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DateTime GetInterpolatedDate(WellOperationDto operation, double depth)
|
|
||||||
{
|
|
||||||
var ratio = (depth - operation.DepthStart) / (operation.DepthEnd - operation.DepthStart);
|
|
||||||
var deltaHours = operation.DurationHours * ratio;
|
|
||||||
var interpolatedDate = operation.DateStart + TimeSpan.FromHours(deltaHours);
|
|
||||||
return interpolatedDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<(double min, double max)> SplitByIntervals(double min, double max)
|
|
||||||
{
|
|
||||||
const double step = 100;
|
|
||||||
var iMin = min;
|
|
||||||
var iMax = (1 + (int)(min / step)) * step;
|
|
||||||
for (; iMax < max; iMax += step)
|
|
||||||
{
|
|
||||||
yield return (iMin, iMax);
|
|
||||||
iMin = iMax;
|
|
||||||
}
|
|
||||||
yield return (iMin, max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#nullable disable
|
|
||||||
}
|
|
@ -42,10 +42,17 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
.Where(t => t.BlockPosition > 0.0001)
|
.Where(t => t.BlockPosition > 0.0001)
|
||||||
.Where(t => t.WellDepth > 0.0001)
|
.Where(t => t.WellDepth > 0.0001)
|
||||||
.Where(t => t.WellDepth - t.BitDepth < 0.01)
|
.Where(t => t.WellDepth - t.BitDepth < 0.01)
|
||||||
.GroupBy(t => new { H = t.DateTime.Hour, W = Math.Truncate(t.WellDepth!.Value) })
|
.Where(t => t.Mode != null)
|
||||||
|
.GroupBy(t => new {
|
||||||
|
t.DateTime.Hour,
|
||||||
|
WellDepthX10 = Math.Truncate(t.WellDepth!.Value * 10),
|
||||||
|
t.Mode,
|
||||||
|
t.IdFeedRegulator})
|
||||||
.Select(g => new TelemetryDataSaubStatDto
|
.Select(g => new TelemetryDataSaubStatDto
|
||||||
{
|
{
|
||||||
Count = g.Count(),
|
Count = g.Count(),
|
||||||
|
Mode = g.Key.Mode??0,
|
||||||
|
IdFeedRegulator = g.Key.IdFeedRegulator,
|
||||||
|
|
||||||
DateMin = DateTime.SpecifyKind(g.Min(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified),
|
DateMin = DateTime.SpecifyKind(g.Min(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified),
|
||||||
DateMax = DateTime.SpecifyKind(g.Max(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified),
|
DateMax = DateTime.SpecifyKind(g.Max(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified),
|
||||||
@ -55,8 +62,6 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
|
|
||||||
Pressure = g.Average(t => t.Pressure!.Value),
|
Pressure = g.Average(t => t.Pressure!.Value),
|
||||||
PressureSp = g.Average(t => t.PressureSp!.Value),
|
PressureSp = g.Average(t => t.PressureSp!.Value),
|
||||||
PressureSpRotor = g.Average(t => t.PressureSpRotor!.Value),
|
|
||||||
PressureSpSlide = g.Average(t => t.PressureSpSlide!.Value),
|
|
||||||
PressureIdle = g.Average(t => t.PressureIdle!.Value),
|
PressureIdle = g.Average(t => t.PressureIdle!.Value),
|
||||||
PressureDeltaLimitMax = g.Average(t => t.PressureDeltaLimitMax!.Value),
|
PressureDeltaLimitMax = g.Average(t => t.PressureDeltaLimitMax!.Value),
|
||||||
PressureDelta = g.Average(t => t.Pressure!.Value - t.PressureIdle!.Value),
|
PressureDelta = g.Average(t => t.Pressure!.Value - t.PressureIdle!.Value),
|
||||||
@ -71,8 +76,6 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
|
|
||||||
BlockSpeed = g.Average(t => t.BlockSpeed!.Value),
|
BlockSpeed = g.Average(t => t.BlockSpeed!.Value),
|
||||||
BlockSpeedSp = g.Average(t => t.BlockSpeedSp!.Value),
|
BlockSpeedSp = g.Average(t => t.BlockSpeedSp!.Value),
|
||||||
BlockSpeedSpRotor = g.Average(t => t.BlockSpeedSpRotor!.Value),
|
|
||||||
BlockSpeedSpSlide = g.Average(t => t.BlockSpeedSpSlide!.Value),
|
|
||||||
})
|
})
|
||||||
.Where(s => s.WellDepthMin != s.WellDepthMax)
|
.Where(s => s.WellDepthMin != s.WellDepthMax)
|
||||||
.Where(s => s.Count > 3)
|
.Where(s => s.Count > 3)
|
||||||
|
@ -44,7 +44,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
var db = serviceProvider.GetRequiredService<IAsbCloudDbContext>();
|
var db = serviceProvider.GetRequiredService<IAsbCloudDbContext>();
|
||||||
var wellService = serviceProvider.GetRequiredService<IWellService>();
|
var wellService = serviceProvider.GetRequiredService<IWellService>();
|
||||||
var operationsStatService = serviceProvider.GetRequiredService<IOperationsStatService>();
|
var operationsStatService = serviceProvider.GetRequiredService<IOperationsStatService>();
|
||||||
var processMapRepository = serviceProvider.GetRequiredService<IProcessMapRepository>();
|
var processMapRepository = serviceProvider.GetRequiredService<IProcessMapPlanRepository>();
|
||||||
var subsystemOperationTimeService = serviceProvider.GetRequiredService<ISubsystemOperationTimeService>();
|
var subsystemOperationTimeService = serviceProvider.GetRequiredService<ISubsystemOperationTimeService>();
|
||||||
|
|
||||||
var activeWells = await wellService.GetAsync(new() {IdState = 1}, token);
|
var activeWells = await wellService.GetAsync(new() {IdState = 1}, token);
|
||||||
|
@ -18,17 +18,17 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class ProcessMapController : CrudWellRelatedController<ProcessMapPlanDto, IProcessMapRepository>
|
public class ProcessMapController : CrudWellRelatedController<ProcessMapPlanDto, IProcessMapPlanRepository>
|
||||||
{
|
{
|
||||||
private readonly ITelemetryService telemetryService;
|
private readonly ITelemetryService telemetryService;
|
||||||
private readonly IProcessMapReportService processMapReportService;
|
private readonly IProcessMapReportMakerService processMapReportService;
|
||||||
private readonly IProcessMapService processMapService;
|
private readonly IProcessMapReportService processMapService;
|
||||||
|
|
||||||
public ProcessMapController(
|
public ProcessMapController(
|
||||||
IWellService wellService,
|
IWellService wellService,
|
||||||
IProcessMapRepository repository,
|
IProcessMapPlanRepository repository,
|
||||||
IProcessMapReportService processMapReportService,
|
IProcessMapReportMakerService processMapReportService,
|
||||||
IProcessMapService processMapService,
|
IProcessMapReportService processMapService,
|
||||||
ITelemetryService telemetryService)
|
ITelemetryService telemetryService)
|
||||||
: base(wellService, repository)
|
: base(wellService, repository)
|
||||||
{
|
{
|
||||||
|
@ -2,34 +2,12 @@
|
|||||||
@contentType = application/json
|
@contentType = application/json
|
||||||
@auth = Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkpXVCJ9.eyJpZCI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiZGV2IiwiaWRDb21wYW55IjoiMSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6InJvb3QiLCJuYmYiOjE2NjI1NDgxNjIsImV4cCI6MTY5NDEwNTc2MiwiaXNzIjoiYSIsImF1ZCI6ImEifQ.OEAlNzxi7Jat6pzDBTAjTbChskc-tdJthJexyWwwUKE
|
@auth = Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkpXVCJ9.eyJpZCI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiZGV2IiwiaWRDb21wYW55IjoiMSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6InJvb3QiLCJuYmYiOjE2NjI1NDgxNjIsImV4cCI6MTY5NDEwNTc2MiwiaXNzIjoiYSIsImF1ZCI6ImEifQ.OEAlNzxi7Jat6pzDBTAjTbChskc-tdJthJexyWwwUKE
|
||||||
|
|
||||||
|
@wellId = 1
|
||||||
|
|
||||||
# https://marketplace.visualstudio.com/items?itemName=humao.rest-client
|
# https://marketplace.visualstudio.com/items?itemName=humao.rest-client
|
||||||
|
|
||||||
###
|
###
|
||||||
GET {{baseUrl}}/api/schedule/test
|
GET {{baseUrl}}/api/processMap/getDrillProcessMap/{{wellId}}
|
||||||
Content-Type: {{contentType}}
|
Content-Type: {{contentType}}
|
||||||
accept: */*
|
accept: */*
|
||||||
Authorization: {{auth}}
|
Authorization: {{auth}}
|
||||||
|
|
||||||
###
|
|
||||||
POST {{baseUrl}}/api/schedule/test
|
|
||||||
Content-Type: {{contentType}}
|
|
||||||
accept: */*
|
|
||||||
Authorization: {{auth}}
|
|
||||||
|
|
||||||
{
|
|
||||||
"id": 0,
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"value": 0.1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 2,
|
|
||||||
"value": 1.
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"value": 2.0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user