diff --git a/AsbCloudApp/Data/SAUB/TelemetryDataSaubStatDto.cs b/AsbCloudApp/Data/SAUB/TelemetryDataSaubStatDto.cs
index 2ca5293c..40514429 100644
--- a/AsbCloudApp/Data/SAUB/TelemetryDataSaubStatDto.cs
+++ b/AsbCloudApp/Data/SAUB/TelemetryDataSaubStatDto.cs
@@ -47,16 +47,6 @@ namespace AsbCloudApp.Data.SAUB
///
public float PressureIdle { get; set; }
- ///
- /// задание давления для роторного режима
- ///
- public float PressureSpRotor { get; set; }
-
- ///
- /// задание давления для режима слайда
- ///
- public float PressureSpSlide { get; set; }
-
///
/// ограничение макс перепада давления
///
@@ -108,13 +98,13 @@ namespace AsbCloudApp.Data.SAUB
public float BlockSpeedSp { get; set; }
///
- /// Талевый блок. Задание скорости для роторного бурения
+ /// Режим САУБ
///
- public float BlockSpeedSpRotor { get; set; }
+ public short Mode { get; set; }
///
- /// Талевый блок. Задание скорости для режима слайда
+ /// Текущий критерий бурения
///
- public float BlockSpeedSpSlide { get; set; }
+ public short? IdFeedRegulator { get; set; }
}
}
diff --git a/AsbCloudApp/Repositories/IProcessMapRepository.cs b/AsbCloudApp/Repositories/IProcessMapRepository.cs
index c0f347e2..b126e18a 100644
--- a/AsbCloudApp/Repositories/IProcessMapRepository.cs
+++ b/AsbCloudApp/Repositories/IProcessMapRepository.cs
@@ -11,7 +11,7 @@ namespace AsbCloudApp.Repositories
///
///
///
- public interface IProcessMapRepository : IRepositoryWellRelated
+ public interface IProcessMapPlanRepository : IRepositoryWellRelated
{
///
/// .
diff --git a/AsbCloudApp/Services/IProcessMapReportService.cs b/AsbCloudApp/Services/IProcessMapReportMakerService.cs
similarity index 90%
rename from AsbCloudApp/Services/IProcessMapReportService.cs
rename to AsbCloudApp/Services/IProcessMapReportMakerService.cs
index a4bf783b..0fea6d7b 100644
--- a/AsbCloudApp/Services/IProcessMapReportService.cs
+++ b/AsbCloudApp/Services/IProcessMapReportMakerService.cs
@@ -7,7 +7,7 @@ namespace AsbCloudApp.Services
///
/// Сервис формирования РТК.
///
- public interface IProcessMapReportService
+ public interface IProcessMapReportMakerService
{
///
/// Сформировать.
diff --git a/AsbCloudApp/Services/IProcessMapService.cs b/AsbCloudApp/Services/IProcessMapService.cs
index 63a611c8..954d899a 100644
--- a/AsbCloudApp/Services/IProcessMapService.cs
+++ b/AsbCloudApp/Services/IProcessMapService.cs
@@ -8,7 +8,7 @@ namespace AsbCloudApp.Services
///
/// Сервис формирования РТК
///
- public interface IProcessMapService
+ public interface IProcessMapReportService
{
///
/// Получение моделей РТК
diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs
index f74de38e..62fa5d3f 100644
--- a/AsbCloudInfrastructure/DependencyInjection.cs
+++ b/AsbCloudInfrastructure/DependencyInjection.cs
@@ -107,7 +107,7 @@ namespace AsbCloudInfrastructure
services.AddTransient();
services.AddTransient();
- services.AddTransient();
+ services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddTransient();
@@ -133,8 +133,8 @@ namespace AsbCloudInfrastructure
services.AddTransient();
services.AddTransient();
services.AddTransient();
+ services.AddTransient();
services.AddTransient();
- services.AddTransient();
services.AddTransient();
// admin crud services:
diff --git a/AsbCloudInfrastructure/Repository/ProcessMapRepository.cs b/AsbCloudInfrastructure/Repository/ProcessMapRepository.cs
index dc0539c7..4b6305ca 100644
--- a/AsbCloudInfrastructure/Repository/ProcessMapRepository.cs
+++ b/AsbCloudInfrastructure/Repository/ProcessMapRepository.cs
@@ -4,10 +4,8 @@ using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
-using DocumentFormat.OpenXml.Spreadsheet;
using Mapster;
using Microsoft.EntityFrameworkCore;
-using Org.BouncyCastle.Asn1.Ocsp;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -19,7 +17,7 @@ namespace AsbCloudInfrastructure.Repository
{
#nullable enable
public class ProcessMapRepository : CrudWellRelatedRepositoryBase,
- IProcessMapRepository
+ IProcessMapPlanRepository
{
private readonly IWellService wellService;
diff --git a/AsbCloudInfrastructure/Repository/WellCompositeRepository.cs b/AsbCloudInfrastructure/Repository/WellCompositeRepository.cs
index 0ec8d6b9..f57326fa 100644
--- a/AsbCloudInfrastructure/Repository/WellCompositeRepository.cs
+++ b/AsbCloudInfrastructure/Repository/WellCompositeRepository.cs
@@ -17,9 +17,9 @@ namespace AsbCloudInfrastructure.Repository
public class WellCompositeRepository : IWellCompositeRepository
{
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.processMapRepository = processMapRepository;
diff --git a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportMakerService.cs b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportMakerService.cs
new file mode 100644
index 00000000..8e444a08
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportMakerService.cs
@@ -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 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 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> 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 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
+}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportService.cs b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportService.cs
index 430da7b4..9cd63e0e 100644
--- a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportService.cs
+++ b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportService.cs
@@ -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 ClosedXML.Excel;
+using AsbCloudApp.Services.Subsystems;
+using AsbCloudDb.Model;
+using AsbCloudApp.Data.Subsystems;
+using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -10,207 +17,86 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.ProcessMap
{
#nullable enable
- public class ProcessMapReportService : IProcessMapReportService
+ public partial class ProcessMapReportService : IProcessMapReportService
{
- const int firstColumn = 2;
- const int lastColumn = 61;
+ private readonly IWellService wellService;
+ private readonly IWellOperationRepository wellOperationRepository;
+ private readonly IProcessMapPlanRepository processMapPlanRepository;
+ private readonly ITelemetryDataSaubService telemetryDataSaubService;
+ private readonly ILimitingParameterRepository limitingParameterRepository;
+ private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
- const int headerRowsCount = 8;
-
- private readonly IProcessMapService processMapService;
-
- public ProcessMapReportService(IProcessMapService processMapService)
+ public ProcessMapReportService(
+ IWellService wellService,
+ IWellOperationRepository wellOperationService,
+ IProcessMapPlanRepository processMapPlanRepository,
+ 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 MakeReportAsync(int idWell, CancellationToken token)
+ ///
+ public async Task> GetProcessMapAsync(int idWell, CancellationToken token)
{
- var stream = GetExcelTemplateStream();
- using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
+ var well = wellService.GetOrDefault(idWell)
+ ?? 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();
- workbook.SaveAs(memoryStream, new SaveOptions { });
- memoryStream.Seek(0, SeekOrigin.Begin);
- return memoryStream;
+ if(!processMapPlan.Any())
+ return Enumerable.Empty();
+
+ var telemetryDataStat = await telemetryDataSaubService.GetTelemetryDataStatAsync(idTelemetry, token);
+
+ var result = CalcByIntervals(processMapPlan, telemetryDataStat);
+
+ return result;
}
- private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable data)
+ private IEnumerable CalcByIntervals(IEnumerable processMapPlan, IEnumerable telemetryDataStat)
{
- 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> 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 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);
+ var result = new List(processMapPlan.Count() * 4);
+ var intervals = GetProcessMapIntervals(processMapPlan);
- 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);
+ return result;
}
- private static void FillIntervalModeDataSpeed(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row)
+ private IEnumerable<(double, double)> GetProcessMapIntervals(IEnumerable processMapPlan)
{
- 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);
+
+ return Enumerable.Empty<(double, double)>();
}
- private static Stream GetExcelTemplateStream()
+ private static DateTime GetInterpolatedDate(WellOperationDto operation, double depth)
{
- var stream = System.Reflection.Assembly.GetExecutingAssembly()
- .GetManifestResourceStream("AsbCloudInfrastructure.Services.ProcessMap.ProcessMapReportTemplate.xlsx");
- return stream!;
+ 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 IXLStyle SetBorders(IXLStyle style)
+ private static IEnumerable<(double min, double max)> SplitByIntervals(double min, double max)
{
- 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;
+ 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
-}
\ No newline at end of file
+}
diff --git a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapService.cs b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapService.cs
deleted file mode 100644
index 5688e0ff..00000000
--- a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapService.cs
+++ /dev/null
@@ -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;
- }
-
- ///
- public async Task> 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?> 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> 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 HandleSection(
- IEnumerable sectionOperations,
- IEnumerable sectionProcessMap,
- IEnumerable telemetryDataStat,
- IEnumerable limitingParameters,
- IEnumerable 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 sectionOperations,
- IEnumerable sectionProcessMap,
- IEnumerable telemetryDataStat,
- IEnumerable limitingParameters,
- IEnumerable 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 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 intervalModeOperations,
- // IEnumerable intervalProcessMap,
- // TelemetryDataSaubStatDto? telemetryDataStat,
- // IEnumerable intervalLimitingParametrs,
- // IEnumerable 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 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 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
-}
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs
index 0d34b80c..6d9a140b 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs
@@ -42,10 +42,17 @@ namespace AsbCloudInfrastructure.Services.SAUB
.Where(t => t.BlockPosition > 0.0001)
.Where(t => t.WellDepth > 0.0001)
.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
{
Count = g.Count(),
+ Mode = g.Key.Mode??0,
+ IdFeedRegulator = g.Key.IdFeedRegulator,
DateMin = DateTime.SpecifyKind(g.Min(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),
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),
PressureDeltaLimitMax = g.Average(t => t.PressureDeltaLimitMax!.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),
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.Count > 3)
diff --git a/AsbCloudInfrastructure/Services/WellInfoService.cs b/AsbCloudInfrastructure/Services/WellInfoService.cs
index 79d59003..998a40f3 100644
--- a/AsbCloudInfrastructure/Services/WellInfoService.cs
+++ b/AsbCloudInfrastructure/Services/WellInfoService.cs
@@ -44,7 +44,7 @@ namespace AsbCloudInfrastructure.Services
var db = serviceProvider.GetRequiredService();
var wellService = serviceProvider.GetRequiredService();
var operationsStatService = serviceProvider.GetRequiredService();
- var processMapRepository = serviceProvider.GetRequiredService();
+ var processMapRepository = serviceProvider.GetRequiredService();
var subsystemOperationTimeService = serviceProvider.GetRequiredService();
var activeWells = await wellService.GetAsync(new() {IdState = 1}, token);
diff --git a/AsbCloudWebApi/Controllers/ProcessMapController.cs b/AsbCloudWebApi/Controllers/ProcessMapController.cs
index 9f5617a2..3613f32c 100644
--- a/AsbCloudWebApi/Controllers/ProcessMapController.cs
+++ b/AsbCloudWebApi/Controllers/ProcessMapController.cs
@@ -18,17 +18,17 @@ namespace AsbCloudWebApi.Controllers
[ApiController]
[Route("api/[controller]")]
[Authorize]
- public class ProcessMapController : CrudWellRelatedController
+ public class ProcessMapController : CrudWellRelatedController
{
private readonly ITelemetryService telemetryService;
- private readonly IProcessMapReportService processMapReportService;
- private readonly IProcessMapService processMapService;
+ private readonly IProcessMapReportMakerService processMapReportService;
+ private readonly IProcessMapReportService processMapService;
public ProcessMapController(
IWellService wellService,
- IProcessMapRepository repository,
- IProcessMapReportService processMapReportService,
- IProcessMapService processMapService,
+ IProcessMapPlanRepository repository,
+ IProcessMapReportMakerService processMapReportService,
+ IProcessMapReportService processMapService,
ITelemetryService telemetryService)
: base(wellService, repository)
{
diff --git a/AsbCloudWebApi/Rest/Example.http b/AsbCloudWebApi/Rest/ProcessMap.http
similarity index 66%
rename from AsbCloudWebApi/Rest/Example.http
rename to AsbCloudWebApi/Rest/ProcessMap.http
index bd156b32..9a7d487e 100644
--- a/AsbCloudWebApi/Rest/Example.http
+++ b/AsbCloudWebApi/Rest/ProcessMap.http
@@ -2,34 +2,12 @@
@contentType = application/json
@auth = Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkpXVCJ9.eyJpZCI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiZGV2IiwiaWRDb21wYW55IjoiMSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6InJvb3QiLCJuYmYiOjE2NjI1NDgxNjIsImV4cCI6MTY5NDEwNTc2MiwiaXNzIjoiYSIsImF1ZCI6ImEifQ.OEAlNzxi7Jat6pzDBTAjTbChskc-tdJthJexyWwwUKE
+@wellId = 1
+
# https://marketplace.visualstudio.com/items?itemName=humao.rest-client
###
-GET {{baseUrl}}/api/schedule/test
+GET {{baseUrl}}/api/processMap/getDrillProcessMap/{{wellId}}
Content-Type: {{contentType}}
accept: */*
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
- }
- ]
-}
\ No newline at end of file