доработка фонового сервиса

This commit is contained in:
eugeniy_ivanov 2022-08-16 02:22:16 +05:00
parent 20f79f461f
commit 4f37564a7b
3 changed files with 85 additions and 103 deletions

View File

@ -1,28 +1,25 @@
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudDb.Model.Subsystems; using AsbCloudDb.Model.Subsystems;
using AsbCloudInfrastructure.Services.DetectOperations;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Data.Common;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.Subsystems namespace AsbCloudInfrastructure.Services.Subsystems
{ {
#nullable enable
internal class SubsystemOperationTimeBackgroundService : BackgroundService internal class SubsystemOperationTimeBackgroundService : BackgroundService
{ {
private readonly string connectionString; private readonly string connectionString;
private readonly TimeSpan period = TimeSpan.FromHours(1); private readonly TimeSpan period = TimeSpan.FromHours(1);
private const int idSubsytemTorqueMaster = 65537; private const int idSubsytemTorqueMaster = 65537;
private const int idSubsytemSpinMaster = 65536; private const int idSubsytemSpinMaster = 65536;
public SubsystemOperationTimeBackgroundService(IConfiguration configuration) public SubsystemOperationTimeBackgroundService(IConfiguration configuration)
{ {
connectionString = configuration.GetConnectionString("DefaultConnection"); connectionString = configuration.GetConnectionString("DefaultConnection");
@ -33,7 +30,6 @@ namespace AsbCloudInfrastructure.Services.Subsystems
var options = new DbContextOptionsBuilder<AsbCloudDbContext>() var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql(connectionString) .UseNpgsql(connectionString)
.Options; .Options;
while (!token.IsCancellationRequested) while (!token.IsCancellationRequested)
{ {
if (DateTime.Now > timeToStartAnalysis) if (DateTime.Now > timeToStartAnalysis)
@ -90,16 +86,14 @@ namespace AsbCloudInfrastructure.Services.Subsystems
var affected = 0; var affected = 0;
foreach (var item in JounedlastDetectedDates) foreach (var item in JounedlastDetectedDates)
{ {
var stopwatch = Stopwatch.StartNew(); var newOperationsSaub = await OperationTimeSaubAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
var newOperationsSaub = await OperationTimeSaubAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token); if (newOperationsSaub?.Any() == true)
stopwatch.Stop();
if (newOperationsSaub is not null && newOperationsSaub.Any())
{ {
db.SubsystemOperationTimes.AddRange(newOperationsSaub); db.SubsystemOperationTimes.AddRange(newOperationsSaub);
affected += await db.SaveChangesAsync(token); affected += await db.SaveChangesAsync(token);
} }
var newOperationsSpin = await OperationTimeSpinAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token); var newOperationsSpin = await OperationTimeSpinAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
if (newOperationsSpin is not null && newOperationsSpin.Any()) if (newOperationsSpin?.Any() == true)
{ {
db.SubsystemOperationTimes.AddRange(newOperationsSpin); db.SubsystemOperationTimes.AddRange(newOperationsSpin);
affected += await db.SaveChangesAsync(token); affected += await db.SaveChangesAsync(token);
@ -108,7 +102,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
return affected; return affected;
} }
private static async Task<IEnumerable<SubsystemOperationTime>> OperationTimeSaubAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token) private static async Task<IEnumerable<SubsystemOperationTime>?> OperationTimeSaubAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
{ {
var query = db.TelemetryDataSaub var query = db.TelemetryDataSaub
.AsNoTracking() .AsNoTracking()
@ -122,40 +116,48 @@ namespace AsbCloudInfrastructure.Services.Subsystems
.OrderBy(d => d.DateTime); .OrderBy(d => d.DateTime);
var take = 4 * 86_400; // 4 дня var take = 4 * 86_400; // 4 дня
var startDate = begin; var startDate = begin;
var firstItem = query.FirstOrDefault();
if (firstItem is null) var resultSubsystemOperationTime = new List<SubsystemOperationTime>();
return null; while (true)
short? mode = firstItem.Mode; {
DateTimeOffset dateBegin = firstItem.DateTime; var data = await query
float? depthStart = firstItem.Depth;
var resultSubsystemOperationTime = new List<SubsystemOperationTime>();
var data = await query
.Where(d => d.DateTime > startDate) .Where(d => d.DateTime > startDate)
.Take(take) .Take(take)
.ToArrayAsync(token); .ToArrayAsync(token);
for (int i = 1; i < data.Length; i++) var firstItem = data.FirstOrDefault();
{ if (firstItem is null)
break;
short? mode = firstItem.Mode;
DateTimeOffset dateBegin = firstItem.DateTime;
float? depthStart = firstItem.Depth;
for (int i = 1; i < data.Length; i++)
{
if (data[i].Mode != mode) if (data[i].Mode != mode)
{ {
var operationTimeItem = new SubsystemOperationTime() var operationTimeItem = new SubsystemOperationTime()
{ {
IdTelemetry = idTelemetry, IdTelemetry = idTelemetry,
DateStart = dateBegin, DateStart = dateBegin,
IdSubsystem = (int)data[i - 1].Mode + 1,
DateEnd = data[i - 1].DateTime, DateEnd = data[i - 1].DateTime,
DepthStart = depthStart, DepthStart = depthStart,
DepthEnd = data[i - 1].Depth DepthEnd = data[i - 1].Depth
}; };
resultSubsystemOperationTime.Add(operationTimeItem); if (mode.HasValue)
{
operationTimeItem.IdSubsystem = (int)mode + 1;
resultSubsystemOperationTime.Add(operationTimeItem);
}
mode = data[i].Mode; mode = data[i].Mode;
dateBegin = data[i].DateTime; dateBegin = data[i].DateTime;
depthStart = data[i].Depth; depthStart = data[i].Depth;
} }
} }
startDate = data.Last().DateTime; startDate = data.Last().DateTime;
}
return resultSubsystemOperationTime; return resultSubsystemOperationTime;
} }
private static async Task<IEnumerable<SubsystemOperationTime>> OperationTimeSpinAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token) private static async Task<IEnumerable<SubsystemOperationTime>?> OperationTimeSpinAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
{ {
Predicate<int> isSubsystemTorqueState = (int state) => state == 7; Predicate<int> isSubsystemTorqueState = (int state) => state == 7;
Predicate<short> isSubsystemTorqueMode = (short mode) => (mode & 2) > 0; Predicate<short> isSubsystemTorqueMode = (short mode) => (mode & 2) > 0;
@ -163,29 +165,20 @@ namespace AsbCloudInfrastructure.Services.Subsystems
var operationTimeSpinWithDepth = var operationTimeSpinWithDepth =
$"select tspin.\"date\", tspin.\"mode\", tspin.\"state\", tsaub.\"well_depth\"" + $"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 , " + $" 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}) as tspin " + $"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}) as tsaub " + $"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) " + $"on EXTRACT(EPOCH from tspin.date) = EXTRACT(EPOCH from tsaub.date) " +
$"where mode!=mode_pre or state != state_pre order by \"date\";"; $"where mode!=mode_pre or state != state_pre order by \"date\";";
using var command = db.Database.GetDbConnection().CreateCommand(); using var command = db.Database.GetDbConnection().CreateCommand();
command.CommandText = operationTimeSpinWithDepth; command.CommandText = operationTimeSpinWithDepth;
db.Database.OpenConnection(); db.Database.OpenConnection();
using var result = command.ExecuteReader(); using var result = await command.ExecuteReaderAsync(token);
var query = new List<SubsystemsSpinWithDepthDto>(); var telemetryOpearationSpinSubsystems = new List<SubsystemsSpinWithDepth>();
//DataTable dt = new DataTable();
//dt.Load(result);
//var query = from c in dt.AsEnumerable()
// select new
// {
// Date = (DateTimeOffset)c["date"],
// Mode = (short)c["mode"],
// State = (int)c["state"],
// Depth = (float)c["float"]
// };
if (result.HasRows) if (result.HasRows)
{
while (result.Read()) while (result.Read())
{ {
var itemEntity = new SubsystemsSpinWithDepthDto() var itemEntity = new SubsystemsSpinWithDepth()
{ {
Date = result.GetFieldValue<DateTimeOffset>(0), Date = result.GetFieldValue<DateTimeOffset>(0),
Mode = result.GetFieldValue<short>(1), Mode = result.GetFieldValue<short>(1),
@ -200,50 +193,52 @@ namespace AsbCloudInfrastructure.Services.Subsystems
if (subsystemId.HasValue) if (subsystemId.HasValue)
{ {
itemEntity.IdSubsystem = subsystemId.Value; itemEntity.IdSubsystem = subsystemId.Value;
query.Add(itemEntity); telemetryOpearationSpinSubsystems.Add(itemEntity);
} }
} }
}
var take = 4 * 86_400; // 4 дня var take = 4 * 86_400; // 4 дня
var startDate = begin; var startDate = begin;
var firstItem = query.FirstOrDefault(); var resultSubsystemOperationTime = new List<SubsystemOperationTime>();
if (firstItem is null) while (true)
return null;
int idSubsystem = firstItem.IdSubsystem;
DateTimeOffset dateBegin = firstItem.Date;
float? depthStart = firstItem.Depth;
var resultSubsystemOperationTime = new List<SubsystemOperationTime>();
var data = query
.Where(d => d.Date > startDate)
.Take(take)
.ToArray();
if (data.Length==0)
return null;
for (int i = 1; i < data.Length; i++)
{ {
if (data[i].IdSubsystem != idSubsystem) var data = telemetryOpearationSpinSubsystems
.Where(d => d.Date > startDate)
.Take(take)
.ToArray();
var firstItem = data.FirstOrDefault();
if (firstItem is null)
break;
int idSubsystem = firstItem.IdSubsystem;
DateTimeOffset dateBegin = firstItem.Date;
float? depthStart = firstItem.Depth;
for (int i = 1; i < data.Length; i++)
{ {
var operationTimeItem = new SubsystemOperationTime() if (data[i].IdSubsystem != idSubsystem)
{ {
IdTelemetry = idTelemetry, var operationTimeItem = new SubsystemOperationTime()
DateStart = dateBegin, {
IdSubsystem = data[i - 1].IdSubsystem, IdTelemetry = idTelemetry,
DateEnd = data[i - 1].Date, DateStart = dateBegin,
DepthStart = depthStart, IdSubsystem = data[i - 1].IdSubsystem,
DepthEnd = data[i - 1].Depth DateEnd = data[i].Date,
DepthStart = depthStart,
DepthEnd = data[i].Depth
}; };
dateBegin = data[i].Date; dateBegin = data[i].Date;
depthStart = data[i].Depth; depthStart = data[i].Depth;
idSubsystem = data[i].IdSubsystem; idSubsystem = data[i].IdSubsystem;
if (data[i-1].IdSubsystem != 0) if (data[i - 1].IdSubsystem != 0)
{ {
resultSubsystemOperationTime.Add(operationTimeItem); resultSubsystemOperationTime.Add(operationTimeItem);
} }
} }
} }
startDate = data.LastOrDefault().Date; startDate = data.LastOrDefault().Date;
}
return resultSubsystemOperationTime; return resultSubsystemOperationTime;
} }
} }
#nullable disable
} }

View File

@ -48,8 +48,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems
return null; return null;
var query = BuildQuery(request); var query = BuildQuery(request);
if (query is null) if (query is null)
return null; return null;
var data = await query.ToListAsync(token);
if (request.SelectMode == SubsystemOperationTimeRequest.SelectModeInner) if (request.SelectMode == SubsystemOperationTimeRequest.SelectModeInner)
{ {
if (request.GtDate is not null) if (request.GtDate is not null)
@ -62,13 +61,16 @@ namespace AsbCloudInfrastructure.Services.Subsystems
{ {
var begin = request.GtDate ?? throw new ArgumentNullException(nameof(request.GtDate)); var begin = request.GtDate ?? throw new ArgumentNullException(nameof(request.GtDate));
var end = request.GtDate ?? throw new ArgumentNullException(nameof(request.LtDate)); var end = request.GtDate ?? throw new ArgumentNullException(nameof(request.LtDate));
data = Trim(data, begin,end ); var data = query.ToList();
data = Trim(data, begin, end);
return data.Select(o => Convert(o, well));
} }
var dtos = data.Select(o => Convert(o,well)); var dtos = query.Select(o => Convert(o,well));
return dtos; return dtos;
} }
public async Task<IEnumerable<SubsystemStatDto>?> GetStatAsync(SubsystemOperationTimeRequest request, CancellationToken token) public async Task<IEnumerable<SubsystemStatDto>?> GetStatAsync(SubsystemOperationTimeRequest request, CancellationToken token)
{ {
request.SelectMode = SubsystemOperationTimeRequest.SelectModeTrim;
var data = await GetOperationTimeAsync(request, token); var data = await GetOperationTimeAsync(request, token);
if (data is null) if (data is null)
return null; return null;

View File

@ -4,27 +4,12 @@ namespace AsbCloudDb.Model.Subsystems
/// <summary> /// <summary>
/// Результат запроса в t_telemetry_data_spin, используется фоновым сервисом анализирующим наработки подсистем /// Результат запроса в t_telemetry_data_spin, используется фоновым сервисом анализирующим наработки подсистем
/// </summary> /// </summary>
public class SubsystemsSpinWithDepthDto internal class SubsystemsSpinWithDepth
{ {
/// <summary>
/// Режим работы
/// </summary>
public short Mode { get; set; } public short Mode { get; set; }
/// <summary>
/// Состояние
/// </summary>
public int State { get; set; } public int State { get; set; }
/// <summary>
/// Дата
/// </summary>
public DateTimeOffset Date { get; set; } public DateTimeOffset Date { get; set; }
/// <summary>
/// Глубина забоя
/// </summary>
public float Depth { get; set; } public float Depth { get; set; }
/// <summary>
/// ИД
/// </summary>
public int IdSubsystem { get; set; } public int IdSubsystem { get; set; }
} }
} }