diff --git a/Common/CommonConsole/PAM03.cs b/Common/CommonConsole/PAM03.cs new file mode 100644 index 00000000..791a40b0 --- /dev/null +++ b/Common/CommonConsole/PAM03.cs @@ -0,0 +1,202 @@ +namespace CommonConsole +{ + using Common.Hardware.SIRT; + using Common.Hardware.SIRT.Parameters; + using Common.Hardware.SIRT.Tasks; + using Common.Hardware.WaterMeter.eRegister; + using Common.Hardware.WaterMeter.eRegister.Features; + + using System; + using System.IO.Ports; + using System.Linq; + using System.Text.RegularExpressions; + using System.Threading; + + public class PAM03 + { + /// + /// Process.ExitCode: + /// 0 - OK + /// 1 - Execution Error + /// 2 - Connection Error + /// 3 - Invalid Arguments + /// + private int exitCode; + private string portName; + private uint address; + private byte[] key; + + public int Run(params string[] args) + { + this.exitCode = this.ParseArguments(args); + + if (this.exitCode == 0) + { + this.exitCode = 2; + + var processAwaiter = new ManualResetEventSlim(); + var sirtBroadcaster = new SIRTBroadcaster(this.portName); + + void SIRTBroadcaster_Connected(SIRTBroadcaster sirt) + { + var auth = new ProvidePin + { + AuthLevel = AuthLevel.I + }; + var task = new CordonelTask(sirt.Frequency) + { + Timeout = 30_000, + DelPamSemi = true, + RequestAddress = address, + EncryptionKey = key, + IsEncrypted = true + }; + + this.exitCode = 1; + + int ResetAlarms(byte alarmMask) + { + task.Data = new ResetAlarms(0xFF).Append(auth); + task.SetPending(); + sirt.Start(task); + task.Wait(); + + if (task.State != SIRTTaskState.Completed) + { + Console.WriteLine($"{nameof(SIRTTaskState)}.{task.State}"); + + return 1; + } + + return 0; + } + + this.exitCode = ResetAlarms(0xFF); + + if (this.exitCode != 0) + { + processAwaiter.Set(); + + return; + } + + this.exitCode = ResetAlarms(0xFE); + + if (this.exitCode != 0) + { + processAwaiter.Set(); + + return; + } + + processAwaiter.Set(); + } + + void SIRTBroadcaster_Disconnected(SIRTBroadcaster _) + => processAwaiter.Set(); + + + sirtBroadcaster.Connected += SIRTBroadcaster_Connected; + sirtBroadcaster.Disconnected += SIRTBroadcaster_Disconnected; + + sirtBroadcaster.Open(); + processAwaiter.Wait(); + sirtBroadcaster.Close(); + + sirtBroadcaster.Disconnected -= SIRTBroadcaster_Disconnected; + sirtBroadcaster.Connected -= SIRTBroadcaster_Connected; + } + + return this.exitCode; + } + + public int ParseArguments(string[] args) + { + if (args.Length != 3) + { + Console.WriteLine($"Falsche anzahl an parameter: '{string.Join("', '", args)}'"); + Console.WriteLine($"Expected: [COM..n as string] [Address as uint] [EncryptionKey as string]"); + + return 3; + } + + this.portName = args[0]; + + if (Regex.IsMatch($"{this.portName}", "[Cc][Oo][Mm][0-9]+")) + { + this.portName = this.portName.ToUpper(); + } + else if (SerialPort.GetPortNames().Any(x => x.Equals(this.portName, StringComparison.CurrentCultureIgnoreCase))) + { + Console.WriteLine($"COM Port: '{this.portName}' - nicht vorhanden"); + + return 3; + } + else + { + Console.WriteLine($"Falsche COM PortName: '{this.portName}' - erwartet: [Cc][Oo][Mm][0-9]+"); + + return 3; + } + + if (!uint.TryParse($"{args[1]}", out this.address)) + { + Console.WriteLine($"Ungültige Funkadresse: '{args[1]}'"); + + return 3; + } + + this.key = $"{args[2]}".GetBytes(); + + if (this.key.Length != 16) + { + Console.WriteLine($"Ungültige Funkschlüssel: '{BitConverter.ToString(this.key)}'"); + + return 3; + } + + return 0; + } + + public class CordonelTask : EregisterTask + { + public CordonelTask(int frequency) : base(frequency) + { + } + + public override Byte[] Start() + { + Console.WriteLine($"TX|{BitConverter.ToString(this.request)}"); + + return base.Start(); + } + + public override void Push(SIRTMessage response) + { + base.Push(response); + + Console.WriteLine($"RX|{BitConverter.ToString(response)}"); + + try + { + if (this.SEMIMessage != null) + { + Console.WriteLine($"-----------------------------------------"); + Console.WriteLine($"AlarmsMask"); + Console.WriteLine($"-----------------------------------------"); + Console.WriteLine($"{new AlarmsMask(response.Payload[10])}"); + Console.WriteLine($"-----------------------------------------"); + Console.WriteLine($"PAMStatus"); + Console.WriteLine($"-----------------------------------------"); + Console.WriteLine($"{new PAMStatus(response.Payload[11]).ToString(true)}"); + Console.WriteLine($"-----------------------------------------"); + } + } + catch (Exception) + { + + } + } + } + } +}