forked from ddrilling/AsbCloudServer
CS2-24: Исправлены либо заменены заглушками данные для графиков аналитики.
This commit is contained in:
parent
70dca51987
commit
5409f5a38f
11
AsbCloudApp/Data/OperationDetailsDto.cs
Normal file
11
AsbCloudApp/Data/OperationDetailsDto.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
public class OperationDetailsDto
|
||||
{
|
||||
public string OperationName { get; set; }
|
||||
public DateTime OperationStartTime { get; set; }
|
||||
public double DurationHours { get; set; }
|
||||
}
|
||||
}
|
12
AsbCloudApp/Data/OperationInfoDto.cs
Normal file
12
AsbCloudApp/Data/OperationInfoDto.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
public class OperationInfoDto
|
||||
{
|
||||
public DateTime IntervalBegin { get; set; }
|
||||
public DateTime IntervalEnd { get; set; }
|
||||
public IEnumerable<OperationDetailsDto> OperationData { get; set; }
|
||||
}
|
||||
}
|
@ -1,12 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AsbCloudApp.Data;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
public interface IAnalyticsService
|
||||
{
|
||||
IEnumerable<WellDepthToDayDto> GetWellDepthToDayData(int wellId);
|
||||
IEnumerable<WellDepthToIntervalDto> GetWellDepthToIntervalData(int wellId,
|
||||
double interval = 24, int beginHour = 8, int beginMinutes = 0);
|
||||
IEnumerable<WellDepthToDayDto> GetWellDepthToDay(int wellId);
|
||||
IEnumerable<WellDepthToIntervalDto> GetWellDepthToInterval(int wellId,
|
||||
int intervalHours = 24, int intervalMinutes = 0, int beginHour = 8, int beginMinutes = 0);
|
||||
IEnumerable<OperationPercentageDto> GetOperationsSummary(int wellId,
|
||||
DateTime begin = default, DateTime end = default);
|
||||
IEnumerable<OperationInfoDto> GetOperationsToTime(int wellId,
|
||||
DateTime begin = default, DateTime end = default);
|
||||
}
|
||||
}
|
||||
|
@ -216,6 +216,33 @@ namespace AsbCloudDb.Model
|
||||
return (datesRange.From, datesRange.To);
|
||||
}
|
||||
|
||||
public IEnumerable<(double?, double?, DateTime)> GetDepthToInterval (int telemetryId,
|
||||
int intervalHoursTimestamp, int workStartTimestamp, double timezoneOffset)
|
||||
{
|
||||
//TODO: Сменить на LINQ группирование
|
||||
using var command = Database.GetDbConnection().CreateCommand();
|
||||
|
||||
command.CommandText = $@"SELECT Min(t.bit_depth) AS MinDepth, Max(t.bit_depth) AS MaxDepth, Min(t.Date) AS dateStart
|
||||
FROM t_data_saub_base AS t
|
||||
WHERE id_telemetry = {telemetryId} AND t.Id % 10 = 0
|
||||
GROUP BY floor((extract(epoch from t.date) - {workStartTimestamp} + {timezoneOffset}) / {intervalHoursTimestamp});";
|
||||
|
||||
Database.OpenConnection();
|
||||
using var reader = command.ExecuteReader();
|
||||
if (reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
yield return
|
||||
(
|
||||
(double?)reader.GetValue(0),
|
||||
(double?)reader.GetValue(1),
|
||||
(DateTime)reader.GetValue(2)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<int> CreatePartitionAsync<TEntity>(string propertyName, int id, CancellationToken token = default)
|
||||
where TEntity : class
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -28,6 +29,8 @@ namespace AsbCloudDb.Model
|
||||
IQueryable<Well> GetWellsByCustomer(int idCustomer);
|
||||
IQueryable<User> GetUsersByLogin(string login);
|
||||
(DateTime From, DateTime To) GetDatesRange<T>(int idTelemetry) where T : class, IIdTelemetryDate;
|
||||
IEnumerable<(double?, double?, DateTime)> GetDepthToInterval(int telemetryId,
|
||||
int intervalHoursTimestamp, int workStartTimestamp, double timezoneOffset);
|
||||
Task<int> CreatePartitionAsync<TEntity>(string propertyName, int id, CancellationToken token = default) where TEntity : class;
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudInfrastructure.Services.Cache;
|
||||
using AsbCloudDb.Model;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -11,14 +12,16 @@ namespace AsbCloudInfrastructure.Services
|
||||
{
|
||||
private readonly IAsbCloudDbContext db;
|
||||
private readonly ITelemetryService telemetryService;
|
||||
private readonly CacheTable<Telemetry> cacheTelemetry;
|
||||
|
||||
public AnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService)
|
||||
public AnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService, CacheDb cacheDb)
|
||||
{
|
||||
this.db = db;
|
||||
this.telemetryService = telemetryService;
|
||||
cacheTelemetry = cacheDb.GetCachedTable<Telemetry>((AsbCloudDbContext)db);
|
||||
}
|
||||
|
||||
public IEnumerable<WellDepthToDayDto> GetWellDepthToDayData(int wellId)
|
||||
public IEnumerable<WellDepthToDayDto> GetWellDepthToDay(int wellId)
|
||||
{
|
||||
var telemetry = telemetryService.GetTelemetryByWellId(wellId);
|
||||
|
||||
@ -27,76 +30,192 @@ namespace AsbCloudInfrastructure.Services
|
||||
|
||||
var depthToTimeData = (from d in db.DataSaubBases
|
||||
where d.IdTelemetry == telemetry.Id
|
||||
select new WellDepthToDayDto
|
||||
select new
|
||||
{
|
||||
WellDepth = d.WellDepth,
|
||||
BitDepth =d.BitDepth,
|
||||
Date = d.Date
|
||||
}).ToList();
|
||||
d.Id,
|
||||
d.WellDepth,
|
||||
d.BitDepth,
|
||||
d.Date
|
||||
});
|
||||
|
||||
var m = (int)Math.Round(1d * depthToTimeData.Count / 2048);
|
||||
var m = (int)Math.Round(1d * depthToTimeData.Count() / 2048);
|
||||
|
||||
if (m > 1)
|
||||
depthToTimeData = depthToTimeData.Where((d, i) => i % m == 0).ToList();
|
||||
depthToTimeData = depthToTimeData.Where(d => d.Id % m == 0);
|
||||
|
||||
return depthToTimeData;
|
||||
return depthToTimeData.Select(d => new WellDepthToDayDto
|
||||
{
|
||||
WellDepth = d.WellDepth,
|
||||
BitDepth = d.BitDepth,
|
||||
Date = d.Date
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<WellDepthToIntervalDto> GetWellDepthToIntervalData(int wellId,
|
||||
double interval = 24.0, int beginHour = 8, int beginMinutes = 0)
|
||||
public IEnumerable<WellDepthToIntervalDto> GetWellDepthToInterval(int wellId,
|
||||
int intervalHours = 24, int intervalMinutes = 0, int workBeginHour = 8, int workBeginMinutes = 0)
|
||||
{
|
||||
var intervalHours = TimeSpan.FromHours(interval);
|
||||
var parseResult = TimeSpan.TryParse($"{beginHour}:{beginMinutes}", out var workDayBeginTime);
|
||||
|
||||
if (!parseResult)
|
||||
workDayBeginTime = TimeSpan.FromHours(8);
|
||||
var intervalTime = new TimeSpan(intervalHours, intervalMinutes, 0) == default
|
||||
? new TimeSpan(24, 0, 0)
|
||||
: new TimeSpan(intervalHours, intervalMinutes, 0);
|
||||
var workDayBeginTime = new TimeSpan(workBeginHour, workBeginMinutes, 0) == default
|
||||
? new TimeSpan(8, 0, 0)
|
||||
: new TimeSpan(intervalHours, intervalMinutes, 0); ;
|
||||
|
||||
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();
|
||||
var timezoneOffset = cacheTelemetry.FirstOrDefault(t => t.Id == telemetry.Id).Info.TimeZoneOffsetTotalHours;
|
||||
|
||||
if (!drillingData.Any())
|
||||
return null;
|
||||
var drillingPeriodsInfo = db.GetDepthToInterval(telemetry.Id, (int)intervalTime.TotalSeconds,
|
||||
(int)workDayBeginTime.TotalSeconds, timezoneOffset);
|
||||
|
||||
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<IEnumerable<(double?, DateTime)>>();
|
||||
|
||||
foreach (var d in drillingData)
|
||||
var wellDepthToIntervalData = drillingPeriodsInfo.Select(d => new WellDepthToIntervalDto
|
||||
{
|
||||
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
|
||||
});
|
||||
IntervalStartDate = d.Item3,
|
||||
IntervalDepthProgress = (d.Item2 - d.Item1) ?? 0.0 / intervalHours
|
||||
}).OrderBy(d => d.IntervalStartDate).ToList();
|
||||
|
||||
return wellDepthToIntervalData;
|
||||
}
|
||||
|
||||
public IEnumerable<OperationPercentageDto> GetOperationsSummary(int wellId,
|
||||
DateTime begin = default, DateTime end = default)
|
||||
{
|
||||
return new List<OperationPercentageDto>
|
||||
{
|
||||
new OperationPercentageDto { ProcessName = "Роторное бурение", Percentage = 19.7 },
|
||||
new OperationPercentageDto { ProcessName = "Подъем с проработкой", Percentage = 6.2 },
|
||||
new OperationPercentageDto { ProcessName = "Спуск с проработкой", Percentage = 9.4 },
|
||||
new OperationPercentageDto { ProcessName = "Подъем с промывкой", Percentage = 18.4 },
|
||||
new OperationPercentageDto { ProcessName = "Неподвижное состояние", Percentage = 12.1 },
|
||||
new OperationPercentageDto { ProcessName = "Вращение без циркуляции", Percentage = 7.4 },
|
||||
new OperationPercentageDto { ProcessName = "Спуск в скважину", Percentage = 16.7 },
|
||||
new OperationPercentageDto { ProcessName = "На поверхности", Percentage = 10.1 }
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<OperationInfoDto> GetOperationsToTime(int wellId,
|
||||
DateTime begin = default, DateTime end = default)
|
||||
{
|
||||
return new List<OperationInfoDto>
|
||||
{
|
||||
new OperationInfoDto
|
||||
{
|
||||
IntervalBegin = new DateTime(2021, 06, 01, 08, 00, 00),
|
||||
IntervalEnd = new DateTime(2021, 06, 02, 08, 00, 00),
|
||||
OperationData = new List<OperationDetailsDto>
|
||||
{
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Роторное бурение",
|
||||
OperationStartTime = new DateTime(2021, 06, 01, 10, 00, 00),
|
||||
DurationHours = 1.2
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Подъем с проработкой",
|
||||
OperationStartTime = new DateTime(2021, 06, 01, 11, 00, 00),
|
||||
DurationHours = 3.2
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Роторное бурение",
|
||||
OperationStartTime = new DateTime(2021, 06, 01, 12, 00, 00),
|
||||
DurationHours = 1.5
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Неподвижное состояние",
|
||||
OperationStartTime = new DateTime(2021, 06, 01, 13, 00, 00),
|
||||
DurationHours = 0.2
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Роторное бурение",
|
||||
OperationStartTime = new DateTime(2021, 06, 01, 14, 00, 00),
|
||||
DurationHours = 3.2
|
||||
}
|
||||
}
|
||||
},
|
||||
new OperationInfoDto
|
||||
{
|
||||
IntervalBegin = new DateTime(2021, 06, 02, 08, 00, 00),
|
||||
IntervalEnd = new DateTime(2021, 06, 03, 08, 00, 00),
|
||||
OperationData = new List<OperationDetailsDto>
|
||||
{
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "На поверхности",
|
||||
OperationStartTime = new DateTime(2021, 06, 13, 10, 01, 00),
|
||||
DurationHours = 2.2
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Спуск в скважину",
|
||||
OperationStartTime = new DateTime(2021, 06, 13, 11, 10, 00),
|
||||
DurationHours = 0.4
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "На поверхности",
|
||||
OperationStartTime = new DateTime(2021, 06, 13, 12, 20, 00),
|
||||
DurationHours = 2.5
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Вращение без циркуляции",
|
||||
OperationStartTime = new DateTime(2021, 06, 13, 13, 00, 00),
|
||||
DurationHours = 1.2
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Роторное бурение",
|
||||
OperationStartTime = new DateTime(2021, 06, 13, 14, 00, 00),
|
||||
DurationHours = 5.2
|
||||
}
|
||||
}
|
||||
},
|
||||
new OperationInfoDto
|
||||
{
|
||||
IntervalBegin = new DateTime(2021, 06, 03, 08, 00, 00),
|
||||
IntervalEnd = new DateTime(2021, 06, 04, 08, 00, 00),
|
||||
OperationData = new List<OperationDetailsDto>
|
||||
{
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Подъем с проработкой",
|
||||
OperationStartTime = new DateTime(2021, 06, 12, 10, 00, 00),
|
||||
DurationHours = 3.2
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Спуск с проработкой",
|
||||
OperationStartTime = new DateTime(2021, 06, 12, 11, 00, 00),
|
||||
DurationHours = 1.4
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Подъем с проработкой",
|
||||
OperationStartTime = new DateTime(2021, 06, 12, 12, 00, 00),
|
||||
DurationHours = 0.5
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "На поверхности",
|
||||
OperationStartTime = new DateTime(2021, 06, 12, 13, 00, 00),
|
||||
DurationHours = 3.2
|
||||
},
|
||||
new OperationDetailsDto
|
||||
{
|
||||
OperationName = "Роторное бурение",
|
||||
OperationStartTime = new DateTime(2021, 06, 13, 14, 00, 00),
|
||||
DurationHours = 1.2
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <returns>Коллекцию данных по скважине "глубина-день"</returns>
|
||||
[HttpGet]
|
||||
[Route("{wellId}/wellDepthToDay")]
|
||||
[ProducesResponseType(typeof(List<WellDepthToDayDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellDepthToDayDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public IActionResult GetWellDepthToDay(int wellId)
|
||||
{
|
||||
int? idCustomer = User.GetCustomerId();
|
||||
@ -39,7 +39,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
if (!wellService.CheckWellOwnership((int)idCustomer, wellId))
|
||||
return Forbid();
|
||||
|
||||
var wellDepthToDayData = analyticsService.GetWellDepthToDayData(wellId);
|
||||
var wellDepthToDayData = analyticsService.GetWellDepthToDay(wellId);
|
||||
|
||||
return Ok(wellDepthToDayData);
|
||||
}
|
||||
@ -48,11 +48,15 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// Возвращает данные по глубине скважины за период
|
||||
/// </summary>
|
||||
/// <param name="wellId">id скважины</param>
|
||||
/// <param name="intervalHours">количество часов в интервале выборки</param>
|
||||
/// <param name="intervalMinutes">количество минут в интервале выборки</param>
|
||||
/// <param name="workBeginHour">время начала рабочей смены (в часах)</param>
|
||||
/// <param name="workBeginMinutes">время начала рабочей смены (в минутах)</param>
|
||||
/// <returns>Коллекцию данных по глубине скважины за период</returns>
|
||||
[HttpGet]
|
||||
[Route("{wellId}/wellDepthToInterval")]
|
||||
[ProducesResponseType(typeof(List<WellDepthToIntervalDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public IActionResult GetWellDepthToInterval(int wellId)
|
||||
[ProducesResponseType(typeof(IEnumerable<WellDepthToIntervalDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public IActionResult GetWellDepthToInterval(int wellId, int intervalHours, int intervalMinutes, int workBeginHour, int workBeginMinutes)
|
||||
{
|
||||
int? idCustomer = User.GetCustomerId();
|
||||
|
||||
@ -62,18 +66,44 @@ namespace AsbCloudWebApi.Controllers
|
||||
if (!wellService.CheckWellOwnership((int)idCustomer, wellId))
|
||||
return Forbid();
|
||||
|
||||
var wellDepthToIntervalData = analyticsService.GetWellDepthToIntervalData(wellId);
|
||||
var wellDepthToIntervalData = analyticsService.GetWellDepthToInterval(wellId, intervalHours, intervalMinutes, workBeginHour, workBeginMinutes);
|
||||
|
||||
return Ok(wellDepthToIntervalData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает данные по операциям на скважине за период
|
||||
/// Возвращает данные по операциям на скважине "операции-время"
|
||||
/// </summary>
|
||||
/// <param name="wellId">id скважины</param>
|
||||
/// <param name="begin">дата начала интервала</param>
|
||||
/// <param name="end">дата окончания интервала</param>
|
||||
/// <returns>Коллекцию операций на скважине</returns>
|
||||
[HttpGet]
|
||||
[Route("{wellId}/operationsSummary")]
|
||||
[ProducesResponseType(typeof(List<OperationPercentageDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public IActionResult GetOperationsSummary(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 = analyticsService.GetOperationsSummary(wellId, begin, end);
|
||||
|
||||
return Ok(analytics);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает детальные данные по операциям на скважине за период
|
||||
/// </summary>
|
||||
/// <param name="wellId">id скважины</param>
|
||||
/// <param name="begin">дата начала интервала</param>
|
||||
/// <param name="end">дата окончания интервала</param>
|
||||
/// <returns>Коллекцию операций на скважине</returns>
|
||||
|
||||
[HttpGet]
|
||||
[Route("{wellId}/operationsToTime")]
|
||||
[ProducesResponseType(typeof(List<OperationPercentageDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
@ -87,17 +117,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
if (!wellService.CheckWellOwnership((int)idCustomer, wellId))
|
||||
return Forbid();
|
||||
|
||||
var analytics = new List<OperationPercentageDto>
|
||||
{
|
||||
new OperationPercentageDto { ProcessName = "Роторное бурение", Percentage = 19.7 },
|
||||
new OperationPercentageDto { ProcessName = "Подъем с проработкой", Percentage = 6.2 },
|
||||
new OperationPercentageDto { ProcessName = "Спуск с проработкой", Percentage = 9.4 },
|
||||
new OperationPercentageDto { ProcessName = "Подъем с промывкой", Percentage = 18.4 },
|
||||
new OperationPercentageDto { ProcessName = "Неподвижное состояние", Percentage = 12.1 },
|
||||
new OperationPercentageDto { ProcessName = "Вращение без циркуляции", Percentage = 7.4 },
|
||||
new OperationPercentageDto { ProcessName = "Спуск в скважину", Percentage = 16.7 },
|
||||
new OperationPercentageDto { ProcessName = "На поверхности", Percentage = 10.1 }
|
||||
};
|
||||
var analytics = GetOperationsToTime(wellId, begin, end);
|
||||
|
||||
return Ok(analytics);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user