From d4f6fa1eb163f5b65fedd06fd81437efcf61473b Mon Sep 17 00:00:00 2001 From: Stoyan Zlatev Date: Tue, 30 Jul 2024 14:02:14 +0200 Subject: [PATCH] temp commit: branch changing --- Common/CommonConsole/Program.cs | 61 +- ...mmon.Hardware.Interfaces.Ports.SIRT.csproj | 4 +- .../SIRTTask[TRequest].cs | 57 ++ .../SirtBroadcaster.cs | 44 +- .../SirtTask.cs | 99 ++-- .../Tasks/ActivateSIRTTask.cs | 17 +- .../Tasks/IdentifySIRTTask.cs | 17 +- .../Tasks/RPAMTask.cs | 19 + .../Tasks/ReadPamPoolTask.cs | 17 +- .../Tasks/WPAMTask.cs | 56 ++ .../Tasks/WritePamTask.cs | 15 - .../Common.Hardware.Interfaces.Ports.csproj | 2 +- .../IrdaSerialPort.cs | 26 +- .../SerialPort.cs | 37 -- .../SerialPortBase.cs | 100 ++-- .../SerialPortExtensions.cs | 70 +-- .../SerialPortSettings.cs | 4 + .../SirtSerialPort.cs | 26 +- .../UI1236Control.cs | 71 +++ .../UniProSerialPort.cs | 21 +- .../Alarm.cs | 49 +- .../RegisterSettings.cs | 2 +- .../IrdaConnection.cs | 11 +- .../OmniConnection.cs | 3 + .../SerialPortConnection.cs | 8 +- .../UniProConnection.cs | 6 +- .../ChangeTransmission.cs | 52 +- .../Pam.cs | 2 +- ...ommon.Hardware.WaterMeter.eRegister.csproj | 2 +- .../Endpoint.cs | 52 +- .../EndpointTask.cs | 81 +-- ...{EndpointsBatch.cs => ProgrammingBatch.cs} | 21 +- .../EregisterConnector/EregisterConnector.cs | 18 +- Common/OmniPlus/InspectionUI/App.config | 4 +- .../OmniPlus/InspectionUI/InspectionUI.csproj | 4 + .../InspectionUI/Plugins/MainWindowVM.cs | 96 ++-- .../InspectionUI/Plugins/PluginsManager.cs | 56 +- Common/OmniPlus/OmniPlus/Features/Alarm.cs | 8 +- .../OmniPlus/OmniPlus/Inspection/OmniMeter.cs | 2 +- Common/PendingEmails/App.config | 2 +- Common/PendingEmails/PendingEmails.csproj | 22 + Common/PendingEmails/Program.cs | 521 +++++++++++------- .../Common.UI.SIRTBroadcaster.csproj | 2 + .../InitInspectionWindow.xaml | 312 ++--------- .../InitInspectionWindow.xaml.cs | 10 +- .../Models/InitInspectionM.cs | 22 + .../Models/SIRTBroadcasterModel.cs | 122 ++-- .../Models/WritePamTask.cs | 6 +- .../ViewModels/InitInspectionTaskVM.cs | 6 + .../ViewModels/InitInspectionVM.cs | 55 +- .../ViewModels/SIRTBroadcasterViewModel.cs | 2 +- .../Common.UI.VFM/Models/OmniShipmentModel.cs | 19 +- .../LaaProduction.Data.Cordonel.csproj | 4 + .../Models/CordonelSpecialRequirement.cs | 1 - .../Models/CordonelStandardRequirement.cs | 2 +- .../LaaProductionWeb.Resources.csproj | 75 +++ .../Properties/AssemblyInfo.cs | 36 ++ .../UITranslations.Designer.cs | 81 +++ .../UITranslations.de.Designer.cs | 0 .../UITranslations.de.resx | 126 +++++ .../UITranslations.en.Designer.cs | 0 .../UITranslations.en.resx | 126 +++++ .../UITranslations.resx | 126 +++++ LaaProductionWeb/LaaProductionWeb.sln | 6 + .../App_Infrastructure/Appsettings.cs | 2 +- .../App_Infrastructure/AuthorizationFilter.cs | 25 +- .../App_Infrastructure/HttpExtensions.cs | 60 +- .../App_Infrastructure/Languages.cs | 8 + .../Views/Shared/_Layout.cshtml | 17 +- .../Controllers/HomeController.cs | 11 + .../LaaProductionWeb/LaaProductionWeb.csproj | 5 + .../Views/Shared/_Layout.cshtml | 15 +- .../Views/SpecialRequirements/Index.cshtml | 46 +- .../SpecialRequirements/TrContent.cshtml | 1 - .../Views/StandardRequirements/Index.cshtml | 41 +- .../StandardRequirements/TrContent.cshtml | 2 - 76 files changed, 2037 insertions(+), 1120 deletions(-) create mode 100644 Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SIRTTask[TRequest].cs create mode 100644 Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/RPAMTask.cs create mode 100644 Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/WPAMTask.cs delete mode 100644 Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/WritePamTask.cs delete mode 100644 Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPort.cs create mode 100644 Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/UI1236Control.cs rename Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/{EndpointsBatch.cs => ProgrammingBatch.cs} (57%) create mode 100644 Common/Ui/Common.UI.SIRTBroadcaster/Models/InitInspectionM.cs create mode 100644 Common/Ui/Common.UI.SIRTBroadcaster/ViewModels/InitInspectionTaskVM.cs create mode 100644 LaaProductionWeb/LaaProductionWeb.Resources/LaaProductionWeb.Resources.csproj create mode 100644 LaaProductionWeb/LaaProductionWeb.Resources/Properties/AssemblyInfo.cs create mode 100644 LaaProductionWeb/LaaProductionWeb.Resources/UITranslations.Designer.cs create mode 100644 LaaProductionWeb/LaaProductionWeb.Resources/UITranslations.de.Designer.cs create mode 100644 LaaProductionWeb/LaaProductionWeb.Resources/UITranslations.de.resx create mode 100644 LaaProductionWeb/LaaProductionWeb.Resources/UITranslations.en.Designer.cs create mode 100644 LaaProductionWeb/LaaProductionWeb.Resources/UITranslations.en.resx create mode 100644 LaaProductionWeb/LaaProductionWeb.Resources/UITranslations.resx create mode 100644 LaaProductionWeb/LaaProductionWeb/App_Infrastructure/Languages.cs diff --git a/Common/CommonConsole/Program.cs b/Common/CommonConsole/Program.cs index 222b95ce..fab693c4 100644 --- a/Common/CommonConsole/Program.cs +++ b/Common/CommonConsole/Program.cs @@ -3,14 +3,71 @@ using Common.Utils.Extensions; using System; + using System.Collections.Generic; public class Program { public static void Main() { - //var connector = new EregisterConnector(); + var econnector = new EregisterConnector.EregisterConnector(); - //connector.InitInspection(); + econnector.InitInspection(); + } + + //var payloadLength = 32; + //var payload = new Byte[payloadLength]; + + //for (var i = 0; i < 32; i++) + //{ + // payload[i] = (Byte)(i + 1); + //} + + //var withAddress = new Byte[payloadLength + 4]; + + //Array.Copy(payload, 0, withAddress, 4, payloadLength); + + //var keyLength = 16; + //var key = new Byte[keyLength]; + + //for (var i = 0; i < keyLength; i++) + //{ + // payload[i] = (Byte)(keyLength - i); + //} + + //Console.WriteLine(BitConverter.ToString(key)); + //Console.WriteLine(BitConverter.ToString(withAddress)); + //Console.WriteLine(BitConverter.ToString(Encrypt(payload, key, 0))); + + static Byte[] Encrypt(Byte[] bytes, Byte[] key, Int32 address) + { + var requestBytesList = new List(bytes); + var addressBytes = address.ToBigEndianBytes(); + requestBytesList.InsertRange(9, addressBytes); + + var bytesToEncryptCount = requestBytesList.Count; // 4(address) + 2(crc) + var keyByte = Byte.MaxValue; + var reference = address; + + for (Int32 encryptIndex = 0; encryptIndex < bytesToEncryptCount; encryptIndex++, encryptIndex++) + { + // Update KeyDefinition for this byte + keyByte += (Byte)(((reference >> ((keyByte & 0x3) << 3)) & 0xFF) >> ((keyByte >> 6) & 1)); + + // Update the unencrypted reference before the byte gets encrypted + reference = reference << 8; + reference += requestBytesList[encryptIndex]; + + // Encrypt the data by applying the resepective key + requestBytesList[encryptIndex] ^= key[(keyByte >> 2) & 0x0F]; + + // Check if data has to be inverted + if (keyByte > 127) + { + requestBytesList[encryptIndex] = (Byte)~requestBytesList[encryptIndex]; + } + } + + return requestBytesList.ToArray(); } } } \ No newline at end of file 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 ab2eff7c..b5cd114f 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 @@ -64,10 +64,12 @@ + - + + diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SIRTTask[TRequest].cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SIRTTask[TRequest].cs new file mode 100644 index 00000000..64eb24d0 --- /dev/null +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SIRTTask[TRequest].cs @@ -0,0 +1,57 @@ +namespace Common.Hardware.Interfaces.Ports.SIRT +{ + using Common.Hardware.Interfaces.Ports.SIRT.Responses; + + using System; + + public abstract class SIRTTask : SIRTTask where TRequest : SIRTRequest, new() + { + protected readonly TRequest request; + + protected SIRTTask(UInt32 timeoutSeconds = TIMEOUT_SECONDS) + { + this.request = new TRequest(); + this.Cmd = this.request.message.Cmd; + } + + protected SIRTTask(TRequest request, UInt32 timeoutSeconds = TIMEOUT_SECONDS) + : this(timeoutSeconds) + => this.request = request; + + public override UInt32 Address + { + get => this.request.Address; + set => this.request.Address = value; + } + + public override Byte[] Payload + { + get => this.request.Payload; + set => this.request.Payload = value; + } + + internal override void BeginAddResponse(AcknOrAnswerResponse response) + { + this.BeginAddResponse(); + + var done = this.AcknOrAnswerReceived(response); + + this.EndAddResponse(done); + } + + internal override void BeginAddResponse(FromAirResponse response) + { + this.BeginAddResponse(); + + var done = this.FromAirReceived(response); + + this.EndAddResponse(done); + } + + protected virtual Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) => false; + + protected virtual Boolean FromAirReceived(FromAirResponse response) => false; + + protected override Byte[] GetRequestBytes() => this.request; + } +} diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtBroadcaster.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtBroadcaster.cs index 61705ff3..d4af4c67 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtBroadcaster.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtBroadcaster.cs @@ -27,22 +27,29 @@ this.DataReceived += this.SirtBroadcaster_DataReceived; } - public String SIRTID { get; private set; } - - public UInt16 Frequency { get; private set; } - + public event Action Activated; public event Action EndpointAvailable; - public event Action PamPoolChanged; + public String SIRTID { get; private set; } + + public UInt16 Frequency { get; private set; } public void Run(SIRTTask task) { task.AddressChanged += (oldAddress, newAddress) => { + task.Done += _ => + { + /// Remove old address from the tasks pool + this.tasks.TryRemove(oldAddress, out var _); + }; + + /// Add the new address to the tasks pool this.tasks .GetOrAdd(newAddress, new Queue()) .Enqueue(task); + /// Remove old address from the pam pool this.Write(new WritePamRequest { DelPamAdr = true, @@ -116,6 +123,8 @@ this.Run(identificationTask); manuelResetEventSlim.Wait(); manuelResetEventSlim.Reset(); + + this.Activated?.Invoke(this.SIRTID, this.Frequency); } private void SirtBroadcaster_DataReceived(Byte[] data) @@ -160,8 +169,6 @@ { if (state is SIRTBroadcaster broadcaster) { - var awaiter = new ManualResetEventSlim(); - /// Loop while cancellation requested ... while (!broadcaster.cancellationToken.IsCancellationRequested) { @@ -190,11 +197,12 @@ /// When current task is not running and is not cancelled or done ... if (!current.IsRunning) { - var notWritePamTask = current.Type != SIRTConstants.WritePam; - var notInPamPool = !broadcaster.pamPool.Values.ToArray().Any(x => x == current.Address); + var notWritePamTask = current.Cmd != SIRTConstants.WritePam; + var pamPoolNotFull = !broadcaster.pamPool.Values.Any(x => x == 0); + var notInPamPool = !broadcaster.pamPool.Values.Any(x => x == current.Address); /// ... and also is write to pam task and is not into the pam pool ... - if (notWritePamTask || notInPamPool) + if (notWritePamTask || (pamPoolNotFull && notInPamPool)) { /// ... mark as running ... current.IsRunning = true; @@ -207,16 +215,7 @@ /// Break and go to the next address with tasks. break; } - - /// Break in case the pam pool is full. - if (pamPool.Count > 0 && !pamPool.Values.Any(x => x == 0)) - { - break; - } } - - awaiter.Wait(250, broadcaster.cancellationToken); - awaiter.Reset(); } } }, this, this.cancellationToken) @@ -249,8 +248,6 @@ task.Done += _ => awaiter.Set(); task.AddressesParsed += addresses => { - broadcaster.PamPoolChanged?.Invoke(addresses); - var length = addresses.Length; for (Byte i = 0; i < length; i++) @@ -265,10 +262,7 @@ broadcaster.Run(task); - awaiter.Wait(broadcaster.cancellationToken); - awaiter.Reset(); - - awaiter.Wait(500, broadcaster.cancellationToken); + awaiter.Wait(); awaiter.Reset(); } } diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtTask.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtTask.cs index 8d72043e..e52f55ac 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtTask.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/SirtTask.cs @@ -1,67 +1,60 @@ namespace Common.Hardware.Interfaces.Ports.SIRT { + using Common.Hardware.Interfaces.Ports.SIRT.Requests; using Common.Hardware.Interfaces.Ports.SIRT.Responses; using System; public abstract class SIRTTask { - protected readonly SIRTRequest request; - private readonly UInt32 timeout; + protected const UInt32 TIMEOUT_SECONDS = 60; + protected readonly UInt32 timeout; + private WriteRegRequest writeRegRequest; + private ReadRegRequest readRegRequest; + private ReadPamRequest readPamRequest; - public SIRTTask(SIRTRequest request, UInt32 timeout = 10) + public SIRTTask(UInt32 timeoutSeconds = TIMEOUT_SECONDS) { - this.request = request; - this.timeout = timeout; - this.Type = this.request.message.Cmd; - this.Address = this.request.Address; + this.timeout = timeoutSeconds; + this.Timestamp = DateTime.MinValue; + } + + protected SIRTTask(WriteRegRequest writeRegRequest) + { + this.writeRegRequest = writeRegRequest; + } + + protected SIRTTask(ReadRegRequest readRegRequest) + { + this.readRegRequest = readRegRequest; + } + + protected SIRTTask(ReadPamRequest readPamRequest) + { + this.readPamRequest = readPamRequest; } public event Action Done; public event Action Cancelled; public event Action AddressChanged; - public Byte Type { get; } - public virtual UInt32 Address { get; set; } - public Boolean IsRunning { get; internal set; } + public virtual Byte[] Payload { get; set; } + + public Boolean IsRunning { get; set; } + + public Byte Cmd { get; protected set; } + + public DateTime Timestamp { get; protected set; } public Boolean IsDone { get; protected set; } public Boolean IsCancelled { get; protected set; } - public DateTime? Timestamp { get; protected set; } + internal abstract void BeginAddResponse(AcknOrAnswerResponse response); - internal void BeginAddResponse(AcknOrAnswerResponse response) - { - if (this.CanReceiveResponses()) - { - var done = this.AcknOrAnswerReceived(response); - - this.EndAddResponse(done); - } - } - - internal void BeginAddResponse(FromAirResponse response) - { - if (this.CanReceiveResponses()) - { - var done = this.FromAirReceived(response); - - this.EndAddResponse(done); - } - } - - protected virtual Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) - { - return false; - } - - protected virtual Boolean FromAirReceived(FromAirResponse response) - { - return false; - } + internal abstract void BeginAddResponse(FromAirResponse response); protected void NotifyCancelled() { @@ -78,38 +71,30 @@ } protected void NotifyAddressChanged(UInt32 oldAddress, UInt32 newAddress) + => this.AddressChanged?.Invoke(oldAddress, newAddress); + + protected void BeginAddResponse() { - this.Address = newAddress; - - this.AddressChanged?.Invoke(oldAddress, newAddress); - } - - protected virtual Byte[] GetRequestBytes() => this.request; - - private Boolean CanReceiveResponses() - { - var canReceiveResponses = !this.IsDone && !this.IsCancelled; - - if (canReceiveResponses && this.Timestamp is null) + if (this.Timestamp == DateTime.MinValue) { this.Timestamp = DateTime.Now; } - - return canReceiveResponses; } - private void EndAddResponse(Boolean isDone) + protected void EndAddResponse(Boolean isDone) { if (isDone) { this.NotifyDone(); } - else if ((DateTime.Now - this.Timestamp.Value).TotalSeconds > this.timeout) + else if ((DateTime.Now - this.Timestamp).TotalSeconds > this.timeout) { this.NotifyCancelled(); } } - public static implicit operator Byte[] (SIRTTask task) => task.request; + protected abstract Byte[] GetRequestBytes(); + + public static implicit operator Byte[] (SIRTTask task) => task.GetRequestBytes(); } } diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/ActivateSIRTTask.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/ActivateSIRTTask.cs index 7a4e4130..8cb37413 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/ActivateSIRTTask.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/ActivateSIRTTask.cs @@ -36,6 +36,21 @@ } }) { } - protected override Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) => response.IsValid; + protected Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) => response.IsValid; + + protected override Byte[] GetRequestBytes() + { + throw new NotImplementedException(); + } + + internal override void BeginAddResponse(AcknOrAnswerResponse response) + { + throw new NotImplementedException(); + } + + internal override void BeginAddResponse(FromAirResponse response) + { + throw new NotImplementedException(); + } } } diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/IdentifySIRTTask.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/IdentifySIRTTask.cs index 5ca91638..edac22cf 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/IdentifySIRTTask.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/IdentifySIRTTask.cs @@ -15,7 +15,7 @@ public event Action Identified; - protected override Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) + protected Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) { if (!response.IsValid) { @@ -36,5 +36,20 @@ return identified; } + + protected override Byte[] GetRequestBytes() + { + throw new NotImplementedException(); + } + + internal override void BeginAddResponse(AcknOrAnswerResponse response) + { + throw new NotImplementedException(); + } + + internal override void BeginAddResponse(FromAirResponse response) + { + throw new NotImplementedException(); + } } } diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/RPAMTask.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/RPAMTask.cs new file mode 100644 index 00000000..902446f9 --- /dev/null +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/RPAMTask.cs @@ -0,0 +1,19 @@ +namespace Common.Hardware.Interfaces.Ports.SIRT.Tasks +{ + using Common.Hardware.Interfaces.Ports.SIRT.Requests; + + using System; + + public class RPAMTask : SIRTTask + { + public RPAMTask(UInt32 timeoutSeconds = TIMEOUT_SECONDS) : base(timeoutSeconds) + { + } + + public Boolean PamStruct + { + get => this.request.PamStruct; + set => this.request.PamStruct = value; + } + } +} diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/ReadPamPoolTask.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/ReadPamPoolTask.cs index 39a2960f..4f7af9ad 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/ReadPamPoolTask.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/ReadPamPoolTask.cs @@ -14,7 +14,7 @@ public event Action AddressesParsed; - protected override Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) + protected Boolean AcknOrAnswerReceived(AcknOrAnswerResponse response) { if (!response.IsValid) { @@ -55,5 +55,20 @@ return parsed; } + + protected override Byte[] GetRequestBytes() + { + throw new NotImplementedException(); + } + + internal override void BeginAddResponse(AcknOrAnswerResponse response) + { + throw new NotImplementedException(); + } + + internal override void BeginAddResponse(FromAirResponse response) + { + throw new NotImplementedException(); + } } } diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/WPAMTask.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/WPAMTask.cs new file mode 100644 index 00000000..c435a02a --- /dev/null +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/WPAMTask.cs @@ -0,0 +1,56 @@ +namespace Common.Hardware.Interfaces.Ports.SIRT.Tasks +{ + using Common.Hardware.Interfaces.Ports.SIRT.Requests; + + using System; + + public class WPAMTask : SIRTTask + { + public WPAMTask(UInt32 timeoutSeconds = TIMEOUT_SECONDS) : base(timeoutSeconds) + { + + } + + public Boolean WakeUpModul + { + get => this.request.WakeUpModul; + set => this.request.WakeUpModul = value; + } + + public Boolean WakeUpCmd + { + get => this.request.WakeUpCmd; + set => this.request.WakeUpCmd = value; + } + + public Boolean IgnoreTimeout + { + get => this.request.IgnoreTimeout; + set => this.request.IgnoreTimeout = value; + } + + public Boolean DelPamSemi + { + get => this.request.DelPamSemi; + set => this.request.DelPamSemi = value; + } + + public Boolean DelPamTx + { + get => this.request.DelPamTx; + set => this.request.DelPamTx = value; + } + + public Boolean DelPamAdr + { + get => this.request.DelPamAdr; + set => this.request.DelPamAdr = value; + } + + public Boolean DelPamAll + { + get => this.request.DelPamAll; + set => this.request.DelPamAll = value; + } + } +} diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/WritePamTask.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/WritePamTask.cs deleted file mode 100644 index da6b353c..00000000 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports.SIRT/Tasks/WritePamTask.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Common.Hardware.Interfaces.Ports.SIRT.Tasks -{ - using System; - - public class WritePamTask : SIRTTask - { - public WritePamTask(SIRTRequest request) : base(request) - { - } - - public WritePamTask(SIRTRequest request, UInt32 timeout) : base(request, timeout) - { - } - } -} diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/Common.Hardware.Interfaces.Ports.csproj b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/Common.Hardware.Interfaces.Ports.csproj index 0e45a2ee..bc0cd0a3 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/Common.Hardware.Interfaces.Ports.csproj +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/Common.Hardware.Interfaces.Ports.csproj @@ -42,7 +42,6 @@ - @@ -52,6 +51,7 @@ + diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/IrdaSerialPort.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/IrdaSerialPort.cs index 63cf221a..f4dd3b72 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/IrdaSerialPort.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/IrdaSerialPort.cs @@ -1,9 +1,8 @@ namespace Common.Hardware.Interfaces.Ports { using System; - using System.Threading; - public class IRDASerialPort : SerialPort + public class IRDASerialPort : SerialPortBase { public IRDASerialPort(SerialPortSettings settings) : base(settings) { @@ -15,33 +14,24 @@ if (data.TryParseToIrda(out var bytes)) { - for (var i = 0; i < 3; i++) + var timeout = 3; + + for (var i = 0; i < timeout; i++) { - this.serialPortBase.Write(new Byte[] { 0x01, 0x01, 0x01, 0x01 }, 0, 4); - - Thread.Sleep(1); - - this.serialPortBase.Write(bytes, 0, bytes.Length); - - var timeout = 3; + this.Write(new Byte[] { 0x01, 0x01, 0x01, 0x01 }, 0, 4); + this.Write(bytes, 0, bytes.Length); + var answerd = false; var buffer = new Byte[0]; while (timeout-- >= 0) { - Thread.Sleep(50); - - var _bytes = this.serialPortBase.Read(); + var _bytes = this.Read(); var bytesLength = _bytes.Length; var bufferLength = buffer.Length; - Thread.Sleep(50); - Array.Resize(ref buffer, bufferLength + bytesLength); - Thread.Sleep(50); - Array.Copy(_bytes, 0, buffer, bufferLength, bytesLength); - Thread.Sleep(50); if (buffer.TryParseFromIrda(out _data)) { diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPort.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPort.cs deleted file mode 100644 index cd39c941..00000000 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPort.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace Common.Hardware.Interfaces.Ports -{ - using System; - - public abstract class SerialPort - { - internal readonly SerialPortBase serialPortBase; - - public SerialPort(SerialPortSettings settings) - => this.serialPortBase = new SerialPortBase(settings); - - public event Action Logging - { - add => this.serialPortBase.Logging += value; - remove => this.serialPortBase.Logging -= value; - } - - public Boolean IsOpen => this.serialPortBase.IsOpen; - - public virtual void Close() => this.serialPortBase.Close(); - - public virtual void EnsureConnected() - { - if (!this.serialPortBase.IsOpen) - { - this.serialPortBase.Close(); - this.serialPortBase.Open(); - } - } - - protected void Notify(String message) => this.serialPortBase.Notify(message); - - public virtual void Open() => this.serialPortBase.Open(); - - public abstract Byte[] Write(params Byte[] data); - } -} diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortBase.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortBase.cs index f14e7bde..ef335ab3 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortBase.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortBase.cs @@ -2,10 +2,10 @@ { using System; using System.Collections.Concurrent; - + using System.Threading; using SystemSerialPort = System.IO.Ports.SerialPort; - internal class SerialPortBase + public abstract class SerialPortBase { private static readonly ConcurrentDictionary serialPorts = new ConcurrentDictionary(); @@ -30,7 +30,7 @@ ? serialPort?.ReadBufferSize ?? default(Int32) : default(Int32); - public void Close() + public virtual void Close() { try { @@ -60,7 +60,16 @@ } } - public void Open() + public virtual void EnsureConnected() + { + if (!this.IsOpen) + { + this.Close(); + this.Open(); + } + } + + public virtual void Open() { try { @@ -96,33 +105,6 @@ } } - public Byte[] Read() - { - var bytes = new Byte[0]; - - if (serialPorts.TryGetValue(this.PortName, out var serialPort) && serialPort.IsOpen) - { - var size = this.ReadBufferSize; - var buffer = new Byte[size]; - - try - { - var copyLength = serialPort.Read(buffer, 0, size); - - Array.Resize(ref bytes, copyLength); - Array.Copy(buffer, 0, bytes, 0, copyLength); - - this.Notify($"RX|{BitConverter.ToString(bytes)}"); - } - catch (Exception e) - { - this.Notify(e.ToString()); - } - } - - return bytes; - } - public override String ToString() => serialPorts.TryGetValue(this.PortName, out var serialPort) ? $"{serialPort.PortName}, " + @@ -136,7 +118,51 @@ $"{this.settings.Parity}, " + $"{this.settings.StopBits}"; - public void Write(Byte[] bytes, Int32 start, Int32 length) + public virtual Byte[] Write(params Byte[] data) + { + this.Write(data, 0, data.Length); + + return data; + } + + protected void Notify(String message) => this.Logging?.Invoke(message); + + protected Byte[] Read(Int32 sleep = 100) + { + Thread.Sleep(sleep); + + var bytes = new Byte[0]; + + if (serialPorts.TryGetValue(this.PortName, out var serialPort) && serialPort.IsOpen) + { + var size = this.ReadBufferSize; + var buffer = new Byte[size]; + + try + { + if (serialPort.IsOpen) + { + var copyLength = serialPort.Read(buffer, 0, size); + + Array.Resize(ref bytes, copyLength); + Array.Copy(buffer, 0, bytes, 0, copyLength); + + if (this.settings.RXLoggingEnabled) + { + this.Notify($"RX|{BitConverter.ToString(bytes)}"); + } + } + } + catch (Exception e) + { + this.Notify(e.ToString()); + } + } + + return bytes; + } + + protected void Write(Byte[] bytes, Int32 start, Int32 length, Int32 sleep = 1) { if (serialPorts.TryGetValue(this.PortName, out var serialPort) && serialPort.IsOpen) { @@ -144,16 +170,18 @@ { serialPort.Write(bytes, start, length); - this.Notify($"TX|{BitConverter.ToString(bytes)}"); + if (this.settings.TXLoggingEnabled) + { + this.Notify($"TX|{BitConverter.ToString(bytes)}"); + } } catch (Exception e) { this.Notify(e.ToString()); } } - } - public void Notify(String message) - => this.Logging?.Invoke(message); + Thread.Sleep(sleep); + } } } diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortExtensions.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortExtensions.cs index d08c78dc..7c274e26 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortExtensions.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortExtensions.cs @@ -2,7 +2,7 @@ { using System; - public static class SerialPortExtensions + public static partial class SerialPortExtensions { public const Byte UNIPRO_START = 0x53; public const Byte UNIPRO_PC2REG = 0x57; @@ -257,7 +257,7 @@ /// n-2. .... - Checksum 0 /// n-1. .... - Checksum 1 /// - public static Boolean FromUI1236(this Byte[] bytes, out Byte[] data) + public static Boolean TryParseFromUI1236(this Byte[] bytes, out Byte[] data) { data = new Byte[0]; @@ -288,7 +288,7 @@ return false; } - var dataLength = bytes[lengthIndex]; + var dataLength = bytes[lengthIndex] - 3; // 3 = protocol bytes length (start|control|length) if (dataIndex + dataLength > bytesLength) { @@ -415,69 +415,5 @@ return BitConverter.GetBytes(crcSum); } - - internal class UI1236Control - { - private readonly Byte[] bits; - - private UI1236Control(Byte[] bits) - => this.bits = bits; - - public Boolean E0Encryption => this.bits[0] == 1; - - public Boolean E1Encryption => this.bits[1] == 1; - - public Boolean E2Encryption => this.bits[2] == 1; - - public Boolean ReturnResponse - { - get => this.bits[3] == 1; - set => this.bits[3] = (Byte)(value ? 1 : 0); - } - - public Boolean NFNetwork => this.bits[4] == 1; - - public Boolean MultipleCommands - { - get => this.bits[5] == 1; - set => this.bits[5] = (Byte)(value ? 1 : 0); - } - - public Boolean LongControl - { - get => this.bits[6] == 1; - set => this.bits[6] = (Byte)(value ? 1 : 0); - } - - public Boolean MultipleFrames - { - get => this.bits[7] == 1; - set => this.bits[7] = (Byte)(value ? 1 : 0); - } - - public static implicit operator UI1236Control(Byte controlByte) - { - var bits = new Byte[8]; - - for (var i = 0; i < 8; i++) - { - bits[i] = (Byte)((controlByte >> i) & 1); - } - - return new UI1236Control(bits); - } - - public static implicit operator Byte(UI1236Control control) - { - var @Byte = default(Byte); - - for (var i = 0; i < 8; i++) - { - @Byte ^= (Byte)(control.bits[i] << i); - } - - return @Byte; - } - } } } diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortSettings.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortSettings.cs index 69804f16..d23fe8af 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortSettings.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SerialPortSettings.cs @@ -15,5 +15,9 @@ public SerialPortStopBits StopBits { get; set; } public Int32 RWTimeout { get; set; } = 3000; + + public Boolean RXLoggingEnabled { get; set; } + + public Boolean TXLoggingEnabled { get; set; } } } \ No newline at end of file diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SirtSerialPort.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SirtSerialPort.cs index b6c917ca..8e8af477 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SirtSerialPort.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/SirtSerialPort.cs @@ -4,7 +4,7 @@ using System.Threading; using System.Threading.Tasks; - public class SIRTSerialPort : SerialPort + public class SIRTSerialPort : SerialPortBase { private CancellationTokenSource cancellationTokenSource; private CancellationToken cancellationToken; @@ -21,7 +21,6 @@ public override void Close() { this.StopListening(); - base.Close(); } @@ -29,27 +28,20 @@ { base.EnsureConnected(); - if (!this.listening) + if (this.listening) { this.StopListening(); - this.StartListening(); } + + this.StartListening(); } public override void Open() { base.Open(); - this.StartListening(); } - public override Byte[] Write(params Byte[] data) - { - this.serialPortBase.Write(data, 0, data.Length); - - return data; - } - private void StartListening() { this.cancellationTokenSource = new CancellationTokenSource(); @@ -66,9 +58,9 @@ var buffer = new Byte[0]; - while (true) + while (!sirtSerialPort.cancellationToken.IsCancellationRequested) { - var bytesIn = sirtSerialPort.serialPortBase.Read(); + var bytesIn = sirtSerialPort.Read(0); var bytesInLength = bytesIn.Length; var bufferLength = buffer.Length; @@ -119,7 +111,7 @@ { if (task.Exception != null) { - sirtSerialPort.serialPortBase.Notify(task.Exception.ToString()); + sirtSerialPort.Notify(task.Exception.ToString()); } sirtSerialPort.listening = false; @@ -137,8 +129,10 @@ } catch (Exception e) { - this.serialPortBase.Notify(e.ToString()); + this.Notify(e.ToString()); } + + Thread.Sleep(1); } } } diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/UI1236Control.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/UI1236Control.cs new file mode 100644 index 00000000..361460c9 --- /dev/null +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/UI1236Control.cs @@ -0,0 +1,71 @@ +namespace Common.Hardware.Interfaces.Ports +{ + using System; + + public static partial class SerialPortExtensions + { + internal class UI1236Control + { + private readonly Byte[] bits; + + private UI1236Control(Byte[] bits) + => this.bits = bits; + + public Boolean E0Encryption => this.bits[0] == 1; + + public Boolean E1Encryption => this.bits[1] == 1; + + public Boolean E2Encryption => this.bits[2] == 1; + + public Boolean ReturnResponse + { + get => this.bits[3] == 1; + set => this.bits[3] = (Byte)(value ? 1 : 0); + } + + public Boolean NFNetwork => this.bits[4] == 1; + + public Boolean MultipleCommands + { + get => this.bits[5] == 1; + set => this.bits[5] = (Byte)(value ? 1 : 0); + } + + public Boolean LongControl + { + get => this.bits[6] == 1; + set => this.bits[6] = (Byte)(value ? 1 : 0); + } + + public Boolean MultipleFrames + { + get => this.bits[7] == 1; + set => this.bits[7] = (Byte)(value ? 1 : 0); + } + + public static implicit operator UI1236Control(Byte controlByte) + { + var bits = new Byte[8]; + + for (var i = 0; i < 8; i++) + { + bits[i] = (Byte)((controlByte >> i) & 1); + } + + return new UI1236Control(bits); + } + + public static implicit operator Byte(UI1236Control control) + { + var @Byte = default(Byte); + + for (var i = 0; i < 8; i++) + { + @Byte ^= (Byte)(control.bits[i] << i); + } + + return @Byte; + } + } + } +} diff --git a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/UniProSerialPort.cs b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/UniProSerialPort.cs index 49beebb0..50cde9c2 100644 --- a/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/UniProSerialPort.cs +++ b/Common/Hardware/Interfaces/Ports/Common.Hardware.Interfaces.Ports/UniProSerialPort.cs @@ -1,9 +1,8 @@ namespace Common.Hardware.Interfaces.Ports { using System; - using System.Threading; - public class UniProSerialPort : SerialPort + public class UniProSerialPort : SerialPortBase { public UniProSerialPort(SerialPortSettings settings) : base(settings) { @@ -15,31 +14,23 @@ if (data.TryParseToUniPro(out var bytes)) { - for (int i = 0; i < 3; i++) + var timeout = 3; + + for (var i = 0; i < timeout; i++) { - this.serialPortBase.Write(bytes, 0, bytes.Length); + this.Write(bytes, 0, bytes.Length); - Thread.Sleep(100); - - var timeout = 3; var answerd = false; var buffer = new Byte[0]; while (timeout-- >= 0) { - Thread.Sleep(100); - - var _bytes = this.serialPortBase.Read(); + var _bytes = this.Read(); var bytesLength = _bytes.Length; var bufferLength = buffer.Length; - Thread.Sleep(100); - Array.Resize(ref buffer, bufferLength + bytesLength); - Thread.Sleep(100); - Array.Copy(_bytes, 0, buffer, bufferLength, bytesLength); - Thread.Sleep(100); if (buffer.TryParseFromUniPro(out _data)) { diff --git a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus.Features/Alarm.cs b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus.Features/Alarm.cs index 577cfd5a..3835b2c6 100644 --- a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus.Features/Alarm.cs +++ b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus.Features/Alarm.cs @@ -41,26 +41,57 @@ /// /// Rate = 0.25 * 1/60 * 1/1 = .0041666667 Gal/sec which converts into a Float32 of into 0x3B888889. /// - public float FlowRateGPM + public float FlowRateGPS { get => BitConverter.ToSingle(this.bytes, 4); - set - { - var flowRateGPM = value * (1F / 60) * (1F / 1); - var flowRateIEEE = BitConverter.GetBytes(flowRateGPM); - - flowRateIEEE.CopyTo(this.bytes, 4); - } + set => BitConverter.GetBytes(value).CopyTo(this.bytes, 4); } /// - /// 0x00015180 (86400) seconds, which is 24 hours. + /// Rate = 0.25 * 1/60 * 1/1 = .0041666667 Gal/sec which converts into a Float32 of into 0x3B888889. + /// + public float FlowRateGPM + { + get => this.FlowRateGPS * 60F; + set => this.FlowRateGPS = value / 60F; + } + + /// + /// Converts the value from and to days. /// public uint TimeLimit { get => BitConverter.ToUInt32(this.bytes, 8); set => BitConverter.GetBytes(value).CopyTo(this.bytes, 8); } + + + /// + /// Converts the value from and to days. + /// + public uint TimeLimitMinutes + { + get => this.TimeLimit / 60; + set => this.TimeLimit = value * 60; + } + + /// + /// Converts the value from and to days. + /// + public uint TimeLimitHours + { + get => this.TimeLimitMinutes / 60; + set => this.TimeLimitMinutes = value * 60; + } + + /// + /// Converts the value from and to days. + /// + public uint TimeLimitDays + { + get => this.TimeLimitHours / 24; + set => this.TimeLimitHours = value * 24; + } } public class LeakAlarm : Alarm diff --git a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus.Features/RegisterSettings.cs b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus.Features/RegisterSettings.cs index 435e4bb5..227c4f11 100644 --- a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus.Features/RegisterSettings.cs +++ b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus.Features/RegisterSettings.cs @@ -43,7 +43,7 @@ } // 6 - public byte VolumePerPulseUnit + public byte VolumePerPulseUnits { get => this.bytes[6]; set => this.bytes[6] = value; diff --git a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/IrdaConnection.cs b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/IrdaConnection.cs index c6a505f7..57e3aa88 100644 --- a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/IrdaConnection.cs +++ b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/IrdaConnection.cs @@ -16,16 +16,21 @@ PortName = portName, StopBits = SerialPortStopBits.One }; - this.serialPort = new IRDASerialPort(settings); + this.serialPortBase = new IRDASerialPort(settings); } public override Byte[] Send(params Byte[] bytes) { - this.serialPort.EnsureConnected(); + this.serialPortBase.EnsureConnected(); if (bytes.TryParseToUI1236(out var _bytes)) { - return this.serialPort.Write(_bytes); + var __bytes = this.serialPortBase.Write(_bytes); + + if (__bytes.TryParseFromUI1236(out var data)) + { + return data; + } } return _bytes; diff --git a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/OmniConnection.cs b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/OmniConnection.cs index b4ca49e1..5d2e8f7c 100644 --- a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/OmniConnection.cs +++ b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/OmniConnection.cs @@ -29,6 +29,9 @@ this.connection.Connect(); } + public Byte[] Send(params Byte[] bytes) + => this.connection.Send(bytes); + public EheadPCB ViewEheadPCB() { var response = this.connection.Send(0xFA, 0x01); diff --git a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/SerialPortConnection.cs b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/SerialPortConnection.cs index 077e88fb..423984d4 100644 --- a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/SerialPortConnection.cs +++ b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/SerialPortConnection.cs @@ -9,11 +9,11 @@ { private readonly StringBuilder records = new StringBuilder(); - protected SerialPort serialPort; + protected SerialPortBase serialPortBase; - public void Connect() => this.serialPort.Open(); + public void Connect() => this.serialPortBase.Open(); - public void Disconnect() => this.serialPort.Close(); + public void Disconnect() => this.serialPortBase.Close(); public String GetRecords() { @@ -30,7 +30,7 @@ { this.records.Clear(); - this.serialPort.Logging += text => this.records.AppendLine(text); + this.serialPortBase.Logging += text => this.records.AppendLine(text); } } } diff --git a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/UniProConnection.cs b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/UniProConnection.cs index 9bc40d80..5d5219cb 100644 --- a/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/UniProConnection.cs +++ b/Common/Hardware/WaterMeter/OmniPlus/Common.Hardware.WaterMeter.OmniPlus/UniProConnection.cs @@ -16,14 +16,14 @@ PortName = portName, StopBits = SerialPortStopBits.One }; - this.serialPort = new UniProSerialPort(settings); + this.serialPortBase = new UniProSerialPort(settings); } public override Byte[] Send(params Byte[] bytes) { - this.serialPort.EnsureConnected(); + this.serialPortBase.EnsureConnected(); - return this.serialPort.Write(bytes); + return this.serialPortBase.Write(bytes); } } } diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeTransmission.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeTransmission.cs index 8e1f3df9..c951eeba 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeTransmission.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/ChangeTransmission.cs @@ -4,6 +4,11 @@ public class ChangeTransmission : Pam { + private Byte oldn; + private Byte newn; + private Byte oldt; + private Byte newt; + protected ChangeTransmission(Int32 length, Byte cmd) : base(length, cmd) { } @@ -12,14 +17,53 @@ { } - public UInt16 Interval + public Byte LatWindowIntervalCount { - get => BitConverter.ToUInt16(this.bytes, 1); + get => this.bytes[1]; set { - var bytes = BitConverter.GetBytes(value); + this.oldn = this.newn; + this.newn = value; - Array.Copy(bytes, 0, this.bytes, 1, 2); + if (this.IsValid) + { + this.bytes[2] = this.newn; + } + else + { + this.newn = this.oldn; + this.oldn = this.bytes[2]; + } + } + } + + public Byte LatTXIntervalSeconds + { + get => this.bytes[2]; + set + { + this.oldt = this.newt; + this.newt = value; + + if (this.IsValid) + { + this.bytes[2] = this.newt; + } + else + { + this.newt = this.oldt; + this.oldt = this.bytes[2]; + } + } + } + + protected Boolean IsValid + { + get + { + var x = this.newt * (this.newn + 1); + + return 0 < x && x <= 3600; } } } diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/Pam.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/Pam.cs index beb02705..d60d600c 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/Pam.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister.Features/Pam.cs @@ -14,7 +14,7 @@ public Pam Append(Pam pam) { - var appendBytes = pam.bytes; + var appendBytes = pam.ToByteArray(); var appendLength = appendBytes.Length; var currentLength = this.bytes.Length; var newLength = currentLength + appendLength; 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 aac56830..4586559a 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 @@ -53,7 +53,7 @@ - + diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Endpoint.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Endpoint.cs index 286f8705..6369952e 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Endpoint.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/Endpoint.cs @@ -15,9 +15,9 @@ public String HexKey { get; set; } - public EndpointTask WakeUpTask() + public EndpointTask WakeUp() { - var request = new WritePamRequest + var request = new EndpointTask { Address = this.Address, DelPamSemi = true, @@ -31,10 +31,54 @@ }) }; - return new EndpointTask(request) + //return new EndpointTask(request) + //{ + // HexKey = this.HexKey + //}; + + return request; + } + + public EndpointTask InitializeForInspection() + { + var payload = new ChangeWakeUp() { - HexKey = this.HexKey + Mode = WakeUpMode.StayAwake + } + .Append(new ChangeLATWindows + { + N = 0 + }) + .Append(new WMBusMode + { + WMBusEnabled = true, + InstallationModeEnabled = true, + EncryptionEnabled = true, + }) + .Append(new ChangeTransmission + { + LatWindowIntervalCount = 0, + LatTXIntervalSeconds = 3 + }) + .Append(new ProvidePin + { + AuthLevel = AuthLevel.II + }); + + var request = new EndpointTask + { + Address = this.Address, + WakeUpCmd = true, + DelPamSemi = true, + Payload = payload }; + + return request; + } + + public EndpointTask ConfigureForInspection() + { + return new EndpointTask(); } } } \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EndpointTask.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EndpointTask.cs index 79225924..a43b695d 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EndpointTask.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EndpointTask.cs @@ -1,17 +1,17 @@ namespace Common.Hardware.WaterMeter.eRegister { - using Common.Hardware.Interfaces.Ports.SIRT; using Common.Hardware.Interfaces.Ports.SIRT.Responses; + using Common.Hardware.Interfaces.Ports.SIRT.Tasks; using Common.Utils.Extensions; using System; using System.Collections.Generic; - public class EndpointTask : SIRTTask + public class EndpointTask : WPAMTask { private Byte[] key; - public EndpointTask(SIRTRequest request, UInt32 timeout = 15) : base(request, timeout) + public EndpointTask(UInt32 timeout = 15) : base(timeout) { } @@ -37,55 +37,7 @@ var payload = response.Payload; var length = response.Payload.Length; - if (this.key?.Length == 16) - { - //var bytesToEncryptCount = this.request.Payload.Length + 6; // 4(address) + 2(crc) - //var keyByte = Byte.MaxValue; - //var reference = address; - - //for (Int32 byteIndex = 9, encryptIndex = 0; byteIndex < bytesToEncryptCount; byteIndex++, encryptIndex++) - //{ - // // Update KeyDefinition for this byte - // keyByte += (Byte)(((reference >> ((keyByte & 0x3) << 3)) & 0xFF) >> ((keyByte >> 6) & 1)); - - // // Update the unencrypted reference before the byte gets encrypted - // reference = reference << 8; - // reference += requestBytesList[encryptIndex]; - - // // Encrypt the data by applying the resepective key - // requestBytesList[encryptIndex] ^= this.key[(keyByte >> 2) & 0x0F]; - - // // Check if data has to be inverted - // if (keyByte > 127) - // { - // requestBytesList[encryptIndex] = (Byte)~requestBytesList[encryptIndex]; - // } - //} - - //byte[] Target = new byte[MessageAppFormat.Length]; - //Array.Copy(MessageAppFormat, Target, MessageAppFormat.Length); - - //int BeginEncryptedChars = 14; - //int EndEncryptedChars = BeginEncryptedChars + MessageAppFormat[7] - 6; - - //byte Zeichen = MessageAppFormat[9]; - - //for (int i = BeginEncryptedChars; i < EndEncryptedChars; i++) - //{ - // Zeichen += (byte)((Target[i - (Zeichen & 0x3) - 1] >> ((Zeichen >> 6) & 0x1))); - // Target[i] ^= Key[((Zeichen >> 2) & 0x0F)]; - // if (Zeichen > 127) - // { - // Target[i] = (byte)~Target[i]; - // } - //} - //if (TelegramCalcCRC(Target) == 0) - //{ - // MessageAppFormat = Target; - // return true; - //} - //return false; - } + this.DecryptIfNecessery(payload, length); if (length == 13) { @@ -172,5 +124,30 @@ return bytes; } + + private void DecryptIfNecessery(Byte[] payload, Int32 length) + { + if (this.key?.Length == 16) + { + var target = new Byte[length]; + + Array.Copy(payload, target, length); + + var end = target[7] - 6; + var token = target[9]; + + for (var start = 0; start < end; start++) + { + token += (Byte)(target[start - (token & 0x3) - 1] >> ((token >> 6) & 0x1)); + + target[start] ^= this.key[(token >> 2) & 0x0F]; + + if (token > 127) + { + target[start] = (Byte)~target[start]; + } + } + } + } } } diff --git a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EndpointsBatch.cs b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingBatch.cs similarity index 57% rename from Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EndpointsBatch.cs rename to Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingBatch.cs index 319a238c..57171f67 100644 --- a/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/EndpointsBatch.cs +++ b/Common/Hardware/WaterMeter/eRegister/Common.Hardware.WaterMeter.eRegister/ProgrammingBatch.cs @@ -7,12 +7,12 @@ using System.Collections.Generic; using System.Linq; - public class EndpointsBatch + public class ProgrammingBatch { - private readonly ICollection endpoints; private readonly SIRTBroadcaster broadcaster; + private readonly ICollection endpoints; - public EndpointsBatch(String portName, Int32 rwTimeout = 3000) + public ProgrammingBatch(String portName, Int32 rwTimeout = 3000) { this.endpoints = new List(); this.broadcaster = new SIRTBroadcaster(new SerialPortSettings @@ -26,13 +26,22 @@ }); } + public event Action Activated + { + add => this.broadcaster.Activated += value; + remove => this.broadcaster.Activated -= value; + } + public Boolean IsConnected => this.broadcaster.IsOpen; - public void ConnectSIRT() => this.broadcaster.Open(); + public void ActivateSIRT() => this.broadcaster.Open(); - public IEnumerable> InitInspection() + public void DeactivateSIRT() => this.broadcaster.Close(); + + public IEnumerable> InitProgramming() { - yield return this.endpoints.Select(x => x.WakeUpTask()); + yield return this.endpoints.Select(x => x.InitializeForInspection()); + yield return this.endpoints.Select(x => x.ConfigureForInspection()); } } } diff --git a/Common/Hardware/WaterMeter/eRegister/EregisterConnector/EregisterConnector.cs b/Common/Hardware/WaterMeter/eRegister/EregisterConnector/EregisterConnector.cs index a40801e0..22bf5e31 100644 --- a/Common/Hardware/WaterMeter/eRegister/EregisterConnector/EregisterConnector.cs +++ b/Common/Hardware/WaterMeter/eRegister/EregisterConnector/EregisterConnector.cs @@ -11,7 +11,7 @@ public class EregisterConnector { - private readonly EndpointsBatch endpoints; + private readonly ProgrammingBatch eprogramming; private Application app; private Window window; @@ -19,9 +19,15 @@ { var portName = Appsettings.Current["SIRT.PortName"]; var _timeout = Appsettings.Current["SIRT.RWTimeout"]; - var _ = Int32.TryParse(_timeout, out var timeout); - this.endpoints = new EndpointsBatch(portName, timeout); + if (Int32.TryParse(_timeout, out var timeout)) + { + this.eprogramming = new ProgrammingBatch(portName, timeout); + } + else + { + this.eprogramming = new ProgrammingBatch(portName); + } } public void Add(Int32 posno, Int32 serialno, Int32 address, String encKey, String setup, Boolean skipChecks) @@ -34,14 +40,14 @@ var awaiter = new ManualResetEventSlim(); var threadStartCallback = new ParameterizedThreadStart((object parameter) => { - if (parameter is EndpointsBatch endpoints) + if (parameter is ProgrammingBatch endpoints) { this.app = new App(); this.window = new InitInspectionWindow(); if (this.window.DataContext is InitInspectionVM vm) { - vm.Set(this.endpoints); + vm.InitInspection(this.eprogramming); } app.Run(window); @@ -50,7 +56,7 @@ }); var staThread = new Thread(threadStartCallback); staThread.SetApartmentState(ApartmentState.STA); - staThread.Start(this.endpoints); + staThread.Start(this.eprogramming); awaiter.Wait(); } } diff --git a/Common/OmniPlus/InspectionUI/App.config b/Common/OmniPlus/InspectionUI/App.config index 5d0d69bd..0c6b9785 100644 --- a/Common/OmniPlus/InspectionUI/App.config +++ b/Common/OmniPlus/InspectionUI/App.config @@ -5,9 +5,9 @@ - - + + diff --git a/Common/OmniPlus/InspectionUI/InspectionUI.csproj b/Common/OmniPlus/InspectionUI/InspectionUI.csproj index 7c77c408..f96f9be0 100644 --- a/Common/OmniPlus/InspectionUI/InspectionUI.csproj +++ b/Common/OmniPlus/InspectionUI/InspectionUI.csproj @@ -148,6 +148,10 @@ {C6BFAC88-5647-4131-90B1-4D6265E08348} InspectionUI.Abstraction + + {8E1431E9-9B14-4BC2-8B65-47357C97B1FC} + InspectionUI.Plugins.Omni + {41E949AD-FBF6-47A3-AC1D-7E17AB7F1252} InspectionUI.RemoteControl diff --git a/Common/OmniPlus/InspectionUI/Plugins/MainWindowVM.cs b/Common/OmniPlus/InspectionUI/Plugins/MainWindowVM.cs index ec6e9f18..b360b6aa 100644 --- a/Common/OmniPlus/InspectionUI/Plugins/MainWindowVM.cs +++ b/Common/OmniPlus/InspectionUI/Plugins/MainWindowVM.cs @@ -1,7 +1,7 @@ namespace InspectionUI { using InspectionUI.Abstraction.Interfaces; - + using InspectionUI.Plugins.Omni; using System.Collections.ObjectModel; using System.Threading.Tasks; using System.Windows; @@ -68,30 +68,30 @@ get => this.plugin; set { - this.Set(() => this.plugin = value); + //this.Set(() => this.plugin = value); - this.Notifications = default(string); - this.IsCancelEnabled = false; - this.IsLoadEnabled = false; - this.IsStartEnabled = false; - this.testBench.Layout.Clear(); - this.testBench.Layout.Refresh(); + //this.Notifications = default(string); + //this.IsCancelEnabled = false; + //this.IsLoadEnabled = false; + //this.IsStartEnabled = false; + //this.testBench.Layout.Clear(); + //this.testBench.Layout.Refresh(); - Task.Factory - .StartNew(() => - { - this.TestBatch = this.pluginsManager.Activate(value, this.testBench); - }) - .ContinueWith(x => - { - if (x.Exception != null) - { - this.Notifications = x.Exception.ToString(); - } + //Task.Factory + // .StartNew(() => + // { + // this.TestBatch = this.pluginsManager.Activate(value, this.testBench); + // }) + // .ContinueWith(x => + // { + // if (x.Exception != null) + // { + // this.Notifications = x.Exception.ToString(); + // } - this.IsLoadEnabled = this.TestBatch != null; - this.TestBatch?.Initialize(); - }); + // this.IsLoadEnabled = this.TestBatch != null; + // this.TestBatch?.Initialize(); + // }); } } @@ -139,7 +139,7 @@ public ObservableCollection Plugins { get; } - protected ITestBatch TestBatch { get; private set; } + protected TestBatch TestBatch { get; private set; } public override void Dispose() { @@ -158,7 +158,7 @@ this.IsLoadEnabled = false; this.IsStartEnabled = false; - this.TestBatch?.LoadInspection(); + this.TestBatch.LoadInspection(); }) .ContinueWith(task => { @@ -183,7 +183,7 @@ this.IsLoadEnabled = false; this.IsStartEnabled = false; - this.TestBatch?.StartInspection(); + this.TestBatch.StartInspection(); }) .ContinueWith(task => { @@ -234,33 +234,33 @@ Task.Factory .StartNew(() => { - this.DispatcherInvoke(() => - { - this.Plugins.Clear(); + //this.DispatcherInvoke(() => + //{ + // this.Plugins.Clear(); - foreach (var plugin in this.pluginsManager.AvailablePlugins()) - { - this.Plugins.Add(plugin); - } + // //foreach (var plugin in this.pluginsManager.AvailablePlugins()) + // //{ + // // this.Plugins.Add(plugin); + // //} - this.PluginsDropdownVisibility = Visibility.Visible; - //= this.Plugins.Count > 1 - //? Visibility.Visible - //: Visibility.Collapsed; + // this.PluginsDropdownVisibility = Visibility.Collapsed; + // //= this.Plugins.Count > 1 + // //? Visibility.Visible + // //: Visibility.Collapsed; - //this.TestBatch = this.pluginsManager.Activate(null, this.testBench); - //this.IsLoadEnabled = this.TestBatch != null; - //this.TestBatch?.Initialize(); - }); + // this.TestBatch = this.pluginsManager.Activate(null, this.testBench); + // this.IsLoadEnabled = this.TestBatch != null; + // this.TestBatch?.Initialize(); + //}); - //this.DispatcherInvoke(this.Plugins.Clear); - //this.PluginsDropdownVisibility - // = this.Plugins.Count > 1 - // ? Visibility.Visible - // : Visibility.Collapsed; - //this.TestBatch = this.pluginsManager.Activate(null, this.testBench); - //this.IsLoadEnabled = this.TestBatch != null; - //this.TestBatch?.Initialize(); + this.DispatcherInvoke(this.Plugins.Clear); + this.PluginsDropdownVisibility + = this.Plugins.Count > 1 + ? Visibility.Visible + : Visibility.Collapsed; + this.TestBatch = this.pluginsManager.Activate(null, this.testBench); + this.IsLoadEnabled = this.TestBatch != null; + this.TestBatch?.Initialize(); }) .ContinueWith(task => { diff --git a/Common/OmniPlus/InspectionUI/Plugins/PluginsManager.cs b/Common/OmniPlus/InspectionUI/Plugins/PluginsManager.cs index a5ef30ef..baa1588d 100644 --- a/Common/OmniPlus/InspectionUI/Plugins/PluginsManager.cs +++ b/Common/OmniPlus/InspectionUI/Plugins/PluginsManager.cs @@ -2,7 +2,7 @@ { using InspectionUI.Abstraction; using InspectionUI.Abstraction.Interfaces; - + using InspectionUI.Plugins.Omni; using System; using System.Collections.Generic; using System.IO; @@ -16,24 +16,26 @@ internal bool IsActivated { get; private set; } - internal ITestBatch Activate(string plugin, ITestBench testBench) + internal TestBatch Activate(string plugin, ITestBench testBench) { - if (!string.IsNullOrWhiteSpace(plugin) && this.entryPoints.ContainsKey(plugin)) - { - var entryPoint = this.entryPoints[plugin]; - var instance = Activator.CreateInstance(entryPoint, new object[] { testBench, App.Appsettings }); + return new TestBatch(testBench, App.Appsettings); - if (instance is ITestBatch testBatch) - { - return testBatch; - } - } + //if (!string.IsNullOrWhiteSpace(plugin) && this.entryPoints.ContainsKey(plugin)) + //{ + // var entryPoint = this.entryPoints[plugin]; + // var instance = Activator.CreateInstance(entryPoint, new object[] { testBench, App.Appsettings }); + + // if (instance is ITestBatch testBatch) + // { + // return testBatch; + // } + //} //else //{ - // return new Plugins.Omni.TestBatch(testBench, App.Appsettings); + // return new TestBatch(testBench, App.Appsettings); //} - return default(ITestBatch); + //return default(ITestBatch); } internal IEnumerable AvailablePlugins() @@ -63,27 +65,27 @@ private static void CopyDirectories(string sourceDirectory, string destinationDirectory) { - CopyFiles(sourceDirectory, destinationDirectory); + //CopyFiles(sourceDirectory, destinationDirectory); - foreach (var subDirectory in Directory.GetDirectories(sourceDirectory)) - { - var subDirectoryName = new DirectoryInfo(subDirectory).Name; - var destinationSubDirectoryPath = Path.Combine(destinationDirectory, subDirectoryName); - var destinationSubDirectory = Directory.CreateDirectory(destinationSubDirectoryPath).FullName; + //foreach (var subDirectory in Directory.GetDirectories(sourceDirectory)) + //{ + // var subDirectoryName = new DirectoryInfo(subDirectory).Name; + // var destinationSubDirectoryPath = Path.Combine(destinationDirectory, subDirectoryName); + // var destinationSubDirectory = Directory.CreateDirectory(destinationSubDirectoryPath).FullName; - CopyDirectories(subDirectory, destinationSubDirectory); - } + // CopyDirectories(subDirectory, destinationSubDirectory); + //} } private static void CopyFiles(string sourceDirectory, string destinationDirectory) { - foreach (var sourceFile in Directory.GetFiles(sourceDirectory)) - { - var sourceFileName = Path.GetFileName(sourceFile); - var destinationFile = Path.Combine(destinationDirectory, sourceFileName); + //foreach (var sourceFile in Directory.GetFiles(sourceDirectory)) + //{ + // var sourceFileName = Path.GetFileName(sourceFile); + // var destinationFile = Path.Combine(destinationDirectory, sourceFileName); - File.Copy(sourceFile, destinationFile, true); - } + // File.Copy(sourceFile, destinationFile, true); + //} } } } diff --git a/Common/OmniPlus/OmniPlus/Features/Alarm.cs b/Common/OmniPlus/OmniPlus/Features/Alarm.cs index 0d330fcb..cadcef41 100644 --- a/Common/OmniPlus/OmniPlus/Features/Alarm.cs +++ b/Common/OmniPlus/OmniPlus/Features/Alarm.cs @@ -44,13 +44,7 @@ public float FlowRateGPM { get => BitConverter.ToSingle(this.bytes, 4); - set - { - var flowRateGPM = value * (1F / 60) * (1F / 1); - var flowRateIEEE = BitConverter.GetBytes(flowRateGPM); - - flowRateIEEE.CopyTo(this.bytes, 4); - } + set => BitConverter.GetBytes(value).CopyTo(this.bytes, 4); } /// diff --git a/Common/OmniPlus/OmniPlus/Inspection/OmniMeter.cs b/Common/OmniPlus/OmniPlus/Inspection/OmniMeter.cs index c2a05b61..a3374600 100644 --- a/Common/OmniPlus/OmniPlus/Inspection/OmniMeter.cs +++ b/Common/OmniPlus/OmniPlus/Inspection/OmniMeter.cs @@ -147,7 +147,7 @@ ReadingPreset = configuration.Readings.Value, RebootCount = 0, SystemTime = Epoch20000101.UTCNow, - DeviceID = "OMNI-01" + DeviceID = defaults.DeviceID }); if (setConfiguration.Completed) diff --git a/Common/PendingEmails/App.config b/Common/PendingEmails/App.config index 9405e824..f0c21a8d 100644 --- a/Common/PendingEmails/App.config +++ b/Common/PendingEmails/App.config @@ -1,7 +1,7 @@  - + diff --git a/Common/PendingEmails/PendingEmails.csproj b/Common/PendingEmails/PendingEmails.csproj index 830ac4fc..ab1bef52 100644 --- a/Common/PendingEmails/PendingEmails.csproj +++ b/Common/PendingEmails/PendingEmails.csproj @@ -11,6 +11,21 @@ v4.0 512 true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true AnyCPU @@ -48,5 +63,12 @@ + + + False + .NET Framework 3.5 SP1 + false + + \ No newline at end of file diff --git a/Common/PendingEmails/Program.cs b/Common/PendingEmails/Program.cs index b2aade1e..ab194ed1 100644 --- a/Common/PendingEmails/Program.cs +++ b/Common/PendingEmails/Program.cs @@ -1,193 +1,328 @@ -namespace PendingEmails -{ - using System; - using System.Collections.Generic; - using System.Configuration; - using System.Data.SqlClient; - using System.IO; - using System.Linq; - using System.Net.Mail; - using System.Threading; - using System.Timers; - using SystemTimersTimer = System.Timers.Timer; - - public class Program - { - private static readonly SystemTimersTimer timer = new SystemTimersTimer(); - - private static void Main() - { - try - { - timer.AutoReset = true; - timer.Interval = 600_000; - timer.Elapsed += Timer_Elapsed; - - while (true) - { - Timer_Elapsed(null, null); - timer.Start(); - var awaiter = new ManualResetEventSlim(); - awaiter.Wait(); - timer.Stop(); - } - } - catch (Exception e) - { - LogToFile(e); - } - - } - - private static void Timer_Elapsed(Object _, ElapsedEventArgs _1) - { - LogToFile($"loading pending emails"); - - var connectionString = ConfigurationManager.ConnectionStrings["Auftrag"].ConnectionString; - - using (var connection = new SqlConnection(connectionString)) - { - connection.FireInfoMessageEventOnUserErrors = true; - connection.InfoMessage += (_2, args) => LogToFile(args.Message); - connection.Open(); - - var updated = new HashSet(); - var countAll = 0; - - using (var command = connection.CreateCommand()) - { - command.CommandText = @" - SELECT [Sender] - , [Subject] - , [Body] - , [Recipients] - , [CC] - , [Id] - FROM [Messages] - WHERE [OutDate] IS NULL - ORDER BY [InDate] DESC"; - - using (var reader = command.ExecuteReader()) - { - countAll++; - - while (reader.Read()) - { - try - { - var email = new MailMessage(); - var from = ConfigurationManager.AppSettings["DefaultSender"]; - var @default = true; - - if (!reader.IsDBNull(0)) - { - from = reader.GetString(0); - @default = false; - } - - email.From = new MailAddress(from); - email.Subject = $"{reader.GetValue(1)}"; - email.Body = $"{reader.GetValue(2)}"; - - $"{reader.GetValue(3)}" - .Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries) - .Select(x => new MailAddress(x)) - .ToList() - .ForEach(email.To.Add); - - $"{reader.GetValue(4)}" - .Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries) - .Select(x => new MailAddress(x)) - .ToList() - .ForEach(email.CC.Add); - - var emailId = reader.GetInt32(5); - - if (SendEmail(email)) - { - updated.Add(emailId); - } - else if (!@default) - { - email.From = new MailAddress(ConfigurationManager.AppSettings["DefaultSender"]); - - if (SendEmail(email)) - { - updated.Add(emailId); - } - } - } - catch (Exception e) - { - LogToFile(e); - } - } - } - } - - var updatedCount = updated.Count; - - if (updatedCount > 0) - { - try - { - LogToFile($"updating: {string.Join(", ", updated)}"); - - using (var command = connection.CreateCommand()) - { - command.CommandText = $@" - UPDATE [Messages] - SET [OutDate] = GETDATE() - WHERE [Id] IN ({string.Join(", ", updated)})"; - - command.ExecuteNonQuery(); - } - - Console.WriteLine($"{updatedCount}/{countAll} email{(updatedCount == 1 ? null : "s")} sent."); - LogToFile($"{updatedCount}/{countAll} emails sent."); - } - catch (Exception e) - { - LogToFile(e); - } - } - else - { - LogToFile($"there are no pending emails to send"); - } - } - } - - private static Boolean SendEmail(MailMessage email) - { - try - { - using (var smtpClient = new SmtpClient("smtp.xylem.com", 587)) - { - smtpClient.Timeout = 5000; - smtpClient.UseDefaultCredentials = true; - smtpClient.Send(email); - } - - return true; - } - catch (Exception e) - { - LogToFile(e); - } - - return false; - } - - private static void LogToFile(Object e) - => File.AppendAllText(GetOrCreateFile(), $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {e}{Environment.NewLine}"); - - private static String GetOrCreateFile() - { - var logFolder = ConfigurationManager.AppSettings["LogFolder"]; - var logPath = Directory.CreateDirectory(logFolder).FullName; - - return Path.Combine(logPath, $"{DateTime.Now:yyyy-MM-dd}.txt"); - } - } -} +namespace PendingEmails +{ + using System; + using System.Collections.Generic; + using System.Configuration; + using System.Data; + using System.Data.SqlClient; + using System.IO; + using System.Linq; + using System.Net.Mail; + using System.Threading; + using System.Timers; + using SystemTimersTimer = System.Timers.Timer; + + public static class Program + { + private static readonly SystemTimersTimer timer = new SystemTimersTimer(); + + private static void Main() + { + try + { + timer.AutoReset = true; + timer.Interval = 600_000; + timer.Elapsed += Timer_Elapsed; + + while (true) + { + Timer_Elapsed(null, null); + timer.Start(); + var awaiter = new ManualResetEventSlim(); + awaiter.Wait(); + timer.Stop(); + } + } + catch (Exception e) + { + LogToFile(e.Message); + } + + } + + public class Ready + { + public string Source { get; set; } + + public string Subject { get; set; } + + public string Body { get; set; } + } + + private static void Timer_Elapsed(Object _, ElapsedEventArgs _1) + { + LogToFile($"loading pending emails"); + + var connectionString = ConfigurationManager.ConnectionStrings["Auftrag"].ConnectionString; + + using (var connection = new SqlConnection(connectionString)) + { + connection.FireInfoMessageEventOnUserErrors = true; + connection.InfoMessage += (_2, args) => LogToFile(args.Message); + connection.Open(); + + var ready = new List(); + + using (var command = connection.CreateCommand()) + { + command.CommandTimeout = 60000; + command.CommandText = @" + SELECT [Pruefstation] + , [Pruefdatum] + , [Mitarbaiter] + , [Auftrag] + , [Position] + , [Fertigungsauftrag] + , [Merkmal] + , [Bezeichnung] + , [Menge] + , [SerienNrVon] + , [SerienNrBis] + , [Kunde] + , [Kundenort] + FROM [AlleAuftraegeMitGarantieAusLetzte13Min] + ORDER BY [Pruefdatum]"; + + using (var reader = command.ExecuteReader()) + { + while (reader.Read()) + { + reader.AddToPendingMessages(); + } + } + } + + var updated = new HashSet(); + var countAll = 0; + + using (var command = connection.CreateCommand()) + { + command.CommandText = @" + SELECT [Sender] + , [Subject] + , [Body] + , [Recipients] + , [CC] + , [Id] + FROM [Messages] + WHERE [OutDate] IS NULL + ORDER BY [InDate] DESC"; + + using (var reader = command.ExecuteReader()) + { + while (reader.Read()) + { + try + { + var email = new MailMessage(); + var from = ConfigurationManager.AppSettings["DefaultSender"]; + email.From = new MailAddress(from); + email.Subject = $"{reader.GetValue(1)}"; + email.Body = $"{reader.GetValue(2)}"; + + $"{reader.GetValue(3)}" + .Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries) + .Select(x => new MailAddress(x)) + .ToList() + .ForEach(email.To.Add); + + $"{reader.GetValue(4)}" + .Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries) + .Select(x => new MailAddress(x)) + .ToList() + .ForEach(email.CC.Add); + + var messageId = reader.GetValue(5); + + if (SendEmail(email)) + { + updated.Add(messageId); + } + } + catch (Exception e) + { + LogToFile(e); + } + + countAll++; + } + } + } + + var updatedCount = updated.Count; + + if (updatedCount > 0) + { + try + { + LogToFile($"updating: {string.Join(", ", updated)}"); + + using (var command = connection.CreateCommand()) + { + command.CommandText = $@" + UPDATE [Messages] + SET [OutDate] = GETDATE() + WHERE [Id] IN ({string.Join(", ", updated)})"; + + command.ExecuteNonQuery(); + } + + Console.WriteLine($"{updatedCount}/{countAll} email{(updatedCount == 1 ? null : "s")} sent."); + LogToFile($"{updatedCount}/{countAll} emails sent."); + } + catch (Exception e) + { + LogToFile(e); + } + } + else + { + LogToFile($"there are no pending emails to send"); + } + } + } + + private static Boolean SendEmail(MailMessage email) + { + try + { + using (var smtpClient = new SmtpClient("smtp.xylem.com", 587)) + { + smtpClient.UseDefaultCredentials = true; + smtpClient.Send(email); + } + + return true; + } + catch (Exception e) + { + LogToFile(e); + } + + return false; + } + + private static void LogToFile(Object e) + => File.AppendAllText(GetOrCreateFile(), $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {e}{Environment.NewLine}"); + + private static String GetOrCreateFile() + { + var logFolder = ConfigurationManager.AppSettings["LogFolder"]; + var logPath = Directory.CreateDirectory(logFolder).FullName; + + return Path.Combine(logPath, $"{DateTime.Now:yyyy-MM-dd}.txt"); + } + + private static void AddToPendingMessages(this SqlDataReader reader) + { + var psno = reader.GetValue(0); + var date = reader.GetValue(1); + var empl = reader.GetValue(2); + var orderno = reader.GetValue(3); + var posno = reader.GetValue(4); + var pono = reader.GetValue(5); + var vako = reader.GetValue(6); + var desc = reader.GetValue(7); + var count = reader.GetValue(8); + var snfrom = reader.GetValue(9); + var snto = reader.GetValue(10); + var client = reader.GetValue(11); + var ort = reader.GetValue(12); + + var source = $"{orderno}/{posno}"; + var subject = $"{ort} - {orderno}/{posno} erfolgreich geprüft - bitte Garantiescheine drucken und bereitlegen!"; + var body = $"Auftrag: {orderno}/{posno}{Environment.NewLine}" + $"FertigungsauftragNr: {pono}{Environment.NewLine}" + + $"{Environment.NewLine}" + $"{count} Stück {desc}{Environment.NewLine}" + $"wurde an der Prüfstation: {psno}{Environment.NewLine}" + $"am {date:dd-MM-yyyy} um {date:HH:mm} Uhr{Environment.NewLine}" + $"von {empl} vollständig geprüft.{Environment.NewLine}" + $"{Environment.NewLine}" + $"Seriennummern: {snfrom} - {snto}{Environment.NewLine}" + + $"{Environment.NewLine}" + + $"{vako}{Environment.NewLine}"; + + var connectionString = ConfigurationManager.ConnectionStrings["Auftrag"].ConnectionString; + + using (var connection = new SqlConnection(connectionString)) + { + connection.FireInfoMessageEventOnUserErrors = true; + connection.InfoMessage += (_2, args) => LogToFile(args.Message); + connection.Open(); + + var ready = new List(); + + using (var command = connection.CreateCommand()) + { + command.CommandText = $@" + IF (SELECT COUNT(1) FROM [Messages] WHERE [Source] = @{nameof(source)}) = 0 + BEGIN + INSERT INTO [Messages] + ( [Source] + , [InDate] + , [StationNr] + , [PCName] + , [IPAddress] + , [Trace] + , [Sender] + , [Subject] + , [Body] + , [IsHtml] + , [Recipients] + , [CC] + , [OutDate] + , [State]) + VALUES (@{nameof(source)} + , GETDATE() + , @{nameof(psno)} + , 'localhost' + , '127.0.0.1' + , 'Xylem.Common.Service.PendingMails.Timer_Elapsed(Object, ElapsedEventArgs))' + , 'noreplay@xylem.com' + , @{nameof(subject)} + , @{nameof(body)} + , 0 + , 'uwe.kubon@xylem.com' + , 'stoyan.zlatev@xylem.com' + , NULL + , 'Automatische fertigmeldung für garantiescheine') + END"; + command.Parameters.AddWithValue(nameof(source), source); + command.Parameters.AddWithValue(nameof(subject), subject); + command.Parameters.AddWithValue(nameof(body), body); + command.Parameters.AddWithValue(nameof(psno), psno); + + LogToFile($"Inserted: {command.ExecuteNonQuery()}"); + + command.Parameters.Clear(); + } + } + } + + private static T GetValue(this SqlDataReader sqlDataReader, Int32 index, T defaultValue = default(T)) + { + var value = defaultValue; + + if (0 <= index && index < sqlDataReader.FieldCount && !sqlDataReader.IsDBNull(index)) + { + var sqlValue = sqlDataReader.GetValue(index); + var type = Nullable.GetUnderlyingType(typeof(T)); + + if (type is null) + { + type = typeof(T); + } + + try + { + sqlValue = Convert.ChangeType(sqlValue, type); + + if (sqlValue is T expectedValue) + { + value = expectedValue; + } + } + catch (Exception e) + { + LogToFile(e); + } + } + + return value; + } + } +} diff --git a/Common/Ui/Common.UI.SIRTBroadcaster/Common.UI.SIRTBroadcaster.csproj b/Common/Ui/Common.UI.SIRTBroadcaster/Common.UI.SIRTBroadcaster.csproj index f8bcb4ba..75043f30 100644 --- a/Common/Ui/Common.UI.SIRTBroadcaster/Common.UI.SIRTBroadcaster.csproj +++ b/Common/Ui/Common.UI.SIRTBroadcaster/Common.UI.SIRTBroadcaster.csproj @@ -64,6 +64,7 @@ InitInspectionWindow.xaml + @@ -72,6 +73,7 @@ + diff --git a/Common/Ui/Common.UI.SIRTBroadcaster/InitInspectionWindow.xaml b/Common/Ui/Common.UI.SIRTBroadcaster/InitInspectionWindow.xaml index f98d1ce4..6ced5c2e 100644 --- a/Common/Ui/Common.UI.SIRTBroadcaster/InitInspectionWindow.xaml +++ b/Common/Ui/Common.UI.SIRTBroadcaster/InitInspectionWindow.xaml @@ -2,7 +2,6 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:VM="clr-namespace:Common.UI.SIRTBroadcaster.ViewModels" - xmlns:U="clr-namespace:Common.UI.SIRTBroadcaster.Utilities" WindowStartupLocation="CenterScreen" WindowStyle="SingleBorderWindow" WindowState="Normal" @@ -11,264 +10,63 @@ Height="500" FontSize="13" FontFamily="Verdana"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -