diff --git a/AsbCloudApp/Data/WellDepthToDayDto.cs b/AsbCloudApp/Data/WellDepthToDayDto.cs new file mode 100644 index 00000000..7b4bc175 --- /dev/null +++ b/AsbCloudApp/Data/WellDepthToDayDto.cs @@ -0,0 +1,11 @@ +using System; + +namespace AsbCloudApp.Data +{ + public class WellDepthToDayDto + { + public double? WellDepth { get; set; } + public double? BitDepth { get; set; } + public DateTime Date { get; set; } + } +} diff --git a/AsbCloudApp/Data/WellDepthToIntervalDto.cs b/AsbCloudApp/Data/WellDepthToIntervalDto.cs new file mode 100644 index 00000000..8f6aef84 --- /dev/null +++ b/AsbCloudApp/Data/WellDepthToIntervalDto.cs @@ -0,0 +1,10 @@ +using System; + +namespace AsbCloudApp.Data +{ + public class WellDepthToIntervalDto + { + public DateTime IntervalStartDate { get; set; } + public double IntervalDepthProgress { get; set; } + } +} diff --git a/AsbCloudApp/Services/IAnalyticsService.cs b/AsbCloudApp/Services/IAnalyticsService.cs new file mode 100644 index 00000000..3bdaad89 --- /dev/null +++ b/AsbCloudApp/Services/IAnalyticsService.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using AsbCloudApp.Data; + +namespace AsbCloudApp.Services +{ + public interface IAnalyticsService + { + IEnumerable GetWellDepthToDayData(int wellId); + IEnumerable GetWellDepthToIntervalData(int wellId, + double interval = 24, int beginHour = 8, int beginMinutes = 0); + } +} diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index b7b4ef6f..63d56782 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -34,6 +34,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); return services; } diff --git a/AsbCloudInfrastructure/Services/AnalyticsService.cs b/AsbCloudInfrastructure/Services/AnalyticsService.cs new file mode 100644 index 00000000..8a47064a --- /dev/null +++ b/AsbCloudInfrastructure/Services/AnalyticsService.cs @@ -0,0 +1,102 @@ +using System; +using System.Linq; +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using System.Collections.Generic; + +namespace AsbCloudInfrastructure.Services +{ + public class AnalyticsService : IAnalyticsService + { + private readonly IAsbCloudDbContext db; + private readonly ITelemetryService telemetryService; + + public AnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService) + { + this.db = db; + this.telemetryService = telemetryService; + } + + public IEnumerable GetWellDepthToDayData(int wellId) + { + var telemetry = telemetryService.GetTelemetryByWellId(wellId); + + if (telemetry is null) + return null; + + var depthToTimeData = (from d in db.DataSaubBases + where d.IdTelemetry == telemetry.Id + select new WellDepthToDayDto + { + WellDepth = d.WellDepth, + BitDepth =d.BitDepth, + Date = d.Date + }).ToList(); + + var m = (int)Math.Round(1d * depthToTimeData.Count / 2048); + + if (m > 1) + depthToTimeData = depthToTimeData.Where((d, i) => i % m == 0).ToList(); + + return depthToTimeData; + } + + public IEnumerable GetWellDepthToIntervalData(int wellId, + double interval = 24.0, int beginHour = 8, int beginMinutes = 0) + { + var intervalHours = TimeSpan.FromHours(interval); + var parseResult = TimeSpan.TryParse($"{beginHour}:{beginMinutes}", out var workDayBeginTime); + + if (!parseResult) + workDayBeginTime = TimeSpan.FromHours(8); + + var telemetry = telemetryService.GetTelemetryByWellId(wellId); + + if (telemetry is null) + return null; + + var drillingData = (from d in db.DataSaubBases + where d.IdTelemetry == telemetry.Id + select new + { + d.WellDepth, + d.Date + }).ToList(); + + if (!drillingData.Any()) + return null; + + var drillingStartDate = drillingData.First().Date; + var periodStart = drillingStartDate.Hour < 8 + ? new DateTime(drillingStartDate.Year, drillingStartDate.Month, drillingStartDate.Day).AddDays(-1) + workDayBeginTime + : new DateTime(drillingStartDate.Year, drillingStartDate.Month, drillingStartDate.Day) + workDayBeginTime; + + var periodEnd = periodStart + intervalHours; + var onePeriodData = new List<(double?, DateTime)>(); + var drillingPeriods = new List>(); + + foreach (var d in drillingData) + { + if (d.Date < periodEnd) + { + onePeriodData.Add((d.WellDepth, d.Date)); + continue; + } + drillingPeriods.Add(onePeriodData); + onePeriodData.Clear(); + periodStart = d.Date; + periodEnd = periodStart + intervalHours; + onePeriodData.Add((d.WellDepth, d.Date)); + } + + var wellDepthToIntervalData = drillingPeriods.Select(d => new WellDepthToIntervalDto + { + IntervalStartDate = d.FirstOrDefault().Item2, + IntervalDepthProgress = (d.Last().Item1 - d.FirstOrDefault().Item1) ?? 0.0 / interval + }); + + return wellDepthToIntervalData; + } + } +} diff --git a/AsbCloudWebApi/Controllers/AnalyticsController.cs b/AsbCloudWebApi/Controllers/AnalyticsController.cs index 41fcb19d..dc2354ad 100644 --- a/AsbCloudWebApi/Controllers/AnalyticsController.cs +++ b/AsbCloudWebApi/Controllers/AnalyticsController.cs @@ -1,6 +1,7 @@ using System; -using AsbCloudApp.Data; using System.Collections.Generic; +using AsbCloudApp.Data; +using AsbCloudApp.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; @@ -11,6 +12,61 @@ namespace AsbCloudWebApi.Controllers [Authorize] public class AnalyticsController : ControllerBase { + private readonly IAnalyticsService analyticsService; + private readonly IWellService wellService; + + public AnalyticsController(IAnalyticsService analyticsService, IWellService wellService) + { + this.analyticsService = analyticsService; + this.wellService = wellService; + } + + /// + /// Возвращает данные по скважине "глубина-день" + /// + /// id скважины + /// Коллекцию данных по скважине "глубина-день" + [HttpGet] + [Route("{wellId}/wellDepthToDay")] + [ProducesResponseType(typeof(List), (int)System.Net.HttpStatusCode.OK)] + public IActionResult GetWellDepthToDay(int wellId) + { + int? idCustomer = User.GetCustomerId(); + + if (idCustomer is null) + return BadRequest(); + + if (!wellService.CheckWellOwnership((int)idCustomer, wellId)) + return Forbid(); + + var wellDepthToDayData = analyticsService.GetWellDepthToDayData(wellId); + + return Ok(wellDepthToDayData); + } + + /// + /// Возвращает данные по глубине скважины за период + /// + /// id скважины + /// Коллекцию данных по глубине скважины за период + [HttpGet] + [Route("{wellId}/wellDepthToInterval")] + [ProducesResponseType(typeof(List), (int)System.Net.HttpStatusCode.OK)] + public IActionResult GetWellDepthToInterval(int wellId) + { + int? idCustomer = User.GetCustomerId(); + + if (idCustomer is null) + return BadRequest(); + + if (!wellService.CheckWellOwnership((int)idCustomer, wellId)) + return Forbid(); + + var wellDepthToIntervalData = analyticsService.GetWellDepthToIntervalData(wellId); + + return Ok(wellDepthToIntervalData); + } + /// /// Возвращает данные по операциям на скважине за период /// @@ -19,10 +75,18 @@ namespace AsbCloudWebApi.Controllers /// дата окончания интервала /// Коллекцию операций на скважине [HttpGet] - [Route("{wellId}/get")] + [Route("{wellId}/operationsToTime")] [ProducesResponseType(typeof(List), (int)System.Net.HttpStatusCode.OK)] - public IActionResult GetAnalytics(int wellId, DateTime begin = default, DateTime end = default) + public IActionResult GetOperationsToTime(int wellId, DateTime begin = default, DateTime end = default) { + int? idCustomer = User.GetCustomerId(); + + if (idCustomer is null) + return BadRequest(); + + if (!wellService.CheckWellOwnership((int)idCustomer, wellId)) + return Forbid(); + var analytics = new List { new OperationPercentageDto { ProcessName = "Роторное бурение", Percentage = 19.7 },