namespace Common.Hardware.WaterMeter.eRegister { using Common.Hardware.SIRT; using Common.Hardware.SIRT.Parameters; using Common.Hardware.WaterMeter.eRegister.Models; using System; using System.Collections.Generic; using System.Linq; using System.Threading; public class Eregister { private readonly EregisterFeatures features; private readonly Action enqueueTask; private readonly Queue runningTasks; private readonly Queue completedTasks; public Eregister(EregisterFeatures features, Action enqueueTask) { this.features = features; this.enqueueTask = enqueueTask; this.runningTasks = new Queue(); this.completedTasks = new Queue(); } public uint Address => this.features?.RequestAddress ?? 4291189262; public void Clear() { this.runningTasks.Clear(); this.completedTasks.Clear(); } internal IEnumerable LoadCustomTasks(EregisterProgrammingParameters parameters) { this.LoadProgrammingParameters(); return this.runningTasks.AsEnumerable(); } internal IEnumerable LoadInspectionFinalizationTasks(EregisterProgrammingParameters parameters) { this.LoadProgrammingParameters(); this.runningTasks.Enqueue(new EregisterCheckFinalizationTask(parameters, this.features.Frequency) { SlotNr = this.features.SlotNr, PoNr = this.features.PoNr, SerialNr = this.features.SerialNr, P1 = new P811 { DelPamSemi = true, }, RequestAddress = this.features.RequestAddress, ResponseAddress = this.features.ResponseAddress, EncryptionKey = this.features.EncryptionKey }); return this.runningTasks.AsEnumerable(); } internal IEnumerable LoadInspectionInitializationTasks(EregisterProgrammingParameters parameters) { this.LoadProgrammingParameters(); this.runningTasks.Enqueue(new EregisterCheckInitializationTask(parameters, this.features.Frequency) { SlotNr = this.features.SlotNr, PoNr = this.features.PoNr, SerialNr = this.features.SerialNr, P1 = new P811 { DelPamSemi = true, }, RequestAddress = this.features.RequestAddress, ResponseAddress = this.features.ResponseAddress, EncryptionKey = this.features.EncryptionKey }); return this.runningTasks.AsEnumerable(); } internal void StartProgramming() { var manualResetEventSlim = new ManualResetEventSlim(); void Completed(SIRTTask _task) { if (_task is EregisterTask task) { task.Completed -= Completed; task.Cancelled -= Cancelled; } if (this.runningTasks.Count > 0) { task = this.runningTasks.Dequeue(); this.completedTasks.Enqueue(task); if (this.runningTasks.Count == 0) { manualResetEventSlim.Set(); } } } void Cancelled(SIRTTask _task) { if (_task is EregisterTask task) { task.Completed -= Completed; task.Cancelled -= Cancelled; } manualResetEventSlim.Set(); } foreach (var task in this.runningTasks.AsEnumerable()) { task.Completed += Completed; task.Cancelled += Cancelled; this.enqueueTask(task); } manualResetEventSlim.Wait(); manualResetEventSlim.Reset(); } private void LoadProgrammingParameters() { this.runningTasks.Clear(); var frequency = this.features.Frequency; this.runningTasks.Enqueue(new EregisterCheckStateTask(frequency) { SlotNr = this.features.SlotNr, PoNr = this.features.PoNr, SerialNr = this.features.SerialNr, P1 = new P811 { DelPamSemi = true, WakeUpCmd = true, }, RequestAddress = this.features.RequestAddress, ResponseAddress = this.features.ResponseAddress, EncryptionKey = this.features.EncryptionKey }); foreach (var pam in this.features.BuildPamsFull()) { this.runningTasks.Enqueue(new EregisterTask(frequency) { SlotNr = this.features.SlotNr, PoNr = this.features.PoNr, SerialNr = this.features.SerialNr, Name = pam.Key, P1 = new P811 { DelPamSemi = true, }, RequestAddress = this.features.RequestAddress, ResponseAddress = this.features.ResponseAddress, Data = pam.Value, EncryptionKey = this.features.EncryptionKey }); } } } }