This commit is contained in:
ngfrolov 2022-09-07 18:01:39 +05:00
parent 4f27adf9ea
commit 79108c754a
9 changed files with 282 additions and 257 deletions

View File

@ -47,14 +47,17 @@ namespace AsbCloudApp.Requests
/// информация попадает в выборку, если интервал выборки частично или полностью пересекается с запрашиваемым интервалом
/// </summary>
public const int SelectModeOuter = 0;
/// <summary>
/// информация попадает в выборку, если интервал выборки строго полностью пересекается с запрашиваемым интервалом.
/// </summary>
public const int SelectModeInner = 1;
/// <summary>
/// аналогично outer, но интервалы в частично пересекающиеся укорачиваются по границам интервала выборки.
/// </summary>
public const int SelectModeTrim = 2;
/// <summary>
/// Режим выборки элементов
/// </summary>

View File

@ -1,19 +1,41 @@
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Requests;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudApp.Services.Subsystems
{
#nullable enable
/// <summary>
/// Получение инфо о наработке подсистем
/// </summary>
public interface ISubsystemOperationTimeService
{
{
/// <summary>
/// Статистика о наработке подсистем
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<SubsystemStatDto>?> GetStatAsync(SubsystemOperationTimeRequest request, CancellationToken token);
/// <summary>
/// Удаление наработки по подсистемам.
/// Если удаляется конец, то фоновый сервис подсчета наработки восстановит эти данные.
/// Может потребоваться для запуска повторного расчета по новому алгоритму.
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> DeleteAsync(SubsystemOperationTimeRequest request, CancellationToken token);
/// <summary>
/// Интервалы работы подсистем
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<SubsystemOperationTimeDto>?> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token);
}
#nullable disable

View File

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
@ -9,9 +6,8 @@ namespace AsbCloudDb.Model.Subsystems
{
[Table("t_subsystem"), Comment("Описание подсистем")]
public class Subsystem : IId
{
[Key]
[Column("id")]
{
[Column("id"), Key]
public int Id { get; set; }
[Column("name")]
@ -22,6 +18,5 @@ namespace AsbCloudDb.Model.Subsystems
[StringLength(255)]
public string? Description { get; set; }
}
}
}

View File

@ -9,8 +9,7 @@ namespace AsbCloudDb.Model.Subsystems
[Table("t_subsystem_operation_time"), Comment("наработки подсистем")]
public partial class SubsystemOperationTime : IId
{
[Key]
[Column("id")]
[Column("id"), Key]
public int Id { get; set; }
[Column("id_telemetry"), Comment("ИД телеметрии по которой выдается информация")]
@ -20,23 +19,23 @@ namespace AsbCloudDb.Model.Subsystems
public int IdSubsystem { get; set; }
[Column("date_start"), Comment("дата/время включения подсистемы")]
public DateTimeOffset DateStart { get; set; }
public DateTimeOffset DateStart { get; set; }
[Column("date_end"), Comment("дата/время выключения подсистемы")]
public DateTimeOffset DateEnd { get; set; }
public DateTimeOffset DateEnd { get; set; }
[Column("depth_start"), Comment("глубина забоя на момент включения подсистемы")]
public float? DepthStart { get; set; }
[Column("depth_end"), Comment("глубина забоя на момент выключения подсистемы")]
public float? DepthEnd { get; set; }
[JsonIgnore]
[ForeignKey(nameof(IdSubsystem))]
public virtual Subsystem Subsystem { get; set; }
[ForeignKey(nameof(IdSubsystem))]
public virtual Subsystem Subsystem { get; set; } = null!;
[JsonIgnore]
[ForeignKey(nameof(IdTelemetry))]
public virtual Telemetry Telemetry { get; set; }
public virtual Telemetry Telemetry { get; set; } = null!;
}
}

View File

@ -7,7 +7,6 @@ using Npgsql;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Threading;
@ -26,17 +25,18 @@ namespace AsbCloudInfrastructure.Services.Subsystems
{
connectionString = configuration.GetConnectionString("DefaultConnection");
}
protected override async Task ExecuteAsync(CancellationToken token)
{
var timeToStartAnalysis = DateTime.Now;
var timeToStart = DateTime.Now;
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql(connectionString)
.Options;
while (!token.IsCancellationRequested)
{
if (DateTime.Now > timeToStartAnalysis)
if (DateTime.Now > timeToStart)
{
timeToStartAnalysis = DateTime.Now + period;
timeToStart = DateTime.Now + period;
try
{
using var context = new AsbCloudDbContext(options);
@ -49,7 +49,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
}
GC.Collect();
}
var ms = (int)(timeToStartAnalysis - DateTime.Now).TotalMilliseconds;
var ms = (int)(timeToStart - DateTime.Now).TotalMilliseconds;
ms = ms > 100 ? ms : 100;
await Task.Delay(ms, token).ConfigureAwait(false);
}
@ -76,7 +76,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
.Select(t => t.Id)
.ToListAsync(token);
var JounedlastDetectedDates = telemetryIds
var telemetryLastDetectedDates = telemetryIds
.GroupJoin(lastDetectedDates,
t => t,
o => o.IdTelemetry,
@ -85,8 +85,9 @@ namespace AsbCloudInfrastructure.Services.Subsystems
IdTelemetry = outer,
inner.SingleOrDefault()?.LastDate,
});
var affected = 0;
foreach (var item in JounedlastDetectedDates)
foreach (var item in telemetryLastDetectedDates)
{
var newOperationsSaub = await OperationTimeSaubAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
if (newOperationsSaub?.Any() == true)
@ -103,139 +104,157 @@ namespace AsbCloudInfrastructure.Services.Subsystems
}
return affected;
}
private static async Task<IEnumerable<SubsystemOperationTime>?> OperationTimeSaubAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
{
var operationTimeSaub =
$"select tt.date, tt.mode, tt.well_depth" +
$" from (select date, mode, well_depth, lag(mode,1) over (order by date) as mode_prev" +
$" from t_telemetry_data_saub where id_telemetry = @idTelemetry) as tt" +
$" where tt.mode != tt.mode_prev and tt.date >= @begin order by tt.date;";
using var command = db.Database.GetDbConnection().CreateCommand();
command.CommandText = operationTimeSaub;
var telemetry = new NpgsqlParameter("@idTelemetry", idTelemetry);
command.Parameters.Add(telemetry);
var dateStart = new NpgsqlParameter("@begin", begin);
command.Parameters.Add(dateStart);
db.Database.OpenConnection();
using var result = await command.ExecuteReaderAsync(token);
var telemetryOpearationSaubSubsystems = new List<SubsystemsSpinWithDepth>();
if (result.HasRows)
private static async Task<IEnumerable<SubsystemOperationTime>> OperationTimeSaubAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
{
static int? GetSubsytemId(short mode)
{
return mode +1;
}
var query =
$"select tt.date, tt.mode, tt.well_depth " +
$"from ( " +
$" select " +
$" date, " +
$" mode, " +
$" well_depth, " +
$" lag(mode,1) over (order by date) as mode_prev " +
$" from t_telemetry_data_saub " +
$" where id_telemetry = @idTelemetry " +
$" order by date ) as tt " +
$"where (tt.mode_prev is null or tt.mode != tt.mode_prev) and tt.date >= @begin " +
$"order by tt.date;";
var idTelemetryParam = new NpgsqlParameter("@idTelemetry", idTelemetry);
var beginParam = new NpgsqlParameter("@begin", begin);
await db.Database.OpenConnectionAsync(token);
using var command = db.Database.GetDbConnection().CreateCommand();
command.CommandText = query;
command.Parameters.Add(idTelemetryParam);
command.Parameters.Add(beginParam);
using var result = await command.ExecuteReaderAsync(token);
var subsystemOperationTime = new List<SubsystemOperationTime>(32);
if (result.Read())
{
var mode = result.GetFieldValue<short>(1);
var idSubsystem = GetSubsytemId(mode);
var dateStart = result.GetFieldValue<DateTimeOffset>(0);
var depthStart = result.GetFieldValue<float>(2);
while (result.Read())
{
var itemEntity = new SubsystemsSpinWithDepth()
var dateEnd = result.GetFieldValue<DateTimeOffset>(0);
var depthEnd = result.GetFieldValue<float>(2);
if (idSubsystem.HasValue)
{
Date = result.GetFieldValue<DateTimeOffset>(0),
IdSubsystem = result.GetFieldValue<short>(1)+1,
Depth = result.GetFieldValue<float>(2)
};
telemetryOpearationSaubSubsystems.Add(itemEntity);
var operationTimeItem = new SubsystemOperationTime()
{
IdTelemetry = idTelemetry,
IdSubsystem = idSubsystem.Value,
DateStart = dateStart,
DateEnd = dateEnd,
DepthStart = depthStart,
DepthEnd = depthEnd
};
subsystemOperationTime.Add(operationTimeItem);
}
mode = result.GetFieldValue<short>(1);
idSubsystem = GetSubsytemId(mode);
dateStart = dateEnd;
depthStart = depthEnd;
}
}
var resultSubsystemOperationTime = new List<SubsystemOperationTime>();
var firstItem = telemetryOpearationSaubSubsystems.FirstOrDefault();
if (firstItem is null)
return null;
int idSubsystem = firstItem.IdSubsystem;
DateTimeOffset dateBegin = firstItem.Date;
float? depthStart = firstItem.Depth;
for (int i = 1; i < telemetryOpearationSaubSubsystems.Count; i++)
{
if (telemetryOpearationSaubSubsystems[i].IdSubsystem != idSubsystem)
{
var operationTimeItem = new SubsystemOperationTime()
{
IdTelemetry = idTelemetry,
DateStart = dateBegin,
IdSubsystem = telemetryOpearationSaubSubsystems[i - 1].IdSubsystem,
DateEnd = telemetryOpearationSaubSubsystems[i].Date,
DepthStart = depthStart,
DepthEnd = telemetryOpearationSaubSubsystems[i].Depth
};
dateBegin = telemetryOpearationSaubSubsystems[i].Date;
depthStart = telemetryOpearationSaubSubsystems[i].Depth;
idSubsystem = telemetryOpearationSaubSubsystems[i].IdSubsystem;
resultSubsystemOperationTime.Add(operationTimeItem);
}
}
return resultSubsystemOperationTime;
return subsystemOperationTime;
}
private static async Task<IEnumerable<SubsystemOperationTime>?> OperationTimeSpinAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
{
Predicate<int> isSubsystemTorqueState = (int state) => state == 7;
Predicate<short> isSubsystemTorqueMode = (short mode) => (mode & 2) > 0;
Predicate<int> isSubsystemSpin = (int state) => state != 0 & state != 6 & state != 7;
var operationTimeSpinWithDepth =
$"select tspin.\"date\", tspin.\"mode\", tspin.\"state\", tsaub.\"well_depth\"" +
$" from (select \"date\" ,\"mode\" ,lag(mode, 1) over (order by \"date\") as mode_pre, state , " +
$"lag(state, 1) over (order by \"date\") as state_pre from t_telemetry_data_spin where id_telemetry = @idTelemetry and date >= @begin) as tspin " +
$"join (select \"date\", well_depth from t_telemetry_data_saub where id_telemetry = @idTelemetry and date >= @begin) as tsaub " +
$"on EXTRACT(EPOCH from tspin.date) = EXTRACT(EPOCH from tsaub.date) " +
$"where mode!=mode_pre or state != state_pre order by \"date\";";
using var command = db.Database.GetDbConnection().CreateCommand();
command.CommandText = operationTimeSpinWithDepth;
var telemetry = new NpgsqlParameter("@idTelemetry", idTelemetry);
command.Parameters.Add(telemetry);
var dateStart = new NpgsqlParameter("@begin", begin);
command.Parameters.Add(dateStart);
db.Database.OpenConnection();
using var result = await command.ExecuteReaderAsync(token);
var telemetryOpearationSpinSubsystems = new List<SubsystemsSpinWithDepth>();
if (result.HasRows)
static int? GetSubsytemId(short mode, int state)
{
if (state == 7 && (mode & 2) > 0)
return idSubsytemTorqueMaster;
if (state != 0 & state != 6 & state != 7)
return idSubsytemSpinMaster;
return null;
}
var query =
$"select " +
$" tspin.date, " +
$" tspin.mode, " +
$" tspin.state, " +
$" tsaub.well_depth " +
$"from ( " +
$" select " +
$" date, " +
$" mode, " +
$" lag(mode, 1) over (order by date) as mode_pre, " +
$" state, " +
$" lag(state, 1) over (order by date) as state_pre " +
$" from t_telemetry_data_spin " +
$" where id_telemetry = @idTelemetry and date >= @begin" +
$" order by date ) as tspin " +
$"left outer join ( " +
$" select " +
$" date, " +
$" well_depth " +
$" from t_telemetry_data_saub " +
$" where id_telemetry = @idTelemetry and date >= @begin) as tsaub " +
$"on EXTRACT(EPOCH from tspin.date) = EXTRACT(EPOCH from tsaub.date) " +
$"where mode_pre is null or state_pre is null or mode != mode_pre or state != state_pre " +
$"order by date;";
var idTelemetryParam = new NpgsqlParameter("@idTelemetry", idTelemetry);
var beginParam = new NpgsqlParameter("@begin", begin);
await db.Database.OpenConnectionAsync(token);
using var command = db.Database.GetDbConnection().CreateCommand();
command.CommandText = query;
command.Parameters.Add(idTelemetryParam);
command.Parameters.Add(beginParam);
using var result = await command.ExecuteReaderAsync(token);
var subsystemOperationTime = new List<SubsystemOperationTime>(32);
if (result.Read())
{
var mode = result.GetFieldValue<short>(1);
var state = result.GetFieldValue<int>(2);
var idSubsystem = GetSubsytemId(mode, state);
var dateStart = result.GetFieldValue<DateTimeOffset>(0);
var depthStart = result.GetFieldValue<float?>(3);
while (result.Read())
{
var itemEntity = new SubsystemsSpinWithDepth()
var dateEnd = result.GetFieldValue<DateTimeOffset>(0);
var depthEnd = result.GetFieldValue<float?>(3);
if (idSubsystem.HasValue)
{
Date = result.GetFieldValue<DateTimeOffset>(0),
Mode = result.GetFieldValue<short>(1),
State = result.GetFieldValue<int>(2),
Depth = result.GetFieldValue<float>(3)
};
int? subsystemId = isSubsystemTorqueState(itemEntity.State) && isSubsystemTorqueMode(itemEntity.Mode)
? idSubsytemTorqueMaster
: isSubsystemSpin(itemEntity.State)
? idSubsytemSpinMaster
: 0;
if (subsystemId.HasValue)
{
itemEntity.IdSubsystem = subsystemId.Value;
telemetryOpearationSpinSubsystems.Add(itemEntity);
var operationTimeItem = new SubsystemOperationTime()
{
IdTelemetry = idTelemetry,
IdSubsystem = idSubsystem.Value,
DateStart = dateStart,
DateEnd = dateEnd,
DepthStart = depthStart,
DepthEnd = depthEnd
};
subsystemOperationTime.Add(operationTimeItem);
}
mode = result.GetFieldValue<short>(1);
state = result.GetFieldValue<int>(2);
idSubsystem = GetSubsytemId(mode, state);
dateStart = dateEnd;
depthStart = depthEnd;
}
}
var resultSubsystemOperationTime = new List<SubsystemOperationTime>();
var firstItem = telemetryOpearationSpinSubsystems.FirstOrDefault();
if (firstItem is null)
return null;
int idSubsystem = firstItem.IdSubsystem;
DateTimeOffset dateBegin = firstItem.Date;
float? depthStart = firstItem.Depth;
for (int i = 1; i < telemetryOpearationSpinSubsystems.Count; i++)
{
if (telemetryOpearationSpinSubsystems[i].IdSubsystem != idSubsystem)
{
var operationTimeItem = new SubsystemOperationTime()
{
IdTelemetry = idTelemetry,
DateStart = dateBegin,
IdSubsystem = telemetryOpearationSpinSubsystems[i - 1].IdSubsystem,
DateEnd = telemetryOpearationSpinSubsystems[i].Date,
DepthStart = depthStart,
DepthEnd = telemetryOpearationSpinSubsystems[i].Depth
};
dateBegin = telemetryOpearationSpinSubsystems[i].Date;
depthStart = telemetryOpearationSpinSubsystems[i].Depth;
idSubsystem = telemetryOpearationSpinSubsystems[i].IdSubsystem;
if (telemetryOpearationSpinSubsystems[i - 1].IdSubsystem != 0)
{
resultSubsystemOperationTime.Add(operationTimeItem);
}
}
}
return resultSubsystemOperationTime;
return subsystemOperationTime;
}
}
#nullable disable

View File

@ -29,6 +29,8 @@ namespace AsbCloudInfrastructure.Services.Subsystems
this.wellService = wellService;
this.subsystemService = subsystemService;
}
/// <inheritdoc/>
public async Task<int> DeleteAsync(SubsystemOperationTimeRequest request, CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(request.IdWell, token);
@ -41,39 +43,40 @@ namespace AsbCloudInfrastructure.Services.Subsystems
return await db.SaveChangesAsync(token);
}
/// <inheritdoc/>
public async Task<IEnumerable<SubsystemOperationTimeDto>?> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(request.IdWell, token);
if (well?.IdTelemetry is null || well.Timezone is null)
return null;
var query = BuildQuery(request);
if (query is null)
return null;
IEnumerable<SubsystemOperationTime> data = await query.ToListAsync(token);
if (request.SelectMode == SubsystemOperationTimeRequest.SelectModeInner)
{
if (request.GtDate is not null)
query = query.Where(o => o.DateStart >= request.GtDate.Value || o.DateEnd >= request.GtDate.Value);
data = data.Where(o => o.DateStart >= request.GtDate.Value);
if (request.LtDate is not null)
query = query.Where(o => o.DateEnd <= request.LtDate.Value || o.DateStart <= request.LtDate.Value);
data = data.Where(o => o.DateEnd <= request.LtDate.Value);
}
if (request.SelectMode == SubsystemOperationTimeRequest.SelectModeTrim)
{
if (!request.GtDate.HasValue)
throw new ArgumentNullException(nameof(request.GtDate));
var begin = request.GtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours);
if (!request.LtDate.HasValue)
throw new ArgumentNullException(nameof(request.LtDate));
var end = request.LtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours);
IEnumerable<SubsystemOperationTime>? data = query.ToList();
data = Trim(data, begin, end);
if (data is not null)
return data.Select(o => Convert(o, well));
return null;
else if (request.SelectMode == SubsystemOperationTimeRequest.SelectModeTrim)
{
var begin = request.GtDate?.ToUtcDateTimeOffset(well.Timezone.Hours);
var end = request.LtDate?.ToUtcDateTimeOffset(well.Timezone.Hours);
data = Trim(data, begin, end);
}
var dtos = query.Select(o => Convert(o, well));
var dtos = data.Select(o => Convert(o, well));
return dtos;
}
/// <inheritdoc/>
public async Task<IEnumerable<SubsystemStatDto>?> GetStatAsync(SubsystemOperationTimeRequest request, CancellationToken token)
{
request.SelectMode = SubsystemOperationTimeRequest.SelectModeTrim;
@ -83,110 +86,104 @@ namespace AsbCloudInfrastructure.Services.Subsystems
var statList = CalcStat(data, request);
return statList;
}
private IEnumerable<SubsystemOperationTime>? Trim(IEnumerable<SubsystemOperationTime>? data, DateTimeOffset gtDate, DateTimeOffset ltDate)
private static IEnumerable<SubsystemOperationTime> Trim(IEnumerable<SubsystemOperationTime> data, DateTimeOffset? gtDate, DateTimeOffset? ltDate)
{
if (data is null)
return null;
var ItemsNormal = data.Where(q =>
(q.DateStart >= gtDate) && (q.DateEnd <= ltDate)).ToList();
var itemsToTrim = data.Where(q =>
q.DateStart < gtDate || ltDate < q.DateEnd)
.Select(o => new SubsystemOperationTime
var items = data.Select((item) =>
{
if (gtDate.HasValue && item.DateStart < gtDate.Value)
{
Id = o.Id,
DateStart = gtDate < o.DateStart ? o.DateStart : gtDate,
DateEnd = ltDate > o.DateEnd ? o.DateEnd : ltDate,
IdSubsystem = o.IdSubsystem,
IdTelemetry = o.IdTelemetry,
DepthStart = gtDate > o.DateEnd ? o.DepthStart : null,
DepthEnd = ltDate < o.DateStart ? o.DepthEnd : null,
Subsystem = o.Subsystem,
Telemetry = o.Telemetry
})
.ToList();
ItemsNormal.AddRange(itemsToTrim);
return ItemsNormal.OrderBy(o => o.DateStart).ToList();
item.DateStart = gtDate.Value;
item.DepthStart = null;
}
if (ltDate.HasValue && item.DateEnd > ltDate.Value)
{
item.DateEnd = ltDate.Value;
item.DepthEnd = null;
}
return item;
});
return items;
}
private IEnumerable<SubsystemStatDto> CalcStat(IEnumerable<SubsystemOperationTimeDto> listOperationTimeSubsystems, SubsystemOperationTimeRequest request)
private IEnumerable<SubsystemStatDto> CalcStat(IEnumerable<SubsystemOperationTimeDto> dtos, SubsystemOperationTimeRequest request)
{
var result = new List<SubsystemStatDto>();
var groupedDataSubsystems = listOperationTimeSubsystems
.GroupBy(x => x.IdSubsystem);
var periodGroupTotal = groupedDataSubsystems
.Sum(g => g.Sum(o=> (o.DateEnd - o.DateStart).TotalHours));
var gtDate = request.GtDate ?? listOperationTimeSubsystems.Min(d => d.DateStart);
var ltDate = request.LtDate ?? listOperationTimeSubsystems.Max(d => d.DateEnd);
var periodRequest = listOperationTimeSubsystems
.Sum(o => (o.DateEnd - o.DateStart).TotalHours);
foreach (var item in groupedDataSubsystems)
{
var periodGroup = item.Sum(g => (g.DateEnd - g.DateStart).TotalHours);
int idSubsystem = item.First().IdSubsystem;
var groupedDataSubsystems = dtos
.GroupBy(o => o.IdSubsystem);
var periodGroupTotal = dtos.Sum(o => (o.DateEnd - o.DateStart).TotalHours);
var gtDate = request.GtDate ?? dtos.Min(o => o.DateStart);
var ltDate = request.LtDate ?? dtos.Max(o => o.DateEnd);
var periodRequest = (ltDate - gtDate).TotalHours;
var result = groupedDataSubsystems.Select(item =>
{
var periodGroup = item.Sum(o => (o.DateEnd - o.DateStart).TotalHours);
var subsystemStat = new SubsystemStatDto()
{
IdSubsystem = idSubsystem,
SubsystemName = subsystemService.GetOrDefault(idSubsystem)?.Name ?? "unknown",
UsedTimeHours =periodGroup,
KUsage = 1d*periodGroup / periodRequest,
K2 = 1d*periodGroup / periodGroupTotal,
IdSubsystem = item.Key,
SubsystemName = subsystemService.GetOrDefault(item.Key)?.Name ?? "unknown",
UsedTimeHours = periodGroup,
KUsage = 1d * periodGroup / periodRequest,
K2 = 1d * periodGroup / periodGroupTotal,
};
result.Add(subsystemStat);
}
return subsystemStat;
});
return result;
}
private IQueryable<SubsystemOperationTime>? BuildQuery(SubsystemOperationTimeRequest request)
{
if (request.SelectMode > 0 && request.GtDate is null && request.LtDate is null)
return null;
var well = wellService.GetOrDefault(request.IdWell);
if (well?.IdTelemetry is null || well.Timezone is null)
return null;
var query = db.SubsystemOperationTimes
.Include(o => o.Subsystem)
.Where(o => o.IdTelemetry == well.IdTelemetry);
DateTimeOffset gtDateWellTime;
DateTimeOffset ltDateWellTime;
.Include(o => o.Subsystem)
.Where(o => o.IdTelemetry == well.IdTelemetry)
.AsNoTracking();
if (request.IdsSubsystems?.Any() == true)
query = query.Where(o => request.IdsSubsystems.Contains(o.IdSubsystem));
if (request.GtDate is not null && request.LtDate is not null)
// # Dates range condition
// [GtDate LtDate]
// [DateStart DateEnd] [DateStart DateEnd]
if (request.GtDate.HasValue)
{
gtDateWellTime = request.GtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours);
ltDateWellTime = request.LtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours);
//query = query.Where(o => (o.DateStart >= gtDateWellTime)
//|| (o.DateEnd <= ltDateWellTime));
query = query.Where(q =>
(q.DateStart < gtDateWellTime && q.DateEnd <= ltDateWellTime && q.DateEnd > gtDateWellTime) ||
(q.DateStart >= gtDateWellTime && q.DateEnd > ltDateWellTime && q.DateStart < ltDateWellTime) ||
(q.DateStart < gtDateWellTime && q.DateEnd > ltDateWellTime) ||
(q.DateStart >= gtDateWellTime && q.DateEnd <= ltDateWellTime));
}
else if (request.GtDate is not null)
{
gtDateWellTime = request.GtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours);
query = query.Where(o => o.DateStart >= gtDateWellTime);
DateTimeOffset gtDate = request.GtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours);
query = query.Where(o => o.DateEnd >= gtDate);
}
else if (request.LtDate is not null)
if (request.LtDate.HasValue)
{
ltDateWellTime = request.LtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours);
query = query.Where(o => o.DateEnd <= ltDateWellTime);
DateTimeOffset ltDate = request.LtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours);
query = query.Where(o => o.DateStart <= ltDate);
}
if (request.GtDepth is not null)
query = query.Where(o => o.DepthStart >= request.GtDepth.Value);
if (request.LtDepth is not null)
query = query.Where(o => o.DepthEnd <= request.LtDepth.Value);
if (request.GtDepth.HasValue)
query = query.Where(o => o.DepthEnd >= request.GtDepth.Value);
if (request.LtDepth.HasValue)
query = query.Where(o => o.DepthStart <= request.LtDepth.Value);
if (request?.SortFields?.Any() == true)
{
query = query.SortBy(request.SortFields);
}
else
{
query = query
.OrderBy(o => o.DateStart)
.ThenBy(o => o.DepthStart);
}
if (request?.Skip > 0)
query = query.Skip((int)request.Skip);
@ -198,7 +195,8 @@ namespace AsbCloudInfrastructure.Services.Subsystems
return query;
}
private SubsystemOperationTimeDto Convert(SubsystemOperationTime operationTime, WellDto well)
private static SubsystemOperationTimeDto Convert(SubsystemOperationTime operationTime, WellDto well)
{
var dto = operationTime.Adapt<SubsystemOperationTimeDto>();
dto.DateStart = operationTime.DateStart.ToRemoteDateTime(well.Timezone.Hours);

View File

@ -27,21 +27,17 @@ namespace AsbCloudInfrastructure.Services.Subsystems
var well = await wellService.GetOrDefaultAsync(idWell, token);
if (well?.IdTelemetry is null || well.Timezone is null)
return null;
var wellSubsystem = await dbContext.SubsystemOperationTimes
var entities = await dbContext.SubsystemOperationTimes
.Include(e => e.Subsystem)
.AsNoTracking()
.Where(o => o.IdTelemetry == well.IdTelemetry)
.DistinctBy(o => o.IdSubsystem)
.Select(d => Convert( new ()
{
Id = d.Subsystem.Id,
Name = d.Subsystem.Name,
Description = d.Subsystem.Description,
}))
.ToListAsync(token);
return wellSubsystem;
.Select(o => o.Subsystem)
.Distinct()
.ToArrayAsync(token);
var dtos = entities.Select(e => e.Adapt<SubsystemDto>());
return dtos;
}
public async Task<IEnumerable<SubsystemDto>?> GetSubsystemAsync(int? idWell, CancellationToken token)
{
if (idWell.HasValue)
@ -52,11 +48,6 @@ namespace AsbCloudInfrastructure.Services.Subsystems
var subsystem = await GetAllAsync(token);
return subsystem;
}
new private static SubsystemDto Convert(Subsystem subsystem)
{
var dto = subsystem.Adapt<SubsystemDto>();
return dto;
}
}
#nullable disable
}

View File

@ -19,5 +19,5 @@ namespace AsbCloudWebApi.Controllers.Subsystems
{
}
}
}
}

View File

@ -21,13 +21,11 @@ namespace AsbCloudWebApi.Controllers.Subsystems
{
private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
private readonly IWellService wellService;
private readonly ICrudService<SubsystemDto> subsystemServiceCrud;
private readonly ISubsystemService subsystemService;
public SubsystemOperationTimeController(ISubsystemOperationTimeService subsystemOperationTimeService, IWellService wellService, ICrudService<SubsystemDto> subsystemServiceCrud, ISubsystemService subsystemService)
public SubsystemOperationTimeController(ISubsystemOperationTimeService subsystemOperationTimeService, IWellService wellService, ISubsystemService subsystemService)
{
this.subsystemOperationTimeService = subsystemOperationTimeService;
this.wellService = wellService;
this.subsystemServiceCrud = subsystemServiceCrud;
this.subsystemService = subsystemService;
}
/// <summary>
@ -53,8 +51,8 @@ namespace AsbCloudWebApi.Controllers.Subsystems
if (idWell.HasValue)
if (!await UserHasAccesToWellAsync(idWell.Value, token))
return Forbid();
var result = await subsystemService.GetSubsystemAsync(idWell, token);
return Ok(result);
var result = await subsystemService.GetSubsystemAsync(idWell, token);
return Ok(result);
}
/// <summary>