laatzen/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Eregister.cs
2026-03-10 11:16:20 +01:00

309 lines
13 KiB
C#

namespace Common.Hardware.WaterMeter.eRegister
{
using Common.Hardware.SIRT;
using Common.Hardware.SIRT.Tasks;
using Common.Hardware.WaterMeter.eRegister.Features;
using Common.Hardware.WaterMeter.eRegister.Models;
using Common.Hardware.WaterMeter.eRegister.Telegrams;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
public class Eregister
{
const string SENSUS_STANDARD = "E6C88800DEB868C0D6A84880CE982840";
private readonly ICollection<EregisterTask> runningTasks;
private readonly EregisterProgrammingParameters parameters;
private readonly EregisterHistory history;
private readonly EregisterState state;
private readonly SIRTHub sirtHub;
private string executionType;
public uint Adresse { get; set; }
public uint TempAdresse { get; set; }
public Eregister(EregisterProgrammingParameters parameters, SIRTHub sirtHub)
{
this.parameters = parameters;
this.sirtHub = sirtHub;
this.state = new EregisterState();
this.history = new EregisterHistory();
this.runningTasks = new List<EregisterTask>();
}
public void Clear() => this.runningTasks.Clear();
internal IEnumerable<EregisterTask> LoadInspectionInitializationTasks()
{
this.executionType = nameof(LoadInspectionInitializationTasks);
var features = this.parameters.LoadInspectionInitializationFeatures();
if (features.RequestAddress > 0 && features.ResponseAddress > 0)
{
this.LoadProgrammingParameters(features);
if (this.runningTasks.Any())
{
this.runningTasks.Add(new EregisterChangeMeterTypeTask(features.Frequency)
{
SlotNr = features.SlotNr,
PoNr = features.PoNr,
SerialNr = features.SerialNr,
RequestAddress = features.RequestAddress,
ResponseAddress = features.ResponseAddress,
EncryptionKeyI = features.EncryptionKey,
EncryptionKeyII = SENSUS_STANDARD.GetEncryptionKey(),
Name = "Change Meter Type"
});
}
}
return this.runningTasks.ToArray();
}
internal IEnumerable<EregisterTask> LoadInspectionFinalizationTasks()
{
this.executionType = nameof(LoadInspectionFinalizationTasks);
var features = this.parameters.LoadInspectionFinalizationFeatures();
if (features.RequestAddress > 0 && features.ResponseAddress > 0)
{
// this.LoadProgrammingParameters(features);
if (this.parameters.StatusFertigung == 30)
{
//this.runningTasks.Add(new EregisterCheckFinalizationTask(this.parameters, features.Frequency)
//{
// WakeUpModul = true,
// SlotNr = features.SlotNr,
// PoNr = features.PoNr,
// SerialNr = features.SerialNr,
// RequestAddress = features.RequestAddress,
// ResponseAddress = features.ResponseAddress,
// EncryptionKeyI = features.EncryptionKey,
// EncryptionKeyII = SENSUS_STANDARD.GetEncryptionKey(),
//});
this.runningTasks.Add(new EregisterTask(this.parameters.Frequency)
{
Name = "WUP",
WakeUpCmd = true,
WakeUpModul = true,
SlotNr = features.SlotNr,
PoNr = features.PoNr,
SerialNr = features.SerialNr,
RequestAddress = features.RequestAddress,
ResponseAddress = features.ResponseAddress,
EncryptionKeyI = features.EncryptionKey,
EncryptionKeyII = SENSUS_STANDARD.GetEncryptionKey(),
Data = new ChangeWakeUp(WakeUpMode.StayAwake)
.Append(new ChangeNumberOfLatWindows(this.parameters.LatWindowsInitialization))
.Append(new ChangeTransmissionInterval(this.parameters.TransmissionIntervalInitialization))
.Append(new ChangeSensusRFEncryptionKey(features.EncryptionKey))
.Append(new ProvidePin(AuthLevel.II)),
Timeout = 10_000
});
this.runningTasks.Add(new EregisterTask(this.parameters.Frequency)
{
WakeUpModul = true,
Name = "0, 2, 16",
SlotNr = features.SlotNr,
PoNr = features.PoNr,
SerialNr = features.SerialNr,
RequestAddress = features.RequestAddress,
ResponseAddress = features.ResponseAddress,
EncryptionKeyI = features.EncryptionKey,
EncryptionKeyII = SENSUS_STANDARD.GetEncryptionKey(),
Data = new ChangeWakeUp((WakeUpMode)this.parameters.Wake_Up_Interval)
.Append(new ChangeNumberOfLatWindows(this.parameters.LAT_Interval))
.Append(new ChangeTransmissionInterval(this.parameters.Transmission_Intervall))
.Append(new ProvidePin(AuthLevel.II)),
});
this.LoadProgrammingParameters(features);
}
}
return this.runningTasks.AsEnumerable();
}
internal EregisterHistory GetHistory() => this.history;
internal EregisterState GetState() => this.state;
internal void StartProgramming(CancellationToken cancellationToken)
{
this.history.SerienNr = this.parameters.SerienNr;
this.history.Adresse = this.parameters.Adresse;
this.history.TempAdresse = this.parameters.TempAdresse;
var tasks = new ConcurrentQueue<EregisterTask>(this.runningTasks);
var factoryState = FactoryState.Production;
var lat = default(LAT);
var debug = default(DEBUG);
var semi = default(SEMI);
while (!cancellationToken.IsCancellationRequested && tasks.TryDequeue(out var task))
{
task.MessageReceived += this.history.Push;
var next = 0;
while (task.State != SIRTTaskState.Completed && task.State != SIRTTaskState.Cancelled && !cancellationToken.IsCancellationRequested && next < 30)
{
if (this.sirtHub.Start(task))
{
this.history.Push(task);
task.Wait();
next++;
}
if (task.ErrorMessage != null)
{
this.state.Bemerkung += task.ErrorMessage.Title + Environment.NewLine;
this.state.Bemerkung += task.ErrorMessage.Text + Environment.NewLine;
}
}
task.MessageReceived -= this.history.Push;
if (task.State != SIRTTaskState.Completed)
{
break;
}
this.UpdateTasksStateInTheQueue(task);
lat = task.LATMessage ?? lat;
debug = task.DEBUGMessage ?? debug;
semi = task.SEMIMessage ?? semi;
factoryState = task.FactoryState;
if (task.DEBUGMessage != null)
{
this.state.SemiDebugDatum = DateTime.Now;
}
if (task.RequestAddress == this.parameters.Adresse)
{
this.state.FunkadresseDatum = DateTime.Now;
}
if (factoryState == FactoryState.Shipment)
{
this.state.GeschlossenDatum = DateTime.Now;
}
}
this.state.ShouldUpdate = true;
this.state.Bemerkung += this.executionType;
this.state.Fabrikationsnummer = debug?.PCBID;
this.state.BUP = lat?.ToString()?.Replace('-', '\t');
this.state.DEBUG = debug?.ToString()?.Replace('-', '\t');
this.state.SEMI = semi?.ToString()?.Replace('-', '\t');
this.state.Seriennummer = this.parameters.SerienNr;
this.state.TempAdresse = this.parameters.TempAdresse;
}
private void UpdateTasksStateInTheQueue(EregisterTask task)
{
var cultureInfo = CultureInfo.InvariantCulture;
var numberStyles = NumberStyles.HexNumber | NumberStyles.AllowHexSpecifier;
foreach (var eregisterTask in this.runningTasks.AsEnumerable())
{
if (eregisterTask.State == SIRTTaskState.Completed)
{
continue;
}
else if (task.State == SIRTTaskState.Cancelled)
{
eregisterTask.SetCancelled();
}
eregisterTask.AnyTelegramReceived = task.AnyTelegramReceived;
eregisterTask.RequestAddress = task.RequestAddress;
eregisterTask.ResponseAddress = task.ResponseAddress;
eregisterTask.FactoryState = task.FactoryState;
eregisterTask.IsEncrypted = task.IsEncrypted;
eregisterTask.EncryptionKeyI = task.EncryptionKeyI;
eregisterTask.EncryptionKeyII = task.EncryptionKeyII;
if (task.DEBUGMessage != null)
{
eregisterTask.RadioFWHex = task.DEBUGMessage.RadioFWVersion;
if (int.TryParse($"{eregisterTask.RadioFWHex}", numberStyles, cultureInfo, out var radioFWVersion))
{
eregisterTask.RadioFWVersion = radioFWVersion;
}
}
}
}
private void LoadProgrammingParameters(EregisterFeatures features, [CallerMemberName] string caller = "")
{
this.Clear();
var frequency = this.parameters.Frequency;
this.runningTasks.Add(new EregisterTask(frequency)
{
Name = "WUP",
WakeUpCmd = true,
WakeUpModul = true,
SlotNr = features.SlotNr,
PoNr = features.PoNr,
SerialNr = features.SerialNr,
RequestAddress = features.RequestAddress,
ResponseAddress = features.ResponseAddress,
EncryptionKeyI = features.EncryptionKey,
EncryptionKeyII = SENSUS_STANDARD.GetEncryptionKey(),
Data = new ChangeWakeUp(WakeUpMode.StayAwake)
.Append(new ChangeNumberOfLatWindows(this.parameters.LatWindowsInitialization))
.Append(new ChangeTransmissionInterval(this.parameters.TransmissionIntervalInitialization))
// .Append(new ChangeSensusRFEncryptionKey(features.EncryptionKey))
.Append(new ProvidePin(AuthLevel.II)),
Timeout = 10_000
});
this.runningTasks.Add(new EregisterCheckInitializationTask(this.parameters, frequency)
{
SlotNr = features.SlotNr,
PoNr = features.PoNr,
SerialNr = features.SerialNr,
RequestAddress = features.RequestAddress,
ResponseAddress = features.ResponseAddress,
EncryptionKeyI = features.EncryptionKey,
EncryptionKeyII = SENSUS_STANDARD.GetEncryptionKey(),
});
foreach (var pam in features.BuildPams())
{
this.runningTasks.Add(new EregisterTask(frequency)
{
SlotNr = features.SlotNr,
PoNr = features.PoNr,
SerialNr = features.SerialNr,
RequestAddress = features.RequestAddress,
ResponseAddress = features.ResponseAddress,
EncryptionKeyI = features.EncryptionKey,
EncryptionKeyII = SENSUS_STANDARD.GetEncryptionKey(),
Data = pam.Value,
Name = pam.Key
});
}
}
}
}