diff --git a/AsbCloudApp/Data/TelemetryTimeZoneDto.cs b/AsbCloudApp/Data/TelemetryTimeZoneDto.cs index ae4b4b9f..b8cd7e2b 100644 --- a/AsbCloudApp/Data/TelemetryTimeZoneDto.cs +++ b/AsbCloudApp/Data/TelemetryTimeZoneDto.cs @@ -5,5 +5,20 @@ namespace AsbCloudApp.Data public double Hours { get; set; } public string TimeZoneId { get; set; } public bool IsOverride { get; set; } + + public override bool Equals(object obj) + { + if(obj is TelemetryTimeZoneDto tTimeZone + && tTimeZone.Hours == Hours + && tTimeZone.TimeZoneId == TimeZoneId + && tTimeZone.IsOverride == IsOverride) + return true; + return false; + } + + public override int GetHashCode() + => Hours.GetHashCode() + | TimeZoneId.GetHashCode() + | IsOverride.GetHashCode(); } } \ No newline at end of file diff --git a/AsbCloudApp/Data/TimeZoneInfo.cs b/AsbCloudApp/Data/TimeZoneInfo.cs index 84fca14e..d8763ecb 100644 --- a/AsbCloudApp/Data/TimeZoneInfo.cs +++ b/AsbCloudApp/Data/TimeZoneInfo.cs @@ -1,17 +1,4 @@ namespace AsbCloudApp.Data { - public class TimeZoneInfo - { - public string Sunrise { get; set; } - public double Lng { get; set; } - public double Lat { get; set; } - public string CountryCode { get; set; } - public double GmtOffset { get; set; } - public double RawOffset { get; set; } - public string Sunset { get; set; } - public string TimezoneId { get; set; } - public double DstOffset { get; set; } - public string CountryName { get; set; } - public string Time { get; set; } - } + } \ No newline at end of file diff --git a/AsbCloudApp/Services/ITelemetryDataService.cs b/AsbCloudApp/Services/ITelemetryDataService.cs index c7530027..6cb8228f 100644 --- a/AsbCloudApp/Services/ITelemetryDataService.cs +++ b/AsbCloudApp/Services/ITelemetryDataService.cs @@ -11,7 +11,7 @@ namespace AsbCloudApp.Services Task> GetAsync(int idWell, DateTime dateBegin = default, double intervalSec = 600d, int approxPointsCount = 1024, bool isUtc = false, CancellationToken token = default); - Task GetDataDatesRangeAsync(int idWell, bool isUtc, + Task GetDataDatesRangeAsync(int idWell, bool isUtc = false, CancellationToken token = default); Task UpdateDataAsync(string uid, IEnumerable dtos, CancellationToken token = default); } diff --git a/AsbCloudApp/Services/ITelemetryService.cs b/AsbCloudApp/Services/ITelemetryService.cs index fbd9c2e5..604ab753 100644 --- a/AsbCloudApp/Services/ITelemetryService.cs +++ b/AsbCloudApp/Services/ITelemetryService.cs @@ -3,22 +3,20 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using TimeZoneInfo = AsbCloudApp.Data.TimeZoneInfo; namespace AsbCloudApp.Services { public interface ITelemetryService { + ITimeZoneService TimeZoneService { get; } + int? GetidWellByTelemetryUid(string uid); int GetOrCreateTemetryIdByUid(string uid); double GetTimezoneOffsetByTelemetryId(int idTelemetry); Task UpdateInfoAsync(string uid, TelemetryInfoDto info, CancellationToken token); Task GetTelemetryTimeZoneOffsetAsync(int idTelemetry, CancellationToken token); - DateTime FixDateToTimeZone(DateTime date, double offsetHours, - CancellationToken token); Task FixDatesRangeByTimeZoneAsync(int telemetryId, DatesRangeDto result, - CancellationToken token); - Task GetTimeZoneInfoAsync(int idWell, CancellationToken token); + CancellationToken token); Task UpdateTimeZoneAsync(string uid, TelemetryTimeZoneDto telemetryTimeZoneInfo, CancellationToken token); int? GetIdTelemetryByIdWell(int idWell); int Merge(IEnumerable telemetryIds); diff --git a/AsbCloudApp/Services/ITimeZoneService.cs b/AsbCloudApp/Services/ITimeZoneService.cs new file mode 100644 index 00000000..87be0d67 --- /dev/null +++ b/AsbCloudApp/Services/ITimeZoneService.cs @@ -0,0 +1,13 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudApp.Services +{ + public interface ITimeZoneService + { + DateTime DateToUtc(DateTime date, double remoteOTimezoneffsetHours); + DateTime DateToTimeZone(DateTime date, double remoteOTimezoneffsetHours); + Task GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token); + } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 92805779..580bb356 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -47,6 +47,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); // admin crud services: services.AddTransient, CrudServiceBase>(); diff --git a/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsBackgroundService.cs b/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsBackgroundService.cs index 9d41fbb5..cee3d994 100644 --- a/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsBackgroundService.cs +++ b/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsBackgroundService.cs @@ -37,7 +37,8 @@ namespace AsbCloudInfrastructure.Services.Analysis try { using var context = new AsbCloudDbContext(options); - var telemetryService = new TelemetryService(context, telemetryTracker, cacheDb); + var timeZoneService = new TimeZoneService(); + var telemetryService = new TelemetryService(context, telemetryTracker, timeZoneService, cacheDb); var analyticsService = new TelemetryAnalyticsService(context, telemetryService, cacheDb); diff --git a/AsbCloudInfrastructure/Services/MessageService.cs b/AsbCloudInfrastructure/Services/MessageService.cs index 355b25e2..56fd30e6 100644 --- a/AsbCloudInfrastructure/Services/MessageService.cs +++ b/AsbCloudInfrastructure/Services/MessageService.cs @@ -40,16 +40,16 @@ namespace AsbCloudInfrastructure.Services bool isUtc = true, CancellationToken token = default) { - var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell); - if (telemetryId is null) + var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); + if (idTelemetry is null) return null; - var events = cacheEvents.Where(e => e.IdTelemetry == telemetryId); + var events = cacheEvents.Where(e => e.IdTelemetry == idTelemetry); if (!events.Any()) return null; - var query = db.TelemetryMessages.Where(m => m.IdTelemetry == telemetryId) + var query = db.TelemetryMessages.Where(m => m.IdTelemetry == idTelemetry) .OrderBy(m => m.Date).AsNoTracking(); if ((categoryids?.Any() == true) || !string.IsNullOrEmpty(searchString)) @@ -70,6 +70,16 @@ namespace AsbCloudInfrastructure.Services query = query.OrderByDescending(m => m.Date); + + var timeOffset = await telemetryService.GetTelemetryTimeZoneOffsetAsync(idTelemetry??default, token) + .ConfigureAwait(false); + + if (timeOffset is not null) + { + begin = telemetryService.TimeZoneService.DateToUtc(begin, timeOffset ?? default); + end = telemetryService.TimeZoneService.DateToUtc(end, timeOffset ?? default); + } + if (begin != default) query = query.Where(m => m.Date >= begin); @@ -92,7 +102,7 @@ namespace AsbCloudInfrastructure.Services if (messagesList.Count == 0) return result; - var users = cacheTUsers.Where(u => u.IdTelemetry == telemetryId); + var users = cacheTUsers.Where(u => u.IdTelemetry == idTelemetry); foreach (var message in messagesList) { @@ -124,18 +134,12 @@ namespace AsbCloudInfrastructure.Services result.Items.Add(messageDto); } - if (isUtc) + if (isUtc && timeOffset is not null) return result; - var telemetry = await cacheTelemetry.FirstOrDefaultAsync(t => t.Id == telemetryId, - token).ConfigureAwait(false); - - if (telemetry?.TelemetryTimeZone is null) - return result; - result.Items = result.Items.Select(m => { - m.Date = m.Date.AddHours(telemetry.TelemetryTimeZone.Hours); + m.Date = telemetryService.TimeZoneService.DateToTimeZone( m.Date, timeOffset ?? default); return m; }).ToList(); diff --git a/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs index b1cf029d..2d8c4852 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs @@ -4,7 +4,6 @@ using AsbCloudDb.Model; using AsbCloudDb; using AsbCloudInfrastructure.Services.Cache; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.ChangeTracking; using System; using System.Collections.Generic; using System.Diagnostics; @@ -20,7 +19,6 @@ namespace AsbCloudInfrastructure.Services { private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; - protected readonly CacheTable cacheTelemetry; protected readonly CacheTable cacheTelemetryUsers; protected readonly CacheTable cacheWells; @@ -32,7 +30,6 @@ namespace AsbCloudInfrastructure.Services { this.db = db; this.telemetryService = telemetryService; - cacheTelemetry = cacheDb.GetCachedTable((AsbCloudDbContext)db); cacheTelemetryUsers = cacheDb.GetCachedTable((AsbCloudDbContext)db); cacheWells = cacheDb.GetCachedTable((AsbCloudDbContext)db); @@ -66,7 +63,7 @@ namespace AsbCloudInfrastructure.Services var e = Convert(d); e.IdTelemetry = idTelemetry; if(offsetHours is not null) - e.Date = telemetryService.FixDateToTimeZone(d.Date, (double)offsetHours, token); + e.Date = telemetryService.TimeZoneService.DateToUtc(d.Date, (double)offsetHours); return e; }); @@ -84,15 +81,17 @@ namespace AsbCloudInfrastructure.Services public virtual async Task> GetAsync(int idWell, DateTime dateBegin = default, double intervalSec = 600d, - int approxPointsCount = 1024, bool isUtc = true, CancellationToken token = default) + int approxPointsCount = 1024, bool isUtc = false, CancellationToken token = default) { var well = cacheWells.FirstOrDefault(w => w.Id == idWell); if (well?.IdTelemetry is null) return default; + var idTelemetry = well?.IdTelemetry ?? default; + if (dateBegin == default) { - dateBegin = telemetryService.GetLastTelemetryDate(well.IdTelemetry ?? 0); + dateBegin = telemetryService.GetLastTelemetryDate(idTelemetry); if (dateBegin != default) dateBegin = dateBegin.AddSeconds(-intervalSec); } @@ -103,13 +102,19 @@ namespace AsbCloudInfrastructure.Services if (dateBegin.Kind == DateTimeKind.Unspecified) dateBegin = DateTime.SpecifyKind(dateBegin, DateTimeKind.Utc); - var datEnd = dateBegin.AddSeconds(intervalSec); + var timeOffset = await telemetryService.GetTelemetryTimeZoneOffsetAsync(idTelemetry, token) + .ConfigureAwait(false); + + if(timeOffset is not null) + dateBegin = telemetryService.TimeZoneService.DateToUtc(dateBegin, timeOffset?? default); + + var dateEnd = dateBegin.AddSeconds(intervalSec); var dbSet = db.Set(); - var query = from data in dbSet - where data.IdTelemetry == well.IdTelemetry - && data.Date >= dateBegin && data.Date < datEnd - select data; + var query = dbSet + .Where(d => d.IdTelemetry == idTelemetry + && d.Date >= dateBegin + && d.Date < dateEnd); var fullDataCount = await query.CountAsync(token) .ConfigureAwait(false); @@ -134,16 +139,13 @@ namespace AsbCloudInfrastructure.Services if (isUtc) return dtos; - - var telemetry = await cacheTelemetry.FirstOrDefaultAsync(t => t.Id == well.IdTelemetry, - token).ConfigureAwait(false); - if (telemetry?.TelemetryTimeZone is null) + if (timeOffset is null) return dtos; dtos = dtos.Select(d => { - d.Date = d.Date.AddHours(telemetry.TelemetryTimeZone.Hours); + d.Date = telemetryService.TimeZoneService.DateToTimeZone(d.Date, timeOffset ?? default); return d; }); diff --git a/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs b/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs index c2b1248f..5ac438c9 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs @@ -6,7 +6,7 @@ using Mapster; namespace AsbCloudInfrastructure.Services { - public class TelemetryDataSaubService: TelemetryDataBaseService + public class TelemetryDataSaubService: TelemetryDataBaseService { public TelemetryDataSaubService( IAsbCloudDbContext db, diff --git a/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs b/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs index a753da67..86ce23b5 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs @@ -6,7 +6,7 @@ using Mapster; namespace AsbCloudInfrastructure.Services { - public class TelemetryDataSpinService : TelemetryDataBaseService + public class TelemetryDataSpinService : TelemetryDataBaseService { public TelemetryDataSpinService( IAsbCloudDbContext db, diff --git a/AsbCloudInfrastructure/Services/TelemetryService.cs b/AsbCloudInfrastructure/Services/TelemetryService.cs index 9acb53b5..6c833fdd 100644 --- a/AsbCloudInfrastructure/Services/TelemetryService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryService.cs @@ -7,11 +7,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System; -using System.Text.Json; -using System.Net.Http; using System.Threading; using Microsoft.EntityFrameworkCore; -using TimeZoneInfo = AsbCloudApp.Data.TimeZoneInfo; namespace AsbCloudInfrastructure.Services { @@ -23,10 +20,14 @@ namespace AsbCloudInfrastructure.Services private readonly CacheTable cacheDeposits; private readonly IAsbCloudDbContext db; private readonly ITelemetryTracker telemetryTracker; - private readonly string timeZoneApiUrl = "http://api.geonames.org/timezoneJSON"; - private readonly string timezoneApiUserName = "asbautodrilling"; + private readonly ITimeZoneService timeZoneService; - public TelemetryService(IAsbCloudDbContext db, ITelemetryTracker telemetryTracker, + public ITimeZoneService TimeZoneService => timeZoneService; + + public TelemetryService( + IAsbCloudDbContext db, + ITelemetryTracker telemetryTracker, + ITimeZoneService timeZoneService, CacheDb cacheDb) { cacheTelemetry = cacheDb.GetCachedTable((AsbCloudDbContext)db); @@ -35,6 +36,7 @@ namespace AsbCloudInfrastructure.Services cacheDeposits = cacheDb.GetCachedTable((AsbCloudDbContext)db); this.db = db; this.telemetryTracker = telemetryTracker; + this.timeZoneService = timeZoneService; } public IEnumerable GetTransmittingTelemetriesAsync(int idCompany) @@ -86,11 +88,8 @@ namespace AsbCloudInfrastructure.Services var telemetry = GetOrCreateTelemetryByUid(uid); telemetry.Info = info.Adapt(); - var isTimeZoneToUpdate = telemetry.TelemetryTimeZone is null || telemetry.TelemetryTimeZone.IsOverride || - (!telemetry.TelemetryTimeZone.IsOverride && - telemetry.TelemetryTimeZone.Hours != info.TimeZoneOffsetTotalHours); - - if (isTimeZoneToUpdate) + if (!string.IsNullOrEmpty(info.TimeZoneId) && + telemetry.TelemetryTimeZone?.IsOverride != true) telemetry.TelemetryTimeZone = new TelemetryTimeZone() { Hours = info.TimeZoneOffsetTotalHours, @@ -106,94 +105,67 @@ namespace AsbCloudInfrastructure.Services var telemetry = await cacheTelemetry.FirstOrDefaultAsync(t => t.Id == idTelemetry, token); - if (telemetry.TelemetryTimeZone is not null) + if (!string.IsNullOrEmpty(telemetry.TelemetryTimeZone?.TimeZoneId)) return telemetry.TelemetryTimeZone.Hours; - - var well = await cacheWells.FirstOrDefaultAsync(w => w.IdTelemetry == telemetry.Id, token) - .ConfigureAwait(false); - if (well is null) - return null; - - var requestedTimeZoneInfo = await GetTimeZoneInfoAsync(well.Id, token) - .ConfigureAwait(false); - - if (requestedTimeZoneInfo.TimezoneId is null) - return null; - - telemetry.TelemetryTimeZone = new TelemetryTimeZone() + if (!string.IsNullOrEmpty(telemetry.Info?.TimeZoneId)) { - Hours = requestedTimeZoneInfo.GmtOffset, - TimeZoneId = requestedTimeZoneInfo.TimezoneId - }; - + telemetry.TelemetryTimeZone = new TelemetryTimeZone + { + Hours = telemetry.Info.TimeZoneOffsetTotalHours, + IsOverride = false, + TimeZoneId = telemetry.Info.TimeZoneId, + }; + } + else + { + var well = await cacheWells.FirstOrDefaultAsync(t => t.IdTelemetry == telemetry.Id, token) + .ConfigureAwait(false); + + if (well is null) + return null; + + var coordinates = await GetWellCoordinatesAsync(well.Id, token); + + if (coordinates is null) + return null; + + var requestedTimeZone = await timeZoneService.GetByCoordinatesAsync(coordinates.Value.latitude, coordinates.Value.longitude, token) + .ConfigureAwait(false); + + if (requestedTimeZone is null) + return null; + + telemetry.TelemetryTimeZone = requestedTimeZone.Adapt(); + } + await cacheTelemetry.UpsertAsync(telemetry, token).ConfigureAwait(false); return telemetry.TelemetryTimeZone.Hours; } - public DateTime FixDateToTimeZone(DateTime date, double offsetHours, + public async Task FixDatesRangeByTimeZoneAsync(int idTelemetry, DatesRangeDto range, CancellationToken token) { - return date.Kind switch - { - DateTimeKind.Utc => date, - DateTimeKind.Local => date.ToUniversalTime(), - _ => date.AddHours(-offsetHours) - }; - } + var offset = await GetTelemetryTimeZoneOffsetAsync(idTelemetry, token); - public async Task FixDatesRangeByTimeZoneAsync(int telemetryId, DatesRangeDto result, - CancellationToken token) - { - var telemetry = await cacheTelemetry.FirstOrDefaultAsync(t => t.Id == telemetryId, - token).ConfigureAwait(false); - - if (telemetry?.TelemetryTimeZone is null) - return result; + if (offset is null) + return range; return new DatesRangeDto() { - From = result.From.AddHours(telemetry.TelemetryTimeZone.Hours), - To = result.To.AddHours(telemetry.TelemetryTimeZone.Hours) + From = timeZoneService.DateToTimeZone(range.From, offset ?? default), + To = timeZoneService.DateToTimeZone(range.To, offset ?? default), }; } - public async Task GetTimeZoneInfoAsync(int idWell, CancellationToken token) - { - var coordinates = await GetWellCoordinatesAsync(idWell, token); - - if (coordinates is null) - return null; - - using var client = new HttpClient(); - - var latitude = coordinates.Value.latitude.Replace(',', '.'); - var longitude = coordinates.Value.longitude.Replace(',', '.'); - - var url = - $"{timeZoneApiUrl}?lat={latitude}&lng={longitude}&username={timezoneApiUserName}"; - - var response = await client.GetAsync(url, token).ConfigureAwait(false); - - var responseJson = await response.Content.ReadAsStringAsync(token) - .ConfigureAwait(false); - - var options = new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true - }; - var timeZoneInfo = JsonSerializer.Deserialize(responseJson, options); - - return timeZoneInfo; - } - public async Task UpdateTimeZoneAsync(string uid, TelemetryTimeZoneDto timeZoneInfo, CancellationToken token) { - var telemetry = GetOrCreateTelemetryByUid(uid); - telemetry.TelemetryTimeZone = timeZoneInfo.Adapt(); - + var telemetry = GetOrCreateTelemetryByUid(uid); + var newTelemetryTimeZone = timeZoneInfo.Adapt(); + if (newTelemetryTimeZone?.Equals(telemetry.TelemetryTimeZone) == true) + return; await cacheTelemetry.UpsertAsync(telemetry, token) .ConfigureAwait(false); } @@ -207,7 +179,7 @@ namespace AsbCloudInfrastructure.Services return well.IdTelemetry; } - private async Task<(string latitude, string longitude)?> GetWellCoordinatesAsync(int idWell, + private async Task<(double latitude, double longitude)?> GetWellCoordinatesAsync(int idWell, CancellationToken token) { var well = await cacheWells.FirstOrDefaultAsync(w => w.Id == idWell, token) @@ -217,19 +189,19 @@ namespace AsbCloudInfrastructure.Services return null; if (well.Latitude is not null && well.Longitude is not null) - return ($"{well.Latitude}", $"{well.Longitude}"); + return (well.Latitude ?? default, well.Longitude??default); 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}"); + return (cluster.Latitude ?? default, cluster.Longitude ?? default); 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 (deposit.Latitude ?? default, deposit.Longitude ?? default); return null; } @@ -396,5 +368,7 @@ namespace AsbCloudInfrastructure.Services return rows; } + + } } diff --git a/AsbCloudInfrastructure/Services/TelemetryTracker.cs b/AsbCloudInfrastructure/Services/TelemetryTracker.cs index 4c05c883..36f72c2c 100644 --- a/AsbCloudInfrastructure/Services/TelemetryTracker.cs +++ b/AsbCloudInfrastructure/Services/TelemetryTracker.cs @@ -42,10 +42,11 @@ namespace AsbCloudInfrastructure.Services var keyValuePairs = new Dictionary(cacheTelemetry.Count()); foreach (var telemetry in cacheTelemetry) { - var date = telemetry.Info?.DrillingStartDate + var date = telemetry.Info?.DrillingStartDate ?? GetDateByUidOrDefault(telemetry.RemoteUid, DateTime.MinValue); - keyValuePairs[telemetry.RemoteUid] = new TrackerStat { + keyValuePairs[telemetry.RemoteUid] = new TrackerStat + { RemoteUid = telemetry.RemoteUid, LastTimeRemote = date, LastTimeServer = date, @@ -53,14 +54,16 @@ namespace AsbCloudInfrastructure.Services } requests = new ConcurrentDictionary(keyValuePairs); - Task.Run(async() => { + Task.Run(async () => + { db.Database.SetCommandTimeout(2 * 60); var dates = await db.TelemetryDataSaub .GroupBy(d => d.IdTelemetry) .Select(g => new { IdTelemetry = g.Key, - Date = g.Max(d=>d.Date) + DateMax = g.Max(d => d.Date), + DateMin = g.Min(d => d.Date), }) .AsNoTracking() .ToListAsync() @@ -70,18 +73,18 @@ namespace AsbCloudInfrastructure.Services var oldReqs = dates.Select(t => new { Uid = cacheTelemetry.FirstOrDefault(c => c.Id == t.IdTelemetry).RemoteUid, - t.Date, + t.DateMax, }); foreach (var oldReq in oldReqs) { var request = requests.GetValueOrDefault(oldReq.Uid); - if(request is not null) + if (request is not null) { - if (request.LastTimeRemote < oldReq.Date) - request.LastTimeRemote = oldReq.Date; - if (request.LastTimeServer < oldReq.Date) - request.LastTimeServer = oldReq.Date; + if (request.LastTimeRemote < oldReq.DateMax) + request.LastTimeRemote = oldReq.DateMax; + if (request.LastTimeServer < oldReq.DateMax) + request.LastTimeServer = oldReq.DateMax; } } }); diff --git a/AsbCloudInfrastructure/Services/TimeZoneService.cs b/AsbCloudInfrastructure/Services/TimeZoneService.cs new file mode 100644 index 00000000..2b69c2d0 --- /dev/null +++ b/AsbCloudInfrastructure/Services/TimeZoneService.cs @@ -0,0 +1,86 @@ +using AsbCloudApp.Services; +using System.Net.Http; +using AsbCloudApp.Data; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using System; + +namespace AsbCloudInfrastructure.Services +{ + public class TimeZoneService : ITimeZoneService + { + class TimeZoneInfo + { + public string Sunrise { get; set; } + public double Lng { get; set; } + public double Lat { get; set; } + public string CountryCode { get; set; } + public double GmtOffset { get; set; } + public double RawOffset { get; set; } + public string Sunset { get; set; } + public string TimezoneId { get; set; } + public double DstOffset { get; set; } + public string CountryName { get; set; } + public string Time { get; set; } + } + + private readonly string timeZoneApiUrl = "http://api.geonames.org/timezoneJSON"; + private readonly string timezoneApiUserName = "asbautodrilling"; + + public async Task GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token) + { + var lat = latitude.ToString(System.Globalization.CultureInfo.InvariantCulture); + var lng = longitude.ToString(System.Globalization.CultureInfo.InvariantCulture); + + var url = + $"{timeZoneApiUrl}?lat={lat}&lng={lng}&username={timezoneApiUserName}"; + + using var client = new HttpClient(); + + var response = await client.GetAsync(url, token) + .ConfigureAwait(false); + + var responseJson = await response.Content.ReadAsStringAsync(token) + .ConfigureAwait(false); + + if (!(responseJson.Contains("timezoneId") && responseJson.Contains("dstOffset"))) + return null; + + var options = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }; + var timeZoneInfo = JsonSerializer.Deserialize(responseJson, options); + + return new TelemetryTimeZoneDto + { + Hours = timeZoneInfo.DstOffset, + IsOverride = false, + TimeZoneId = timeZoneInfo.TimezoneId, + }; + } + + public DateTime DateToUtc(DateTime date, double remoteTimezoneOffsetHours) + { + var newDate = date.Kind switch + { + DateTimeKind.Local => date.ToUniversalTime(), + DateTimeKind.Unspecified => date.AddHours(-remoteTimezoneOffsetHours), + _ => date, + }; + return DateTime.SpecifyKind(newDate, DateTimeKind.Utc); + } + + public DateTime DateToTimeZone(DateTime date, double remoteTimezoneOffsetHours) + { + var newDate = date.Kind switch + { + DateTimeKind.Local => date.ToUniversalTime().AddHours(remoteTimezoneOffsetHours), + DateTimeKind.Utc => date.AddHours(remoteTimezoneOffsetHours), + _ => date, + }; + return DateTime.SpecifyKind(newDate, DateTimeKind.Unspecified); + } + } +} diff --git a/AsbCloudWebApi/Controllers/TelemetryController.cs b/AsbCloudWebApi/Controllers/TelemetryController.cs index 49023a88..765c2e99 100644 --- a/AsbCloudWebApi/Controllers/TelemetryController.cs +++ b/AsbCloudWebApi/Controllers/TelemetryController.cs @@ -50,7 +50,7 @@ namespace AsbCloudWebApi.Controllers public async Task PostInfoAsync(string uid, [FromBody] TelemetryInfoDto info, CancellationToken token = default) { - await telemetryService.UpdateInfoAsync(uid, info, token); + await telemetryService.UpdateInfoAsync(uid, info, token).ConfigureAwait(false); return Ok(); } @@ -66,7 +66,8 @@ namespace AsbCloudWebApi.Controllers public async Task UpdateTimeZoneAsync(string uid, TelemetryTimeZoneDto timeZoneInfo, CancellationToken token = default) { - await telemetryService.UpdateTimeZoneAsync(uid, timeZoneInfo, token); + await telemetryService.UpdateTimeZoneAsync(uid, timeZoneInfo, token) + .ConfigureAwait(false); return Ok(); } @@ -122,33 +123,5 @@ namespace AsbCloudWebApi.Controllers telemetryUserService.Upsert(uid, users); return Ok(); } - - ///// - ///// Загрузка архива (sqlite3). - ///// - ///// var fileName = @"C:\temp\default.sqlite3"; - ///// var fileStream = System.IO.File.OpenRead(fileName); - ///// var file = new FileParameter(fileStream, System.IO.Path.GetFileName(fileName)); - ///// cli.ApiTelemetryDbAsync("1", new List<FileParameter> { file }).Wait(); - ///// - ///// - ///// - ///// - ///// - //[HttpPost] - //[Route("{uid}/db")] - //public IActionResult PostDb(string uid, IFormFileCollection files) - //{ - // foreach (var file in files) - // { - // var fileName = string.IsNullOrEmpty(file.FileName) - // ? System.IO.Path.GetTempFileName() - // : file.FileName; - // using (var stream = System.IO.File.Create(fileName)) - // file.CopyTo(stream); - // } - // return Ok(); - //} - } } diff --git a/AsbCloudWebApi/Controllers/TelemetryDataBaseController.cs b/AsbCloudWebApi/Controllers/TelemetryDataBaseController.cs index 0a1d46f2..1e5bd396 100644 --- a/AsbCloudWebApi/Controllers/TelemetryDataBaseController.cs +++ b/AsbCloudWebApi/Controllers/TelemetryDataBaseController.cs @@ -73,7 +73,7 @@ namespace AsbCloudWebApi.Controllers /// [HttpGet("{idWell}")] public virtual async Task> GetDataAsync(int idWell, DateTime begin = default, - int intervalSec = 600, int approxPointsCount = 1024, bool isUtc = true, CancellationToken token = default) + int intervalSec = 600, int approxPointsCount = 1024, bool isUtc = false, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); @@ -102,7 +102,7 @@ namespace AsbCloudWebApi.Controllers [HttpGet] [Route("{idWell}/datesRange")] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] - public virtual async Task GetDataDatesRangeAsync(int idWell, bool isUtc = true, + public virtual async Task GetDataDatesRangeAsync(int idWell, bool isUtc = false, CancellationToken token = default) { int? idCompany = User.GetCompanyId();