This commit is contained in:
Фролов 2021-09-13 09:39:23 +05:00
commit 278445cdbd
3 changed files with 75 additions and 12 deletions

View File

@ -24,5 +24,7 @@ namespace AsbCloudApp.Services
int intervalHoursTimestamp, int workBeginTimestamp,
CancellationToken token = default);
void SaveAnalytics(DataSaubBaseDto dataSaub);
Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell,
CancellationToken token = default);
}
}

View File

@ -161,8 +161,12 @@ namespace AsbCloudInfrastructure.Services
if (telemetryId is null)
return null;
var unixBegin = (begin - new DateTime(1970, 1, 1)).TotalSeconds;
var unixEnd = (end - new DateTime(1970, 1, 1)).TotalSeconds;
var unixBegin = begin == default
? 0
: (begin - new DateTime(1970, 1, 1)).TotalSeconds;
var unixEnd = end == default
? (DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds
: (end - new DateTime(1970, 1, 1)).TotalSeconds;
return await (from a in db.TelemetryAnalysis
where a.IdTelemetry == telemetryId &&
@ -256,6 +260,36 @@ namespace AsbCloudInfrastructure.Services
}
}
public async Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell,
CancellationToken token = default)
{
var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell);
if (telemetryId is null)
return null;
var datesRange = await (from d in db.TelemetryAnalysis
where d.IdTelemetry == telemetryId
select d.UnixDate).DefaultIfEmpty()
.GroupBy(g => true)
.AsNoTracking()
.Select(g => new
{
From = g.Min(),
To = g.Max()
}).OrderBy(gr => gr.From)
.FirstOrDefaultAsync(token)
.ConfigureAwait(false);
return new DatesRangeDto
{
From = DateTimeOffset.FromUnixTimeSeconds(datesRange.From).DateTime,
To = datesRange.To == default
? DateTime.MaxValue
: DateTimeOffset.FromUnixTimeSeconds(datesRange.To).DateTime
};
}
private static IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> DivideOperationsByIntervalLength(
IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> operations, int intervalSeconds)
{
@ -263,41 +297,41 @@ namespace AsbCloudInfrastructure.Services
var operationDurationTimeCounter = 0;
foreach (var op in operations)
foreach (var (IntervalStart, OperationName, OperationDuration) in operations)
{
if (op.OperationDuration < (intervalSeconds - operationDurationTimeCounter))
if (OperationDuration < (intervalSeconds - operationDurationTimeCounter))
{
splittedOperationsByInterval.Add((op.IntervalStart, op.OperationName, op.OperationDuration));
operationDurationTimeCounter += op.OperationDuration;
splittedOperationsByInterval.Add((IntervalStart, OperationName, OperationDuration));
operationDurationTimeCounter += OperationDuration;
}
else
{ // if operation duration overflows current interval it shoud be divided into 2 or more parts for this and next intervals
var remainingIntervalTime = intervalSeconds - operationDurationTimeCounter;
splittedOperationsByInterval.Add((op.IntervalStart, op.OperationName, remainingIntervalTime)); // first part of long operation
splittedOperationsByInterval.Add((IntervalStart, OperationName, remainingIntervalTime)); // first part of long operation
var operationDurationAfterDividing = op.OperationDuration - remainingIntervalTime; // second part of long operation. Can be less or more than interval
var operationDurationAfterDividing = OperationDuration - remainingIntervalTime; // second part of long operation. Can be less or more than interval
// If operation duration even after dividing is still more than interval,
// it should be divided several times to several intervals.
if (operationDurationAfterDividing > intervalSeconds)
{
var counter = 0;
var updatedIntervalStartTime = op.IntervalStart + remainingIntervalTime;
var updatedIntervalStartTime = IntervalStart + remainingIntervalTime;
while (operationDurationAfterDividing > intervalSeconds)
{
splittedOperationsByInterval.Add((updatedIntervalStartTime + intervalSeconds * counter, op.OperationName, intervalSeconds));
splittedOperationsByInterval.Add((updatedIntervalStartTime + intervalSeconds * counter, OperationName, intervalSeconds));
operationDurationAfterDividing -= intervalSeconds;
counter++;
}
splittedOperationsByInterval.Add((updatedIntervalStartTime + operationDurationAfterDividing, op.OperationName, operationDurationAfterDividing));
splittedOperationsByInterval.Add((updatedIntervalStartTime + operationDurationAfterDividing, OperationName, operationDurationAfterDividing));
operationDurationTimeCounter = operationDurationAfterDividing;
}
else
{
splittedOperationsByInterval.Add((op.IntervalStart, op.OperationName, operationDurationAfterDividing));
splittedOperationsByInterval.Add((IntervalStart, OperationName, operationDurationAfterDividing));
operationDurationTimeCounter = operationDurationAfterDividing;
}
}

View File

@ -170,5 +170,32 @@ namespace AsbCloudWebApi.Controllers
return Ok(analytics);
}
/// <summary>
/// Возвращает даты первой и последней операций на скважине
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="token">Токен для отмены задачи</param>
/// <returns>Даты самой первой и самой последней операций на скважине</returns>
[HttpGet]
[Route("datesRange")]
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetOperationsDateRangeAsync(int idWell,
CancellationToken token = default)
{
int? idCompany = User.GetCompanyId();
if (idCompany is null)
return Forbid();
if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
idWell, token).ConfigureAwait(false))
return Forbid();
DatesRangeDto wellOperationsDatesRange = await analyticsService.GetOperationsDateRangeAsync(idWell,
token).ConfigureAwait(false);
return Ok(wellOperationsDatesRange);
}
}
}