2021-06-17 15:12:39 +05:00
|
|
|
|
using System;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using AsbCloudApp.Data;
|
|
|
|
|
using AsbCloudApp.Services;
|
2021-06-22 09:49:53 +05:00
|
|
|
|
using AsbCloudInfrastructure.Services.Cache;
|
2021-06-17 15:12:39 +05:00
|
|
|
|
using AsbCloudDb.Model;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
namespace AsbCloudInfrastructure.Services
|
|
|
|
|
{
|
|
|
|
|
public class AnalyticsService : IAnalyticsService
|
|
|
|
|
{
|
|
|
|
|
private readonly IAsbCloudDbContext db;
|
|
|
|
|
private readonly ITelemetryService telemetryService;
|
2021-06-24 13:02:31 +05:00
|
|
|
|
private readonly CacheTable<Operation> cacheOperations;
|
2021-06-25 15:10:05 +05:00
|
|
|
|
private readonly OperationDetectorService operationDetectorService;
|
2021-06-24 13:02:31 +05:00
|
|
|
|
private readonly IEnumerable<Operation> operations;
|
2021-06-17 15:12:39 +05:00
|
|
|
|
|
2021-06-22 09:49:53 +05:00
|
|
|
|
public AnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService, CacheDb cacheDb)
|
2021-06-17 15:12:39 +05:00
|
|
|
|
{
|
|
|
|
|
this.db = db;
|
|
|
|
|
this.telemetryService = telemetryService;
|
2021-06-24 13:02:31 +05:00
|
|
|
|
cacheOperations = cacheDb.GetCachedTable<Operation>((AsbCloudDbContext)db);
|
|
|
|
|
operations = cacheOperations.Select(c => true);
|
2021-06-25 15:10:05 +05:00
|
|
|
|
operationDetectorService = new OperationDetectorService(operations);
|
2021-06-17 15:12:39 +05:00
|
|
|
|
}
|
|
|
|
|
|
2021-06-22 09:49:53 +05:00
|
|
|
|
public IEnumerable<WellDepthToDayDto> GetWellDepthToDay(int wellId)
|
2021-06-17 15:12:39 +05:00
|
|
|
|
{
|
|
|
|
|
var telemetry = telemetryService.GetTelemetryByWellId(wellId);
|
|
|
|
|
|
|
|
|
|
if (telemetry is null)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
var depthToTimeData = (from d in db.DataSaubBases
|
|
|
|
|
where d.IdTelemetry == telemetry.Id
|
2021-06-22 09:49:53 +05:00
|
|
|
|
select new
|
2021-06-17 15:12:39 +05:00
|
|
|
|
{
|
2021-06-22 09:49:53 +05:00
|
|
|
|
d.Id,
|
|
|
|
|
d.WellDepth,
|
|
|
|
|
d.BitDepth,
|
|
|
|
|
d.Date
|
|
|
|
|
});
|
2021-06-17 15:12:39 +05:00
|
|
|
|
|
2021-06-22 09:49:53 +05:00
|
|
|
|
var m = (int)Math.Round(1d * depthToTimeData.Count() / 2048);
|
2021-06-17 15:12:39 +05:00
|
|
|
|
|
|
|
|
|
if (m > 1)
|
2021-06-22 09:49:53 +05:00
|
|
|
|
depthToTimeData = depthToTimeData.Where(d => d.Id % m == 0);
|
2021-06-17 15:12:39 +05:00
|
|
|
|
|
2021-06-22 09:49:53 +05:00
|
|
|
|
return depthToTimeData.Select(d => new WellDepthToDayDto
|
|
|
|
|
{
|
2021-06-25 15:10:05 +05:00
|
|
|
|
WellDepth = d.WellDepth ?? 0.0,
|
|
|
|
|
BitDepth = d.BitDepth ?? 0.0,
|
2021-06-22 09:49:53 +05:00
|
|
|
|
Date = d.Date
|
|
|
|
|
}).ToList();
|
2021-06-17 15:12:39 +05:00
|
|
|
|
}
|
|
|
|
|
|
2021-06-22 09:49:53 +05:00
|
|
|
|
public IEnumerable<WellDepthToIntervalDto> GetWellDepthToInterval(int wellId,
|
2021-06-25 15:10:05 +05:00
|
|
|
|
int intervalHoursTimestamp, int workBeginTimestamp)
|
2021-06-17 15:12:39 +05:00
|
|
|
|
{
|
2021-06-25 15:10:05 +05:00
|
|
|
|
intervalHoursTimestamp = intervalHoursTimestamp == 0 ? 86400 : intervalHoursTimestamp;
|
|
|
|
|
|
|
|
|
|
var intervalTime = new TimeSpan(0, 0, intervalHoursTimestamp);
|
|
|
|
|
var workDayBeginTime = new TimeSpan(0, 0, workBeginTimestamp);
|
2021-06-17 15:12:39 +05:00
|
|
|
|
|
|
|
|
|
var telemetry = telemetryService.GetTelemetryByWellId(wellId);
|
|
|
|
|
|
|
|
|
|
if (telemetry is null)
|
|
|
|
|
return null;
|
|
|
|
|
|
2021-06-25 15:10:05 +05:00
|
|
|
|
var timezoneOffset = telemetryService.GetTimezoneOffsetByTelemetryId(telemetry.Id);
|
2021-06-17 15:12:39 +05:00
|
|
|
|
|
2021-06-22 09:49:53 +05:00
|
|
|
|
var drillingPeriodsInfo = db.GetDepthToInterval(telemetry.Id, (int)intervalTime.TotalSeconds,
|
|
|
|
|
(int)workDayBeginTime.TotalSeconds, timezoneOffset);
|
|
|
|
|
|
|
|
|
|
var wellDepthToIntervalData = drillingPeriodsInfo.Select(d => new WellDepthToIntervalDto
|
|
|
|
|
{
|
2021-06-25 15:10:05 +05:00
|
|
|
|
IntervalStartDate = d.BeginPeriodDate,
|
|
|
|
|
IntervalDepthProgress = (d.MaxDepth - d.MinDepth) ?? 0.0 / intervalHoursTimestamp
|
2021-06-22 09:49:53 +05:00
|
|
|
|
}).OrderBy(d => d.IntervalStartDate).ToList();
|
2021-06-17 15:12:39 +05:00
|
|
|
|
|
2021-06-22 09:49:53 +05:00
|
|
|
|
return wellDepthToIntervalData;
|
|
|
|
|
}
|
2021-06-17 15:12:39 +05:00
|
|
|
|
|
2021-06-22 09:49:53 +05:00
|
|
|
|
public IEnumerable<OperationPercentageDto> GetOperationsSummary(int wellId,
|
|
|
|
|
DateTime begin = default, DateTime end = default)
|
|
|
|
|
{
|
|
|
|
|
return new List<OperationPercentageDto>
|
|
|
|
|
{
|
|
|
|
|
new OperationPercentageDto { ProcessName = "Роторное бурение", Percentage = 19.7 },
|
|
|
|
|
new OperationPercentageDto { ProcessName = "Подъем с проработкой", Percentage = 6.2 },
|
|
|
|
|
new OperationPercentageDto { ProcessName = "Спуск с проработкой", Percentage = 9.4 },
|
|
|
|
|
new OperationPercentageDto { ProcessName = "Подъем с промывкой", Percentage = 18.4 },
|
|
|
|
|
new OperationPercentageDto { ProcessName = "Неподвижное состояние", Percentage = 12.1 },
|
|
|
|
|
new OperationPercentageDto { ProcessName = "Вращение без циркуляции", Percentage = 7.4 },
|
|
|
|
|
new OperationPercentageDto { ProcessName = "Спуск в скважину", Percentage = 16.7 },
|
|
|
|
|
new OperationPercentageDto { ProcessName = "На поверхности", Percentage = 10.1 }
|
|
|
|
|
};
|
|
|
|
|
}
|
2021-06-17 15:12:39 +05:00
|
|
|
|
|
2021-06-22 09:49:53 +05:00
|
|
|
|
public IEnumerable<OperationInfoDto> GetOperationsToTime(int wellId,
|
|
|
|
|
DateTime begin = default, DateTime end = default)
|
|
|
|
|
{
|
|
|
|
|
return new List<OperationInfoDto>
|
2021-06-17 15:12:39 +05:00
|
|
|
|
{
|
2021-06-22 09:49:53 +05:00
|
|
|
|
new OperationInfoDto
|
|
|
|
|
{
|
|
|
|
|
IntervalBegin = new DateTime(2021, 06, 01, 08, 00, 00),
|
|
|
|
|
IntervalEnd = new DateTime(2021, 06, 02, 08, 00, 00),
|
|
|
|
|
OperationData = new List<OperationDetailsDto>
|
|
|
|
|
{
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Роторное бурение",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 01, 10, 00, 00),
|
|
|
|
|
DurationHours = 1.2
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Подъем с проработкой",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 01, 11, 00, 00),
|
|
|
|
|
DurationHours = 3.2
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Роторное бурение",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 01, 12, 00, 00),
|
|
|
|
|
DurationHours = 1.5
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Неподвижное состояние",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 01, 13, 00, 00),
|
|
|
|
|
DurationHours = 0.2
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Роторное бурение",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 01, 14, 00, 00),
|
|
|
|
|
DurationHours = 3.2
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
new OperationInfoDto
|
2021-06-17 15:12:39 +05:00
|
|
|
|
{
|
2021-06-22 09:49:53 +05:00
|
|
|
|
IntervalBegin = new DateTime(2021, 06, 02, 08, 00, 00),
|
|
|
|
|
IntervalEnd = new DateTime(2021, 06, 03, 08, 00, 00),
|
|
|
|
|
OperationData = new List<OperationDetailsDto>
|
|
|
|
|
{
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "На поверхности",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 13, 10, 01, 00),
|
|
|
|
|
DurationHours = 2.2
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Спуск в скважину",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 13, 11, 10, 00),
|
|
|
|
|
DurationHours = 0.4
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "На поверхности",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 13, 12, 20, 00),
|
|
|
|
|
DurationHours = 2.5
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Вращение без циркуляции",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 13, 13, 00, 00),
|
|
|
|
|
DurationHours = 1.2
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Роторное бурение",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 13, 14, 00, 00),
|
|
|
|
|
DurationHours = 5.2
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
new OperationInfoDto
|
|
|
|
|
{
|
|
|
|
|
IntervalBegin = new DateTime(2021, 06, 03, 08, 00, 00),
|
|
|
|
|
IntervalEnd = new DateTime(2021, 06, 04, 08, 00, 00),
|
|
|
|
|
OperationData = new List<OperationDetailsDto>
|
|
|
|
|
{
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Подъем с проработкой",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 12, 10, 00, 00),
|
|
|
|
|
DurationHours = 3.2
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Спуск с проработкой",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 12, 11, 00, 00),
|
|
|
|
|
DurationHours = 1.4
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Подъем с проработкой",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 12, 12, 00, 00),
|
|
|
|
|
DurationHours = 0.5
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "На поверхности",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 12, 13, 00, 00),
|
|
|
|
|
DurationHours = 3.2
|
|
|
|
|
},
|
|
|
|
|
new OperationDetailsDto
|
|
|
|
|
{
|
|
|
|
|
OperationName = "Роторное бурение",
|
|
|
|
|
OperationStartTime = new DateTime(2021, 06, 13, 14, 00, 00),
|
|
|
|
|
DurationHours = 1.2
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-06-17 15:12:39 +05:00
|
|
|
|
}
|
2021-06-22 09:49:53 +05:00
|
|
|
|
};
|
2021-06-17 15:12:39 +05:00
|
|
|
|
}
|
2021-06-24 13:02:31 +05:00
|
|
|
|
|
|
|
|
|
public DrillingAnalysis GetDrillingAnalysis(IEnumerable<DataSaubBase> dataSaubBases)
|
|
|
|
|
{
|
2021-06-28 11:35:52 +05:00
|
|
|
|
var lastSaubDate = dataSaubBases.Last().Date;
|
2021-06-24 13:02:31 +05:00
|
|
|
|
|
2021-06-28 11:35:52 +05:00
|
|
|
|
var saubWellDepths = dataSaubBases.Where(sw => sw.WellDepth is not null)
|
|
|
|
|
.Select(s => (Value: (double)s.WellDepth,
|
|
|
|
|
(s.Date - dataSaubBases.First().Date).TotalSeconds));
|
|
|
|
|
var saubBitDepths = dataSaubBases.Where(sw => sw.BitDepth is not null)
|
|
|
|
|
.Select(s => (Value: (double)s.BitDepth,
|
|
|
|
|
(s.Date - dataSaubBases.First().Date).TotalSeconds));
|
|
|
|
|
var saubBlockPositions = dataSaubBases.Where(sw => sw.BlockPosition is not null)
|
|
|
|
|
.Select(s => (Value: (double)s.BlockPosition,
|
|
|
|
|
(s.Date - dataSaubBases.First().Date).TotalSeconds));
|
|
|
|
|
var saubRotorSpeeds = dataSaubBases.Where(sw => sw.RotorSpeed is not null)
|
|
|
|
|
.Select(s => (Value: (double)s.RotorSpeed,
|
|
|
|
|
(s.Date - dataSaubBases.First().Date).TotalSeconds));
|
|
|
|
|
var saubPressures = dataSaubBases.Where(sw => sw.Pressure is not null)
|
|
|
|
|
.Select(s => (Value: (double)s.Pressure,
|
|
|
|
|
(s.Date - dataSaubBases.First().Date).TotalSeconds));
|
|
|
|
|
var saubHookWeights = dataSaubBases.Where(sw => sw.HookWeight is not null)
|
|
|
|
|
.Select(s => (Value: (double)s.HookWeight,
|
|
|
|
|
(s.Date - dataSaubBases.First().Date).TotalSeconds));
|
|
|
|
|
|
|
|
|
|
var wellDepthChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubWellDepths);
|
|
|
|
|
var bitPositionChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubBitDepths);
|
|
|
|
|
var blockPositionChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubBlockPositions);
|
|
|
|
|
var rotorSpeedChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubRotorSpeeds);
|
|
|
|
|
var pressureChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubPressures);
|
|
|
|
|
var hookWeightChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubHookWeights);
|
|
|
|
|
|
|
|
|
|
var IsBlockRising = LinearFunctionCalculator.IsValueGoesDown(blockPositionChangingIndex, -0.0001);
|
|
|
|
|
var IsBlockGoesDown = LinearFunctionCalculator.IsValueGoesUp(blockPositionChangingIndex, 0.0001);
|
|
|
|
|
var IsBlockStandsStill = LinearFunctionCalculator.IsValueNotChanges(blockPositionChangingIndex, (0.0001, -0.0001));
|
2021-06-24 13:02:31 +05:00
|
|
|
|
|
|
|
|
|
var drillingAnalysis = new DrillingAnalysis
|
|
|
|
|
{
|
|
|
|
|
IdTelemetry = dataSaubBases.First().IdTelemetry,
|
2021-06-28 11:35:52 +05:00
|
|
|
|
Date = lastSaubDate,
|
|
|
|
|
IsDepthChanges = LinearFunctionCalculator.IsValueChanges(wellDepthChangingIndex, (0.0001, -0.0001)),
|
|
|
|
|
IsDepthNotChanges = LinearFunctionCalculator.IsValueNotChanges(wellDepthChangingIndex, (0.0001, -0.0001)),
|
|
|
|
|
IsBitRising = LinearFunctionCalculator.IsValueGoesDown(bitPositionChangingIndex, -0.0001),
|
|
|
|
|
IsBitGoesDown = LinearFunctionCalculator.IsValueGoesUp(bitPositionChangingIndex, 0.0001),
|
|
|
|
|
IsBitStandsStill = LinearFunctionCalculator.IsValueNotChanges(bitPositionChangingIndex, (0.0001, -0.0001)),
|
|
|
|
|
IsBitDepthLess20 = LinearFunctionCalculator.IsAverageLessThanBound(saubBitDepths, 20),
|
|
|
|
|
IsBlockRising = LinearFunctionCalculator.IsValueGoesDown(blockPositionChangingIndex, -0.0001),
|
|
|
|
|
IsBlockGoesDown = LinearFunctionCalculator.IsValueGoesUp(blockPositionChangingIndex, 0.0001),
|
|
|
|
|
IsBlockStandsStill = LinearFunctionCalculator.IsValueNotChanges(blockPositionChangingIndex, (0.0001, -0.0001)),
|
|
|
|
|
IsRotorSpeedLess3 = LinearFunctionCalculator.IsAverageLessThanBound(saubRotorSpeeds, 3),
|
|
|
|
|
IsRotorSpeedMore3 = LinearFunctionCalculator.IsAverageMoreThanBound(saubRotorSpeeds, 3),
|
|
|
|
|
IsPressureLess20 = LinearFunctionCalculator.IsAverageLessThanBound(saubPressures, 20),
|
|
|
|
|
IsPressureMore20 = LinearFunctionCalculator.IsAverageMoreThanBound(saubPressures, 20),
|
|
|
|
|
IsHookWeightNotChanges = LinearFunctionCalculator.IsValueNotChanges(hookWeightChangingIndex, (0.0001, -0.0001)),
|
|
|
|
|
IsHookWeightLess3 = LinearFunctionCalculator.IsAverageLessThanBound(saubHookWeights, 3),
|
2021-06-24 13:02:31 +05:00
|
|
|
|
IdOperation = 1
|
|
|
|
|
};
|
|
|
|
|
|
2021-06-25 15:10:05 +05:00
|
|
|
|
drillingAnalysis.IdOperation = operationDetectorService.DetectOperation(drillingAnalysis).Id;
|
2021-06-24 13:02:31 +05:00
|
|
|
|
|
|
|
|
|
return drillingAnalysis;
|
|
|
|
|
}
|
2021-06-17 15:12:39 +05:00
|
|
|
|
}
|
|
|
|
|
}
|