using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.Cache; using AutoMapper; using System; using System.Collections.Generic; using System.Linq; namespace AsbCloudInfrastructure.Services { public class DataService : IDataService { private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; private readonly IAnalyticsService analyticsService; private readonly ISaubDataCache saubDataCache; private readonly IMapper mapper; private readonly CacheTable cacheTelemetry; private readonly CacheTable cacheWells; public DataService(IAsbCloudDbContext db, ITelemetryService telemetryService, IAnalyticsService analyticsService, ISaubDataCache saubDataCache, CacheDb cacheDb, MapperConfiguration mapperConfiguration) { this.db = db; this.telemetryService = telemetryService; this.analyticsService = analyticsService; this.saubDataCache = saubDataCache; mapper = mapperConfiguration.CreateMapper(); cacheTelemetry = cacheDb.GetCachedTable((AsbCloudDbContext)db); cacheWells = cacheDb.GetCachedTable((AsbCloudDbContext)db); } public IEnumerable Get(int wellId, DateTime dateBegin = default, double intervalSec = 600d, int approxPointsCount = 1024) { var well = cacheWells.FirstOrDefault(w => w.Id == wellId); if (well is null) return default; var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == well.IdTelemetry); if (telemetry is null) return default; if (dateBegin == default) dateBegin = DateTime.Now.AddSeconds(-intervalSec); var datEnd = dateBegin.AddSeconds(intervalSec); var fullData = from data in db.DataSaubBases where data.IdTelemetry == telemetry.Id && data.Date >= dateBegin && data.Date < datEnd select data; var fullDataCount = fullData.Count(); if (fullDataCount == 0) return default; if (fullDataCount > 1.75 * approxPointsCount) { var m = (int)Math.Round(1d*fullDataCount / approxPointsCount); if(m > 1) fullData = fullData.Where(d => d.Id % m == 0); } var dbData = fullData.ToList(); var result = new List(dbData.Count); foreach (var item in dbData) result.Add(mapper.Map(item)); return result; } public void UpdateData(string uid, IEnumerable dtos) { if (dtos == default || !dtos.Any()) return; var telemetryId = telemetryService.GetOrCreateTemetryIdByUid(uid); var dtoMinDate = dtos.Min(d => d.Date); var dtoMaxDate = dtos.Max(d => d.Date); var oldDataSaubBase = (from d in db.DataSaubBases where d.IdTelemetry == telemetryId && d.Date > dtoMinDate && d.Date < dtoMaxDate select d).ToList(); if (oldDataSaubBase.Any()) { db.DataSaubBases.RemoveRange(oldDataSaubBase); } foreach (var item in dtos) { var dataSaub = mapper.Map(item); dataSaub.IdTelemetry = telemetryId; db.DataSaubBases.Add(dataSaub); saubDataCache.AddData(dataSaub); if (saubDataCache.GetOrCreateCache(dataSaub.IdTelemetry).Count() > 1) { var dataSaubs = saubDataCache.GetOrCreateCache(dataSaub.IdTelemetry) .OrderBy(d => d.Date); var telemetryAnalysis = analyticsService.GetDrillingAnalysis(dataSaubs); if(saubDataCache.CurrentAnalysis is null) saubDataCache.CurrentAnalysis = telemetryAnalysis; if (saubDataCache.CurrentAnalysis.IdOperation == telemetryAnalysis.IdOperation) { saubDataCache.CurrentAnalysis.Duration += telemetryAnalysis.Duration; saubDataCache.CurrentAnalysis.OperationEndDepth = item.WellDepth; } else { db.TelemetryAnalysis.Add(saubDataCache.CurrentAnalysis); saubDataCache.CurrentAnalysis = telemetryAnalysis; saubDataCache.CurrentAnalysis.OperationStartDepth = item.WellDepth; } } } db.SaveChanges(); } public DatesRangeDto GetDataDatesRange(int wellId) { var telemetry = telemetryService.GetTelemetryByWellId(wellId); if (telemetry is null) return null; var (From, To) = db.GetDatesRange(telemetry.Id); return new DatesRangeDto { From = From, To = To}; } } }