forked from ddrilling/AsbCloudServer
CS2-37: Fixed OperationsToInterval() analytics. Half done.
This commit is contained in:
parent
eaf1b9509d
commit
b218187117
@ -6,6 +6,6 @@ namespace AsbCloudApp.Data
|
||||
public class TelemetryOperationInfoDto
|
||||
{
|
||||
public DateTimeOffset IntervalBegin { get; set; }
|
||||
public IEnumerable<TelemetryOperationDetailsDto> Operations { get; set; }
|
||||
public IList<TelemetryOperationDetailsDto> Operations { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -178,6 +178,7 @@ namespace AsbCloudInfrastructure.Services
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// This method is not finished (only half done). It returns not correct Dtos.
|
||||
public async Task<IEnumerable<TelemetryOperationInfoDto>> GetOperationsToIntervalAsync(int idWell,
|
||||
int intervalSeconds, int workBeginSeconds, CancellationToken token = default)
|
||||
{
|
||||
@ -190,36 +191,40 @@ namespace AsbCloudInfrastructure.Services
|
||||
|
||||
var timezoneOffset = telemetryService.GetTimezoneOffsetByTelemetryId((int)telemetryId);
|
||||
|
||||
var operations = await (from a in db.TelemetryAnalysis
|
||||
// Get'n'Group all operations only by start date and by name (if there were several operations in interval).
|
||||
// Without dividing these operations duration by given interval
|
||||
var ops = await (from a in db.TelemetryAnalysis
|
||||
where a.IdTelemetry == telemetryId
|
||||
join o in db.TelemetryOperations on a.IdOperation equals o.Id
|
||||
group a by new
|
||||
{
|
||||
Interval = Math.Floor((a.UnixDate - workBeginSeconds + timezoneOffset) / intervalSeconds),
|
||||
OperationId = a.IdOperation,
|
||||
o.Name
|
||||
} into g
|
||||
select new
|
||||
{
|
||||
IntervalStart = g.Min(d => d.UnixDate),
|
||||
OperationName = g.Key.Name,
|
||||
OperationsDuration = g.Sum(an => an.DurationSec)
|
||||
}).AsNoTracking().ToListAsync(token)
|
||||
OperationDuration = g.Sum(an => an.DurationSec)
|
||||
}).AsNoTracking()
|
||||
.OrderBy(op => op.IntervalStart)
|
||||
.ToListAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var operationsGroupedByInterval = operations.GroupBy(op => op.IntervalStart)
|
||||
.Select(o => new TelemetryOperationInfoDto
|
||||
{
|
||||
IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(o.Key),
|
||||
Operations = o.Select(opr => new TelemetryOperationDetailsDto
|
||||
{
|
||||
OperationName = opr.OperationName,
|
||||
DurationSec = opr.OperationsDuration
|
||||
}).ToList()
|
||||
})
|
||||
.OrderBy(ops => ops.IntervalBegin);
|
||||
|
||||
return operationsGroupedByInterval;
|
||||
var groupedOperationsList = new List<TelemetryOperationInfoDto>();
|
||||
|
||||
|
||||
if (operations is not null && operations.Any())
|
||||
{
|
||||
var operations = ops.Select(o => (o.IntervalStart, o.OperationName, o.OperationDuration));
|
||||
|
||||
var splittedOperationsByInterval = DivideOperationsByIntervalLength(operations, intervalSeconds); // divides good
|
||||
|
||||
groupedOperationsList = UniteOperationsInDto(splittedOperationsByInterval, intervalSeconds).ToList(); // unites not good
|
||||
}
|
||||
|
||||
return groupedOperationsList;
|
||||
}
|
||||
|
||||
public void SaveAnalytics(DataSaubBaseDto dataSaubDto)
|
||||
@ -251,6 +256,103 @@ namespace AsbCloudInfrastructure.Services
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> DivideOperationsByIntervalLength(
|
||||
IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> operations, int intervalSeconds)
|
||||
{
|
||||
var splittedOperationsByInterval = new List<(long IntervalStart, string OperationName, int OperationDuration)>();
|
||||
|
||||
var operationDurationTimeCounter = 0;
|
||||
|
||||
foreach (var op in operations)
|
||||
{
|
||||
if (op.OperationDuration < (intervalSeconds - operationDurationTimeCounter))
|
||||
{
|
||||
splittedOperationsByInterval.Add((op.IntervalStart, op.OperationName, op.OperationDuration));
|
||||
operationDurationTimeCounter += op.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
|
||||
|
||||
var operationDurationAfterDividing = op.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;
|
||||
|
||||
while (operationDurationAfterDividing > intervalSeconds)
|
||||
{
|
||||
splittedOperationsByInterval.Add((updatedIntervalStartTime + intervalSeconds * counter, op.OperationName, intervalSeconds));
|
||||
operationDurationAfterDividing -= intervalSeconds;
|
||||
counter++;
|
||||
}
|
||||
|
||||
splittedOperationsByInterval.Add((updatedIntervalStartTime + operationDurationAfterDividing, op.OperationName, operationDurationAfterDividing));
|
||||
|
||||
operationDurationTimeCounter = operationDurationAfterDividing;
|
||||
}
|
||||
else
|
||||
{
|
||||
splittedOperationsByInterval.Add((op.IntervalStart, op.OperationName, operationDurationAfterDividing));
|
||||
operationDurationTimeCounter = operationDurationAfterDividing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return splittedOperationsByInterval;
|
||||
}
|
||||
|
||||
private static IEnumerable<TelemetryOperationInfoDto> UniteOperationsInDto(
|
||||
IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> operations, int intervalSeconds)
|
||||
{
|
||||
var groupedOperationsList = new List<TelemetryOperationInfoDto>();
|
||||
|
||||
var groupedOperationsObj = new TelemetryOperationInfoDto
|
||||
{
|
||||
IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(operations.First().IntervalStart),
|
||||
Operations = new List<TelemetryOperationDetailsDto>()
|
||||
};
|
||||
|
||||
var intervalEndDate = operations.First().IntervalStart + intervalSeconds;
|
||||
|
||||
foreach (var op in operations)
|
||||
{
|
||||
if (op.IntervalStart < intervalEndDate)
|
||||
{
|
||||
groupedOperationsObj.Operations.Add(new TelemetryOperationDetailsDto
|
||||
{
|
||||
OperationName = op.OperationName,
|
||||
DurationSec = op.OperationDuration
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
groupedOperationsList.Add(groupedOperationsObj);
|
||||
|
||||
intervalEndDate = op.IntervalStart + intervalSeconds;
|
||||
groupedOperationsObj = new TelemetryOperationInfoDto
|
||||
{
|
||||
IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(op.IntervalStart),
|
||||
Operations = new List<TelemetryOperationDetailsDto>()
|
||||
};
|
||||
|
||||
groupedOperationsObj.Operations.Add(new TelemetryOperationDetailsDto
|
||||
{
|
||||
OperationName = op.OperationName,
|
||||
DurationSec = op.OperationDuration
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
groupedOperationsList.Add(groupedOperationsObj);
|
||||
|
||||
return groupedOperationsList;
|
||||
}
|
||||
|
||||
private TelemetryAnalysisDto GetDrillingAnalysis(IEnumerable<DataSaubBaseDto> dataSaubBases)
|
||||
{
|
||||
var lastSaubDate = dataSaubBases.Last().Date;
|
||||
|
Loading…
Reference in New Issue
Block a user