forked from ddrilling/AsbCloudServer
146 lines
5.6 KiB
C#
146 lines
5.6 KiB
C#
using AsbCloudDb.Model;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System;
|
|
using System.Data.Common;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Collections.Generic;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
namespace AsbCloudInfrastructure.Background.PeriodicWorks;
|
|
|
|
public class WorkLimitingParameterCalc : Work
|
|
{
|
|
public WorkLimitingParameterCalc()
|
|
: base("Limiting parameter calc")
|
|
{
|
|
Timeout = TimeSpan.FromMinutes(30);
|
|
}
|
|
|
|
protected override async Task Action(string id, IServiceProvider services, Action<string, double?> onProgressCallback, CancellationToken token)
|
|
{
|
|
using var db = services.GetRequiredService<IAsbCloudDbContext>();
|
|
db.Database.SetCommandTimeout(TimeSpan.FromMinutes(5));
|
|
var lastDetectedDates = await db.LimitingParameter
|
|
.GroupBy(o => o.IdTelemetry)
|
|
.Select(g => new
|
|
{
|
|
IdTelemetry = g.Key,
|
|
LastDate = g.Max(o => o.DateEnd)
|
|
})
|
|
.ToListAsync(token);
|
|
|
|
var telemetryIds = await db.Telemetries
|
|
.Where(t => t.Info != null && t.TimeZone != null)
|
|
.Select(t => t.Id)
|
|
.ToListAsync(token);
|
|
|
|
var telemetryLastDetectedDates = telemetryIds
|
|
.GroupJoin(lastDetectedDates,
|
|
t => t,
|
|
o => o.IdTelemetry,
|
|
(outer, inner) => new
|
|
{
|
|
IdTelemetry = outer,
|
|
inner.SingleOrDefault()?.LastDate,
|
|
});
|
|
|
|
var count = telemetryLastDetectedDates.Count();
|
|
var i = 0d;
|
|
foreach (var item in telemetryLastDetectedDates)
|
|
{
|
|
onProgressCallback($"Start hanling telemetry: {item.IdTelemetry} from {item.LastDate}", i++ / count);
|
|
var newLimitingParameters = await GetLimitingParameterAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
|
|
if (newLimitingParameters?.Any() == true)
|
|
{
|
|
db.LimitingParameter.AddRange(newLimitingParameters);
|
|
await db.SaveChangesAsync(token);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static async Task<IEnumerable<LimitingParameter>> GetLimitingParameterAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
|
|
{
|
|
var query =
|
|
$"select " +
|
|
$"limiting_parameters.date, limiting_parameters.id_feed_regulator, limiting_parameters.well_depth " +
|
|
$"from ( " +
|
|
$"select " +
|
|
$"date, id_feed_regulator, well_depth, " +
|
|
$"lag(id_feed_regulator, 1) over (order by date) as id_feed_regulator_lag, " +
|
|
$"lead(id_feed_regulator, 1) over (order by date) as id_feed_regulator_lead " +
|
|
$"from t_telemetry_data_saub " +
|
|
$"where id_feed_regulator is not null " +
|
|
$"and id_telemetry = {idTelemetry} " +
|
|
$"and date >= '{begin:u}' " +
|
|
$"order by date) as limiting_parameters " +
|
|
$"where id_feed_regulator_lag is null " +
|
|
$"or (id_feed_regulator != id_feed_regulator_lag and id_feed_regulator_lead != id_feed_regulator_lag) " +
|
|
$"order by date;";
|
|
|
|
var limitingParameters = new List<LimitingParameter>(32);
|
|
using (var result = await ExecuteReaderAsync(db, query, token))
|
|
{
|
|
LimitingParameter? limitingLast = null;
|
|
while (result.Read())
|
|
{
|
|
var date = result.GetFieldValue<DateTimeOffset>(0);
|
|
var idLimiting = result.GetFieldValue<short>(1);
|
|
var wellDepth = result.GetFieldValue<float>(2);
|
|
|
|
if (limitingLast is null)
|
|
{
|
|
limitingLast = new LimitingParameter
|
|
{
|
|
DateStart = date,
|
|
DepthStart = wellDepth,
|
|
IdFeedRegulator = idLimiting
|
|
};
|
|
}
|
|
|
|
if (limitingLast.IdFeedRegulator != idLimiting || limitingLast.DepthStart < wellDepth)
|
|
{
|
|
limitingParameters.Add(new LimitingParameter
|
|
{
|
|
IdTelemetry = idTelemetry,
|
|
IdFeedRegulator = limitingLast.IdFeedRegulator,
|
|
DateStart = limitingLast.DateStart,
|
|
DateEnd = date,
|
|
DepthStart = limitingLast.DepthStart,
|
|
DepthEnd = wellDepth
|
|
});
|
|
|
|
limitingLast = new LimitingParameter
|
|
{
|
|
DateStart = date,
|
|
DepthStart = wellDepth,
|
|
IdFeedRegulator = idLimiting
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
return limitingParameters;
|
|
}
|
|
|
|
private static async Task<DbDataReader> ExecuteReaderAsync(IAsbCloudDbContext db, string query, CancellationToken token)
|
|
{
|
|
var connection = db.Database.GetDbConnection();
|
|
if (
|
|
connection?.State is null ||
|
|
connection.State == ConnectionState.Broken ||
|
|
connection.State == ConnectionState.Closed)
|
|
{
|
|
await db.Database.OpenConnectionAsync(token);
|
|
connection = db.Database.GetDbConnection();
|
|
}
|
|
using var command = connection.CreateCommand();
|
|
command.CommandText = query;
|
|
|
|
var result = await command.ExecuteReaderAsync(token);
|
|
return result;
|
|
}
|
|
}
|