From ea35d1ee755c6151ec21c83b20f9821441a304ef Mon Sep 17 00:00:00 2001 From: Thomas Wiedebusch Date: Thu, 12 Feb 2026 15:39:57 +0100 Subject: [PATCH] ProductionUiCordonel: - reboot counter check skipped on retry if passed at first run --- .../Genesis/GenesisCore/GenesisMeter.cs | 10 +++++++ .../Genesis/GenesisCore/IGenesisMeter.cs | 11 ++++++++ .../GenericProcesses/ConnectCordonel.cs | 27 ++++++++++++------- .../ProductionProcesses/ProcessController.cs | 7 ++--- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs index 85f7f574..ac6708ce 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs @@ -77,6 +77,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore public GenesisMeter() { SetLogger(); + CheckRebootCtr = true; } //initially do not signal event @@ -100,6 +101,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore { Logger = NLogHelper.CreateOrGetMultiLogger($"Slot:{slot}", "Slot", "Meter", "MeterBase", "MeterBase"); SetupGenesisMeter(slot, requestPort, streamingPort, ignoreCorruptedData, password); + CheckRebootCtr = true; + } #endregion @@ -195,6 +198,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore get; protected set; } + /// + public Boolean CheckRebootCtr + { + get; + set; + } + /// public List MeterAppListVersion { diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/IGenesisMeter.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/IGenesisMeter.cs index 310c6e4b..c77e6511 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/IGenesisMeter.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/IGenesisMeter.cs @@ -25,6 +25,17 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore get; } + /// + /// A new meter has to be checked for the reboot counter. On retries the reboot counter + /// may have increased on unsuccessfully after-reboot procedure. This would force failing + /// the 'ConnectCordonel'. + /// + Boolean CheckRebootCtr + { + get; + set; + } + /// /// Interface information /// diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericProcesses/ConnectCordonel.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericProcesses/ConnectCordonel.cs index 5d4045b9..cdad399e 100644 --- a/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericProcesses/ConnectCordonel.cs +++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericProcesses/ConnectCordonel.cs @@ -73,18 +73,27 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener // Read reboot count and compare with hardcoded maximum value var rebootCount = RegisterConverter.ByteArrayToValue(Meter.ReadRegister("CUSTOMER_RebootCount")); - if (rebootCount > MeterResetPsu.MAX_REBOOTS_FOR_HEALTHY_HW) + + + if (Meter.CheckRebootCtr) { - ErrorMsgDispatcher(Resources.StrErrorMsgTooManyReboots + - $" - {Resources.StrProcessStateAllowed}: {MeterResetPsu.MAX_REBOOTS_FOR_HEALTHY_HW}" + - $" - {Resources.StrProcessStateDetected}: {rebootCount}"); - return StatusReturn.Failed; + if (rebootCount > MeterResetPsu.MAX_REBOOTS_FOR_HEALTHY_HW) + { + ErrorMsgDispatcher(Resources.StrErrorMsgTooManyReboots + + $" - {Resources.StrProcessStateAllowed}: {MeterResetPsu.MAX_REBOOTS_FOR_HEALTHY_HW}" + + $" - {Resources.StrProcessStateDetected}: {rebootCount}"); + return StatusReturn.Failed; + } + + // Skip reboot counter check on reties as it passed here the initial phase as a retry may follow an + // unsuccessfully hardware-reboot-procedure + Meter.CheckRebootCtr = false; + + SuccessMsgDispatcher(Resources.StrSuccessMsgRebootCounts + + $" - {Resources.StrProcessStateAllowed}: {MeterResetPsu.MAX_REBOOTS_FOR_HEALTHY_HW}" + + $" - {Resources.StrProcessStateDetected}: {rebootCount}"); } - SuccessMsgDispatcher(Resources.StrSuccessMsgRebootCounts + - $" - {Resources.StrProcessStateAllowed}: {MeterResetPsu.MAX_REBOOTS_FOR_HEALTHY_HW}" + - $" - {Resources.StrProcessStateDetected}: {rebootCount}"); - // If interface is outdated if (!Meter.InterfaceSupportsFwVersion) { diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/ProcessController.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/ProcessController.cs index 001a8ed4..32de106b 100644 --- a/Common/Production/ProductionUiCordonel/ProductionProcesses/ProcessController.cs +++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/ProcessController.cs @@ -38,6 +38,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses private ProcessState _lockedStateMachineState; // sender of state change event to evaluate in e.g. error process private IProductionProcess _stateChangeRequestProcess; + // List of production processes public List Processes { @@ -147,7 +148,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses { // Timer for cyclic call of state machine _processCtrlTimer = new Timer(TmrProcessCtrlCycle_Elapsed, null, ProcessTimerCycleMs, ProcessTimerCycleMs); - + // Delay timer between final-param-exec finished and start of 'StoreConfiguration' _paramExeFinishedToStoreConfigDelayTimer = new DispatcherTimer(); _paramExeFinishedToStoreConfigDelayTimer.Tick += TmrParamExeFinishedToStoreConfigCycle_Tick; @@ -281,7 +282,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses break; } // Delay timer init and start if parametrization exec finished but only for 'EMEA' region - if (pp != null && + if (pp != null && pp.ProcessName != null && pp.Meter != null && pp.Meter.Region.Equals("EMEA") && @@ -834,7 +835,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses _stateMachineState = (ProcessState)processStateStruct.NextStateOnSuccess; return; } - + // Process is waiting for execution after init, this overrides the eventually abort state processStateStruct.ProductionProcess.InitProcess();