using AsbCloudDb.Model; namespace AsbCloudInfrastructure.Services.DetectOperations { #nullable enable abstract class DetectorAbstract { public int StepLength { get; set; } = 3; public int FragmentLength { get; set; } = 6; public int IdCategory { get; } // TODO: assert MaxDurationSeconds and MinDurationSeconds public double MaxDurationSeconds { get; } = 31 * 24 * 60 * 60; public double MinDurationSeconds { get; } = 3; /// /// Конструктор детектора. /// Словарь с IdCategory в дефолтных данных AsbCloudDbContext для таблицы WellOperationCategory /// /// ключ названия/описания операции из таблицы WellOperationCategory public DetectorAbstract(int IdCategory) { this.IdCategory = IdCategory; } public virtual DetectedOperation? DetectOrDefault(DetectableTelemetry[] telemetry, ref int position) { if ((telemetry.Length > position + FragmentLength + StepLength) && DetectStart(telemetry, position)) { var skip = position + StepLength; while (telemetry.Length > skip + FragmentLength) { if (DetectEnd(telemetry, skip)) { var dateStart = telemetry[position].DateTime; var dateEnd = telemetry[skip].DateTime; var durationSec = (dateEnd - dateStart).TotalSeconds; if (durationSec < MinDurationSeconds || durationSec > MaxDurationSeconds) return null; var result = new DetectedOperation { IdCategory = IdCategory, IdUsersAtStart = telemetry[position].IdUser ?? -1, DateStart = dateStart, DateEnd = dateEnd, DepthStart = telemetry[position].WellDepth ?? -1d, DepthEnd = telemetry[skip].WellDepth ?? -1d, }; position = skip + FragmentLength; return result; } skip = skip + StepLength; } } return null; } protected abstract bool DetectStart(DetectableTelemetry[] telemetry, int position); protected abstract bool DetectEnd(DetectableTelemetry[] telemetry, int position); } #nullable disable }