This commit is contained in:
ngfrolov 2023-04-06 10:25:51 +05:00
parent 1f904a7434
commit 40a3d3ab50
Signed by: ng.frolov
GPG Key ID: E99907A0357B29A7
7 changed files with 99 additions and 63 deletions

View File

@ -79,7 +79,7 @@ namespace AsbCloudApp.Data.ProcessMap
/// <summary> /// <summary>
/// Ограничение скорости, м/ч /// Ограничение скорости, м/ч
/// </summary> /// </summary>
public ProcessMapReportParamsDto SpeedLimit { get; set; } = new(); public ProcessMapReportParamsDto SpeedLimit { get; set; } = new();
/// <summary> /// <summary>
/// Процент использования системы АПД, % /// Процент использования системы АПД, %
@ -89,6 +89,6 @@ namespace AsbCloudApp.Data.ProcessMap
/// <summary> /// <summary>
/// Фактическая механическая скорость, м/ч /// Фактическая механическая скорость, м/ч
/// </summary> /// </summary>
public double Rop { get; set; } public double? Rop { get; set; }
} }
} }

View File

@ -1,10 +1,4 @@
using System; namespace AsbCloudApp.Data.ProcessMap
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsbCloudApp.Data.ProcessMap
{ {
/// <summary> /// <summary>
/// Параметры РТК /// Параметры РТК
@ -34,6 +28,6 @@ namespace AsbCloudApp.Data.ProcessMap
/// <summary> /// <summary>
/// Процент бурения по уставке, % /// Процент бурения по уставке, %
/// </summary> /// </summary>
public double? PercDrillingBySetpoint { get; set; } public double? SetpointUsage { get; set; }
} }
} }

View File

@ -16,6 +16,6 @@ namespace AsbCloudApp.Services
/// <param name="idWell"></param> /// <param name="idWell"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<ProcessMapReportDto>> GetProcessMapAsync(int idWell, CancellationToken token); Task<IEnumerable<ProcessMapReportDto>> GetProcessMapReportAsync(int idWell, CancellationToken token);
} }
} }

View File

@ -29,7 +29,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
var stream = GetExcelTemplateStream(); var stream = GetExcelTemplateStream();
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled); using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
var data = await processMapService.GetProcessMapAsync(idWell, token); var data = await processMapService.GetProcessMapReportAsync(idWell, token);
FillProcessMapToWorkbook(workbook, data); FillProcessMapToWorkbook(workbook, data);
@ -168,7 +168,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
.SetVal(dataParam.Limit); .SetVal(dataParam.Limit);
sheet.Cell(row, column + columnOffsetPercent) sheet.Cell(row, column + columnOffsetPercent)
.SetVal(dataParam.PercDrillingBySetpoint); .SetVal(dataParam.SetpointUsage);
} }
private static void FillIntervalModeDataSpeed(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row) private static void FillIntervalModeDataSpeed(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row)
@ -192,7 +192,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
.SetVal(dataParam.Limit); .SetVal(dataParam.Limit);
sheet.Cell(row, column + columnOffsetPercent) sheet.Cell(row, column + columnOffsetPercent)
.SetVal(dataParam.PercDrillingBySetpoint); .SetVal(dataParam.SetpointUsage);
} }
private static Stream GetExcelTemplateStream() private static Stream GetExcelTemplateStream()

View File

@ -32,7 +32,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
} }
/// <inheritdoc/> /// <inheritdoc/>
public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapAsync(int idWell, CancellationToken token) public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapReportAsync(int idWell, CancellationToken token)
{ {
var well = wellService.GetOrDefault(idWell) var well = wellService.GetOrDefault(idWell)
?? throw new ArgumentInvalidException("idWell not found", nameof(idWell)); ?? throw new ArgumentInvalidException("idWell not found", nameof(idWell));
@ -56,10 +56,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
private IEnumerable<ProcessMapReportDto> CalcByIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan, TelemetryDataSaubStatDto[] telemetryDataStat) private IEnumerable<ProcessMapReportDto> CalcByIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan, TelemetryDataSaubStatDto[] telemetryDataStat)
{ {
var processMapIntervals = processMapPlan var processMapIntervals = CalcDepthIntervals(processMapPlan);
.Select(p => (p.DepthStart, p.DepthEnd))
.Distinct()
.OrderBy(i => i.DepthStart);
var result = new List<ProcessMapReportDto>(processMapIntervals.Count() * 4); var result = new List<ProcessMapReportDto>(processMapIntervals.Count() * 4);
@ -75,6 +72,8 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
.Where(p => p.DepthStart >= interval.DepthStart && p.DepthEnd <= interval.DepthEnd); .Where(p => p.DepthStart >= interval.DepthStart && p.DepthEnd <= interval.DepthEnd);
var telemetryIndexEnd = Array.FindIndex(telemetryDataStat, telemetryIndexStart, t => t.WellDepthMin >= interval.DepthEnd); var telemetryIndexEnd = Array.FindIndex(telemetryDataStat, telemetryIndexStart, t => t.WellDepthMin >= interval.DepthEnd);
if (telemetryIndexEnd < 0)
telemetryIndexEnd = telemetryDataStat.Length - 1;
var telemetryDataInterval = telemetryDataStat.AsSpan(telemetryIndexStart, telemetryIndexEnd - telemetryIndexStart); var telemetryDataInterval = telemetryDataStat.AsSpan(telemetryIndexStart, telemetryIndexEnd - telemetryIndexStart);
IEnumerable<ProcessMapReportDto> subIntervalsResult = CalcSubIntervals(interval, processMapPlanInterval, telemetryDataInterval, sectionTypes); IEnumerable<ProcessMapReportDto> subIntervalsResult = CalcSubIntervals(interval, processMapPlanInterval, telemetryDataInterval, sectionTypes);
@ -86,7 +85,24 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
return result; return result;
} }
private IEnumerable<ProcessMapReportDto> CalcSubIntervals( private static IEnumerable<(double DepthStart, double DepthEnd)> CalcDepthIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan)
{
if(!processMapPlan.Any())
yield break;
var intervalStarts = processMapPlan
.OrderBy(i => i.DepthStart)
.Select(p => p.DepthStart)
.Distinct()
.ToArray();
for (var i = 1; i < intervalStarts.Length; i++)
yield return (intervalStarts[i - 1], intervalStarts[i]);
yield return (intervalStarts[^1], processMapPlan.Max(p=>p.DepthEnd));
}
private static IEnumerable<ProcessMapReportDto> CalcSubIntervals(
(double DepthStart, double DepthEnd) interval, (double DepthStart, double DepthEnd) interval,
IEnumerable<ProcessMapPlanDto> processMapPlanInterval, IEnumerable<ProcessMapPlanDto> processMapPlanInterval,
Span<TelemetryDataSaubStatDto> telemetryDataInterval, Span<TelemetryDataSaubStatDto> telemetryDataInterval,
@ -100,14 +116,17 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
var telemetryIndexStart = 0; var telemetryIndexStart = 0;
var subInterval = interval; var subInterval = interval;
for (var i = telemetryIndexStart; i < telemetryDataIntervalLength; i++) for (var i = telemetryIndexStart + 1; i < telemetryDataIntervalLength; i++)
{ {
if (!IsSimilar(telemetryDataInterval[telemetryIndexStart], telemetryDataInterval[i])) if (IsDifferent(telemetryDataInterval[telemetryIndexStart], telemetryDataInterval[i]))
{ {
subInterval.DepthEnd = telemetryDataInterval[i].WellDepthMax; subInterval.DepthEnd = telemetryDataInterval[i - 1].WellDepthMax;
var telemetryRowSpan = telemetryDataInterval[telemetryIndexStart..(i - 1)];
var intervalReportRow = CalcSubIntervalReportRow(subInterval, processMapPlanInterval, telemetryDataInterval[telemetryIndexStart..i], sectionTypes); if (!telemetryRowSpan.IsEmpty)
{
var intervalReportRow = CalcSubIntervalReportRow(subInterval, processMapPlanInterval, telemetryRowSpan, sectionTypes);
result.Add(intervalReportRow); result.Add(intervalReportRow);
}
telemetryIndexStart = i; telemetryIndexStart = i;
subInterval.DepthStart = subInterval.DepthEnd; subInterval.DepthStart = subInterval.DepthEnd;
} }
@ -119,7 +138,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
return result; return result;
} }
private ProcessMapReportDto CalcSubIntervalReportRow( private static ProcessMapReportDto CalcSubIntervalReportRow(
(double DepthStart, double DepthEnd) subInterval, (double DepthStart, double DepthEnd) subInterval,
IEnumerable<ProcessMapPlanDto> processMap, IEnumerable<ProcessMapPlanDto> processMap,
Span<TelemetryDataSaubStatDto> telemetryRowSpan, Span<TelemetryDataSaubStatDto> telemetryRowSpan,
@ -149,10 +168,10 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
DeltaDepth = telemetryLast.WellDepthMax - telemetryFirst.WellDepthMin, DeltaDepth = telemetryLast.WellDepthMax - telemetryFirst.WellDepthMin,
PressureDiff = telemetryStat.Pressure.MakeParams(processMapByMode?.Pressure.Plan), PressureDiff = telemetryStat.Pressure.MakeParams(processMapByMode?.Pressure.Plan, telemetryStat.SpUsageDepthTotal),
AxialLoad = telemetryStat.AxialLoad.MakeParams(processMapByMode?.AxialLoad.Plan), AxialLoad = telemetryStat.AxialLoad.MakeParams(processMapByMode?.AxialLoad.Plan, telemetryStat.SpUsageDepthTotal),
TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan), TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan, telemetryStat.SpUsageDepthTotal),
SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan), SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan, telemetryStat.SpUsageDepthTotal),
Rop = telemetryStat.Rop, Rop = telemetryStat.Rop,
Usage = telemetryStat.UsageSaub, Usage = telemetryStat.UsageSaub,
@ -194,32 +213,35 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
return (0, "Ручной"); return (0, "Ручной");
} }
private static bool IsSimilar(TelemetryDataSaubStatDto telemetry1, TelemetryDataSaubStatDto telemetry2) private static bool IsDifferent(TelemetryDataSaubStatDto intervalStart, TelemetryDataSaubStatDto current)
{ {
if (telemetry1.IdMode != telemetry2.IdMode) if (intervalStart.WellDepthMin > current.WellDepthMin)
return false; return true;
if (Math.Abs(telemetry1.PressureSp - telemetry2.PressureSp) > 5d) if (intervalStart.IdMode != current.IdMode)
return false; return true;
if (Math.Abs(telemetry1.AxialLoadSp - telemetry2.AxialLoadSp) > 1d) if (Math.Abs(intervalStart.PressureSp - current.PressureSp) > 5d)
return false; return true;
if (Math.Abs(telemetry1.RotorTorqueSp - telemetry2.RotorTorqueSp) > 5d) if (Math.Abs(intervalStart.AxialLoadSp - current.AxialLoadSp) > 1d)
return false; return true;
var blockSpeedSpDiff = Math.Abs(telemetry1.BlockSpeedSp - telemetry2.BlockSpeedSp); if (Math.Abs(intervalStart.RotorTorqueSp - current.RotorTorqueSp) > 5d)
return true;
var blockSpeedSpDiff = Math.Abs(intervalStart.BlockSpeedSp - current.BlockSpeedSp);
if (blockSpeedSpDiff > 5d) if (blockSpeedSpDiff > 5d)
{ {
if (telemetry1.BlockSpeedSp < 30) if (intervalStart.BlockSpeedSp <= 30)
return false; return true;
else if (telemetry1.BlockSpeedSp > 30 && blockSpeedSpDiff > 15d) else if (intervalStart.BlockSpeedSp > 30 && blockSpeedSpDiff > 15d)
return false; return true;
else if (telemetry1.BlockSpeedSp > 80 && blockSpeedSpDiff > 20d) else if (intervalStart.BlockSpeedSp > 80 && blockSpeedSpDiff > 20d)
return false; return true;
} }
return true; return false;
} }
} }
@ -228,8 +250,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
{ {
private double spWSum; private double spWSum;
private double pvWSum; private double pvWSum;
private double? limitMaxWSum; private double limitMaxWSum;
private double spUsageDepth;
private double deltaDepthSum; private double deltaDepthSum;
@ -241,6 +262,8 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
private TelemetryDataSaubStatDto? previous; private TelemetryDataSaubStatDto? previous;
public double SpUsageDepth { get; private set; }
public ParamStat(Func<TelemetryDataSaubStatDto, double> getterSp, public ParamStat(Func<TelemetryDataSaubStatDto, double> getterSp,
Func<TelemetryDataSaubStatDto, double> getterPv, Func<TelemetryDataSaubStatDto, double> getterPv,
Func<TelemetryDataSaubStatDto, double>? getterLimitMax, Func<TelemetryDataSaubStatDto, double>? getterLimitMax,
@ -262,13 +285,22 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
var deltaDepthHalf = deltaDepth / 2; var deltaDepthHalf = deltaDepth / 2;
double CalculateWeight(Func<TelemetryDataSaubStatDto, double> getter) => (getter(previous!) + getter(current)) * deltaDepthHalf; double CalculateWeight(Func<TelemetryDataSaubStatDto, double> getter) => (getter(previous!) + getter(current)) * deltaDepthHalf;
spWSum = CalculateWeight(getterSp); spWSum += CalculateWeight(getterSp);
pvWSum = CalculateWeight(getterPv); pvWSum += CalculateWeight(getterPv);
if(getterLimitMax is not null) if(getterLimitMax is not null)
limitMaxWSum = CalculateWeight(getterLimitMax!); limitMaxWSum += CalculateWeight(getterLimitMax!);
if (current.IdFeedRegulator == idFeedRegulator) if (current.IdFeedRegulator is not null)
spUsageDepth += deltaDepth; {
if(current.IdFeedRegulator == idFeedRegulator)
SpUsageDepth += deltaDepth;
}
else
{
var pvErr = (getterSp(current) - getterPv(current)) / getterSp(current);
if (pvErr < 0.03d) //3%
SpUsageDepth += deltaDepth;
}
deltaDepthSum += deltaDepth; deltaDepthSum += deltaDepth;
} }
@ -277,15 +309,22 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
previous = current; previous = current;
} }
public ProcessMapReportParamsDto MakeParams(double? spPlan) public ProcessMapReportParamsDto MakeParams(double? spPlan, double SpUsageDepthTotal)
=> new ProcessMapReportParamsDto => new ProcessMapReportParamsDto
{ {
SetpointPlan = spPlan, SetpointPlan = spPlan,
SetpointFact = spWSum / deltaDepthSum, SetpointFact = DivideValByDepth(spWSum),
Fact = pvWSum / deltaDepthSum, Fact = DivideValByDepth(pvWSum),
Limit = limitMaxWSum / deltaDepthSum, Limit = (getterLimitMax is not null) ? DivideValByDepth(limitMaxWSum) : null,
PercDrillingBySetpoint = spUsageDepth / deltaDepthSum, SetpointUsage = deltaDepthSum > 0d ? SpUsageDepth / SpUsageDepthTotal : null,
}; };
private double? DivideValByDepth(double? val)
{
if(val is null || val == 0d || deltaDepthSum == 0d)
return null;
return val / deltaDepthSum;
}
} }
class TelemetryStat { class TelemetryStat {
@ -294,11 +333,13 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
public ParamStat RotorTorque {get; } public ParamStat RotorTorque {get; }
public ParamStat BlockSpeed {get; } public ParamStat BlockSpeed {get; }
public double SpUsageDepthTotal => Pressure.SpUsageDepth + AxialLoad.SpUsageDepth + RotorTorque.SpUsageDepth + BlockSpeed.SpUsageDepth;
private TelemetryDataSaubStatDto? previous; private TelemetryDataSaubStatDto? previous;
private double depthSum = 0d; private double depthSum = 0d;
private double hoursSum = 0d; private double hoursSum = 0d;
public double Rop => depthSum / hoursSum; public double? Rop => hoursSum == 0d ? null : depthSum / hoursSum;
private double depthWithSaub = 0d; private double depthWithSaub = 0d;
public double UsageSaub => depthWithSaub / depthSum; public double UsageSaub => depthWithSaub / depthSum;

View File

@ -122,7 +122,7 @@ namespace AsbCloudWebApi.Controllers
[ProducesResponseType(typeof(IEnumerable<ProcessMapReportDto>), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(IEnumerable<ProcessMapReportDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetDrillProcessMap(int wellId, CancellationToken token) public async Task<IActionResult> GetDrillProcessMap(int wellId, CancellationToken token)
{ {
var data = await processMapService.GetProcessMapAsync(wellId, token); var data = await processMapService.GetProcessMapReportAsync(wellId, token);
return Ok(data); return Ok(data);
} }

View File

@ -11,3 +11,4 @@ GET {{baseUrl}}/api/processMap/getDrillProcessMap/{{wellId}}
Content-Type: {{contentType}} Content-Type: {{contentType}}
accept: */* accept: */*
Authorization: {{auth}} Authorization: {{auth}}
l