From 15f978ab3d7a95b202e253b89d585e630660667e Mon Sep 17 00:00:00 2001 From: Thomas Wiedebusch Date: Tue, 27 May 2025 11:30:35 +0200 Subject: [PATCH] merged Dev_picking to main --- Common/Common.sln | 142 +- .../GenesisCore/RegisterRestorer.cs.bak | 1516 ----------------- .../BaseProcessStatesDef.cs | 2 +- .../EolProcesses/CheckRadio.cs.bak | 829 +++++++++ .../ProductionProcesses/IProcessStateDef.cs | 2 +- .../ProductionProcesses/ProcessController.cs | 2 +- .../ProductionUiCordonel.csproj | 4 - .../ProductionWindow.xaml.cs | 1 - 8 files changed, 903 insertions(+), 1595 deletions(-) delete mode 100644 Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs.bak create mode 100644 Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckRadio.cs.bak diff --git a/Common/Common.sln b/Common/Common.sln index 05500228..17747b42 100644 --- a/Common/Common.sln +++ b/Common/Common.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.33423.255 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36121.58 d17.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{7A0EE7B8-6B7E-41E9-B679-319C8CA48CF1}" EndProject @@ -346,7 +346,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LaaPackages.Features.Cordon EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LaaPackages.Extensions", "LaaPackages\LaaPackages.Extensions\LaaPackages.Extensions.csproj", "{15A06398-ECB6-49C9-ACB4-52A495A886A6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LaaProductionWeb.Resources", "LaaPackages\LaaProductionWeb.Resources\LaaProductionWeb.Resources.csproj", "{DA65E376-3D35-4D96-913A-7197FCA6DF48}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LaaProductionWeb.Resources", "LaaPackages\LaaProductionWeb.Resources\LaaProductionWeb.Resources.csproj", "{9E070488-15DE-418A-8606-5B79056C6E9F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserAccessCtrl", "Utils\UserAccessCtrl\UserAccessCtrl.csproj", "{2D55BBD1-5373-484C-8781-C6ECEAFC2A90}" EndProject @@ -365,9 +365,6 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonConsole", "CommonConsole\CommonConsole.csproj", "{AFC428F5-0141-4A3F-BEF2-470A89D972F6}" EndProject Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - Utils\DateTimeServerShared\DateTimeServerShared.projitems*{4806d89a-fbfb-41bc-aaa7-2242444bf55a}*SharedItemsImports = 4 - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution _MANUAL_CONTROL|Any CPU = _MANUAL_CONTROL|Any CPU _MANUAL_CONTROL|Mixed Platforms = _MANUAL_CONTROL|Mixed Platforms @@ -5326,70 +5323,70 @@ Global {15A06398-ECB6-49C9-ACB4-52A495A886A6}.XP32bit|x64.Build.0 = Release|Any CPU {15A06398-ECB6-49C9-ACB4-52A495A886A6}.XP32bit|x86.ActiveCfg = Release|Any CPU {15A06398-ECB6-49C9-ACB4-52A495A886A6}.XP32bit|x86.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.COM|Any CPU.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.COM|Any CPU.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.COM|Mixed Platforms.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.COM|Mixed Platforms.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.COM|x64.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.COM|x64.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.COM|x86.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.COM|x86.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Debug|x64.ActiveCfg = Debug|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Debug|x64.Build.0 = Debug|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Debug|x86.ActiveCfg = Debug|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Debug|x86.Build.0 = Debug|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.GenesisDisplayTool_V01|Any CPU.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.GenesisDisplayTool_V01|Any CPU.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.GenesisDisplayTool_V01|Mixed Platforms.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.GenesisDisplayTool_V01|Mixed Platforms.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.GenesisDisplayTool_V01|x64.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.GenesisDisplayTool_V01|x64.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.GenesisDisplayTool_V01|x86.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.GenesisDisplayTool_V01|x86.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.PerformTest|Any CPU.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.PerformTest|Any CPU.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.PerformTest|Mixed Platforms.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.PerformTest|Mixed Platforms.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.PerformTest|x64.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.PerformTest|x64.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.PerformTest|x86.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.PerformTest|x86.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Release|Any CPU.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Release|x64.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Release|x64.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Release|x86.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.Release|x86.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.ReleaseTest|x64.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.ReleaseTest|x64.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.ReleaseTest|x86.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.ReleaseTest|x86.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.XP32bit|Any CPU.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.XP32bit|x64.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.XP32bit|x64.Build.0 = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.XP32bit|x86.ActiveCfg = Release|Any CPU - {DA65E376-3D35-4D96-913A-7197FCA6DF48}.XP32bit|x86.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.COM|Any CPU.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.COM|Any CPU.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.COM|Mixed Platforms.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.COM|Mixed Platforms.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.COM|x64.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.COM|x64.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.COM|x86.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.COM|x86.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Debug|x64.ActiveCfg = Debug|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Debug|x64.Build.0 = Debug|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Debug|x86.ActiveCfg = Debug|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Debug|x86.Build.0 = Debug|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.GenesisDisplayTool_V01|Any CPU.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.GenesisDisplayTool_V01|Any CPU.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.GenesisDisplayTool_V01|Mixed Platforms.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.GenesisDisplayTool_V01|Mixed Platforms.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.GenesisDisplayTool_V01|x64.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.GenesisDisplayTool_V01|x64.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.GenesisDisplayTool_V01|x86.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.GenesisDisplayTool_V01|x86.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.PerformTest|Any CPU.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.PerformTest|Any CPU.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.PerformTest|Mixed Platforms.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.PerformTest|Mixed Platforms.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.PerformTest|x64.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.PerformTest|x64.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.PerformTest|x86.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.PerformTest|x86.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Release|Any CPU.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Release|x64.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Release|x64.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Release|x86.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.Release|x86.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.ReleaseTest|x64.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.ReleaseTest|x64.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.ReleaseTest|x86.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.ReleaseTest|x86.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.XP32bit|Any CPU.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.XP32bit|x64.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.XP32bit|x64.Build.0 = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.XP32bit|x86.ActiveCfg = Release|Any CPU + {9E070488-15DE-418A-8606-5B79056C6E9F}.XP32bit|x86.Build.0 = Release|Any CPU {2D55BBD1-5373-484C-8781-C6ECEAFC2A90}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU {2D55BBD1-5373-484C-8781-C6ECEAFC2A90}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU {2D55BBD1-5373-484C-8781-C6ECEAFC2A90}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU @@ -5914,7 +5911,7 @@ Global {F69A79FA-548D-4E21-887E-01FABDAD9E73} = {696A94BE-7237-4AE2-9E36-6059DE519971} {8BEFD3AC-BB21-4B62-8D9A-CF8CBFD439EB} = {2E31C385-4FFC-473E-9C00-D7DC48140704} {15A06398-ECB6-49C9-ACB4-52A495A886A6} = {2E31C385-4FFC-473E-9C00-D7DC48140704} - {DA65E376-3D35-4D96-913A-7197FCA6DF48} = {2E31C385-4FFC-473E-9C00-D7DC48140704} + {9E070488-15DE-418A-8606-5B79056C6E9F} = {2E31C385-4FFC-473E-9C00-D7DC48140704} {2D55BBD1-5373-484C-8781-C6ECEAFC2A90} = {7A0EE7B8-6B7E-41E9-B679-319C8CA48CF1} {30BF7357-0B6C-498D-8123-5AACC66B3E5F} = {7A0EE7B8-6B7E-41E9-B679-319C8CA48CF1} {4928FC37-15EC-4872-8514-EA4ADCC4139D} = {AE29BDE3-843C-4B9B-8B02-D3C4814028AC} @@ -5926,6 +5923,9 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4BCB7B69-696C-436A-86F7-C91EA5588164} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + Utils\DateTimeServerShared\DateTimeServerShared.projitems*{4806d89a-fbfb-41bc-aaa7-2242444bf55a}*SharedItemsImports = 4 + EndGlobalSection GlobalSection(Performance) = preSolution HasPerformanceSessions = true EndGlobalSection diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs.bak b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs.bak deleted file mode 100644 index 5a31d27f..00000000 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs.bak +++ /dev/null @@ -1,1516 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using Newtonsoft.Json; -using Xylem.Common.CommonCore.Configuration; -using Xylem.Common.CommonCore.Consts; -using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties; -using Xylem.Common.Hardware.WaterMeter.Genesis.Registers; -using Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes; -using Xylem.Common.Logic.ProductionOrderCore; -using Xylem.Common.Logic.SoftwareAccessHelper; -using Xylem.Common.Utils.ProcessExec; -using Xylem.Common.Utils.ProcessExec.EventArguments; -using Access = Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Access; - -namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore -{ - /// - /// Read, compare and restore if unequal al registers marked with - /// equals - /// ". - /// The reader will use the byte values as they are unmodified and - /// will not be rounded and therefor possibly fail the comparison. - /// For logging the register value will be converted its unit. - /// - public class RegisterRestorer : IProcessState - { - /// - /// PCB ID for pre update read for comparison - /// - private String _pcbIdInitialRegisterRead = Constants.StrUnknown; - - /// - /// PCB ID for pre update write for comparison - /// - private String _pcbIdWriteRegisters; - - /// - /// PCB ID for post update for comparison - /// - private String _pcbIdFinalRegisterRead = Constants.StrUnknown; - - /// - /// Collection of recovery registers and values - /// - public List RecoveryRegisters; - - /// - /// Register content on initial connect to keep those during update - /// - private List _initialRegisters = new List(); - - /// - /// Register content after all operation had been performed - /// - private List _finalRegisters = new List(); - - /// - /// Register which shall be restored after change of FW or after register recovery - /// - public Int32 RecoveryRegisterCount => RecoveryRegisters.Count; - - /// - /// Register access event for message dispatcher to caller - /// - public event EventHandler OnProcessUpdate; - - /// - /// List for un-reversed parameters which can be written, all others need to be swapped byte-wise - /// - private static readonly List _unReversedParameters = new List - { - "SENSUSRADIO_Authentification", //UInt96 - "SENSUSRADIO_EncryptionKey", //UInt128 - "SENSUSRADIO_TfxSecondaryChannelInfo_1", //UInt48 - "SENSUSRADIO_TfxSecondaryChannelInfo_2", //UInt48 - "SENSUSRADIO_CustomerText", //UInt72 - "SENSUSRADIO_Tfx_Structure", //UInt88 - "GENESISFLOW_DisplayPow10", //SInt8 - "METROLOGYASST_FlowPoint", //Enum8 - "CUSTOMER_SerialNumber", //String - "SYSTEM_CustomerSerialNumber0", //String - "SYSTEM_CustomerSerialNumber1", //String - "SYSTEM_CustomerSerialNumber2", //String - "SYSTEM_CustomerSerialNumber3", //String - "TESTMANAGER_OutputFile" //String - }; - - /// - /// Registers manually explicit excluded from comparison as those may change even if those have the - /// "StaticType": "static" in the configuration.json but will change for some reason. - /// - private static readonly List _excludedFromCompareParameters = new List - { - "CUSTOMER_AlarmVisualMask", // Fully hard coded, cannot be overwritten - "CUSTOMER_AlarmEnableMask", // Will be overwritten by SENSUSRADIO if set System state to 0xFF - "CUSTOMER_AppArrangement", // Is read only, makes no sense to compare anything - "SENSUSRADIO_UpgFWVersion" // After a FW-Update the FW version has changed - }; - - /// - /// Registers manually explicit excluded from reading as those do not contain useful information. - /// Applies for RW commands not RPC data type. - /// - private static readonly List _excludedFromReadParameters = new List - { - "CUSTOMER_InternalLoginTest", // Does NOT respond - "CUSTOMER_AlarmVisualAutoClearMask", // Does NOT respond - "SYSTEM_CRC", // Needs application number written to it - "SYSTEM_CRC32", // Needs application number written to it - "SYSTEM_ExitReason", // Needs application number written to it - "SYSTEM_DriveCapacity", // Needs drive number written to it - "GENESISFLOW_TriggerActive", // Does NOT respond - "SENSUSRADIO_CurrentLoopMax", // Does NOT respond - "SENSUSRADIO_CurrentLoopSource", // Does NOT respond - "SENSUSRADIO_CustomerText", // Does NOT respond - "SENSUSRADIO_TfxSecondaryChannelInfo_1",// Does NOT respond - "SENSUSRADIO_TfxSecondaryChannelInfo_2" // Does NOT respond - }; - - /// - /// Pre-programming parameters for all devices defined here, will be filled with radio parameters - /// if meter has radio - /// - private static readonly List _prepareProgramming = new List - { - // The display needs to be unsealed for change of unit and resolution - new RecoveryRegisterItem("GENESISFLOW_SealDisplay", new Byte[] { 0x00 }) - }; - - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - private readonly List _failedComparisonRegisters = new List(); - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - private List _dbParameterRegisterList = new List(); - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - private List _initialRegisterList = new List(); - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - private List _finalRegisterList = new List(); - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - private readonly List _readableRegisterList = new List(); - - /// - /// Post programming parameters for all devices - /// - private static readonly List _finalizeProgrammingAll = new List - { - new RecoveryRegisterItem("LOGGER_TriggerLogFlush", new Byte[] { 0x01 }), - // set counter to 0 as this is a value how often the radio detected a reset - new RecoveryRegisterItem("PERIODICLOG_ResetCounter", new Byte[] { 0x00 }), - // trigger idle 0 releases the display to normal operation - new RecoveryRegisterItem("GENESISFLOW_TriggerIdle", new Byte[] { 0x00 }) - }; - - /// - /// Post programming parameters for EMEA region as NA region doesn't have radio and seal display shouldn't - /// be executed. - /// - private static readonly List _finalizeProgrammingEmea = new List - { - // System state 0xFF will force a storage of all parameters and reset, followed by system state 0x02 - // for customer mode, the reset needs only a few milliseconds - // Attention logout-delay-login required after this step! - new RecoveryRegisterItem("SENSUSRADIO_SystemState", new Byte[] { 0xFF }), - // seal the display to lock against changes - new RecoveryRegisterItem("GENESISFLOW_SealDisplay", new Byte[] { 0x01 }), - }; - - /// - /// Post programming parameters for EOL (end of line, prepare for shipping workplace) - /// - private static readonly List _finalizeProgrammingEol = new List - { - new RecoveryRegisterItem("GENESISFLOW_ResetAccumulators", new Byte[] { 0x01 }), - new RecoveryRegisterItem("NFC_EraseRMA", new Byte[] { 0x01 }), - new RecoveryRegisterItem("CUSTOMER_RebootCount", new Byte[] { 0x00 }) - }; - - /// - /// Actual register counter - /// - private Int32 _actualRegisterCtr; - - /// - /// Stop register access - /// - public Boolean StopRegisterAccess; - - /// - /// Genesis meter object - /// - private IGenesisMeter _currentGenesis; - - /// - /// Struct to observe replacements - /// - private struct ReplaceVakoByCsd - { - public String RegisterName; - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - public List VakoValue; - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - public List CsdValue; - } - - /// - /// Ctor - /// - /// - public RegisterRestorer(IGenesisMeter currentGenesis) - { - _currentGenesis = currentGenesis; - RecoveryRegisters = null; - RecoveryRegisters = new List(); - } - - /// - /// Assign new genesis after reboot and keep the RegisterRestorer object. - /// - /// - /// - /// - Initial - /// - public void AssignGenesis(IGenesisMeter genesisMeter) - { - _currentGenesis = genesisMeter; - } - - /// - /// Enable comparison from external set registers for read back with written value - /// - /// - /// - Initial - /// - public void EnableCompareExternalSetRegisters() - { - _pcbIdFinalRegisterRead = _currentGenesis.PcbId; - _pcbIdWriteRegisters = _currentGenesis.PcbId; - } - - /// - /// Export list of programming parameters to file being able to use it for test purposes. - /// - /// - /// - /// - /// - /// - /// - Initial. - /// - public static Boolean ExportRawProgrammingParametersToFile(String path, String fileName, - List programmingParameters) - { - try - { - var fileNamePath = Path.Combine(path, fileName); - var text = JsonConvert.SerializeObject(programmingParameters); - File.WriteAllText(fileNamePath, text); - } - catch (Exception e) - { - Console.WriteLine(e); - return false; - } - - return true; - } - - /// - /// Import list of programming parameters from file being able to use it for test purposes. - /// The input request the absolut path to the XX_YY_RawParameterExample.json and the filters for: - /// - Region, - /// - MeterSize, - /// - "RawParams" and - /// - ".json" - /// - /// - /// path where all raw parameter examples are stored - /// Region for configuration - /// Meter size for programming parameters - /// - /// - /// - /// - Initial. - /// - public static Boolean ImportRawProgrammingParametersFromFile(String paramsRootPath, String region, - String meterSize, List programmingParameters) - { - if (string.IsNullOrEmpty(paramsRootPath) || - string.IsNullOrEmpty(region) || - string.IsNullOrEmpty(meterSize)) - return false; - - programmingParameters.Clear(); - try - { - var filePathNames = Directory.GetFiles(paramsRootPath); - if (filePathNames.Length == 0) - return false; - - foreach (var filePathName in filePathNames) - { - var fileName = Path.GetFileName(filePathName); - if (fileName.Contains(region) && - fileName.Contains(meterSize) && - fileName.Contains("RawParams") && - fileName.Contains(".json")) - { - var rawParamsFilePathMane = Path.Combine(paramsRootPath, fileName); - if (!File.Exists(rawParamsFilePathMane)) - return false; - - var text = File.ReadAllText(filePathName); - var progParams = JsonConvert.DeserializeObject>(text); - programmingParameters.AddRange(progParams); - return true; - } - } - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - return false; - } - - return false; - } - - /// - /// Process the raw programming parameters got from the database or meanwhile in raw-format stored to file - /// being able to fill the register restorer from external with values and test the byte-wise reverting - /// of the parameter (optional un-reverted if defined in the list ). - /// The priority of the parameters forced by its source is: - /// - CSD (highest), - /// - VAKO, - /// - Order based or standard config (lowest). - /// - /// unprocessed data, not filtered by the priority and un-reversed - /// output as recovery registers reduced to the real needed ones and - /// processed as reverted or non-reverted values which directly can be written to the meter using the - /// meter specific "IGenesisMeter.WriteRegister" - /// error message for caller - /// - /// - /// - Initial imported from . - /// - /// - /// - Return error message, - /// - Requirement to fulfill the at least one parameter has to be a CSD parameter as initially all programming - /// parameters are going to be preset with the default values (coming from the Web-API). After this they are - /// going to be overwritten with the VAKO (variant configuration) and finally again with the CSD of the - /// customer if required. - /// - /// - /// - Debug for overwriting VAKO with CSD including real values. - /// - public static StatusReturn RawProgrammingParametersFilterAndSort(List rawProgParams, - List recoveryRegisters, out String errorMsg) - { - errorMsg = ""; - try - { - if (rawProgParams == null || rawProgParams.Count == 0) - { - return StatusReturn.Failed; - } - - // Create DEBUG lists - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - var vakoRegisterList = new List(); - var csdRegisterList = new List(); - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - var orderRegisterList = new List(); - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - var sortableRegisterList = new List(); - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - var multipleAssignedRegisterList = new List(); - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG - var replacedVakoFromCsdList = new List(); - - // Temporary storage for sorting before assembling those registers with the preparation and - // finalization of programming and therefore building a sequence - var sortableProgrammingParameters = new List(); - - foreach (var proPar in rawProgParams) - { - // reverse byte order for all parameters except those listed below - if (!string.IsNullOrEmpty(proPar.RegisterName)) - { - // Catch multiple assignments - if (sortableRegisterList.Any(a => proPar.RegisterName.Equals(a))) - multipleAssignedRegisterList.Add(proPar.RegisterName); - - // Fill DEBUG lists START with all registers even if they are multiple assigned - sortableRegisterList.Add(proPar.RegisterName); - - switch (proPar.Source) - { - case ProgrammingSource.Vako: - vakoRegisterList.Add(proPar.RegisterName); - break; - case ProgrammingSource.Csd: - csdRegisterList.Add(proPar.RegisterName); - break; - case ProgrammingSource.Order: - orderRegisterList.Add(proPar.RegisterName); - break; - } - - if (_unReversedParameters.Contains(proPar.RegisterName)) - { - // Add parameter if it is not in the list - if (sortableProgrammingParameters.All(a => !proPar.RegisterName.Equals(a.RegisterName))) - { - sortableProgrammingParameters.Add(proPar); - continue; - } - // if parameter from VAKO is in the list and the new is from CSD, replace this with CSD - if (proPar.Source == ProgrammingSource.Csd && sortableProgrammingParameters.Any(a => - proPar.RegisterName.Equals(a.RegisterName) && a.Source == ProgrammingSource.Vako)) - { - var removeProPar = - sortableProgrammingParameters.LastOrDefault(a => proPar.RegisterName.Equals(a.RegisterName)); - - var replace = new ReplaceVakoByCsd - { - RegisterName = proPar.RegisterName, - VakoValue = new List(), - CsdValue = new List() - }; - - if (removeProPar != null) - { - replace.VakoValue.AddRange(removeProPar.RegisterValue); - replace.CsdValue.AddRange(proPar.RegisterValue); - replacedVakoFromCsdList.Add(replace); - - sortableProgrammingParameters.Remove(removeProPar); - sortableProgrammingParameters.Add(proPar); - } - } - } - else - { - // ATTENTION: These parameters are coming out of the DB in wrong byte order and needed - // to be reversed for the entire sequence - var reversedValue = proPar.RegisterValue.Reverse().ToArray(); - - // Add parameter if it is not in the list - if (sortableProgrammingParameters.All(a => !proPar.RegisterName.Equals(a.RegisterName))) - { - sortableProgrammingParameters.Add(new ProgrammingParameters(proPar.RegisterName, - reversedValue, proPar.Source)); - continue; - } - // if parameter from VAKO is in the list and the new is from CSD, replace this with CSD - if (proPar.Source == ProgrammingSource.Csd && sortableProgrammingParameters.Any(a => - proPar.RegisterName.Equals(a.RegisterName) && a.Source == ProgrammingSource.Vako)) - { - var removeProPar = - sortableProgrammingParameters.LastOrDefault(a => proPar.RegisterName.Equals(a.RegisterName)); - - var replace = new ReplaceVakoByCsd - { - RegisterName = proPar.RegisterName, - VakoValue = new List(), - CsdValue = new List() - }; - - if (removeProPar != null) - { - replace.VakoValue.AddRange(removeProPar.RegisterValue); - replace.CsdValue.AddRange(reversedValue); - replacedVakoFromCsdList.Add(replace); - - sortableProgrammingParameters.Remove(removeProPar); - sortableProgrammingParameters.Add(new ProgrammingParameters(proPar.RegisterName, - reversedValue, proPar.Source)); - } - } - } - } // register for this FW is defined - else - { - return StatusReturn.Failed; - } - } - - // Sort the programming parameters coming from DB (VAKO/CSD) - sortableProgrammingParameters.Sort((x, y) => string.Compare(x.RegisterName, y.RegisterName, - StringComparison.Ordinal)); - - // Sort DEBUG lists - csdRegisterList.Sort(); - vakoRegisterList.Sort(); - orderRegisterList.Sort(); - sortableRegisterList.Sort(); - multipleAssignedRegisterList.Sort(); - replacedVakoFromCsdList.Sort((x, y) => string.Compare(x.RegisterName, y.RegisterName, - StringComparison.Ordinal)); - - // convert to RecoveryRegisterItem - if (sortableProgrammingParameters.Count > 0) - { - foreach (var proPar in sortableProgrammingParameters) - { - var recReg = new RecoveryRegisterItem(proPar.RegisterName, proPar.RegisterValue); - recoveryRegisters.Add(recReg); - } - } - - // Requirement to fulfill that at least one parameter has to be a CSD parameter - if (csdRegisterList.Count == 0) - { - errorMsg = Resources.StrErrorMsgCsdMissing; - return StatusReturn.Failed; - } - - return StatusReturn.Okay; - } - catch (Exception) - { - return StatusReturn.Failed; - } - } - - /// - /// Collect programming parameters from DB. - /// - /// - /// registers key value pair from database - /// error message from parameter analysis - /// recovery registers - /// - /// - Initial. - /// - /// - /// - Sort the registers from DB but keep the PrepareProgramming and FinalizeProgramming in the required sequence. - /// - /// - /// - Removed preparation and finalization of register recovery to remove sequencing as this will be done in the - /// RegisterRestorer by the FwUpdateSw worker giving the ability to log this in the report. - /// - /// - /// - Data base access imported to have a common interface for programming parameters for EOL (shipping) and CUST. - /// - /// - /// - Removed prohibited parameters. - /// - /// - /// - Added un-reversed parameters based on data type (string, uint128). - /// - /// - /// - Check and validate register values with installed or intended to be installed FW and given - /// configuration.json. - /// - /// - /// - Exported register range check to . - /// - /// - /// - Debug lists for CSD and VAKO parameters. - /// - /// - /// - Sorting, filtering for VAKO, CSD and order, reverting or un-reverting parameter value order exported - /// for the ability to load the raw programming parameters from any source and check the correct processing. - /// This will be especially used for unit-tests - /// - /// - /// - Error message. - /// - public static StatusReturn DownloadProgrammingParametersFromDb(String pcbId, - List recoveryRegistersDb, out String errorMsg) - { - errorMsg = ""; - try - { - var url = $"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetProgrammingParameters?PcbID={pcbId}"; - var ppJson = LocalWebRequest.GetRequest(url, 30000); - - if (string.IsNullOrEmpty(ppJson)) - { - return StatusReturn.Failed; - } - - var programmingParameters = JsonConvert.DeserializeObject>(ppJson); - - if (programmingParameters == null || programmingParameters.Count == 0) - { - return StatusReturn.Failed; - } - - return RawProgrammingParametersFilterAndSort(programmingParameters, recoveryRegistersDb, out errorMsg); - } - catch (Exception) - { - return StatusReturn.Failed; - } - } - - /// - /// Avoid doubling of register restore on subsequent FW-Update trials. - /// - /// true if registers already backed up - /// - /// - Initial. - /// - public Boolean RegisterRestoreExecuted() - { - if (_currentGenesis == null) - return false; - if (_currentGenesis.PcbId != _pcbIdFinalRegisterRead) - return false; - return _finalRegisters.Count > 0; - } - - /// - /// EOL (end of line) programming contains a reset of the accumulators. Else it is identical with recover - /// registers. - /// - /// list of registers to update from database without special sequence - /// - /// true if setup succeeded - /// - /// - Initial. - /// - public StatusReturn EolProgrammingRegisters(List recoveryRegistersDb) - { - // mark EOL as true to force accu reset - return WriteRegisters(recoveryRegistersDb, true); - } - - /// - /// Validate the range of the register. - /// - /// register key value pair - /// register definition by configuration.json - /// error message if range check failed - /// check default value and supply warning - /// status - /// - /// - Initial, imported from - /// - /// - /// - Leave the message generation to the - /// - public static StatusReturn ValidateRegisterRange(RecoveryRegisterItem recReg, - RegisterDefinition regDef, out String errorMessage, Boolean checkDefault = false) - { - - // Error message will be returned on failed check or on default value - errorMessage = null; - try - { - // check the limits and avoid writing if not in range - return RegisterCheck.CheckRange(regDef, recReg.WriteValue, out errorMessage, checkDefault); - } - catch (Exception ex) - { - errorMessage = ex.Message; - return StatusReturn.Failed; - } - } - - /// - /// Recover all registers set from caller. Additional preparation and finalization will be added. - /// settings. - /// - /// list of registers to update from database without special sequence - /// - /// EOL (end of line) programming with accu reset - /// true if restoring succeeded - /// - /// - Initial. - /// - /// - /// - Return true if already recovered, - /// - replace _restoreRegisters with new value. - /// - /// - /// - Added preparation and finalization of register recovery giving the ability to log this in the report. - /// - /// - /// - Moved register dictionary value set to inner try catch loop to avoid early exit if one register is - /// unknown. - /// - /// - /// - Logging of some exception messages. - /// - /// - /// - EOL sequence for accumulators reset, - /// - Remind pcbId as already recovered before the true return, - /// - Exclude lock of repeated execution for EOL. - /// - /// - /// - Avoid writing of parameters if not writable. The DB delivers parameters which exclusively have to be - /// compared to the specified value. - /// - /// - /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list, - /// - Preset RecoveryRegisters if not set as those have to be compared later on. - /// - /// - /// - Add only registers to recovery list which are found in the generated register list based on installed - /// applications. - /// - /// - /// - Avoid writing of NOT writable registers. - /// - /// - /// - Check register limits, if those are out of range avoid writing and log warning message. - /// - /// - /// - Exported register range check to . - /// - /// - /// - Removed skip recovery if already done in previous run to enable a retry. - /// - /// - /// - Seal display and Sensus radio to EMEA finalization. - /// - /// - /// - Exported write routines to . - /// - public StatusReturn WriteRegisters(List recoveryRegistersDb, Boolean eolProgramming = false) - { - if (_currentGenesis == null || - string.IsNullOrEmpty(_currentGenesis.PcbId) || - recoveryRegistersDb == null || - recoveryRegistersDb.Count == 0) - return StatusReturn.Failed; - - // preset recovery registers if not already set - if (RecoveryRegisters == null) - { - RecoveryRegisters = new List(); - } - if (RecoveryRegisters.Count == 0) - { - RecoveryRegisters = recoveryRegistersDb; - } - - StopRegisterAccess = false; - _actualRegisterCtr = 0; - - // Build string list for debug - _dbParameterRegisterList.Clear(); - _dbParameterRegisterList = recoveryRegistersDb.Select(register => register.RegisterIdent).ToList(); - _dbParameterRegisterList.Sort(); - - // write values to Genesis - _currentGenesis.ReLogin(); - if (!_currentGenesis.IsLoggedOn) - return StatusReturn.Failed; - - // get the pre-defined dictionary - var meterRegisters = _currentGenesis.GetConfigRegistersDefinitions(); - - // prepare list for finalization depending on SENSUSRADIO installation - var finalizeProgrammingAll = new List(); - - // add EOL (shipping reset of accumulators, alarms and setup of manufacturing date) - if (eolProgramming) - { - finalizeProgrammingAll.AddRange(_finalizeProgrammingEol.Where(finalReg => - meterRegisters.MeterRegisterDic.Any(x => x.Key.GetIdent().Contains(finalReg.RegisterIdent)))); - } - - // add only registers which are defined as needed to restore and in the found register list - // from installed applications - finalizeProgrammingAll.AddRange(_finalizeProgrammingAll.Where(finalReg => - meterRegisters.MeterRegisterDic.Any(x => x.Key.GetIdent().Contains(finalReg.RegisterIdent)))); - - // add special registers for EMEA version - if (_currentGenesis.Region.Equals("EMEA")) - { - finalizeProgrammingAll.AddRange(_finalizeProgrammingEmea.Where(finalReg => - meterRegisters.MeterRegisterDic.Any(x => x.Key.GetIdent().Contains(finalReg.RegisterIdent)))); - } - - // set the process counter - var recRegistersCount = recoveryRegistersDb.Count > 0 ? recoveryRegistersDb.Count : 1; - recRegistersCount += _prepareProgramming.Count; - recRegistersCount += finalizeProgrammingAll.Count; - - // prepare recovery - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryPreparation, - actualProcessMessage: Resources.StrRegisterRecoveryPreparation)); - - if (StatusReturn.Failed == WriteRegisterParameterSet(_prepareProgramming, recRegistersCount, meterRegisters)) - { - // the logout will force the radio app to activate the settings - _currentGenesis?.Logout(); - return StatusReturn.Failed; - } - - // register recovery - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryExec, - actualProcessMessage: Resources.StrRegisterRecoveryExec)); - - if (StatusReturn.Failed == WriteRegisterParameterSet(recoveryRegistersDb, recRegistersCount, meterRegisters)) - { - // the logout will force the radio app to activate the settings - _currentGenesis?.Logout(); - return StatusReturn.Failed; - } - - // finalize recovery - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryFinalization, - actualProcessMessage: Resources.StrRegisterRecoveryFinalization)); - - if (StatusReturn.Failed == WriteRegisterParameterSet(finalizeProgrammingAll, recRegistersCount, meterRegisters)) - { - // the logout will force the radio app to activate the settings - _currentGenesis?.Logout(); - return StatusReturn.Failed; - } - - // remind pcbId of this run to avoid endless repetition - _pcbIdWriteRegisters = _currentGenesis.PcbId; - - // the logout will force the radio app to activate the settings - _currentGenesis?.Logout(); - - // Wait for completion as storing may need a certain time - Thread.Sleep(1000); - - return StatusReturn.Okay; - } - - /// - /// Write a parameter set: - /// - - /// - /// - /// - /// - /// - /// - /// - Initial imported from . - /// - private StatusReturn WriteRegisterParameterSet(List recoveryRegistersDb, Int32 recRegistersCount, - MeterRegisters meterRegisters) - { - foreach (var recReg in recoveryRegistersDb) - { - _actualRegisterCtr++; - var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / recRegistersCount; - - RegisterDefinition regDef; - - try - { - // If this call does not throw an exception, the register is present - regDef = meterRegisters.GetRegisterDefinitionByName(recReg.RegisterIdent); - } - catch (Exception ex) - { - _currentGenesis.WriteLog(ex.Message); - regDef = null; - } - - if (null == regDef) - { - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs( - $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", - overallProcessCtrPercent, Resources.StrErrorMsgRegisterNotFound + " Register: " + - recReg.RegisterIdent)); - return StatusReturn.Failed; - } - - // avoid writing of NOT writable registers - if (regDef.RegisterDetail.Privilege.Lvl8 != Access.WO - && regDef.RegisterDetail.Privilege.Lvl8 != Access.RW) - continue; - - // check the limits and avoid writing if not in range - var retVal = ValidateRegisterRange(recReg, regDef, out var errorMessage); - if (StatusReturn.Failed == retVal) - { - _currentGenesis.WriteLog(errorMessage); - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs( - $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", - overallProcessCtrPercent, Resources.StrRegisterValueOutOfRange + " " + errorMessage)); - return StatusReturn.Failed; - } - - if (!_currentGenesis.WriteRegister(recReg.RegisterIdent, recReg.WriteValue)) - { - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs( - $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", - overallProcessCtrPercent, Resources.StrErrorMsgRegisterWrite + " Register: " + - recReg.RegisterIdent)); - return StatusReturn.Failed; - - } - var strRawAndConvertedValue = ""; - try - { - strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, recReg.WriteValue); - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Could not convert register value of " + recReg.RegisterIdent + - "; " + ex.Message); - } - finally - { - var actualProcessMsg = $"{Resources.StrWriteRegister}: {strRawAndConvertedValue} "; - - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs( - $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", - overallProcessCtrPercent, actualProcessMsg)); - } - - if (StopRegisterAccess) - break; - } - - return StatusReturn.Okay; - } - - /// - /// Compare all registers which can be restored without new access to meter. - /// Precondition: - /// - The _restoreRegisters has to be filled with all registers being able to restore (RW), - /// - The _finalReadRegisters has to be filled. - /// - /// true if equal - /// - /// - Initial. - /// - /// - /// - Compare registers reactivated based on new interface (configuration.json) with new - /// "StaticType": “approximate”. - /// - /// - /// - Removed as those will change on e.g. FW update. - /// - /// - /// - Avoid message event if message is empty. - /// - /// - /// - Remind registers which failed the comparison including values. - /// - /// - /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. - /// - /// - /// - Removed all registers from comparison which are neither static nor approximate. - /// - /// - /// - Exception logging extended, - /// - Data size base on write data size as this may be shorter than the read data size which is always filled up - /// to a 4 byte chunk size. - /// - /// - /// - Add only registers to recovery list which are found in the generated register list based on installed applications. - /// - /// - /// - Used RecoveryRegisters WriteValue and ReadBackValue for comparison. - /// - /// - /// - Hash password and encryption key with SHA256. - /// - public Boolean CompareRegisters() - { - if (_pcbIdFinalRegisterRead != _pcbIdWriteRegisters || - RecoveryRegisters == null) - return false; - - StopRegisterAccess = false; - _actualRegisterCtr = 0; - var retVal = true; - - // DEBUG - _failedComparisonRegisters?.Clear(); - - // build a string list of the registers being able to sort those - var registerNames = RecoveryRegisters.Select(register => register.RegisterIdent).ToList(); - // Remove all excluded registers - foreach (var regName in _excludedFromCompareParameters.Where(regName => registerNames.Any(reg => reg == regName))) - { - registerNames.Remove(regName); - } - // sort the list of register names - registerNames.Sort(); - // limit the count to 1 to avoid division by zero - var registersCount = registerNames.Count > 0 ? registerNames.Count : 1; - - // get the pre-defined dictionary - var meterRegisters = _currentGenesis.GetConfigRegistersDefinitions(); - - // access every register - foreach (var regName in registerNames) - { - _actualRegisterCtr++; - var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / registersCount; - - RegisterDefinition regDef = null; - try - { - // take the register properties from configuration.json - regDef = meterRegisters.GetRegisterDefinitionByName(regName); - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Meter register not defined or application not installed " + - regName + "; " + ex.Message); - } - - // skip all registers from comparison which are neither static nor approximate or not detected - // in meter registers based on installed applications - if (regDef == null || !regDef.RestoreCapability.CheckRestoreCapability()) - { - continue; - } - - try - { - // Get the raw byte array of this register - var recReg = RecoveryRegisters.First(reg => reg.RegisterIdent.Equals(regName)); - var writtenValue = recReg.WriteValue; - var readBackValue = recReg.ReadBackValue; - - // If any value is null then there is nothing to compare - if (writtenValue == null || readBackValue == null) - { - _failedComparisonRegisters?.Add(new RecoveryRegisterItem(regName, writtenValue, readBackValue)); - continue; //TODO THW check if error should be signalized - } - - // ATTENTION: Take the size of the read back value as this will be filled up to a chunk of 4 - // bytes and therefore the required write value may have a smaller byte list! - var dataSize = writtenValue.Length; - - var strRequiredRegisterValue = ""; - try - { - var isApproximated = false; - var isIdentical = false; - if (regDef.RegisterDetail.StaticType == StaticType.ReadBackApproximated) - { - Int64 restoreValue = 0; - Int64 finalValue = 0; - if (regDef.DataType.Name.Equals("Int32")) - { - restoreValue = RegisterConverter.ByteArrayToValue(writtenValue); - finalValue = RegisterConverter.ByteArrayToValue(readBackValue); - } - else if (regDef.DataType.Name.Equals("UInt32")) - { - restoreValue = RegisterConverter.ByteArrayToValue(writtenValue); - finalValue = RegisterConverter.ByteArrayToValue(readBackValue); - } - // Just half of number range will work due to cast to Int64 - else if (regDef.DataType.Name.Equals("UInt64")) - { - restoreValue = (Int64)RegisterConverter.ByteArrayToValue(writtenValue); - finalValue = (Int64)RegisterConverter.ByteArrayToValue(readBackValue); - } - else if (regDef.DataType.Name.Equals("Int64")) - { - restoreValue = RegisterConverter.ByteArrayToValue(writtenValue); - finalValue = RegisterConverter.ByteArrayToValue(readBackValue); - } - else if (regDef.DataType.Name.Equals("Byte")) - { - restoreValue = RegisterConverter.ByteArrayToValue(writtenValue); - finalValue = RegisterConverter.ByteArrayToValue(readBackValue); - } - else if (regDef.DataType.Name.Equals("SByte")) - { - restoreValue = RegisterConverter.ByteArrayToValue(writtenValue); - finalValue = RegisterConverter.ByteArrayToValue(readBackValue); - } - // Check limited to +/- 3 - if (restoreValue - 3 <= finalValue && restoreValue + 3 >= finalValue) - { - isApproximated = true; - } - } - else - { - for (var c = 0; c < dataSize; c++) - { - if (writtenValue[c] != readBackValue[c]) - { - isIdentical = false; - break; - } - isIdentical = true; - } - } - // convert register content to text with raw and converted value depending on data type - strRequiredRegisterValue = - RegisterConverter.GetRegisterContentText(regDef, writtenValue); - if (readBackValue != null && (isIdentical || isApproximated)) - { - strRequiredRegisterValue += $" - {Resources.StrRegisterCompareSucceeded}"; - } - else - { - var encryptRawData = regName.Contains("EncryptionKey") || regName.Contains("Password"); - - var strReadBackRegisterValue = RegisterConverter.GetRegisterRawText(regDef, readBackValue, - encryptRawData); - - strRequiredRegisterValue += $" - {Resources.StrMeterValue} ({strReadBackRegisterValue})h" + - $" - {Resources.StrRegisterCompareFailed}"; - _failedComparisonRegisters?.Add(new RecoveryRegisterItem(regName, writtenValue, - readBackValue)); - retVal = false; - } - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Could not compare register value of " + regName + "; " + ex.Message); - } - finally - { - var actualProcessMsg = $"{Resources.StrRegisterCompare} {strRequiredRegisterValue} "; - - // Avoid message if nothing to tell - if (!string.IsNullOrEmpty(strRequiredRegisterValue)) - { - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrRegisterCompare}" + - $@" {_actualRegisterCtr} / {registersCount}", - overallProcessCtrPercent, actualProcessMsg)); - } - } - - if (StopRegisterAccess) - break; - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Could not access register for comparison " + regName + "; " + ex.Message); - } - } - return retVal; - } - - /// - /// Read the registers after the update for comparision. Build the post update registers here, - /// because an update may have changed the registers (new or removed registers). - /// - /// true if registers could be read - /// - /// - Initial. - /// - /// - /// - Build here the post update registers, they may have changed due to update! - /// - /// - /// - Clear pre update registers if post indicates a different PCB ID to avoid wrong overwriting of - /// registers to non-matching new meter. - /// - /// - /// - Return true if already executed in previous run. - /// - /// - /// - Return false if PcbId between initial- and final-read does NOT match return false. - /// - /// - /// - Allow final read out as often as called even if done before. - /// - /// - /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. - /// - /// - /// - Backup _finalRegisters to RecoveryRegisters. - /// - /// - /// - Check readBack value for null. - /// - public Boolean FinalReadRegisters() - { - if (_currentGenesis == null) - return false; - - Boolean retVal; - try - { - - // create a dictionary for final read being able to compare those with the initial read and restored - if (!BuildReadableRegisterDictionary(ref _finalRegisters)) - return false; - - // log to report file the after update register read string - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}", 0, - Resources.StrReadRegistersAfterUpdate)); - - // Build string list for debug - _finalRegisterList.Clear(); - _finalRegisterList = _finalRegisters.Select(register => register.RegisterIdent).ToList(); - _finalRegisterList.Sort(); - - // executes login read logout - retVal = ReadRegistersSet(ref _finalRegisters); - - // backup read data to RecoveryRegisters - if (RecoveryRegisters != null && _finalRegisters != null) - { - foreach (var recReg in RecoveryRegisters) - { - foreach (var finalReg in _finalRegisters.Where(finalReg => - recReg.RegisterIdent.Equals(finalReg.RegisterIdent))) - { - if (finalReg.ReadBackValue == null) - { - recReg.ReadBackValue = null; - continue; - } - - recReg.ReadBackValue = new Byte[finalReg.ReadBackValue.Length]; - for (var c = 0; c < finalReg.ReadBackValue.Length; c++) - recReg.ReadBackValue[c] = finalReg.ReadBackValue[c]; - } - } - } - - // remind the PCB ID before update for comparison - _pcbIdFinalRegisterRead = _currentGenesis.PcbId; - - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Copying read back data failed " + ex.Message); - retVal = false; - } - return retVal; - } - - /// - /// Get DEFINED registers from GenesisMeter class and read all registers which are flagged with - /// read write (RW) or read only (RO). Build a list of all registers being able to restore flagged - /// with equals ". - /// The defined registers are based on the "configuration.json" and the installed application with - /// a specific version. - /// - /// true if registers could be read - /// - /// - Initial. - /// - /// - /// - Stored registers before and after update. - /// - /// - /// - Extended register check. - /// - /// - /// - Removed after update registers and moved them to FinalReadRegisters. They may have changed - /// during the update. - /// - /// - /// - Deny register pre update if _pcbIdPreUpdate indicates, that this has been already processed. - /// - /// - /// - Removed login/logout, - /// - if _initialReadRegisters and _restoreRegisters are filled, return true. - /// - /// - /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. - /// - public Boolean InitialReadRegisters() - { - if (_currentGenesis == null) - return false; - - // deny update of registers if already done - if (_pcbIdInitialRegisterRead == _currentGenesis.PcbId && - _initialRegisters.Count > 0) - return true; - - // remind the PCB ID before update for comparison - _pcbIdInitialRegisterRead = _currentGenesis.PcbId; - - // create the dictionaries out of the configuration.json - if (!BuildReadableRegisterDictionary(ref _initialRegisters)) - return false; - - // log to report file the initial register read string - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}", 0, - Resources.StrReadRegistersBeforeUpdate)); - - // Build string list for debug - _initialRegisterList.Clear(); - _initialRegisterList = _initialRegisters.Select(register => register.RegisterIdent).ToList(); - _initialRegisterList.Sort(); - - return ReadRegistersSet(ref _initialRegisters); - } - - /// - /// Get DEFINED registers from GenesisMeter class and build a list all registers which are flagged - /// with read write (RW) or read only (RO). - /// The defined registers are based on the "configuration.json" and the installed application with - /// a specific version. - /// - /// all readable registers dictionary creation - /// true if register dictionary is not empty - /// true if registers could be read - /// - /// - Initial from . - /// - /// - /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. - /// - /// - /// - Excluded registers which do not contain useful information. - /// - public Boolean BuildReadableRegisterDictionary(ref List registers) - { - if (_currentGenesis == null || registers == null) - return false; - - registers.Clear(); - _readableRegisterList.Clear(); - - // get the pre-defined dictionary - var meterRegisters = _currentGenesis.GetConfigRegistersDefinitions(); - // extract all registers which can be read and create two dictionaries for before update to safe program - // internally the register content for comparison ability. Exclude register which contain no useful info. - foreach (var reg in meterRegisters.MeterRegisterDic.Where(r => r.Key.RegisterDetail.Version.First != null - && r.Key.RegisterDetail.Version.Last != null && r.Key.RestoreCapability.StaticTypeValue != null - && r.Key.DataType != typeof(Rpc) && r.Key.IsAvailable && - (r.Key.RegisterDetail.Privilege.Lvl8 == Access.RW || r.Key.RegisterDetail.Privilege.Lvl8 == Access.RO) - && _excludedFromReadParameters.All(regName => regName != r.Key.GetIdent()))) - { - var registerIdent = reg.Key.GetIdent(); - registers.Add(new RecoveryRegisterItem(registerIdent, reg.Value)); - _readableRegisterList.Add(registerIdent); - } - - _readableRegisterList.Sort(); - registers.Sort((a, b) => String.Compare(a.RegisterIdent, b.RegisterIdent, StringComparison.Ordinal)); - return registers.Count > 0; - } - - /// - /// Get DEFINED registers from GenesisMeter class and read all registers which are flagged with read write - /// (RW) or read only (RO). - /// The defined registers are based on the "configuration.json" and the installed application with a specific - /// version. - /// - /// true if registers could be read - /// - /// - Initial. - /// - /// - /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. - /// - public Boolean ReadRegisters() - { - if (_currentGenesis == null) - return false; - - // temporary list of registers just for read and log without keeping them alive - var registers = new List(); - - if (!BuildReadableRegisterDictionary(ref registers)) - return false; - - // log to report file the initial register read string - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}", 0, - Resources.StrReadRegistersBeforeUpdate)); - - return ReadRegistersSet(ref registers); - } - - /// - /// Read predefined registers from RecoveryRegisters. - /// - /// true if registers could be read - /// - /// - Initial. - /// - public Boolean ReadPresetRegisters() - { - if (_currentGenesis == null || RecoveryRegisters == null || RecoveryRegisters.Count == 0) - return false; - - // Assume that this meter shall be used for comparison even if nothing has been written. - // The RecoveryRegisters can be preset with a writeValue being able to use FinalReadRegisters - // and compare the readBackValue from those with the preset writeValue. - _pcbIdWriteRegisters = _currentGenesis.PcbId; - _pcbIdFinalRegisterRead = _currentGenesis.PcbId; - - return ReadRegistersSet(ref RecoveryRegisters); - } - - /// - /// Register read loop. - /// All registers needed to be read from the Genesis meter as they are only prepared as template and NOT filled - /// with the register data! - /// The uses the overall process text and value for user information process - /// bar and text and the actual process text for logging to the report file! - /// Executes login, read cycle and logout. - /// - /// registers to read - /// true if registers could be read - /// - /// - Initial. - /// - /// - /// - Set value to actual process message. - /// - /// - /// - Added PCB ID to logging. - /// - /// - /// - Removed PCB ID from logging. - /// - /// - /// - Simplified input of set of registers to read. - /// - /// - /// - Set raw values in register dictionaries. - /// - /// - /// - Extended try catch to avoid break on one register failed. - /// - /// - /// - Filtered restore registers to access only if assigned, - /// - Logging of some exception messages. - /// - /// - /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. - /// - private Boolean ReadRegistersSet(ref List registers) - { - if (_currentGenesis == null) - return false; - StopRegisterAccess = false; - _actualRegisterCtr = 0; - - // read values from Genesis - _currentGenesis.ReLogin(); - if (!_currentGenesis.IsLoggedOn) - return false; - - // build a string list of the registers being able to sort those - var registerNames = registers.Select(register => register.RegisterIdent).ToList(); - // sort the list of register names - registerNames.Sort(); - // limit the count to 1 to avoid division by zero - var registersCount = registerNames.Count > 0 ? registerNames.Count : 1; - - // get the pre-defined dictionary - var meterRegisters = _currentGenesis.GetConfigRegistersDefinitions(); - // access every register - foreach (var regName in registerNames) - { - _actualRegisterCtr++; - - // get register definition to analyze the data type and therefore the expected length - var regDef = meterRegisters.GetRegisterDefinitionByName(regName); - - // get the register out of the given list - var register = registers.FirstOrDefault(reg => reg.RegisterIdent.Equals(regName)); - - var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / registersCount; - - try - { - var rawRegister = _currentGenesis.ReadRegister(regName, RegisterConverter.SizeOf(regDef)); - try - { - if (register != null && rawRegister != null) - { - register.ReadBackValue = new Byte[rawRegister.Length]; - for (var c = 0; c < rawRegister.Length; c++) - register.ReadBackValue[c] = rawRegister[c]; - } - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Register value backup failed " + regName + "; " + ex.Message); - } - - var strRawAndConvertedValue = $"{regName} - ?"; - try - { - if (rawRegister != null) - { - // convert register content to text with raw and converted value depending on data type - strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, rawRegister); - } - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Register value conversion failed " + regName + "; " + ex.Message); - } - finally - { - var actualProcessMsg = $"{Resources.StrReadRegister}: {strRawAndConvertedValue} "; - - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}" + - $@" {_actualRegisterCtr} / {registersCount}", - overallProcessCtrPercent, actualProcessMsg)); - } - - if (StopRegisterAccess) - break; - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Register value read access failed " + regName + "; " + ex.Message); - } - } - _currentGenesis.Logout(); - return true; - } - } -} diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/BaseProcessStatesDef.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/BaseProcessStatesDef.cs index 45ae18aa..384c954a 100644 --- a/Common/Production/ProductionUiCordonel/ProductionProcesses/BaseProcessStatesDef.cs +++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/BaseProcessStatesDef.cs @@ -139,7 +139,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses } /// - public List GetAllEolRelevantProcesses() + public List GetAllProductionProcesses() { var sortedList = StateContainer .Where(y => y.ProductionProcessNo != null) diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckRadio.cs.bak b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckRadio.cs.bak new file mode 100644 index 00000000..ac3db873 --- /dev/null +++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckRadio.cs.bak @@ -0,0 +1,829 @@ +using System; +using System.Configuration; +using System.Linq; +using System.Net; +using System.Threading; +using System.Windows.Threading; +using LaaPackages.Features.Cordonel.Models; +using Newtonsoft.Json.Linq; +using SIRTCOM; +using Xylem.Common.CommonCore.Configuration; +using Xylem.Common.CommonCore.Consts; +using Xylem.Common.Hardware.WaterMeter.Genesis.Registers; +using Xylem.Common.Logic.ProductionOrderCore; +using Xylem.Common.Logic.SoftwareAccessHelper; +using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum; +using Xylem.Common.Production.ProductionUiCordonel.Properties; +using Xylem.Common.Production.ProductionUiCordonel.UserControls; +using Button = System.Windows.Controls.Button; +// ReSharper disable UnusedAutoPropertyAccessor.Local + +namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses +{ + public class CheckRadio : BaseProductionProcess + { + /// + /// Maximum of expected processing steps for this process to feed the GUI progress bar. + /// Use the sleep 250 to create x seconds timeout; + /// + private const Int32 TimeoutLoop_ms = 250; + private const Int32 Timeout_s = 10; + private const Int32 MaxActualProgressSteps = 1000 / TimeoutLoop_ms * Timeout_s; + + /// + /// Remind the ID of the radio result as feedback from the DB. + /// + private Int64 _radioResultCheckId; + + /// + /// Final state of radio system. + /// + private Int32 _finalRadioSystemState; + /// + /// Reminder for specific user control + /// + private UcRadioCheck _checkRadioUserControl; + + /// + /// Signal level successfully tested + /// + private Boolean _successSignalLevel; + + /// + /// Radio encryption key converted to string + /// + private String _radioEncryptionKey; + + /// + /// Test finished can be good or abort by done button to exit this production process + /// + private Boolean _testFinished; + + /// + /// SIRT communication okay + /// + private Boolean _sirtComOkay; + + private DataContainer _dataContainer; + private Statemashine _stateMachine; + + /// + /// Minimum PAM signal level of SIRT got from DB + /// + private Byte? _rssiPamSirtDbMin; + /// + /// Maximum PAM signal level of SIRT got from DB + /// + private Byte? _rssiPamSirtDbMax; + /// + /// Minimum SEMI signal level of Cordonel response got from DB + /// + private Byte? _rssiSemiCordonelDbMin; + /// + /// Maximum SEMI signal level of Cordonel response got from DB + /// + private Byte? _rssiSemiCordonelDbMax; + + /// + /// Measured from SIRT the signal strength of the Cordonel SEMI answer + /// + private Byte? _rssiSemiCordonelMeasuredBySirt; + + /// + /// Measured from Cordonel the signal strength of the SIRT PAM received + /// + private Byte? _rssiPamSirtMeasuredByCordonel; + + /// + /// Number of the SIRT box as these are evaluated for their signal strength + /// + private Byte _sirtBoxNr; + + /// + /// Comport number of SIRT + /// + private Byte _sirtComport; + + /// + /// Radio address Cordonel + /// + private UInt32 _radioAddressCordonel; + + /// + /// Ctor + /// + public CheckRadio(String name) : base(name) + { + } + + /// + protected override void InitUserControl() + { + UserControl = new UcRadioCheck(); + _checkRadioUserControl = (UcRadioCheck)UserControl; + _checkRadioUserControl.OnResetRequested += delegate + { + Retry(); + }; + //_checkRadioUserControl.OnDoneRequested += delegate + //{ + // SaveRssiLevelsToDb(); + //}; + } + + /// + /// Check of radio signal strength, skips process on special permission or if NA region + /// + /// + /// + /// - Initial + /// + /// + /// - Skip process on special permission or if NA region, + /// - Remove userControl from main screen if skipped. + /// + /// + /// - Fire SingleProcessState event with argument. + /// + /// + /// - Removed signals for and as + /// these will be automatically set based on return value in + /// . + /// + /// + /// - Assignment of stateMachine and dataContainer. + /// + /// + /// - Get encryption key moved to process to speed up + /// this process as this process needs to be run exclusively. + /// + /// + /// - EOL progress signaled. + /// + /// + /// - Logout at finalization, + /// - Log all write accesses. + /// + /// + /// - SkipRadioCheck not nullable. + /// + /// + /// - SetTestInit as bool. + /// + /// + /// - Separate TestInit and SirtInit (only if test shouldn't be skipped). + /// + /// + /// - CancellationToken. + /// + public override StatusReturn ExecuteProcess() + { + // This will force to reset all values, Sentinel and Prepare shipping will fail based on EOL Progress + if (Meter == null || ProductionRequirements == null || + (!Meter.Region.Equals("NA") && RadioEncryptionKey?.Count == 0)) + { + return StatusReturn.Failed; + } + + // Setup all parameters being able to execute initially or repeat the test + TestInit(); + + // Check first if radio is installed, + // North America Region(NA) doesn't have a Sensus radio application installed + if (Meter.Region.Equals("NA")) + { + EolProgress.FinalRadioSystemStateCheck = EOLStatus.NA; + LogNewStatusMsg(Resources.StrSkippedMsgRadioCheckRegion); + PrepareExit(); + return StatusReturn.Skipped; + } + + // Starting point of time-consuming operations + SignalRunningState(MaxActualProgressSteps); + + // If requirement forces skipping but radio is installed, it should at least be set to customer mode and checked for + // it. + // Reminder for skip radio check forced by requirements + var skipRadioCheck = ProductionRequirements.SkipRadioCheck; + + try + { + if (!Meter.IsLoggedOn) + { + Meter.Login(); + if (!Meter.IsLoggedOn) + { + return SetTestFailed(Resources.StrErrorMsgCordonelLogin); + } + } + + // Standard run for radio signal test (RSSI) + if (!skipRadioCheck) + { + if (UserControl == null) + { + return SetTestFailed(Resources.StrErrorMsgRadioCheck); + } + + // Initialize the SIRT + if (!SirtInit()) + { + return SetTestFailed(Resources.StrErrorMsgSirt); + } + + //FrequencyIndicator + var freq = RegisterConverter.ByteArrayToValue( + Meter.ReadRegister("SENSUSRADIO_FrequencyIndicator")); + _radioAddressCordonel = + RegisterConverter.ByteArrayToValue(Meter.ReadRegister("SENSUSRADIO_RadioAddress")); + ActualProcessProgress++; + + var meterRawEncryptionKey = Meter.ReadRegister("SENSUSRADIO_EncryptionKey", 16); + var meterEncryptionKey = ""; + + // convert byte array to string + if (meterRawEncryptionKey != null) + { + meterEncryptionKey = BitConverter.ToString(meterRawEncryptionKey.ToArray()).Replace("-", ""); + } + + if (RadioEncryptionKey != null) + { + _radioEncryptionKey = RadioEncryptionKey[0].ToUpper(); + } + + // Compare the meterEncryptionKey read out from meter with the database RadioEncryptionKey + // got with the MeterProcessState/api/FinalCheck/GetEncryptionKey + if (meterRawEncryptionKey == null || RadioEncryptionKey == null || + string.IsNullOrEmpty(meterEncryptionKey) || string.IsNullOrEmpty(_radioEncryptionKey) || + !_radioEncryptionKey.Equals(meterEncryptionKey)) + { + return SetTestFailed(Resources.StrErrorMsgRadioKey); + } + + SuccessMsgDispatcher(Resources.StrSuccessMsgDbToMeterEncryptionKey); + ActualProcessProgress++; + + _sirtComport = Convert.ToByte(ConfigurationManager.AppSettings[$"SirtComport{freq}"]); + _sirtBoxNr = Convert.ToByte(ConfigurationManager.AppSettings["SirtBoxNr"]); + var ucRadio = (UcRadioCheck)UserControl; + ucRadio.SetHeadline($"{Resources.StrStateRadioCheck} BOX: {_sirtBoxNr}"); + LogNewStatusMsg($"{Resources.StrStateRadioCheck} Port: COM{_sirtComport}, BOX: {_sirtBoxNr}, " + + $"f: {freq} MHz"); + + // Tell the radio that something is in the slot which will impact the radio transmission + WriteRegisterLogAndProcessCtr(new ProgrammingParameters("SENSUSRADIO_IrDAModulePresent", + new Byte[] { 1 }, ProgrammingSource.ProgramInternal)); + + ActualProcessProgress++; + + // Clear the measurement as on a retry started from main control the old values will be displayed + ClearRssiMeasurement(); + // kick off RSSI test + StartRssiMeasurement(); + + // Exit if meanwhile cancellation is required + if (CancellationToken.IsCancellationRequested) + CancellationProcedure(); + + var exitTime = DateTime.Now + TimeSpan.FromSeconds(Timeout_s); + var actualTime = DateTime.Now; + // wait on result or timeout or stop request from main window + while (!_testFinished && exitTime > actualTime && SingleProcessState != SingleProcessState.Idle) + { + // Exit if meanwhile cancellation is required + if (CancellationToken.IsCancellationRequested) + CancellationProcedure(); + + Thread.Sleep(TimeoutLoop_ms); + actualTime = DateTime.Now; + ActualProcessProgress++; + } + + // lock all buttons as process is finished + DisableAllButtons(); + }// !skipRadioCheck + + // reset all radio alarms + WriteRegisterLogAndProcessCtr(new ProgrammingParameters("SENSUSRADIO_MainAlarmMask", + new Byte[] { 0 }, ProgrammingSource.ProgramInternal)); + WriteRegisterLogAndProcessCtr(new ProgrammingParameters("SENSUSRADIO_ExtendedAlarmMask", + new Byte[] { 0 }, ProgrammingSource.ProgramInternal)); + // set system state back to shipping mode + WriteRegisterLogAndProcessCtr(new ProgrammingParameters("SENSUSRADIO_SystemState", + new Byte[] { 0xFF }, ProgrammingSource.ProgramInternal)); + ActualProcessProgress++; + + // check radio is in customer mode 0x02 and alarm masks are 0 + var mainAlarmMask = + RegisterConverter.ByteArrayToValue(Meter.ReadRegister("SENSUSRADIO_MainAlarmMask")); + var extendedAlarmMask = + RegisterConverter.ByteArrayToValue(Meter.ReadRegister("SENSUSRADIO_ExtendedAlarmMask")); + _finalRadioSystemState = RegisterConverter.ByteArrayToValue(Meter.ReadRegister("SENSUSRADIO_SystemState")); + ActualProcessProgress++; + + if (// Radio mode and alarm masks NOT okay forces always an error + // radio system state 0x02 shipping mode, 0x01 production mode, 0x0C transmission and data logger active + _finalRadioSystemState != 0x02 || mainAlarmMask != 0 || extendedAlarmMask != 0 + // If radio check is enabled the signal level has to be in range and the test has to be finished + || (!skipRadioCheck && (!_successSignalLevel || !_sirtComOkay || !_testFinished))) + { + return SetTestFailed(!_sirtComOkay ? Resources.StrErrorMsgSirt : Resources.StrErrorMsgRadioCheck); + } + + SuccessMsgDispatcher(Resources.StrSuccessMsgRadioInCustomerMode); + SuccessMsgDispatcher(Resources.StrSuccessMsgRadioAlarmsReset); + + // Skip radio check by requirement + if (skipRadioCheck) + { + EolProgress.FinalRadioSystemStateCheck = EOLStatus.NA; + WarningMsgDispatcher(Resources.StrSkippedMsgRadioCheckSpecialPermission); + PrepareExit(); + return StatusReturn.Skipped; + } + return SetTestSucceeded(); + + } + catch (Exception ex) + { + Meter?.WriteLog(ex.Message); + return SetTestFailed(Resources.StrErrorMsgRadioCheck); + } + } + + /// + /// Common for test Init + /// + private void TestInit() + { + // Uncheck executed process to leave the result open needed for retries + EolProgress.RadioCheckId = null; + EolProgress.FinalRadioSystemState = null; + EolProgress.FinalRadioSystemStateCheck = null; + // Value not saved as test hasn't been executed + _radioResultCheckId = 0; + _finalRadioSystemState = 0; + + _sirtComOkay = false; + _testFinished = false; + _successSignalLevel = false; + } + + /// + /// Initialize the SIRT + /// + /// + private Boolean SirtInit() + { + try + { + // Reset needed for repeated run + _stateMachine?.Stop(); + _stateMachine?.ClearBUPRadioAdresses(); + _stateMachine?.ClearPam(); + _stateMachine = null; + _dataContainer = null; + _stateMachine = new Statemashine(); + _dataContainer = new DataContainer(); + + } + catch (Exception ex) + { + Meter?.WriteLog(ex.Message); + return false; + } + + return true; + } + + + /// + /// Common to prepare exit for all status returns + /// + private void PrepareExit() + { + EolProgress.RadioCheckId = _radioResultCheckId; + EolProgress.FinalRadioSystemState = _finalRadioSystemState; + + // Essential to logout from meter at any exit + Meter?.Logout(); + + _stateMachine?.Stop(); + _stateMachine = null; + _dataContainer = null; + } + + /// + /// Common for test failed + /// + /// error message to dispatch and log + /// + private StatusReturn SetTestFailed(String errorMsg) + { + EolProgress.FinalRadioSystemStateCheck = EOLStatus.FAIL; + ErrorMsgDispatcher(errorMsg); + PrepareExit(); + return StatusReturn.Failed; + } + + /// + /// Common for test succeeded + /// + /// + private StatusReturn SetTestSucceeded() + { + EolProgress.FinalRadioSystemStateCheck = EOLStatus.OK; + PrepareExit(); + return StatusReturn.Okay; + } + + /// + /// Disable all buttons of user control. + /// + /// + /// + /// - Initial + /// + private void DisableAllButtons() + { + //EnableBtn(_checkRadioUserControl.btnSkip, false); + EnableBtn(_checkRadioUserControl.btnRetry, false); + } + + private void EnableBtn(Button btn, Boolean enable) + { + btn.Dispatcher.Invoke(DispatcherPriority.Send, + new Action(() => + { + btn.IsEnabled = enable; + } + )); + } + + private void UpdateUc() + { + _checkRadioUserControl.SetUi(new UcRadioCheck.UiContainer(_rssiPamSirtDbMin, _rssiSemiCordonelDbMin, + _rssiPamSirtMeasuredByCordonel, _rssiSemiCordonelMeasuredBySirt, _rssiPamSirtDbMax, _rssiSemiCordonelDbMax)); + } + + /// + /// Check of radio signal strength. + /// + /// + /// + /// - Initial + /// + private void StartRssiMeasurement() + { + // disable all buttons during ongoing measurement process + DisableAllButtons(); + UpdateUc(); + + try + { + ActualProcessProgress++; + GetRssiMinMaxValuesFromDb(_sirtBoxNr, Meter.OrderNumber); + SendPamListenSemi((Int32)_radioAddressCordonel, _sirtComport, _radioEncryptionKey); + UpdateUc(); + ActualProcessProgress++; + } + catch (Exception ex) + { + _testFinished = true; + Meter?.WriteLog(ex.Message); + LogNewStatusMsg(Resources.StrErrorMsgRadioCheck); + } + } + + /// + /// Clear RSSI values for display of unknown values but leave limits active as + /// those are already loaded from DB and will not change during retry. Therefore, + /// the process can be optimized to avoid recurrent DB access! + /// + /// + /// + /// - Initial + /// + private void ClearRssiMeasurement() + { + _sirtComOkay = false; + _rssiPamSirtMeasuredByCordonel = null; + _rssiSemiCordonelMeasuredBySirt = null; + } + + /// + /// Retry collection of RSSI values (entire process with sending PAM and receiving SEMI). + /// + /// + /// + /// - Initial + /// + private void Retry() + { + // reset process counter to start from scratch + ActualProcessProgress = 0; + if (_stateMachine != null) + { + _stateMachine.ClearPam(); + _stateMachine.Stop(); + } + ClearRssiMeasurement(); + UpdateUc(); + SendPamListenSemi((Int32)_radioAddressCordonel, _sirtComport, _radioEncryptionKey); + } + + /// + /// ATTENTION: + /// As those definitions are directly used as DB definitions for pushing the result: + /// + /// LEAVE THOSE NAMING AS DEFINED HERE! + /// + /// + private class DataContainer + { + public Int32 RadioAdress + { + get; set; + } + public Byte RSSI_PAM + { + get; set; + } + public Byte RSSI_SEMI + { + get; set; + } + public Int32 LimitId + { + get; set; + } + public Byte Result + { + get; set; + } + } + + + /// + /// Save RSSI values to DB. + /// + /// + /// + /// - Initial + /// + private void SaveRssiLevelsToDb() + { + try + { + if (_dataContainer != null) + { + _dataContainer.RadioAdress = (Int32)_radioAddressCordonel; // 0-4294967295 + var url = $"{ServiceUrls.GenesisRadioCheckServiceUrl()}SaveRSSI"; + + var response = LocalWebRequest.PostRequestAsync(url, 30000, out var httpStatus, _dataContainer); + if (!string.IsNullOrEmpty(response) && httpStatus == HttpStatusCode.OK) + { + var jsonObj = JObject.Parse(response); + _radioResultCheckId = Convert.ToInt32(jsonObj.SelectToken("radiocheckid")); + } + + SuccessMsgDispatcher(Resources.StrSuccessMsgSetRadioRssiLimitsToDb); + ActualProcessProgress++; + } + else + { + ErrorMsgDispatcher(Resources.StrErrorMsgSetRadioRssiLimitsToDb); + } + } + catch (Exception ex) + { + Meter?.WriteLog(ex.Message); + ErrorMsgDispatcher(Resources.StrErrorMsgSetRadioRssiLimitsToDb); + } + finally + { + _testFinished = true; + } + } + + /// + /// Get RSSI values from DB. + /// + /// + /// + /// - Initial + /// + private void GetRssiMinMaxValuesFromDb(Byte BoxNr, Int32 productionOrderNo) + { + try + { + if (_dataContainer != null) + { + var url = $"{ServiceUrls.GenesisRadioCheckServiceUrl()}GetLimits/{BoxNr}/{productionOrderNo}"; + var body = LocalWebRequest.GetRequest(url, 300000, out var httpStatus); + if (httpStatus != HttpStatusCode.OK || string.IsNullOrEmpty(body)) + { + ErrorMsgDispatcher(Resources.StrErrorMsgGetRadioRssiLimitsFromDb); + return; + } + var o = JObject.Parse(body); + + _dataContainer.LimitId = Convert.ToInt32(o.SelectToken("LimitId")?.ToString()); + _rssiPamSirtDbMin = Convert.ToByte(o.SelectToken("RSSI_PAM_Min")?.ToString()); + _rssiPamSirtDbMax = Convert.ToByte(o.SelectToken("RSSI_PAM_Max")?.ToString()); + _rssiSemiCordonelDbMin = Convert.ToByte(o.SelectToken("RSSI_SEMI_Min")?.ToString()); + _rssiSemiCordonelDbMax = Convert.ToByte(o.SelectToken("RSSI_SEMI_Max")?.ToString()); + SuccessMsgDispatcher(Resources.StrSuccessMsgGetRadioRssiLimitsFromDb + + $": ID: ({_dataContainer.LimitId}), " + + $"SIRT Min: ({_rssiPamSirtDbMin}), " + + $"SIRT Max: ({_rssiPamSirtDbMax}), " + + $"Cordonel Min: ({_rssiSemiCordonelDbMin}), " + + $"Cordonel Max: ({_rssiSemiCordonelDbMax})"); + ActualProcessProgress++; + } + } + catch (Exception ex) + { + Meter?.WriteLog(ex.Message); + ErrorMsgDispatcher(Resources.StrErrorMsgGetRadioRssiLimitsFromDb); + } + } + + /// + /// Send PAM to force a BUP and a SEMI and start the RSSI observer to measure the signal strength. + /// + /// + /// + /// - Initial + /// + /// + /// - Optimized based on new documentations. + /// + private void SendPamListenSemi(Int32 radioAddress, Int32 byteComPort, String strKey) + { + if (_dataContainer == null || _stateMachine == null) + return; + + _rssiPamSirtMeasuredByCordonel = null; + _rssiSemiCordonelMeasuredBySirt = null; + + Byte P81_1 = 0; + + _dataContainer.RadioAdress = radioAddress; + + _stateMachine.initialise((Byte)byteComPort); + var date = DateTime.Now.Date; + var loggingPath = $"C:\\GenesisLog\\{date:yyyy-MM-dd}\\ProductionUiCordonel\\{Meter.PcbId}_RadioCheck.log"; + _stateMachine.StartLoggin(loggingPath); + + LogNewStatusMsg($"{Resources.StrRadioMsgSendPam}: {radioAddress.ToString()}"); + + // Initialize the state machine of the SIRT dll + _stateMachine.Stop(); + _stateMachine.ClearPam(); + _stateMachine.Timeout_s = 30; + + // Dummy PAM 00 with radio encryption key, SIRT dll takes the key for the response and the + // address for the request and response, CommandHex 00 is data size of 0, so it makes no sense + // to encrypt the 00 PAM, but the key will be used in the SEMI response + _stateMachine.SendPAM(radioAddress.ToString(), "00", "", P81_1, 1, 0, strKey, "0", true); + ActualProcessProgress++; + + // SystemState 0x55 will force meter immediately to send BUP, internal the system state remains + // on 0x02. This has to be sent after PAM! + Meter.WriteRegister("SENSUSRADIO_SystemState", 0x55); + + // Start polling + _stateMachine.OnStateChanged += StateMachineOnStateChange_Handler; + _stateMachine.Start(); + + ActualProcessProgress++; + } + + /// + /// Get RSSI (Received Signal Strength Indicator) values from SIRT (Sensus Interface Radio Tool). + /// Set the + /// + /// + /// + /// - Initial + /// + /// + /// - Initial + /// + private void GotRssiCallback(Byte rssiSemiCordonel, Byte rssiPamSirt) + { + if (_dataContainer == null) + return; + + // RSSI PAM sent by SIRT and measured by Cordonel + LogNewStatusMsg($"{Resources.StrMeasuredMsgRadioRssiSirt}: ({rssiPamSirt})"); + // RSSI SEMI sent by Cordonel and measured by SIRT + LogNewStatusMsg($"{Resources.StrMeasuredMsgRadioRssiCordonel}: ({rssiSemiCordonel})"); + + _rssiPamSirtMeasuredByCordonel = rssiPamSirt; + _rssiSemiCordonelMeasuredBySirt = rssiSemiCordonel; + _dataContainer.RSSI_PAM = rssiPamSirt; + _dataContainer.RSSI_SEMI = rssiSemiCordonel; + + UpdateUc(); + + // threshold check for failed test + if (_rssiPamSirtMeasuredByCordonel < _rssiPamSirtDbMin || + _rssiPamSirtMeasuredByCordonel > _rssiPamSirtDbMax || + _rssiSemiCordonelMeasuredBySirt < _rssiSemiCordonelDbMin || + _rssiSemiCordonelMeasuredBySirt > _rssiSemiCordonelDbMax) + { + _dataContainer.Result = 0; + // done can finish the test which is equal to abort on error + //EnableBtn(_checkRadioUserControl.btnSkip, true); + // reset can repeat the test as often as wanted + EnableBtn(_checkRadioUserControl.btnRetry, true); + _successSignalLevel = false; + } + else + { + // on success there is no choice to made, it is finished + _dataContainer.Result = 1; + _successSignalLevel = true; + + // safe those results to DB for logging + SaveRssiLevelsToDb(); + } + } + + /// + /// State machine state change handler. + /// + /// + /// + /// - Initial + /// + private void StateMachineOnStateChange_Handler(Object sender, MyEventArgs e) + { + if (_stateMachine == null) + return; + try + { + // Reading back sent PAM from SIRT to Cordonel + var pam = _stateMachine.GetPAM(1); + + if (pam != null) + { + if (pam.State == PAM.PAMStates.Timeout) + { + LogNewStatusMsg($"Timeout {pam.GetTime()} s"); + } + + if (pam.CountSemi > 0) + { + // SEMI received from Cordonel + _stateMachine.Stop(); + _stateMachine.ClearPam(); + + var hexBytesSemi = pam.Semi.HexData.Replace(" ", ""); + var semiBytes = new Byte[hexBytesSemi.Length / 2]; + + for (var i = 0; i < hexBytesSemi.Length; i += 2) + semiBytes[i / 2] = Convert.ToByte(hexBytesSemi.Substring(i, 2), 16); + + // SEMI Status okay if 0, if SIRT dll returns unequal to 0 the encryption key is wrong + // If 0 the encryption key is correct + if (semiBytes[19] == 0) + { + // RSSI SEMI sent by Cordonel and measured by SIRT (signal level of Cordonel in byte 2) + var rssiSemiMeasuredBySirt = semiBytes[2]; + + // RSSI PAM sent by SIRT and measured by Cordonel (signal level of SIRT packet to SEMI in byte 20) + var rssiPamMeasuredByCordonel = semiBytes[20]; + + GotRssiCallback(rssiSemiMeasuredBySirt, rssiPamMeasuredByCordonel); + _sirtComOkay = true; + } + else + { + // SEMI Status not 0 is internal error which should be logged + LogNewStatusMsg(pam.Semi.GetPamErrorMessage()); + _sirtComOkay = false; + } + } + else + { + LogNewStatusMsg($"BUPS: ({pam.CountBup})"); + _sirtComOkay = false; + } + }//pam not null + else + { + _stateMachine.Stop(); + _stateMachine.ClearPam(); + } + } + catch (Exception ex) + { + Meter?.WriteLog(ex.Message); + } + } + } +} diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/IProcessStateDef.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/IProcessStateDef.cs index c5022e48..9fa7f526 100644 --- a/Common/Production/ProductionUiCordonel/ProductionProcesses/IProcessStateDef.cs +++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/IProcessStateDef.cs @@ -99,6 +99,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses /// /// - Changed to sorted list by production process number /// - List GetAllEolRelevantProcesses(); + List GetAllProductionProcesses(); } } diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/ProcessController.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/ProcessController.cs index ad66190a..5ff2e2e4 100644 --- a/Common/Production/ProductionUiCordonel/ProductionProcesses/ProcessController.cs +++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/ProcessController.cs @@ -605,7 +605,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses Processes = new List(); // get all processes relevant for EOL from table which has to be sorted - var processes = _processStateDef.GetAllEolRelevantProcesses(); + var processes = _processStateDef.GetAllProductionProcesses(); foreach (var process in processes) { diff --git a/Common/Production/ProductionUiCordonel/ProductionUiCordonel.csproj b/Common/Production/ProductionUiCordonel/ProductionUiCordonel.csproj index 33c0554b..aacaff13 100644 --- a/Common/Production/ProductionUiCordonel/ProductionUiCordonel.csproj +++ b/Common/Production/ProductionUiCordonel/ProductionUiCordonel.csproj @@ -370,11 +370,7 @@ Designer MSBuild:Compile -<<<<<<< HEAD - -======= ->>>>>>> Dev_Picking Designer MSBuild:Compile diff --git a/Common/Production/ProductionUiCordonel/ProductionWindow.xaml.cs b/Common/Production/ProductionUiCordonel/ProductionWindow.xaml.cs index 774a2546..493733e2 100644 --- a/Common/Production/ProductionUiCordonel/ProductionWindow.xaml.cs +++ b/Common/Production/ProductionUiCordonel/ProductionWindow.xaml.cs @@ -21,7 +21,6 @@ using Xylem.Common.CommonCore.Consts; using Xylem.Common.Hardware.Interfaces.Ports.PortCore; using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses; using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum; -using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses; using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EventArgs; using Xylem.Common.Utils.Logging; using Xylem.Common.Utils.UserAccessCtrl;