diff --git a/AsbCloudApp/Repositories/ITelemetryDataCache.cs b/AsbCloudApp/Repositories/ITelemetryDataCache.cs index f90f2ac4..851fce0b 100644 --- a/AsbCloudApp/Repositories/ITelemetryDataCache.cs +++ b/AsbCloudApp/Repositories/ITelemetryDataCache.cs @@ -78,6 +78,6 @@ namespace AsbCloudApp.Repositories /// /// /// - IEnumerable? GetIds(TelemetryDataRequest request); + IEnumerable GetIds(TelemetryDataRequest request); } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs index 8369ffa2..d6b4a257 100644 --- a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs +++ b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs @@ -31,23 +31,37 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks using var db = services.GetRequiredService(); var telemetryDataCache = services.GetRequiredService>(); - var telemetryIds = telemetryDataCache.GetIds(new TelemetryDataRequest() + var cacheRequest = new TelemetryDataRequest() { GeDate = DateTime.UtcNow.AddDays(-Gap) - }); + }; + var idTelemetries = telemetryDataCache.GetIds(cacheRequest); - if (telemetryIds == null || !telemetryIds.Any()) + if (!idTelemetries.Any()) return; - var dateEnd = db.Set() - .OrderByDescending(c => c.DateEnd) - .FirstOrDefault()?.DateEnd - ?? DateTimeOffset.MinValue; + var stats = await db.Set() + .Where(s => idTelemetries.Contains(s.IdTelemetry)) + .GroupBy(s => s.IdTelemetry) + .ToDictionaryAsync( + g => g.Key, + g => g.OrderByDescending(s => s.DateEnd).First(), + token + ); + foreach ( var idTelemetry in idTelemetries) + { + var lastDate = stats.GetValueOrDefault(idTelemetry)?.DateEnd ?? DateTimeOffset.UnixEpoch; + await CreateStatForTelemetryFromDate(db, idTelemetry, lastDate, token); + } + } + + private async Task CreateStatForTelemetryFromDate(IAsbCloudDbContext db, int idTelemetry, DateTimeOffset begin, CancellationToken token) + { var detectedOperations = await db.Set() - .Where(o => o.DateStart > dateEnd) + .Where(o => o.IdTelemetry == idTelemetry) + .Where(o => o.DateStart > begin) .Where(o => o.OperationCategory.IdParent == MechanicalDrillingCategoryId) - .Where(o => telemetryIds.Contains(o.IdTelemetry)) .OrderBy(o => o.DateStart) .Take(500) .ToArrayAsync(token); @@ -55,45 +69,47 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks if (!detectedOperations.Any()) return; - var minDate = detectedOperations.FirstOrDefault()?.DateStart; - var maxDate = detectedOperations.OrderByDescending(d => d.DateEnd).FirstOrDefault()?.DateEnd; + var minDate = detectedOperations.First().DateStart; + var maxDate = detectedOperations.OrderByDescending(d => d.DateEnd).First().DateEnd; - var telemetryDataSaub = (await db.Set() + var telemetryDataSaub = await db.Set() + .Where(t => t.IdTelemetry == idTelemetry) .Where(t => t.DateTime >= minDate) .Where(t => t.DateTime <= maxDate) .Where(t => Math.Abs(t.BitDepth - t.WellDepth) < 0.0001) - .Where(t => telemetryIds.Contains(t.IdTelemetry)) - .ToArrayAsync(token)) - .GroupBy(t => t.IdTelemetry) - .ToDictionary(g => g.Key, g => g.OrderBy(t => t.DateTime).ToArray()); + .ToArrayAsync(token); - CreateDataSaubStat(db, detectedOperations, telemetryDataSaub); + if (!telemetryDataSaub.Any()) + return; + + var dataSaubStats = CreateDataSaubStat(detectedOperations, telemetryDataSaub); + + db.Set().AddRange(dataSaubStats); + await db.SaveChangesAsync(token); } - private static void CreateDataSaubStat(IAsbCloudDbContext db, DetectedOperation[] detectedOperations, Dictionary telemetryDataSaub) + private static IEnumerable CreateDataSaubStat(IEnumerable detectedOperations, TelemetryDataSaub[] telemetryDataSaub) { var indexStart = 0; var indexEnd = 0; foreach (var operation in detectedOperations) { - if (!telemetryDataSaub.TryGetValue(operation.IdTelemetry, out TelemetryDataSaub[]? telemetryDataSaubPart)) - break; - - indexStart = Array.FindIndex(telemetryDataSaubPart, indexEnd, t => t.DateTime >= operation.DateStart); - indexEnd = Array.FindIndex(telemetryDataSaubPart, indexStart, t => t.DateTime > operation.DateEnd) - 1; + indexStart = Array.FindIndex(telemetryDataSaub, indexEnd, t => t.DateTime >= operation.DateStart); + indexEnd = Array.FindIndex(telemetryDataSaub, indexStart, t => t.DateTime > operation.DateEnd) - 1; if (indexStart >= 0 && indexEnd >= indexStart) { var length = indexEnd - indexStart; - var subset = telemetryDataSaubPart.AsSpan(indexStart, length + 1); - CalcStats(operation, subset, db); - db.SaveChanges(); + var subset = telemetryDataSaub.AsSpan(indexStart, length + 1); + var stats = CalcStats(operation, subset); + foreach (var stat in stats) + yield return stat; } } } - private static void CalcStats(DetectedOperation operation, Span telemetryDataSaub, IAsbCloudDbContext db) + private static IEnumerable CalcStats(DetectedOperation operation, Span telemetryDataSaub) { var indexStart = 0; for (var i = 1; i < telemetryDataSaub.Length; i++) @@ -106,8 +122,8 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks var length = i - indexStart; var span = telemetryDataSaub.Slice(indexStart, length); indexStart = i; - var dataSaubStatItem = CalcStat(operation, span); - db.Set().Add(dataSaubStatItem); + var stat = CalcStat(operation, span); + yield return stat; } } } @@ -162,11 +178,11 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks var diffDepthTotal = span[^1].WellDepth - span[0].WellDepth; for (var i = 0; i < span.Length - 1; i++) { - var weigth = span[i + 1].WellDepth - span[i].WellDepth; - sumPressure += weigth * span[i].Pressure; - sumAxialLoad += weigth * span[i].AxialLoad; - sumRotorTorque += weigth * span[i].RotorTorque; - sumRotorSpeed += weigth * span[i].RotorSpeed; + var diffDepth = span[i + 1].WellDepth - span[i].WellDepth; + sumPressure += diffDepth * span[i].Pressure; + sumAxialLoad += diffDepth * span[i].AxialLoad; + sumRotorTorque += diffDepth * span[i].RotorTorque; + sumRotorSpeed += diffDepth * span[i].RotorSpeed; flow = span[i + 1].Flow > flow ? span[i + 1].Flow ?? 0.0 : flow; } return ( diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs index fef27bc3..ec92c00f 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs @@ -325,22 +325,28 @@ namespace AsbCloudInfrastructure.Services.SAUB return data; } - public IEnumerable? GetIds(TelemetryDataRequest request) + public IEnumerable GetIds(TelemetryDataRequest request) { - var data = new Dictionary(); + var data = caches.Where(i => i.Value.LastData.Count > 0); if (request.GeDate.HasValue) { - data = caches - .Where(item => item.Value.LastData.Any(d => d.DateTime >= request.GeDate.Value.ToRemoteDateTime(item.Value.TimezoneHours))) - .ToDictionary(item => item.Key, item => item.Value); + data = data + .Where(item => { + var lastItem = item.Value.LastData.Last(); + var geDate = request.GeDate.Value.ToOffset(TimeSpan.FromHours(item.Value.TimezoneHours)); + return lastItem.DateTime >= geDate; + }); } if (request.LeDate.HasValue) { - data = caches - .Where(item => item.Value.LastData.Any(d => d.DateTime <= request.LeDate.Value.ToRemoteDateTime(item.Value.TimezoneHours))) - .ToDictionary(item => item.Key, item => item.Value); + data = data + .Where(item => { + var firstItem = item.Value.LastData.First(); + var leDate = request.LeDate.Value.ToOffset(TimeSpan.FromHours(item.Value.TimezoneHours)); + return firstItem.DateTime <= leDate; + }); } var telemetryIds = data.Select(item => item.Key);