forked from ddrilling/AsbCloudServer
Add Db store for detected operations.
Add backgroudService for periodically detect.
This commit is contained in:
parent
4a91a29f07
commit
45fb5ab8e8
5844
AsbCloudDb/Migrations/20220425110530_Add_DetectedOperations.Designer.cs
generated
Normal file
5844
AsbCloudDb/Migrations/20220425110530_Add_DetectedOperations.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Add_DetectedOperations : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "t_detected_operation",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
id_telemetry = table.Column<int>(type: "integer", nullable: false),
|
||||
id_category = table.Column<int>(type: "integer", nullable: false, comment: "Id категории операции"),
|
||||
id_user = table.Column<int>(type: "integer", nullable: false, comment: "Id пользователя по телеметрии на момент начала операции"),
|
||||
date_start = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата начала операции"),
|
||||
date_end = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата начала операции"),
|
||||
depth_start = table.Column<double>(type: "double precision", nullable: false, comment: "Глубина на начало операции, м"),
|
||||
depth_end = table.Column<double>(type: "double precision", nullable: false, comment: "Глубина после завершения операции, м")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_t_detected_operation", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_detected_operation_t_telemetry_id_telemetry",
|
||||
column: x => x.id_telemetry,
|
||||
principalTable: "t_telemetry",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_detected_operation_t_well_operation_category_id_category",
|
||||
column: x => x.id_category,
|
||||
principalTable: "t_well_operation_category",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
},
|
||||
comment: "автоматически определенные операции по телеметрии");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_detected_operation_id_category",
|
||||
table: "t_detected_operation",
|
||||
column: "id_category");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_detected_operation_id_telemetry",
|
||||
table: "t_detected_operation",
|
||||
column: "id_telemetry");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "t_detected_operation");
|
||||
}
|
||||
}
|
||||
}
|
@ -171,6 +171,60 @@ namespace AsbCloudDb.Migrations
|
||||
b.HasComment("Месторождение");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DetectedOperation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTimeOffset>("DateEnd")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date_end")
|
||||
.HasComment("Дата начала операции");
|
||||
|
||||
b.Property<DateTimeOffset>("DateStart")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date_start")
|
||||
.HasComment("Дата начала операции");
|
||||
|
||||
b.Property<double>("DepthEnd")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("depth_end")
|
||||
.HasComment("Глубина после завершения операции, м");
|
||||
|
||||
b.Property<double>("DepthStart")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("depth_start")
|
||||
.HasComment("Глубина на начало операции, м");
|
||||
|
||||
b.Property<int>("IdCategory")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_category")
|
||||
.HasComment("Id категории операции");
|
||||
|
||||
b.Property<int>("IdTelemetry")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_telemetry");
|
||||
|
||||
b.Property<int>("IdUsersAtStart")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_user")
|
||||
.HasComment("Id пользователя по телеметрии на момент начала операции");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdCategory");
|
||||
|
||||
b.HasIndex("IdTelemetry");
|
||||
|
||||
b.ToTable("t_detected_operation");
|
||||
|
||||
b.HasComment("автоматически определенные операции по телеметрии");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DrillFlowChart", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -5142,6 +5196,25 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("CompanyType");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DetectedOperation", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdCategory")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdTelemetry")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("OperationCategory");
|
||||
|
||||
b.Navigation("Telemetry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DrillFlowChart", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
|
@ -12,6 +12,7 @@ namespace AsbCloudDb.Model
|
||||
public virtual DbSet<Company> Companies { get; set; }
|
||||
public virtual DbSet<CompanyType> CompaniesTypes { get; set; }
|
||||
public virtual DbSet<Deposit> Deposits { get; set; }
|
||||
public virtual DbSet<DetectedOperation> DetectedOperations { get; set; }
|
||||
public virtual DbSet<DrillingProgramPart> DrillingProgramParts { get; set; }
|
||||
public virtual DbSet<FileCategory> FileCategories { get; set; }
|
||||
public virtual DbSet<FileInfo> Files { get; set; }
|
||||
|
52
AsbCloudDb/Model/DetectedOperation.cs
Normal file
52
AsbCloudDb/Model/DetectedOperation.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
[Table("t_detected_operation"), Comment("автоматически определенные операции по телеметрии")]
|
||||
public class DetectedOperation
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("id_telemetry")]
|
||||
public int IdTelemetry { get; set; }
|
||||
|
||||
[Column("id_category"), Comment("Id категории операции")]
|
||||
public int IdCategory { get; set; }
|
||||
|
||||
[Column("id_user"), Comment("Id пользователя по телеметрии на момент начала операции")]
|
||||
public int IdUsersAtStart { get; set; }
|
||||
|
||||
[Column("date_start", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
|
||||
[Column("date_end", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
|
||||
public DateTimeOffset DateEnd { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
|
||||
|
||||
[Column("depth_start"), Comment("Глубина на начало операции, м")]
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
[Column("depth_end"), Comment("Глубина после завершения операции, м")]
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[ForeignKey(nameof(IdTelemetry))]
|
||||
public virtual Telemetry Telemetry { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[ForeignKey(nameof(IdCategory))]
|
||||
public virtual WellOperationCategory OperationCategory { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
=> $"{IdCategory}\t{DateStart:G}\t{DateEnd:G}\t{DurationMinutes:#0.#}\t{DepthStart:#0.#}\t{DepthEnd:#0.#}";
|
||||
//=> $"{{\"type\": {IdType},\t\"begin\":\"{Begin:G}\",\t\"end\":\"{End:G}\",\t\"depthBegin\":\"{BeginWellDepth:#0.#}\",\t\"depthEnd\":\"{EndWellDepth:#0.#}\"}}";
|
||||
}
|
||||
}
|
@ -42,6 +42,7 @@ namespace AsbCloudDb.Model
|
||||
DbSet<DrillingProgramPart> DrillingProgramParts { get; set; }
|
||||
DbSet<RelationUserDrillingProgramPart> RelationDrillingProgramPartUsers { get; set; }
|
||||
DbSet<RelationCompanyWell> RelationCompaniesWells { get; set; }
|
||||
DbSet<DetectedOperation> DetectedOperations { get; set; }
|
||||
|
||||
int SaveChanges();
|
||||
int SaveChanges(bool acceptAllChangesOnSuccess);
|
||||
|
@ -1,19 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.DetectOperations
|
||||
{
|
||||
public class DetectedOperation
|
||||
{
|
||||
public int IdCategory { get; set; }
|
||||
public int IdUsersAtStart { get; set; }
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
public DateTimeOffset DateEnd { get; set; }
|
||||
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
|
||||
public double DepthStart { get; set; }
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
=> $"{IdCategory}\t{DateStart:G}\t{DateEnd:G}\t{DurationMinutes:#0.#}\t{DepthStart:#0.#}\t{DepthEnd:#0.#}";
|
||||
//=> $"{{\"type\": {IdType},\t\"begin\":\"{Begin:G}\",\t\"end\":\"{End:G}\",\t\"depthBegin\":\"{BeginWellDepth:#0.#}\",\t\"depthEnd\":\"{EndWellDepth:#0.#}\"}}";
|
||||
}
|
||||
}
|
@ -51,7 +51,8 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
|
||||
try
|
||||
{
|
||||
using var context = new AsbCloudDbContext(options);
|
||||
|
||||
var added = await DetectedAllTelemetriesAsync(context, token);
|
||||
Trace.TraceInformation($"Total detection complete. Added {added} operations.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -72,21 +73,42 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
|
||||
await base.StopAsync(token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<DateTime> GetLastAnalysisDateAsync(int idTelemetry, IAsbCloudDbContext db, CancellationToken token)
|
||||
private async Task<int> DetectedAllTelemetriesAsync(IAsbCloudDbContext db, CancellationToken token)
|
||||
{
|
||||
var lastAnalysisInDb = await (from analysis in db.TelemetryAnalysis
|
||||
where analysis.IdTelemetry == idTelemetry
|
||||
orderby analysis.UnixDate
|
||||
select analysis)
|
||||
.LastOrDefaultAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
var lastDetectedDatesQuery = db.DetectedOperations
|
||||
.GroupBy(o => o.IdTelemetry)
|
||||
.Select(g => new
|
||||
{
|
||||
IdTelemetry = g.Key,
|
||||
LastDate = g.Max(o => o.DateEnd)
|
||||
});
|
||||
|
||||
DateTime lastAnalysisDate = new DateTime(0, DateTimeKind.Utc);
|
||||
var lastDetectedDates = await db.Telemetries
|
||||
.Join(lastDetectedDatesQuery,
|
||||
t => t.Id,
|
||||
o => o.IdTelemetry,
|
||||
(outer, inner) => new
|
||||
{
|
||||
IdTelemetry = outer.Id,
|
||||
inner.LastDate
|
||||
})
|
||||
.ToListAsync(token);
|
||||
|
||||
if (lastAnalysisInDb is not null)
|
||||
lastAnalysisDate = DateTime.UnixEpoch.AddSeconds(lastAnalysisInDb.DurationSec + lastAnalysisInDb.UnixDate);
|
||||
bool isAnyAdded = false;
|
||||
|
||||
return lastAnalysisDate;
|
||||
foreach (var item in lastDetectedDates)
|
||||
{
|
||||
var newOperations = await DetectOperationsAsync(item.IdTelemetry, item.LastDate, db, token);
|
||||
if (newOperations.Any())
|
||||
{
|
||||
db.DetectedOperations.AddRange(newOperations);
|
||||
isAnyAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
return isAnyAdded
|
||||
? await db.SaveChangesAsync(token)
|
||||
: 0;
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<DetectedOperation>> DetectOperationsAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
|
Loading…
Reference in New Issue
Block a user