diff --git a/AsbCloudApp/Services/ITelemetryService.cs b/AsbCloudApp/Services/ITelemetryService.cs index 567d4a50..ff3605a5 100644 --- a/AsbCloudApp/Services/ITelemetryService.cs +++ b/AsbCloudApp/Services/ITelemetryService.cs @@ -13,6 +13,8 @@ namespace AsbCloudApp.Services int GetOrCreateTemetryIdByUid(string uid); double GetTimezoneOffsetByTelemetryId(int idTelemetry); Task UpdateInfoAsync(string uid, TelemetryInfoDto info, CancellationToken token); + Task FixDateToTimeZoneAsync(int idTelemetry, DateTime date, + CancellationToken token); Task GetTimeZoneInfoAsync(int idWell, CancellationToken token); Task UpdateTimeZoneAsync(string uid, TelemetryTimeZoneDto telemetryTimeZoneInfo, CancellationToken token); int? GetIdTelemetryByIdWell(int idWell); diff --git a/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs index e23be42b..f8258785 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs @@ -60,20 +60,24 @@ namespace AsbCloudInfrastructure.Services dtosList.Remove(duplicate); } - var enitties = dtosList.Select(d => { - var e = Convert(d); - e.IdTelemetry = idTelemetry; - return e; + var tasks = dtosList.Select(async d => { + var e = Convert(d); + e.IdTelemetry = idTelemetry; + e.Date = await telemetryService.FixDateToTimeZoneAsync(idTelemetry, d.Date, token) + .ConfigureAwait(false); + return e; }); + var entities = await Task.WhenAll(tasks); + var dbset = db.Set(); try { - return await db.Database.ExecInsertOrUpdateAsync(dbset, enitties, token).ConfigureAwait(false); + return await db.Database.ExecInsertOrUpdateAsync(dbset, entities, token).ConfigureAwait(false); } catch(Exception ex) { - Trace.WriteLine($"Fail to save data telemerty uid: {uid}, idTelemetry {idTelemetry} count: {enitties.Count()} dataDate: {enitties.FirstOrDefault()?.Date}. Message: {ex.Message}"); + Trace.WriteLine($"Fail to save data telemerty uid: {uid}, idTelemetry {idTelemetry} count: {entities.Count()} dataDate: {entities.FirstOrDefault()?.Date}. Message: {ex.Message}"); return 0; } } diff --git a/AsbCloudInfrastructure/Services/TelemetryService.cs b/AsbCloudInfrastructure/Services/TelemetryService.cs index e257686b..b0b4945c 100644 --- a/AsbCloudInfrastructure/Services/TelemetryService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryService.cs @@ -19,6 +19,8 @@ namespace AsbCloudInfrastructure.Services { private readonly CacheTable cacheTelemetry; private readonly CacheTable cacheWells; + private readonly CacheTable cacheClusters; + private readonly CacheTable cacheDeposits; private readonly IAsbCloudDbContext db; private readonly ITelemetryTracker telemetryTracker; private readonly string timeZoneApiUrl = "http://api.geonames.org/timezoneJSON"; @@ -96,16 +98,60 @@ namespace AsbCloudInfrastructure.Services await cacheTelemetry.UpsertAsync(telemetry, token) .ConfigureAwait(false); } + + public async Task FixDateToTimeZoneAsync(int idTelemetry, DateTime date, + CancellationToken token) + { + if(date.Kind == DateTimeKind.Utc) + return date; + + if (date.Kind == DateTimeKind.Local) + return date.ToUniversalTime(); + + var telemetry = + await cacheTelemetry.FirstOrDefaultAsync(t => t.Id == idTelemetry, token); + + if (telemetry is null) + return date; + + if (telemetry.TelemetryTimeZone is null) + { + var well = await cacheWells.FirstOrDefaultAsync(w => w.IdTelemetry == telemetry.Id, token) + .ConfigureAwait(false); + + if (well is null) + return date; + + var requestedTimeZoneInfo = await GetTimeZoneInfoAsync(well.Id, token) + .ConfigureAwait(false); + + if (requestedTimeZoneInfo.TimezoneId is null) + return date; + + telemetry.TelemetryTimeZone = new TelemetryTimeZone() + { + Hours = requestedTimeZoneInfo.GmtOffset, + TimeZoneId = requestedTimeZoneInfo.TimezoneId + }; + + await cacheTelemetry.UpsertAsync(telemetry, token).ConfigureAwait(false); + } + + var offsetHours = telemetry.TelemetryTimeZone.Hours; + return date.AddHours(offsetHours * -1); + } public async Task GetTimeZoneInfoAsync(int idWell, CancellationToken token) { - var well = await db.Wells.FirstOrDefaultAsync(w => w.Id == idWell, token) - .ConfigureAwait(false); + var coordinates = await GetWellCoordinatesAsync(idWell, token); + + if (coordinates is null) + return null; using var client = new HttpClient(); - var latitude = $"{well.Latitude}".Replace(',', '.'); - var longitude = $"{well.Longitude}".Replace(',', '.'); + var latitude = coordinates.Value.latitude.Replace(',', '.'); + var longitude = coordinates.Value.longitude.Replace(',', '.'); var url = $"{timeZoneApiUrl}?lat={latitude}&lng={longitude}&username={timezoneApiUserName}"; @@ -143,6 +189,33 @@ namespace AsbCloudInfrastructure.Services return well.IdTelemetry; } + private async Task<(string latitude, string longitude)?> GetWellCoordinatesAsync(int idWell, + CancellationToken token) + { + var well = await cacheWells.FirstOrDefaultAsync(w => w.Id == idWell, token) + .ConfigureAwait(false); + + if (well is null) + return null; + + if (well.Latitude is not null && well.Longitude is not null) + return ($"{well.Latitude}", $"{well.Longitude}"); + + var cluster = await cacheClusters.FirstOrDefaultAsync(c => c.Id == well.IdCluster, token) + .ConfigureAwait(false); + + if (cluster.Latitude is not null && cluster.Longitude is not null) + return ($"{cluster.Latitude}", $"{cluster.Longitude}"); + + var deposit = await cacheDeposits.FirstOrDefaultAsync(d => d.Id == cluster.IdDeposit, token) + .ConfigureAwait(false); + + if (deposit.Latitude is not null && deposit.Longitude is not null) + return ($"{deposit.Latitude}", $"{deposit.Longitude}"); + + return null; + } + private Well GetWellByTelemetryUid(string uid) { var tele = cacheTelemetry.FirstOrDefault(t => t.RemoteUid == uid);