Files
laatzen/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterTask.cs
T

228 lines
7.1 KiB
C#

namespace Common.Hardware.WaterMeter.eRegister
{
using Common.Hardware.SIRT;
using Common.Hardware.SIRT.Parameters;
using Common.Hardware.WaterMeter.eRegister.Features;
using Common.Hardware.WaterMeter.eRegister.Models;
using Common.Hardware.WaterMeter.eRegister.Telegrams;
using System;
using System.Timers;
public class EregisterTask : SIRTTask
{
public EregisterTask(int frequency, int timeout = 6_000)
: base(frequency, timeout)
{
this.Cmd = SIRTMessage.W_PAM;
this.RSSI = new RSSI(0, frequency);
this.Label = nameof(SIRTTaskState.Pending);
}
public event Action<EregisterTask> Changed;
public event Action<object> Telegram;
public int SlotNr { get; internal set; }
public int PoNr { get; internal set; }
public int SerialNr { get; internal set; }
public string Name { get; internal set; }
public string Label { get; protected set; }
public string Info { get; private set; }
public string RSSI { get; private set; }
public P11 P11 { get; private set; }
public P12 P12 { get; private set; }
public BUP BUP { get; private set; }
public LAT LAT { get; private set; }
public DEBUG DEBUG { get; private set; }
public SEMI SEMI { get; protected set; }
public bool IsEncrypted { get; set; }
public byte[] EncryptionKey { get; set; }
public StateModes Mode { get; set; }
public override void UpdateFrom(SIRTTask task)
{
base.UpdateFrom(task);
if (task is EregisterTask etask)
{
this.Mode = etask.Mode;
this.IsEncrypted = etask.IsEncrypted;
if (this.Mode == StateModes.Shipment)
{
this.Data = new EregisterAvailableParametersParser(this.Data);
}
}
}
public override byte[] ToByteArray()
{
var data = this.request.Data;
// if (this.SEMI?.PAMStatus?.WRONG_AUTH == true || this.Mode == StateModes.Shipment)
{
data = new EregisterAvailableParametersParser(data);
}
if (this.IsEncrypted || this.Mode == StateModes.Shipment)
{
data = data.EncryptRequest(this.EncryptionKey, this.RequestAddress);
}
return new SIRTMessage
{
Address = this.request.Address,
Cmd = this.request.Cmd,
Data = data,
P1 = this.request.P1,
P2 = this.request.P2,
}.ToByteArray();
}
protected override void OnTimeout(object sender, ElapsedEventArgs e)
{
this.NotifyTimeouted();
this.State = SIRTTaskState.Pending;
}
protected override void ProcessResponse(SIRTMessage response)
{
if (this.State == SIRTTaskState.Cancelled)
{
this.Label = nameof(SIRTTaskState.Cancelled);
return;
}
if (response.Cmd == SIRTMessage.FROMAIR)
{
var data = response.Data;
var dataLength = data?.Length ?? 0;
this.P11 = new P11(response.P1);
this.RSSI = new RSSI(response.P2, (ushort)this.Frequency);
if (dataLength > 0)
{
var type = data[0];
if (this.IsEncrypted)
{
data = data.DecryptResponse(this.EncryptionKey);
}
if (type == SIRTMessage.BUP)
{
this.Label = nameof(SIRTMessage.BUP);
this.BUP = new BUP(data, this.P11);
this.NotifyTelegram(this.BUP);
}
else if (type == SIRTMessage.LAT)
{
this.Label = nameof(SIRTMessage.LAT);
this.LAT = new LAT(data, this.P11);
this.NotifyTelegram(this.LAT);
}
else if (type == SIRTMessage.DEBUG)
{
this.Label = nameof(SIRTMessage.DEBUG);
this.DEBUG = new DEBUG(data, this.P11);
this.NotifyTelegram(this.DEBUG);
this.Mode = (StateModes)(this.DEBUG.FactoryState - 1);
this.IsEncrypted = this.Mode == StateModes.Shipment;
this.NotifyUpdated();
}
else if (type == SIRTMessage.SEMI)
{
this.ProcessSEMI(data);
if (this.State == SIRTTaskState.Completed || this.State == SIRTTaskState.Cancelled)
{
this.EndProcessResponse(response);
}
}
else
{
this.Label = "NA";
}
}
}
else if (response.Cmd == SIRTMessage.ACKNANSW)
{
this.P12 = new P12(response.P1);
this.Label = "ACKN";
}
else
{
this.Label = "NA";
}
this.NotifyChanged();
}
protected virtual void EndProcessResponse(SIRTMessage response)
=> base.ProcessResponse(response);
protected void NotifyChanged() => this.Changed?.Invoke(this);
protected void NotifyTelegram(object value) => this.Telegram?.Invoke(value);
private void ProcessSEMI(byte[] data)
{
this.SEMI = new SEMI(data, this.Frequency, this.P11);
if (this.SEMI.PAMStatus == PAMStatus.OK)
{
this.State = SIRTTaskState.Completed;
this.Label = this.SEMI.PAMStatus.ToString();
}
else
{
var isEncrypted = this.IsEncrypted;
this.IsEncrypted = this.SEMI.Crc != 0;
if (this.IsEncrypted != isEncrypted)
{
data = data.DecryptResponse(this.EncryptionKey);
}
this.SEMI = new SEMI(data, this.Frequency, this.P11);
if (this.SEMI.PAMStatus == PAMStatus.OK)
{
this.State = SIRTTaskState.Completed;
this.Label = this.SEMI.PAMStatus.ToString();
}
else if (this.SEMI.PAMStatus == PAMStatus.EXPIREDAUTH)
{
this.State = SIRTTaskState.Cancelled;
this.Label = this.SEMI.PAMStatus.ToString();
this.timeoutTimer.Stop();
}
this.Label = this.SEMI.PAMStatus.ToString();
}
this.NotifyTelegram(this.SEMI);
this.NotifyUpdated();
}
}
}