diff --git a/Common/CommonConsole/CommonConsole.csproj b/Common/CommonConsole/CommonConsole.csproj index d5c05ce5..12a2ae0b 100644 --- a/Common/CommonConsole/CommonConsole.csproj +++ b/Common/CommonConsole/CommonConsole.csproj @@ -49,9 +49,12 @@ + + + @@ -97,6 +100,8 @@ Common.Utils.Extensions - + + + \ No newline at end of file diff --git a/Common/CommonConsole/Program.cs b/Common/CommonConsole/Program.cs index 8ea99ce5..f1fdb0ec 100644 --- a/Common/CommonConsole/Program.cs +++ b/Common/CommonConsole/Program.cs @@ -2,20 +2,222 @@ { using Common.Hardware.WaterMeter.eRegister; using Common.Hardware.WaterMeter.eRegister.Features; + using Common.Logic.Extensions.SQL; using System; + using System.Xml.Serialization; public class Program { public static void Main() { - var eregister = EregisterModel(); + var serialNumbers = String.Join(", ", new Object[] { 17833444, 18743226, 18752765, 19744225, 18743225, 19793034, 19793035, 20731121, 20731265, 18743224 }); + var xml = new SQLConnection("Server=SLASQL01.emea.sensus.net; Database=Auftrag; User ID=sa; Password=sqlserver;") + .CreateCommand($@" + SELECT CAST((SELECT vm.Wert AS CSD + , SUBSTRING(ISNULL(fs.Wert, ''), 1, 1) AS RadioKeyType + , aps.SerienNr + , aps.StatusFertigung + , CAST(CASE WHEN vm.Wert LIKE 'CSD 769400%' + OR vm.Wert LIKE 'CSD 770951%' + OR vm.Wert LIKE 'CSD 772721%' + THEN RIGHT(er.Adresse, 9) + ELSE aps.SerienNr END AS NVARCHAR(10)) AS MeterId + , er.TempAdresse + , er.Adresse + , x.FertigungsauftragNr + , x.Frequency + , x.Metersize + , x.Volume_per_Pulse AS VolumePerPulse + , x.Volume_per_LED_Pulse AS VolumePerLedPulse + , CAST(0 AS TINYINT) AS OffsetFactor + , CAST(5 AS TINYINT) AS OffsetTime + , CAST(0 AS TINYINT) AS FactoryCalibration + , CAST(3 AS TINYINT) AS TransmissionInterval + , CAST(7 AS TINYINT) AS MBusStatus + , CAST(0 AS TINYINT) AS LatWindows + , x.Byte11 AS UnitOfMesure + , x.Bit56 AS DecimalPoint + , x.Disallow_Reverse_Volume AS CandI + , x.Alarm_Low_Battery + , x.Alarm_Leakage + , x.Alarm_Magnetic_Tamper + , x.Alarm_Metrology_Unavailable + , x.Alarm_Backflow + , x.Alarm_Broken_Pipe + , x.Alarm_Medium_Absent + , x.Alarm_Specific_Error + , x.LeakagePeriod + , x.LeakageThreshold + , x.BrokenPipePeriod + , x.BrokenPipeThreshold + , x.History_Error_Limits_Days + , x.Data_Logging_Period + , x.Data_Logging_Forward_Counter + , x.Data_Logging_Time_Of_Minimum_Flow + , x.Data_Logging_Minimum_Flow + , x.Data_Logging_Time_Of_Broken_Pipe + , x.Data_Logging_Broken_Pipe_Flow + , x.Data_Logging_Current_Flow + , x.Data_Logging_Time_Of_Peak_Flow + , x.Data_Logging_Peak_Flow + , x.Data_Logging_Time_Of_Maximum_Flow + , x.Data_Logging_Maximum_Flow + , x.Data_Logging_Backward_Volume + , x.Data_Logging_Counter + , x.Data_Logging_Alarm_State + , x.FDR_Day_Of_Data_Reading + , x.FDR_Forward_Counter + , x.FDR_Time_Of_Minimum_Flow + , x.FDR_Minimum_Flow + , x.FDR_Time_Of_Broken_Pipe + , x.FDR_Broken_Pipe_Flow + , x.FDR_Current_Flow + , x.FDR_Time_Of_Peak_Flow + , x.FDR_Peak_Flow + , x.FDR_Time_Of_Maximum_Flow + , x.FDR_Maximum_Flow + , x.FDR_Backward_Volume + , x.FDR_Counter + , x.FDR_Alarm_State + , x.Transmission_Intervall + , x.PowerLevelHex + , CAST(CASE WHEN vm.Wert LIKE 'CSD 769400%' + OR vm.Wert LIKE 'CSD 770951%' + OR vm.Wert LIKE 'CSD 773102%' THEN 0 ELSE 1 END AS BIT) AS DisableOTA + , CAST(CASE WHEN vm.Wert LIKE 'CSD 764144%' + OR vm.Wert LIKE 'CSD 760407%' + THEN 0 ELSE x.LAT_Interval END AS TINYINT) AS LATInterval + , CAST(CASE WHEN vm.Wert LIKE 'CSD 769400%' THEN 0 + WHEN x.Metersize BETWEEN 53 AND 55 THEN 8 + ELSE 10 END AS TINYINT) AS ActivationByThreshold + , CAST(CASE WHEN vm.Wert LIKE 'CSD 760407%' + OR vm.Wert LIKE 'CSD 764144%' THEN 16 + WHEN vm.Wert LIKE 'CSD 38102_BU%' THEN 30 + WHEN vm.Wert LIKE 'CSD 772100_WE%' THEN 15 * 60 + ELSE 60 * 60 END AS SMALLINT) AS OpenMeteringTransmissionIntervalSeconds + , x.UTC_Offset AS UtcOffset + , x.Wake_Up_Interval AS WakeUpInterval + , CASE WHEN idn.Nennweite < 150 THEN 500 ELSE 50 END AS DisplayVolume + , CAST(CASE WHEN er.GeschlossenDatum IS NULL THEN 0 ELSE 1 END AS BIT) AS Sealed + FROM eRegister AS er + JOIN (SELECT DISTINCT + AuftragNr + , PositionNr + , SerienNr + , MAX(StatusFertigung) OVER (PARTITION BY SerienNr) AS StatusFertigung + FROM AuftragPositionSerienNr + WHERE SerienNr IN ({serialNumbers})) AS aps + ON er.Seriennummer = aps.SerienNr + JOIN AlleAuftragPositionen AS aap + ON aps.AuftragNr = aap.AuftragNr + AND aps.PositionNr = aap.PositionNr + JOIN (SELECT ap.FertigungsauftragNr + , rf.Frequency + , ms.Metersize + , ms.Volume_per_Pulse + , ms.Volume_per_LED_Pulse + , u.Byte11 + , dp.Bit56 + , ap.Disallow_Reverse_Volume + , ap.Alarm_Low_Battery + , ap.Alarm_Leakage + , ap.Alarm_Magnetic_Tamper + , ap.Alarm_Metrology_Unavailable + , ap.Alarm_Backflow + , ap.Alarm_Broken_Pipe + , ap.Alarm_Medium_Absent + , ap.Alarm_Specific_Error + , lp.[Bit0-2] AS LeakagePeriod + , lt.[Bit3-7] AS LeakageThreshold + , bpp.[Bit0-2] AS BrokenPipePeriod + , bpt.[Bit3-7] AS BrokenPipeThreshold + , ap.History_Error_Limits_Days + , dl.Data_Logging_Period + , ap.Data_Logging_Forward_Counter + , ap.Data_Logging_Time_Of_Minimum_Flow + , ap.Data_Logging_Minimum_Flow + , ap.Data_Logging_Time_Of_Broken_Pipe + , ap.Data_Logging_Broken_Pipe_Flow + , ap.Data_Logging_Current_Flow + , ap.Data_Logging_Time_Of_Peak_Flow + , ap.Data_Logging_Peak_Flow + , ap.Data_Logging_Time_Of_Maximum_Flow + , ap.Data_Logging_Maximum_Flow + , ap.Data_Logging_Backward_Volume + , ap.Data_Logging_Counter + , ap.Data_Logging_Alarm_State + , ap.FDR_Day_Of_Data_Reading + , ap.FDR_Forward_Counter + , ap.FDR_Time_Of_Minimum_Flow + , ap.FDR_Minimum_Flow + , ap.FDR_Time_Of_Broken_Pipe + , ap.FDR_Broken_Pipe_Flow + , ap.FDR_Current_Flow + , ap.FDR_Time_Of_Peak_Flow + , ap.FDR_Peak_Flow + , ap.FDR_Time_Of_Maximum_Flow + , ap.FDR_Maximum_Flow + , ap.FDR_Backward_Volume + , ap.FDR_Counter + , ap.FDR_Alarm_State + , ap.Transmission_Intervall + , ap.LAT_Interval + , utc.UTC_Offset + , wup.Wake_Up_Interval + , rfpl.PowerLevelHex + FROM eRegister_Auftragposition AS ap + LEFT JOIN eRegister_Metersize AS ms + ON ap.Meter_Size_Id = ms.Id + LEFT JOIN eRegister_Radiofrequency AS rf + ON ap.Radiofrequency_Id = rf.Id + LEFT JOIN eRegister_Unit AS u + ON ap.Unit_Id = u.Id + LEFT JOIN eRegister_DecimalPoint AS dp + ON ap.Decimal_Point_Id = dp.Id + LEFT JOIN eRegister_LeakagePeriod AS lp + ON ap.Leakage_Period_Id = lp.Id + LEFT JOIN eRegister_LeakageThreshold AS lt + ON ap.Leakage_Threshold_Id = lt.Id + LEFT JOIN eRegister_BrokenPipePeriod AS bpp + ON ap.Broken_Pipe_Period_Id = bpp.Id + LEFT JOIN eRegister_BrokenPipeThreshold AS bpt + ON ap.Broken_Pipe_Threshold_Id = bpt.Id + LEFT JOIN eRegister_DataLoggingPeriod AS dl + ON ap.Data_Logging_Period_Id = dl.Id + LEFT JOIN eRegister_UtcOffset AS utc + ON ap.UTC_Offset_Id = utc.Id + LEFT JOIN eRegister_WakeUpInterval AS wup + ON ap.Wake_Up_Interval_Id = wup.Id + LEFT JOIN eRegister_RFPowerlevel AS rfpl + ON rf.Frequency = rfpl.Frequenz + AND ms.Nennweite = rfpl.Nennweite) AS x + ON aap.FertigungsauftragNr = x.FertigungsauftragNr + JOIN Identnr AS idn + ON aap.IdentNr = idn.IdentNr + LEFT JOIN VAKO_Merkmale AS vm + ON SUBSTRING(idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis + AND SUBSTRING(idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode + AND vm.Wert LIKE 'CSD%' + LEFT JOIN VAKO_Merkmale AS fs + ON SUBSTRING(idn.VakoCode, 1, LEN(fs.Basis)) = fs.Basis + AND SUBSTRING(idn.VakoCode, fs.Stelle, fs.Laenge) = fs.Charcode + AND fs.Bezeichnung LIKE 'Funkschlüssel' + FOR XML PATH('eProgrammingParameters') + , ROOT('eProgramingParametersList')) AS XML)") + .FirstOrDefault(x => x.GetXml(0)); - var pams = eregister.BuildPams(); - foreach (var pam in pams) + var serializer = new XmlSerializer(typeof(eProgramingParametersList)); + var model = serializer.Deserialize(xml); + + if (model is Eregister eregister) { - Console.WriteLine($"{pam.Name}: {BitConverter.ToString(pam.CommandBytes.ToArray()).Replace("-", String.Empty)}"); + foreach (var pam in eregister.BuildPams()) + { + Console.WriteLine($"{pam.PamNames}: {BitConverter.ToString(pam.CommandBytes.ToArray())}"); + Console.WriteLine(); + } } } @@ -23,7 +225,7 @@ { ChangeWakeUp = new ChangeWakeUp { - Mode = WakeUpMode.StayAwake + WakeUpMode = WakeUpMode.StayAwake }, ChangeMeterReading = new ChangeMeterReading { diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Common.Hardware.Interfaces.Ports.SIRT.csproj b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Common.Hardware.Interfaces.Ports.SIRT.csproj index aae88833..910d4233 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Common.Hardware.Interfaces.Ports.SIRT.csproj +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Common.Hardware.Interfaces.Ports.SIRT.csproj @@ -41,11 +41,11 @@ - - - - - + + + + + diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtBroadcaster.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SIRT.cs similarity index 76% rename from Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtBroadcaster.cs rename to Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SIRT.cs index b3078ae4..0df8c07e 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtBroadcaster.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SIRT.cs @@ -4,15 +4,15 @@ using System.Collections.Concurrent; using System.Threading; - public class JustSirtBroadcaster + public class SIRT { - private static readonly ConcurrentDictionary runningTasks - = new ConcurrentDictionary(); - private readonly JustSirtProxy proxy; + private static readonly ConcurrentDictionary runningTasks + = new ConcurrentDictionary(); + private readonly SirtProxy proxy; - public JustSirtBroadcaster(String portName) + public SIRT(String portName) { - this.proxy = new JustSirtProxy(portName); + this.proxy = new SirtProxy(portName); this.proxy.MessageReceived += this.Proxy_MessageReceived; } @@ -39,11 +39,11 @@ var awaiter = new ManualResetEventSlim(); - var task = JustSirtTask.ActivateSIRT; + var task = SirtTask.ActivateSIRT; task.Cancelled += _ => awaiter.Set(); task.Completed += _task => { - activated = _task.TaskStatus == JustTaskStatus.Completed; + activated = _task.TaskStatus == TaskStatus.Completed; if (activated) { @@ -60,11 +60,11 @@ if (activated) { - task = JustSirtTask.IdentifySIRT; + task = SirtTask.IdentifySIRT; task.Cancelled += _ => awaiter.Set(); task.Completed += _task => { - activated = _task.TaskStatus == JustTaskStatus.Completed; + activated = _task.TaskStatus == TaskStatus.Completed; if (activated) { @@ -96,25 +96,25 @@ return this.proxy.TryClose(); } - public JustTaskStatus TryRun(JustSirtTask task) + public TaskStatus TryRun(SirtTask task) { if (!this.proxy.IsOpen) { - return JustTaskStatus.ProxyNotOpen; + return TaskStatus.ProxyNotOpen; } var address = task.Address; if (runningTasks.TryGetValue(address, out var runningTask) && runningTask != null) { - return JustTaskStatus.InRunningTasks; + return TaskStatus.InRunningTasks; } var countInPamPool = 0; foreach (var _task in runningTasks.Values) { - if (_task != null && _task.Cmd == JustSirtMessage.W_PAM) + if (_task != null && _task.Cmd == SirtMessage.W_PAM) { countInPamPool++; } @@ -122,16 +122,16 @@ if (countInPamPool >= 5) { - return JustTaskStatus.PamPoolIsFull; + return TaskStatus.PamPoolIsFull; } task = runningTasks.AddOrUpdate(address, task, (a, t) => task); - if (task.TaskStatus == JustTaskStatus.Completed) + if (task.TaskStatus == TaskStatus.Completed) { this.Task_DismissFromRunningTasks(task); - return JustTaskStatus.Completed; + return TaskStatus.Completed; } task.Cancelled += this.Task_DismissFromRunningTasks; @@ -141,10 +141,10 @@ this.proxy.WriteBytes(task); this.Log($"{task.Address}|{BitConverter.ToString(task)}"); - return JustTaskStatus.Sent; + return TaskStatus.Sent; } - private void Proxy_MessageReceived(JustSirtMessage message) + private void Proxy_MessageReceived(SirtMessage message) { var address = message.Address; @@ -155,7 +155,7 @@ } } - private void Task_DismissFromRunningTasks(JustSirtTask task) + private void Task_DismissFromRunningTasks(SirtTask task) { task.Cancelled -= this.Task_DismissFromRunningTasks; task.Completed -= this.Task_DismissFromRunningTasks; diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtMessage.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtMessage.cs similarity index 94% rename from Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtMessage.cs rename to Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtMessage.cs index e868a598..c2b53f16 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtMessage.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtMessage.cs @@ -2,7 +2,7 @@ { using System; - public class JustSirtMessage + public class SirtMessage { public const Byte MIN_LEN = 12; public const Byte PC2SIRT = 0x55; @@ -23,14 +23,14 @@ private Byte[] bytes; - public JustSirtMessage(DateTime? timestamp = null) + public SirtMessage(DateTime? timestamp = null) { this.timestamp = timestamp ?? DateTime.Now; this.bytes = new Byte[MIN_LEN]; this.bytes[0] = PC2SIRT; } - public JustSirtMessage(Byte[] bytes, DateTime? timestamp = null) + public SirtMessage(Byte[] bytes, DateTime? timestamp = null) { this.timestamp = timestamp ?? DateTime.Now; this.bytes = bytes; @@ -132,7 +132,7 @@ public override String ToString() => BitConverter.ToString(this.ToByteArray()); - public static implicit operator Byte[](JustSirtMessage message) + public static implicit operator Byte[](SirtMessage message) => message.ToByteArray() ?? new Byte[0]; private UInt16 CRCCCITT(Int32 start, Int32 length) diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtProxy.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtProxy.cs similarity index 89% rename from Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtProxy.cs rename to Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtProxy.cs index 8b872724..05e9ee51 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtProxy.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtProxy.cs @@ -2,16 +2,15 @@ { using System; using System.Collections.Generic; - using System.Diagnostics; using System.Timers; - public class JustSirtProxy + public class SirtProxy { private readonly JustSerialPort serialPort; private readonly List buffer; private readonly Timer timer; - public JustSirtProxy(String portName) + public SirtProxy(String portName) { var settings = new SerialPortSettings { @@ -26,7 +25,7 @@ this.timer = new Timer(); } - public event Action MessageReceived; + public event Action MessageReceived; public Boolean IsOpen => this.serialPort.IsOpen; @@ -96,7 +95,7 @@ } this.bufferLength = this.buffer.Count; - this.start = this.buffer.IndexOf(JustSirtMessage.SIRT2PC); + this.start = this.buffer.IndexOf(SirtMessage.SIRT2PC); if (this.start < 0) { @@ -119,7 +118,7 @@ { return; } - else if (this.buffer[this.stopIX] != JustSirtMessage.STOP) + else if (this.buffer[this.stopIX] != SirtMessage.STOP) { return; } @@ -129,7 +128,7 @@ this.buffer.CopyTo(this.start, this.bytes, 0, this.bytesLength); this.buffer.RemoveRange(0, this.start + this.bytesLength); - this.MessageReceived?.Invoke(new JustSirtMessage(this.bytes)); + this.MessageReceived?.Invoke(new SirtMessage(this.bytes)); } } } diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtTask.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtTask.cs similarity index 61% rename from Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtTask.cs rename to Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtTask.cs index da171d71..e1c47187 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustSirtTask.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtTask.cs @@ -6,14 +6,14 @@ using System.Collections.Concurrent; using System.Timers; - public class JustSirtTask + public class SirtTask { private readonly Timer timer = new Timer(); - private readonly JustSirtMessage request = new JustSirtMessage(); - private readonly ConcurrentStack responses = new ConcurrentStack(); + private readonly SirtMessage request = new SirtMessage(); + private readonly ConcurrentStack responses = new ConcurrentStack(); - public event Action Completed; - public event Action Cancelled; + public event Action Completed; + public event Action Cancelled; public Byte Cmd { @@ -45,35 +45,35 @@ set => this.request.Data = value; } - public JustTaskStatus TaskStatus { get; protected set; } + public TaskStatus TaskStatus { get; protected set; } public Byte[] LastPayload => this.responses.TryPeek(out var response) ? response.Data : default(Byte[]); - public virtual void ReceiveMessage(JustSirtMessage response, Int32 mhz) + public virtual void ReceiveMessage(SirtMessage response, Int32 mhz) { this.responses.Push(response); - if (this.TaskStatus != JustTaskStatus.Completed) + if (this.TaskStatus != TaskStatus.Completed) { - this.TaskStatus = JustTaskStatus.Running; + this.TaskStatus = TaskStatus.Running; - if (this.request.Cmd == JustSirtMessage.W_PAM) + if (this.request.Cmd == SirtMessage.W_PAM) { - if (response.Cmd == JustSirtMessage.FROMAIR && response.Data[0] == JustSirtMessage.SEMI) + if (response.Cmd == SirtMessage.FROMAIR && response.Data[0] == SirtMessage.SEMI) { - this.TaskStatus = JustTaskStatus.Completed; + this.TaskStatus = TaskStatus.Completed; } } - else if (response.Cmd == JustSirtMessage.ACKNANSW) + else if (response.Cmd == SirtMessage.ACKNANSW) { - this.TaskStatus = JustTaskStatus.Completed; + this.TaskStatus = TaskStatus.Completed; } } - if (this.TaskStatus == JustTaskStatus.Completed) + if (this.TaskStatus == TaskStatus.Completed) { this.Completed?.Invoke(this); this.timer.Stop(); @@ -83,12 +83,12 @@ public virtual void PrepareForRun() { this.responses.Clear(); - this.TaskStatus = JustTaskStatus.Pending; + this.TaskStatus = TaskStatus.Pending; this.timer.AutoReset = false; this.timer.Interval = 10_000; this.timer.Elapsed += (sender, _1) => { - this.TaskStatus = JustTaskStatus.Cancelled; + this.TaskStatus = TaskStatus.Cancelled; this.Cancelled?.Invoke(this); }; @@ -101,12 +101,12 @@ public override String ToString() => BitConverter.ToString(this.ToByteArray()); - public static implicit operator Byte[] (JustSirtTask task) + public static implicit operator Byte[] (SirtTask task) => task?.ToByteArray() ?? new Byte[] { }; - public static readonly JustSirtTask ActivateSIRT = new JustSirtTask + public static readonly SirtTask ActivateSIRT = new SirtTask { - Cmd = JustSirtMessage.W_REG, + Cmd = SirtMessage.W_REG, Address = 0x20000000, P2 = 0x05, Data = new Byte[] @@ -119,22 +119,22 @@ } }; - public static readonly JustSirtTask IdentifySIRT = new JustSirtTask + public static readonly SirtTask IdentifySIRT = new SirtTask { - Cmd = JustSirtMessage.R_REG, + Cmd = SirtMessage.R_REG, Address = 0x11001820, P2 = 0x08 }; - public static readonly JustSirtTask ReadPamPool = new JustSirtTask + public static readonly SirtTask ReadPamPool = new SirtTask { - Cmd = JustSirtMessage.R_PAM, + Cmd = SirtMessage.R_PAM, Address = 0xFFFFFFFF }; - public static JustSirtTask DeleteFromPamPool(UInt32 address) => new JustSirtTask + public static SirtTask DeleteFromPamPool(UInt32 address) => new SirtTask { - Cmd = JustSirtMessage.W_PAM, + Cmd = SirtMessage.W_PAM, P1 = new P811 { DelPamAdr = true }, Address = address }; diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustTaskStatus.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/TaskStatus.cs similarity index 89% rename from Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustTaskStatus.cs rename to Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/TaskStatus.cs index baf4dbb6..ac00bafd 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/JustTaskStatus.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/TaskStatus.cs @@ -1,6 +1,6 @@ namespace Common.Hardware.Interfaces.Ports.SIRT { - public enum JustTaskStatus + public enum TaskStatus { Pending = 0, Running = 1, diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/JustSerialPort.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/JustSerialPort.cs index 47254b14..528ea128 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/JustSerialPort.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/JustSerialPort.cs @@ -21,7 +21,6 @@ public JustSerialPort(SerialPortSettings serialPortSettings) { - this.serialPortSettings = serialPortSettings; this.portName = this.serialPortSettings.PortName; } diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeCustomerText.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeCustomerText.cs index 155f3cee..277477a0 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeCustomerText.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeCustomerText.cs @@ -5,12 +5,14 @@ public class ChangeCustomerText : Pam { + private Int32 serialno; + public ChangeCustomerText() : base(10, ChangeCustomerText) { } - public ChangeCustomerText(String text) : this() - => this.Text = text; + public ChangeCustomerText(Object text) : this() + => this.Text = $"{text}".Trim(); public String Text { diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeSensusRFEncryptionKey.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeSensusRFEncryptionKey.cs index 0dbeeb1d..00aae55d 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeSensusRFEncryptionKey.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeSensusRFEncryptionKey.cs @@ -35,7 +35,7 @@ public String HexKey { get => BitConverter.ToString(this.Key).Replace("-", String.Empty); - set => this.Key = value.ToBytes(); + set => this.Key = value.ToByteArray(); } } } diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeWakeUp.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeWakeUp.cs index 8127277d..07a5d89a 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeWakeUp.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeWakeUp.cs @@ -9,14 +9,20 @@ } public ChangeWakeUp(WakeUpMode mode) : base(2, ChangeWakeUpMode) - => this.Mode = mode; + => this.WakeUpMode = mode; - public WakeUpMode Mode + public WakeUpMode WakeUpMode { get => (WakeUpMode)this.bytes[1]; set => this.bytes[1] = (Byte)value; } + public Byte Mode + { + get => this.bytes[1]; + set => this.bytes[1] = value; + } + public static ChangeWakeUp AutoOff => WakeUpMode.SleepAutoOff; public static ChangeWakeUp AutoOn => WakeUpMode.SleepAutoOn; diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/DeactivateAlarms.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/DeactivateAlarms.cs index 690038d0..5daeaf87 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/DeactivateAlarms.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/DeactivateAlarms.cs @@ -1,9 +1,15 @@ namespace Common.Hardware.WaterMeter.eRegister.Features { + using System; + public class DeactivateAlarms : AlarmsMask { public DeactivateAlarms() : base(2, DeactivateAlarms) { } + + public DeactivateAlarms(Byte alarmsMask) : base(alarmsMask, DeactivateAlarms) + { + } } } diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Common.Hardware.WaterMeter.eRegister.csproj b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Common.Hardware.WaterMeter.eRegister.csproj index 47af8b77..5d8617b9 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Common.Hardware.WaterMeter.eRegister.csproj +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Common.Hardware.WaterMeter.eRegister.csproj @@ -63,6 +63,7 @@ + diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Eregister.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Eregister.cs index 38ae81d1..4935fc5c 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Eregister.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Eregister.cs @@ -2,11 +2,6 @@ { using Common.Hardware.WaterMeter.eRegister.Features; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Reflection; - public class Eregister { [PamType(AuthLevel.II)] @@ -90,6 +85,10 @@ [PamType(AuthLevel.III)] public SetBytterySeconds SetBytterySeconds { get; set; } + // TODO: Implement in builder + [PamType(AuthLevel.III)] + public ChangeRadioId ChangeRadioId { get; set; } + [PamType(AuthLevel.III)] public SetPcbId SetPcbId { get; set; } @@ -99,6 +98,22 @@ [PamType(AuthLevel.O, true)] public RequestLoggingData RequestLoggingData { get; set; } + // TODO: Implement in builder + // [PamType(AuthLevel.I, true)] + public ChangePin ChangePinI { get; set; } + + // TODO: Implement in builder + // [PamType(AuthLevel.II, true)] + public ChangePin ChangePinII { get; set; } + + // TODO: Implement in builder + // [PamType(AuthLevel.III, true)] + public ChangePin ChangePinIII { get; set; } + + // TODO: Implement in builder + // [PamType(AuthLevel.O)] + public ProvidePin ProvidePin { get; set; } + [PamType(AuthLevel.III, true)] public SendTestPattern SendTestPattern { get; set; } @@ -114,7 +129,11 @@ [PamType(AuthLevel.II)] public ChangeCustomerText ChangeCustomerText { get; set; } - [PamType(AuthLevel.O, true)] + // TODO: Implement in builder + // [PamType(AuthLevel.O)] + public ChangeSensusRFEncryptionKey ChangeSensusRFEncryptionKey { get; set; } + + [PamType(AuthLevel.II)] public EncapsulatedFlexNet EncapsulatedFlexNet { get; set; } [PamType(AuthLevel.O)] @@ -128,147 +147,5 @@ [PamType(AuthLevel.III)] public SetVariablePcbId SetVariablePcbId { get; set; } - - public IEnumerable BuildPams() - { - var pams = this.GetPams() - .OrderBy(x => x.CommandBytes[0]); - var cmds = new List(); - var pamsLevel0 = new List(); - var pamsLevel1 = new List(); - var pamsLevel2 = new List(); - var pamsLevel3 = new List(); - - var pin1 = new ProvidePin { AuthLevel = AuthLevel.I }.ToByteArray(); - var pin2 = new ProvidePin { AuthLevel = AuthLevel.II }.ToByteArray(); - var pin3 = new ProvidePin { AuthLevel = AuthLevel.III }.ToByteArray(); - - foreach (var pam in pams) - { - if (pam.IsSingleCmd) - { - if (pam.AuthLevel == AuthLevel.I) - { - pam.CommandBytes.AddRange(pin1); - } - else if (pam.AuthLevel == AuthLevel.II) - { - pam.CommandBytes.AddRange(pin2); - } - else if (pam.AuthLevel == AuthLevel.III) - { - pam.CommandBytes.AddRange(pin3); - } - - cmds.Add(pam); - } - else - { - if (pam.AuthLevel == AuthLevel.O) - { - pamsLevel0.Add(pam); - } - else if (pam.AuthLevel == AuthLevel.I) - { - pamsLevel1.Add(pam); - } - else if (pam.AuthLevel == AuthLevel.II) - { - pamsLevel2.Add(pam); - } - else if (pam.AuthLevel == AuthLevel.III) - { - pamsLevel3.Add(pam); - } - } - } - - var pamLevel0 = new EregisterPam(); - - foreach (var pam in pamsLevel0) - { - pamLevel0.Name += $"{pam.Name}{Environment.NewLine}"; - pamLevel0.CommandBytes.AddRange(pam.CommandBytes); - } - - pamLevel0.Name = pamLevel0.Name.Trim(); - - var pamLevel1 = new EregisterPam(); - - foreach (var pam in pamsLevel1) - { - pamLevel1.Name += $"{pam.Name}{Environment.NewLine}"; - pamLevel1.CommandBytes.AddRange(pam.CommandBytes); - } - - pamLevel1.Name = pamLevel1.Name.Trim(); - pamLevel1.CommandBytes.AddRange(pin1); - - var pamLevel2 = new EregisterPam(); - - foreach (var pam in pamsLevel2) - { - pamLevel2.Name += $"{pam.Name}{Environment.NewLine}"; - pamLevel2.CommandBytes.AddRange(pam.CommandBytes); - } - - pamLevel2.Name = pamLevel2.Name.Trim(); - pamLevel2.CommandBytes.AddRange(pin2); - - var pamLevel3 = new EregisterPam(); - - foreach (var pam in pamsLevel3) - { - pamLevel3.Name += $"{pam.Name}{Environment.NewLine}"; - pamLevel3.CommandBytes.AddRange(pam.CommandBytes); - } - - pamLevel3.Name = pamLevel3.Name.Trim(); - pamLevel3.CommandBytes.AddRange(pin3); - - cmds.Insert(0, pamLevel3); - cmds.Insert(0, pamLevel2); - cmds.Insert(0, pamLevel1); - cmds.Insert(0, pamLevel0); - - return cmds; - } - - private IEnumerable GetPams() - { - foreach (var eregisterProperty in typeof(Eregister).GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - var pamType = eregisterProperty.GetCustomAttribute(); - - if (pamType is null) - { - continue; - } - - var propertyValue = eregisterProperty.GetValue(this); - - if (propertyValue is null) - { - continue; - } - else if (propertyValue is EregisterDebug debug) - { - foreach (var pam in debug.GetPams().OrderBy(x => x.CommandBytes[2])) - { - yield return pam; - } - } - else if (propertyValue is Pam pam) - { - yield return new EregisterPam - { - Name = eregisterProperty.Name, - AuthLevel = pamType.AuthLevel, - IsSingleCmd = pamType.IsSingleCmd, - CommandBytes = pam.ToByteArray().ToList() - }; - } - } - } } } diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterDebug.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterDebug.cs index a25820bf..d1574bdd 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterDebug.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterDebug.cs @@ -1,10 +1,6 @@ namespace Common.Hardware.WaterMeter.eRegister { using Common.Hardware.WaterMeter.eRegister.Features; - - using System.Collections.Generic; - using System.Linq; - using System.Reflection; public class EregisterDebug { @@ -52,35 +48,5 @@ [PamType(AuthLevel.III, true)] public SetMeterType SetMeterType { get; set; } - - internal IEnumerable GetPams() - { - foreach (var eregisterProperty in typeof(EregisterDebug).GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - var pamType = eregisterProperty.GetCustomAttribute(); - - if (pamType is null) - { - continue; - } - - var propertyValue = eregisterProperty.GetValue(this); - - if (propertyValue is null) - { - continue; - } - else if (propertyValue is Pam pam) - { - yield return new EregisterPam - { - Name = eregisterProperty.Name, - AuthLevel = pamType.AuthLevel, - IsSingleCmd = pamType.IsSingleCmd, - CommandBytes = pam.ToByteArray().ToList() - }; - } - } - } } } \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterExtensions.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterExtensions.cs new file mode 100644 index 00000000..ad3b0d1e --- /dev/null +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterExtensions.cs @@ -0,0 +1,211 @@ +namespace Common.Hardware.WaterMeter.eRegister +{ + using Common.Hardware.WaterMeter.eRegister.Features; + + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + + public static class EregisterExtensions + { + public static IEnumerable BuildPams(this Eregister eregister) + { + var pams = eregister + .GetPams() + .OrderBy(x => x.CommandBytes[0]); + var cmds = new List(); + var pamsLevel0 = new List(); + var pamsLevel1 = new List(); + var pamsLevel2 = new List(); + var pamsLevel3 = new List(); + + var pin1 = new ProvidePin { AuthLevel = AuthLevel.I }.ToByteArray(); + var pin2 = new ProvidePin { AuthLevel = AuthLevel.II }.ToByteArray(); + var pin3 = new ProvidePin { AuthLevel = AuthLevel.III }.ToByteArray(); + + foreach (var pam in pams) + { + if (pam.IsSingleCmd) + { + if (pam.AuthLevel == AuthLevel.I) + { + pam.CommandBytes.AddRange(pin1); + } + else if (pam.AuthLevel == AuthLevel.II) + { + pam.CommandBytes.AddRange(pin2); + } + else if (pam.AuthLevel == AuthLevel.III) + { + pam.CommandBytes.AddRange(pin3); + } + + cmds.Add(pam); + } + else + { + if (pam.AuthLevel == AuthLevel.O) + { + pamsLevel0.Add(pam); + } + else if (pam.AuthLevel == AuthLevel.I) + { + pamsLevel1.Add(pam); + } + else if (pam.AuthLevel == AuthLevel.II) + { + pamsLevel2.Add(pam); + } + else if (pam.AuthLevel == AuthLevel.III) + { + pamsLevel3.Add(pam); + } + } + } + + if (pamsLevel3.Count > 0) + { + var pamLevel3 = new EregisterPam(); + + foreach (var pam in pamsLevel3) + { + pamLevel3.PamNames += $"{pam.PamNames}{Environment.NewLine}"; + pamLevel3.CommandBytes.AddRange(pam.CommandBytes); + } + + pamLevel3.PamNames = pamLevel3.PamNames?.Trim(); + pamLevel3.CommandBytes.AddRange(pin3); + cmds.Insert(0, pamLevel3); + } + + if (pamsLevel2.Count > 0) + { + var pamLevel2 = new EregisterPam(); + + foreach (var pam in pamsLevel2) + { + pamLevel2.PamNames += $"{pam.PamNames}{Environment.NewLine}"; + pamLevel2.CommandBytes.AddRange(pam.CommandBytes); + } + + pamLevel2.PamNames = pamLevel2.PamNames?.Trim(); + pamLevel2.CommandBytes.AddRange(pin2); + cmds.Insert(0, pamLevel2); + } + + if (pamsLevel1.Count > 0) + { + var pamLevel1 = new EregisterPam(); + + foreach (var pam in pamsLevel1) + { + pamLevel1.PamNames += $"{pam.PamNames}{Environment.NewLine}"; + pamLevel1.CommandBytes.AddRange(pam.CommandBytes); + } + + pamLevel1.PamNames = pamLevel1.PamNames?.Trim(); + pamLevel1.CommandBytes.AddRange(pin1); + cmds.Insert(0, pamLevel1); + } + + if (pamsLevel0.Count > 0) + { + var pamLevel0 = new EregisterPam(); + + foreach (var pam in pamsLevel0) + { + pamLevel0.PamNames += $"{pam.PamNames}{Environment.NewLine}"; + pamLevel0.CommandBytes.AddRange(pam.CommandBytes); + } + + pamLevel0.PamNames = pamLevel0.PamNames?.Trim(); + cmds.Insert(0, pamLevel0); + } + + return cmds; + } + + public static IEnumerable BuildTasks(this IEnumerable pams, Action taskOptions) + { + foreach (var pam in pams) + { + var task = new ProgrammingTask(); + + taskOptions(task); + + task.PamNames = pam.PamNames; + task.Data = pam.CommandBytes.ToArray(); + } + + yield break; + } + + public static IEnumerable GetPams(this Eregister eregister) + { + foreach (var eregisterProperty in typeof(Eregister).GetProperties(BindingFlags.Public | BindingFlags.Instance)) + { + var pamType = eregisterProperty.GetCustomAttribute(); + + if (pamType is null) + { + continue; + } + + var propertyValue = eregisterProperty.GetValue(eregister); + + if (propertyValue is null) + { + continue; + } + else if (propertyValue is EregisterDebug debug) + { + foreach (var pam in debug.GetPams().OrderByDescending(x => x.CommandBytes[2])) + { + yield return pam; + } + } + else if (propertyValue is Pam pam) + { + yield return new EregisterPam + { + PamNames = eregisterProperty.Name, + AuthLevel = pamType.AuthLevel, + IsSingleCmd = pamType.IsSingleCmd, + CommandBytes = pam.ToByteArray().ToList() + }; + } + } + } + + public static IEnumerable GetPams(this EregisterDebug debug) + { + foreach (var eregisterProperty in typeof(EregisterDebug).GetProperties(BindingFlags.Public | BindingFlags.Instance)) + { + var pamType = eregisterProperty.GetCustomAttribute(); + + if (pamType is null) + { + continue; + } + + var propertyValue = eregisterProperty.GetValue(debug); + + if (propertyValue is null) + { + continue; + } + else if (propertyValue is Pam pam) + { + yield return new EregisterPam + { + PamNames = eregisterProperty.Name, + AuthLevel = pamType.AuthLevel, + IsSingleCmd = pamType.IsSingleCmd, + CommandBytes = pam.ToByteArray().ToList() + }; + } + } + } + } +} diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterPam.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterPam.cs index a1ad9f3a..f445ac0d 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterPam.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EregisterPam.cs @@ -7,7 +7,7 @@ public class EregisterPam { - public String Name { get; set; } + public String PamNames { get; set; } public AuthLevel AuthLevel { get; set; } diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ParameterSet.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ParameterSet.cs index a3aac8ea..00e7c22d 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ParameterSet.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ParameterSet.cs @@ -103,7 +103,7 @@ internal ProgrammingTask BuildWupTxLatMBusTask() => new ProgrammingTask { - Cmd = JustSirtMessage.W_PAM, + Cmd = SirtMessage.W_PAM, P1 = new P811 { DelPamSemi = true, @@ -124,7 +124,7 @@ internal ProgrammingTask BuildTestParametersTask() => new ProgrammingTask { - Cmd = JustSirtMessage.W_PAM, + Cmd = SirtMessage.W_PAM, P1 = new P811 { DelPamSemi = true @@ -142,7 +142,7 @@ } .Append(new ProvidePin { - AuthLevel = Features.AuthLevel.III + AuthLevel = AuthLevel.III }), EncryptionKey = this.IsSealed ? this.EncryptionKey : null }; @@ -150,7 +150,7 @@ internal ProgrammingTask BuildSetupDisplayTask() => new ProgrammingTask { - Cmd = JustSirtMessage.W_PAM, + Cmd = SirtMessage.W_PAM, P1 = new P811 { DelPamSemi = true @@ -167,7 +167,7 @@ internal ProgrammingTask BuildOptoOnTask() => new ProgrammingTask { - Cmd = JustSirtMessage.W_PAM, + Cmd = SirtMessage.W_PAM, P1 = new P811 { DelPamSemi = true @@ -183,7 +183,7 @@ EncryptionKey = this.IsSealed ? this.EncryptionKey : null }; - internal void ParseParameters() + public void ParseParameters() { var length = this.Parameters?.Length ?? 0; @@ -252,78 +252,70 @@ if (!String.IsNullOrWhiteSpace(radioKey)) { - this.EncryptionKey = radioKey.ToBytes(); + this.EncryptionKey = radioKey.ToByteArray(); } } } } - - var httpClient = new HttpClient(); } - internal IEnumerable BuildFinalProgrammingTasks() + public IEnumerable BuildFinalProgrammingTasks() { - yield return new ProgrammingTask + var tasks = new Eregister { - Cmd = JustSirtMessage.W_PAM, - Address = this.RadioAddress, - P1 = new P811 + ChangeWakeUp = new ChangeWakeUp(WakeUpMode.StayAwake), + ChangeMeterReading = new ChangeMeterReading(this.DisplayVolume), + ChangeCustomerText = new ChangeCustomerText(this.Serialno), + DeactivateAlarms = new DeactivateAlarms(this.AlarmsMask), + ResetAlarms = new ResetAlarms(Byte.MaxValue), + ParameterizeLeakageDetection = new ParameterizeLeakageDetection(this.LeakageDetection), + ParameterizeBrokenPipeDetection = new ParameterizeBrokenPipeDetection(this.BrokenPipeDetection), + SetHistoricalErrorLimit = new SetHistoricalErrorLimit(this.HistoricalErrorLimit), + ChangeDataLoggerSettings = new ChangeDataLoggerSettings + { + TimeInterval = this.DataLoggerTimeInterval, + TimeOfMinimumFlow = this.DataLoggerMinFlowTime, + MinimumFlow = this.DataLoggerMinFlow + }, + ChangeFixedDateReadingSettings = new ChangeFixedDateReadingSettings + { + DayOfMonth = this.FixedDateReadingDay, + SettingI = this.FixedDateReadingSettingI, + SettingII = this.FixedDateReadingSettingII + }, + WirelessMBusMode = new WirelessMBusMode(this.MBusStatus), + SetPowerLevelSensusRF = new SetPowerLevel(this.PowerModeSensusRF), + SetPowerLevelFlexNet = new SetPowerLevel(this.PowerModeFlexNet), + ChangeNumberOfLatWindows = new ChangeNumberOfLatWindows(this.NumberOfLatWindows), + ChangeTransmissionInterval = new ChangeTransmissionInterval(this.TransmissionIntervalLast), + OpenMeteringTransmitionIntervalWMBus = new OpenMeteringTransmitionIntervalWMBus(this.OpenMeteringTransmissionInterval), + Debug = new EregisterDebug + { + DisableOTAFirmwareUpdate = new DisableOTAFirmwareUpdate(this.OTASettings), + SetActivationByThreshold = new SetActivationByThreshold(this.OTASettings), + } + } + .BuildPams() + .BuildTasks(options => + { + options.Address = this.RadioAddress; + options.Cmd = SirtMessage.W_PAM; + options.P1 = new P811 { DelPamSemi = true - }, - Data = ChangeWakeUp.StayAwake - // Pin level 2 ^ - // Pin level 3 - only production mode - .Append(new ChangeMeterId(this.MeterId)) - // Pin level 3 - only production mode - .Append(new ChangeMeterReading(this.DisplayVolume)) - // Pin level 2 - .Append(new ChangeCustomerText($"{this.Serialno}")) - // Pin level 0 - .Append(new AlarmsMask(this.AlarmsMask, Pam.DeactivateAlarms)) - // Pin level 1 - .Append(new ResetAlarms()) - // Pin level 0 - .Append(new ParameterizeLeakageDetection(this.LeakageDetection)) - // Pin level 0 - .Append(new ParameterizeBrokenPipeDetection(this.BrokenPipeDetection)) - // Pin level 1 - .Append(new SetHistoricalErrorLimit(this.HistoricalErrorLimit)) - // Pin level 0 - .Append(new ChangeDataLoggerSettings - { - TimeInterval = this.DataLoggerTimeInterval, - TimeOfMinimumFlow = this.DataLoggerMinFlowTime, - MinimumFlow = this.DataLoggerMinFlow - }) - // Pin level 0 - .Append(new ChangeFixedDateReadingSettings - { - DayOfMonth = this.FixedDateReadingDay, - SettingI = this.FixedDateReadingSettingI, - SettingII = this.FixedDateReadingSettingII - }) - // Pin level 2 - .Append(new WirelessMBusMode(this.MBusStatus)) - // Pin level 0 - .Append(new SetPowerLevel(this.PowerModeSensusRF)) - // Pin level 3 - only production mode - .Append(new SetPowerLevel(this.PowerModeFlexNet)) - // Pin level 3 - single cmd - .Append(new DisableOTAFirmwareUpdate(this.OTASettings)) - // Pin level 3 - single cmd - .Append(new SetActivationByThreshold(this.OTASettings)) - // Pin level 2 - .Append(new OpenMeteringTransmitionIntervalWMBus(this.OpenMeteringTransmissionInterval)) - // Pin level 2 - .Append(new ChangeTransmissionInterval(this.TransmissionIntervalLast)) - // Pin level 2 - .Append(new ChangeNumberOfLatWindows(this.NumberOfLatWindows)) - // Pin level 2 - .Append(new ChangeSensusRFEncryptionKey(this.EncryptionKey)) - // Pin level 3 - .Append(new ChangeRadioId(this.FinalAddress)) - }; + }; + }); + + foreach (var task in tasks) + { + yield return task; + } } } } + +//// TODO: +//// Pin level 2 +//.Append(new ChangeSensusRFEncryptionKey(this.EncryptionKey)) +//// Pin level 3 +//.Append(new ChangeRadioId(this.FinalAddress)) \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingBatch.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingBatch.cs index 5d56ef50..98a9e5c2 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingBatch.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingBatch.cs @@ -21,7 +21,7 @@ private readonly Dictionary> completedTasks = new Dictionary>(); private readonly ILogger logger = CreateNLogger("SIRT"); - private JustSirtBroadcaster broadcaster; + private SIRT broadcaster; private Int32 rssiRow; public event Action OnProgress; @@ -272,7 +272,7 @@ foreach (var task in tasks) { - if (task.TaskStatus != JustTaskStatus.Completed) + if (task.TaskStatus != TaskStatus.Completed) { this.broadcaster.TryRun(task); @@ -337,7 +337,7 @@ while (true) { - if (this.broadcaster.TryRun(task) == JustTaskStatus.Sent) + if (this.broadcaster.TryRun(task) == TaskStatus.Sent) { task.Cancelled += _ => awaiter.Set(); task.Completed += _ => awaiter.Set(); @@ -346,7 +346,7 @@ awaiter.Reset(); } - if (task.TaskStatus == JustTaskStatus.Completed) + if (task.TaskStatus == TaskStatus.Completed) { break; } @@ -379,20 +379,6 @@ } } - public void Run(ProgrammingTask task) - { - var status = this.broadcaster.TryRun(task); - var awaiter = new ManualResetEventSlim(); - - while (status != JustTaskStatus.Sent) - { - awaiter.Wait(1000); - awaiter.Reset(); - - status = this.broadcaster.TryRun(task); - } - } - public Boolean StartOnCOMPort(String portName) { var activated = false; @@ -401,7 +387,7 @@ { this.Stop(); - this.broadcaster = new JustSirtBroadcaster(portName); + this.broadcaster = new SIRT(portName); this.broadcaster.Logging += this.logger.Debug; if (this.broadcaster.TryActivate()) diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingTask.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingTask.cs index ee2696b7..02f20cd6 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingTask.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingTask.cs @@ -8,7 +8,7 @@ using System.Collections.Generic; using System.Linq; - public class ProgrammingTask : JustSirtTask + public class ProgrammingTask : SirtTask { private const String PENDING = nameof(PENDING); @@ -31,6 +31,8 @@ public TaskState State { get; private set; } = TaskState.None; + public String PamNames { get; internal set; } + public override void PrepareForRun() { this.OnProgress?.Invoke(this); @@ -38,21 +40,21 @@ base.PrepareForRun(); } - public override void ReceiveMessage(JustSirtMessage response, Int32 mhz) + public override void ReceiveMessage(SirtMessage response, Int32 mhz) { if (this.EncryptionKey != null && this.EncryptionKey.Length == 16) { this.DecryptResponse(response); } - if (this.State != TaskState.Success && response.Cmd == JustSirtMessage.FROMAIR) + if (this.State != TaskState.Success && response.Cmd == SirtMessage.FROMAIR) { var label = this.Label; var state = this.State; var data = response.Data; var type = data[0]; - if (type == JustSirtMessage.SEMI) + if (type == SirtMessage.SEMI) { var semi = new SEMI(data, (UInt16)mhz); label = semi.PAMStatus.ToString(); @@ -60,33 +62,33 @@ if (semi.PAMStatus == PAMStatus.OK) { state = TaskState.Success; - this.TaskStatus = JustTaskStatus.Completed; + this.TaskStatus = TaskStatus.Completed; } else { state = TaskState.Error; - this.TaskStatus = JustTaskStatus.Cancelled; + this.TaskStatus = TaskStatus.Cancelled; } this.semis.Add(semi); } - else if (type == JustSirtMessage.BUP) + else if (type == SirtMessage.BUP) { - label = nameof(JustSirtMessage.BUP); + label = nameof(SirtMessage.BUP); state = TaskState.Warning; this.bups.Add(new BUP(data)); } - else if (type == JustSirtMessage.LAT) + else if (type == SirtMessage.LAT) { - label = nameof(JustSirtMessage.LAT); + label = nameof(SirtMessage.LAT); state = TaskState.Warning; this.lats.Add(new LAT(data)); } - else if (type == JustSirtMessage.DEBUG) + else if (type == SirtMessage.DEBUG) { - label = nameof(JustSirtMessage.DEBUG); + label = nameof(SirtMessage.DEBUG); state = TaskState.Warning; this.debugs.Add(new DEBUG(data)); @@ -130,7 +132,7 @@ } else if (this.LastPayload != null) { - var last = new JustSirtMessage(this.LastPayload); + var last = new SirtMessage(this.LastPayload); P11 p11 = last.P1; if (p11.LenOverflow) @@ -205,7 +207,7 @@ return new Tuple(label, TaskState.Success); } - private void DecryptResponse(JustSirtMessage response) + private void DecryptResponse(SirtMessage response) { var data = response.Data; var length = data.Length; diff --git a/Common/Logic/Common.Logic.Extensions.SQL/Interfaces/ISQLReader.cs b/Common/Logic/Common.Logic.Extensions.SQL/Interfaces/ISQLReader.cs index 14652d85..b7ee3dd1 100644 --- a/Common/Logic/Common.Logic.Extensions.SQL/Interfaces/ISQLReader.cs +++ b/Common/Logic/Common.Logic.Extensions.SQL/Interfaces/ISQLReader.cs @@ -1,9 +1,12 @@ namespace Common.Logic.Extensions.SQL.Interfaces { using System; + using System.Xml; public interface ISQLReader { + XmlReader GetXml(Int32 index); + T GetValue(Int32 index); } } \ No newline at end of file diff --git a/Common/Logic/Common.Logic.Extensions.SQL/SQLReader.cs b/Common/Logic/Common.Logic.Extensions.SQL/SQLReader.cs index 1a19eaf5..470d15db 100644 --- a/Common/Logic/Common.Logic.Extensions.SQL/SQLReader.cs +++ b/Common/Logic/Common.Logic.Extensions.SQL/SQLReader.cs @@ -5,6 +5,8 @@ using System; using System.Data.SqlClient; using System.Diagnostics; + using System.IO; + using System.Xml; public class SQLReader : ISQLReader, IDisposable { @@ -19,6 +21,21 @@ this.sqlDataReader.Dispose(); } + public XmlReader GetXml(Int32 index) + { + var value = default(XmlReader); + + if (0 <= index && index < this.sqlDataReader.FieldCount) + { + if (!this.sqlDataReader.IsDBNull(index)) + { + value = this.sqlDataReader.GetSqlXml(index)?.CreateReader(); + } + } + + return value; + } + public T GetValue(Int32 index) { var value = default(T); diff --git a/Common/Utils/Common.Utils.Extensions/BytesExtensions.cs b/Common/Utils/Common.Utils.Extensions/BytesExtensions.cs index 55eedd39..63d39276 100644 --- a/Common/Utils/Common.Utils.Extensions/BytesExtensions.cs +++ b/Common/Utils/Common.Utils.Extensions/BytesExtensions.cs @@ -233,7 +233,7 @@ return (Byte)sum; } - public static Byte[] ToBytes(this String hexString) + public static Byte[] ToByteArray(this String hexString) { var bytes = new List(); diff --git a/LaaProductionWeb/LaaProductionWeb/API/Eregister/RadioKeyController.cs b/LaaProductionWeb/LaaProductionWeb/API/Eregister/RadioKeyController.cs index 256bd1ac..71677e58 100644 --- a/LaaProductionWeb/LaaProductionWeb/API/Eregister/RadioKeyController.cs +++ b/LaaProductionWeb/LaaProductionWeb/API/Eregister/RadioKeyController.cs @@ -13,30 +13,70 @@ { const String SENSUS_STANDARD = "E6C88800DEB868C0D6A84880CE982840"; + private readonly SqlConnection sqlConnection; + + public RadioKeyController() + => this.sqlConnection = WebApiApplication.GetService(); + [HttpGet] - [Route] - public IHttpActionResult Get([FromUri] Int32 serialno, [FromUri] Byte radioKeyType = 0) + [Route("byserialno/{serialno}")] + public IHttpActionResult Get([FromUri] Int32 serialno) { + var pono = default(Int32); + var address = default(Int64); + var keyType = default(String); + + this.sqlConnection + .CreateCommand($@" + SELECT DISTINCT + aap.FertigungsauftragNr + , aps.SerienNr + , er.Adresse + , idn.KeyType + FROM (SELECT DISTINCT + __idn.IdentNr + , SUBSTRING(vm.Wert, 1, 1) AS KeyType + FROM (SELECT DISTINCT + _idn.IdentNr + , _idn.VakoCode + FROM Identnr AS _idn + JOIN VAKO_Merkmale AS vm + ON SUBSTRING(_idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis + AND SUBSTRING(_idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode + AND ((vm.Stelle = 26 AND vm.Laenge = 1 AND vm.Charcode IN ('K', 'L', 'M')) + OR (vm.Stelle = 9 AND vm.Laenge = 1 AND vm.Charcode IN ('K', 'L', 'M'))) + AND (vm.Wert LIKE '%eRegister%')) AS __idn + JOIN VAKO_Merkmale AS vm + ON SUBSTRING(__idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis + AND SUBSTRING(__idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode + WHERE vm.Schluessel = 'Funkschluessel') AS idn + JOIN AlleAuftragPositionen AS aap + ON idn.IdentNr = aap.IdentNr + JOIN AuftragPositionSerienNr AS aps + ON aap.AuftragNr = aps.AuftragNr + AND aap.PositionNr = aps.PositionNr + JOIN eRegister AS er + ON aps.SerienNr = er.Seriennummer + WHERE aps.SerienNr = @{nameof(serialno)}") + .SetParameter(nameof(serialno), serialno) + .FirstOrDefault(x => + { + pono = x.GetValue(0); + address = x.GetValue(2); + keyType = x.GetValue(3); + }); + var radioKey = default(String); - if (radioKeyType == 1) + if (keyType == "S") { radioKey = SENSUS_STANDARD; } - else if (radioKeyType == 2) + else if (keyType == "Z") { - radioKey = this.GetOrdernoAndAddress(serialno, out var orderno, out var address); - - if (String.IsNullOrWhiteSpace(radioKey)) - { - radioKey = this.GetRadioKeyV2(orderno, address); - } - else - { - return this.BadRequest(radioKey); - } + radioKey = this.GetRadioKeyV2(pono, address); } - else if (radioKeyType == 3) + else if (keyType == "K") { radioKey = this.GetRadioKeyCSD(serialno); } @@ -44,47 +84,70 @@ return this.Ok(radioKey); } - private String GetOrdernoAndAddress(Int32 serialno, out Int32 orderno, out Int64 address) + [HttpGet] + [Route("byaddress/{address}")] + public IHttpActionResult Get([FromUri] Int64 address) { - orderno = 0; - address = 0; + var pono = default(Int32); + var serialno = default(Int32); + var keyType = default(String); - var result = default(String); + this.sqlConnection + .CreateCommand($@" + SELECT DISTINCT + aap.FertigungsauftragNr + , aps.SerienNr + , er.Adresse + , idn.KeyType + FROM (SELECT DISTINCT + __idn.IdentNr + , SUBSTRING(vm.Wert, 1, 1) AS KeyType + FROM (SELECT DISTINCT + _idn.IdentNr + , _idn.VakoCode + FROM Identnr AS _idn + JOIN VAKO_Merkmale AS vm + ON SUBSTRING(_idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis + AND SUBSTRING(_idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode + AND ((vm.Stelle = 26 AND vm.Laenge = 1 AND vm.Charcode IN ('K', 'L', 'M')) + OR (vm.Stelle = 9 AND vm.Laenge = 1 AND vm.Charcode IN ('K', 'L', 'M'))) + AND (vm.Wert LIKE '%eRegister%')) AS __idn + JOIN VAKO_Merkmale AS vm + ON SUBSTRING(__idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis + AND SUBSTRING(__idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode + WHERE vm.Schluessel = 'Funkschluessel') AS idn + JOIN AlleAuftragPositionen AS aap + ON idn.IdentNr = aap.IdentNr + JOIN AuftragPositionSerienNr AS aps + ON aap.AuftragNr = aps.AuftragNr + AND aap.PositionNr = aps.PositionNr + JOIN eRegister AS er + ON aps.SerienNr = er.Seriennummer + WHERE er.Adresse = @{nameof(address)}") + .SetParameter(nameof(address), address) + .FirstOrDefault(x => + { + pono = x.GetValue(0); + serialno = x.GetValue(1); + keyType = x.GetValue(3); + }); - try + var radioKey = default(String); + + if (keyType == "S") { - var _orderno = 0; - var _address = 0L; - - WebApiApplication - .GetService() - .CreateCommand($@" - SELECT DISTINCT TOP 1 - aap.FertigungsauftragNr - , er.Adresse - FROM eRegister AS er - JOIN AuftragPositionSerienNr AS aps - ON er.Seriennummer = aps.SerienNr - JOIN AlleAuftragPositionen AS aap - ON aps.AuftragNr = aap.AuftragNr - AND aps.PositionNr = aap.PositionNr - WHERE er.Seriennummer = @{nameof(serialno)}") - .SetParameter(nameof(serialno), serialno) - .FirstOrDefault(reader => - { - _orderno = reader.GetValue(0); - _address = reader.GetValue(1); - }); - - orderno = _orderno; - address = _address; + radioKey = SENSUS_STANDARD; } - catch (Exception e) + else if (keyType == "Z") { - result = e.Message; + radioKey = this.GetRadioKeyV2(pono, address); + } + else if (keyType == "K") + { + radioKey = this.GetRadioKeyCSD(serialno); } - return result; + return this.Ok(radioKey); } private string GetRadioKeyCSD(Int32 serialno) @@ -93,17 +156,21 @@ try { - radioKey = WebApiApplication - .GetService() + radioKey = this.sqlConnection .CreateCommand($@" - SELECT DISTINCT - errk.Radiokey - FROM AlleAuftragPositionSerienNr AS aaps - JOIN AlleAuftragPositionVakoMerkmale AS aapvm - ON aaps.FertigungsauftragNr = aapvm.FertigungsauftragNr - JOIN eRegister_CSD_Radiokey AS errk - ON aapvm.Wert LIKE '%' + errk.CSD + '%' - WHERE aaps.SerienNr = @{nameof(serialno)}") + SELECT DISTINCT csd.Radiokey + FROM AuftragPositionSerienNr AS aps + JOIN AlleAuftragPositionen AS aap + ON aps.AuftragNr = aap.AuftragNr + AND aps.PositionNr = aap.PositionNr + JOIN Identnr AS idn + ON aap.IdentNr = idn.IdentNr + JOIN VAKO_Merkmale AS vm + ON SUBSTRING(idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis + AND SUBSTRING(idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode + JOIN eRegister_CSD_Radiokey AS csd + ON vm.Wert LIKE ('%' + csd.CSD + '%') + WHERE aps.SerienNr = @{nameof(serialno)}") .SetParameter(nameof(serialno), serialno) .FirstOrDefault(reader => reader.GetValue(0)); } @@ -135,7 +202,14 @@ using (var httpResponseMessage = new HttpClient().SendAsync(httpRequestMessage).Result) { - radioKey = httpResponseMessage?.Content?.ReadAsStringAsync()?.Result?.Trim('"'); + if (httpResponseMessage.IsSuccessStatusCode) + { + radioKey = httpResponseMessage?.Content?.ReadAsStringAsync()?.Result?.Trim('"'); + } + else + { + radioKey = httpResponseMessage.ReasonPhrase; + } } ServicePointManager.Expect100Continue = expect100Continue; diff --git a/LaaProductionWeb/LaaProductionWeb/Controllers/SearchController.cs b/LaaProductionWeb/LaaProductionWeb/Controllers/SearchController.cs index 42f2adcf..396158f2 100644 --- a/LaaProductionWeb/LaaProductionWeb/Controllers/SearchController.cs +++ b/LaaProductionWeb/LaaProductionWeb/Controllers/SearchController.cs @@ -193,41 +193,11 @@ } else { - const String UrlFormat = "https://nodes.sms-esaap.com/keygenproxy/api/v2/keys/devices?orderNumber={0}&radioaddress={1}"; - const String XNodeTokenHeaderName = "X-Node-Token"; - const String XNodeTokenHeaderValue = "d5b8c0b2-81f6-4421-80d0-44eb2093e616"; - - var ponr = this.http + result = this.http .SetBearer(this.bearer) - .Get(request => request - .SetPath($"/LaaProductionWeb/api/search/pono/eregister/address/{token}")) + .Get(request => request + .SetPath($"/LaaProductionWeb/api/eregister/radiokey/byaddress/{token}")) .Value; - - using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, String.Format(UrlFormat, ponr, token))) - { - httpRequestMessage.Headers.Add(XNodeTokenHeaderName, XNodeTokenHeaderValue); - - var expect100Continue = ServicePointManager.Expect100Continue; - var securityProtokol = ServicePointManager.SecurityProtocol; - - ServicePointManager.Expect100Continue = true; - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; - - using (var httpResponseMessage = new HttpClient().SendAsync(httpRequestMessage).Result) - { - if (httpResponseMessage.IsSuccessStatusCode) - { - result = httpResponseMessage.Content?.ReadAsStringAsync()?.Result?.Trim('"'); - } - else - { - result = httpResponseMessage.StatusCode.ToString(); - } - } - - ServicePointManager.Expect100Continue = expect100Continue; - ServicePointManager.SecurityProtocol = securityProtokol; - } } } catch (Exception e)