diff --git a/Common/Common.sln.DotSettings b/Common/Common.sln.DotSettings
index 9421a131..77a48996 100644
--- a/Common/Common.sln.DotSettings
+++ b/Common/Common.sln.DotSettings
@@ -48,6 +48,7 @@
True
True
True
+ True
True
True
@@ -59,6 +60,7 @@
True
True
True
+ True
True
True
True
@@ -70,6 +72,7 @@
True
True
True
+ True
True
True
True
diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs
index eebd89ba..d7f940f1 100644
--- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs
+++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs
@@ -115,6 +115,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// temporary setup values which do not survive a reboot. This is done to overcome a FW-bug which overwrites
/// those values after the reboot procedure!
///
+ ///
+ /// - Initial to restore values which do not survive the reboot as workaround for R1.4.22 and below.
+ ///
private static readonly List _restoreAfterRebootIfCompareFailed = new List
{
"CUSTOMER_AlarmEnableMask" // Restored to hard coded value up to FW R1.4.22
@@ -129,6 +132,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// All commands defined here will not be accepted from 'external' to adjust. Program internally, those
/// commands are potentially allowed if those do not change any MID dependent 'values'.
///
+ ///
+ /// - SENSUSRADIO_WakeupInterval added to keep radio active after field update if it was active before.
+ ///
private static readonly List _fieldUpdateBlacklist = new List
{
"CUSTOMER_AlarmVisualMask",
@@ -252,6 +258,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
"SENSUSRADIO_Tfx_Structure", //21
"SENSUSRADIO_UpgFWVersion", //22
"SENSUSRADIO_UtcTimeOffset", //23
+ "SENSUSRADIO_WakeupInterval", //24
"SYSTEM_CalendarSeconds", // 1
"SYSTEM_CheckPresence", // 2
diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterResetPsu.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterResetPsu.cs
index 2a29ebca..c422336a 100644
--- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterResetPsu.cs
+++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterResetPsu.cs
@@ -74,7 +74,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
// position of version string
private const Int32 FlexVersionStringIndex = 0x66;
-
private Int32 _processRetryCtr;
private IGenesisMeter _genesisMeter;
@@ -101,6 +100,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
///
public Boolean StoreConfigEnable = true;
+ ///
+ /// Threshold to waste the HW if reboots too high
+ ///
+ public const Int32 MAX_REBOOTS_FOR_HEALTHY_HW = 4;
+
#endregion
#region Events
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckFinalParametrization.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckFinalParametrization.cs
index f21ab7c6..ecda626e 100644
--- a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckFinalParametrization.cs
+++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckFinalParametrization.cs
@@ -14,7 +14,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// Ctor
///
- public CheckFinalParametrization(String name) : base( name)
+ public CheckFinalParametrization(String name) : base(name)
{
}
@@ -49,7 +49,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - CancellationToken.
///
- ///
+ ///
/// - Restore registers after reboot if failed - temporary workaround for FW-bug.
///
public override StatusReturn ExecuteProcess()
@@ -86,7 +86,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
RegisterRestorer.OnProcessUpdate += ProcessUpdate_Handler;
var retValBol = RegisterRestorer.FinalReadRegisters(CancellationToken);
RegisterRestorer.OnProcessUpdate -= ProcessUpdate_Handler;
-
+
// Exit if meanwhile cancellation is required
if (CancellationToken.IsCancellationRequested)
return CancellationProcedure();
@@ -105,13 +105,13 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Restore registers after reboot if failed
if (RegisterRestorer.HasRestoreRegistersAfterRebootIfCompareFailed)
{
+ WarningMsgDispatcher(Resources.StrWarningMsgParameterCompare);
// Write and compare those registers
RegisterRestorer.OnProcessUpdate += ProcessUpdate_Handler;
retValBol = RegisterRestorer.RestoreAndCompareRegistersAfterReboot(CancellationToken);
RegisterRestorer.OnProcessUpdate -= ProcessUpdate_Handler;
if (retValBol)
{
- WarningMsgDispatcher(Resources.StrWarningMsgParameterCompare);
EolProgress.ParametrizationCompareChecked = EOLStatus.OK;
Meter?.Logout();
return StatusReturn.Warning;
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/ExecRebootCordonel.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/ExecRebootCordonel.cs
index c102fe5a..6d35f68c 100644
--- a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/ExecRebootCordonel.cs
+++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/ExecRebootCordonel.cs
@@ -51,6 +51,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - Accumulator reset if setting to zero failed as defined by A.F. as workaround for FW bug.
///
+ ///
+ /// - Threshold for allowed reboots to detect erroneous hardware.
+ ///
public override StatusReturn ExecuteProcess()
{
// Uncheck executed process to leave the result open needed for retries
@@ -77,7 +80,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
return StatusReturn.Failed;
}
}
- var ale = Meter.ReadRegister("CUSTOMER_AlarmEnableMask");
+ // Read and automatically log it to database if logging is active
+ Meter.ReadRegister("CUSTOMER_AlarmEnableMask");
+
#region ----------------------------------- Reboot ----------------------------------------------------
// reboot the meter and avoid doubled storage of configurations
var _meterResetPsu = new MeterResetPsu(Meter)
@@ -107,6 +112,18 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
}
}
ActualProcessProgress++;
+ #endregion
+ #region ----------------------------------- Check reboot count ----------------------------------------
+ // 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)
+ {
+ ErrorMsgDispatcher(Resources.StrErrorMsgTooManyReboots);
+ EolProgress.RebootDoneChecked = EOLStatus.FAIL;
+ return StatusReturn.Failed;
+ }
+
#endregion
#region ----------------------------------- Set Time and Reset Counters -------------------------------
// Get the time in UTC to program the time for the Cordonel in seconds since 01. Jan 2000
@@ -123,7 +140,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
ProgrammingSource.ProgramInternal));
ActualProcessProgress++;
// Reset reboot counter
- retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("CUSTOMER_RebootCount",
+ retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("CUSTOMER_RebootCount",
new Byte[] { 0x00 }, ProgrammingSource.ProgramInternal));
// Reset alarms Customer
retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("CUSTOMER_TriggerAlarmCancel",
@@ -173,11 +190,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
var retryCtr = 2;
// Check all values for 0 after reset and followed reboot which may use the
- var readBackScaledBilling =
+ var readBackScaledBilling =
RegisterConverter.ByteArrayToValue(Meter.ReadRegister("GENESISFLOW_ScaledBilling"));
- var readBackUnscaledFwd =
+ var readBackUnscaledFwd =
RegisterConverter.ByteArrayToValue(Meter.ReadRegister("GENESISFLOW_UnscaledFwd"));
- var readBackUnscaledRev =
+ var readBackUnscaledRev =
RegisterConverter.ByteArrayToValue(Meter.ReadRegister("GENESISFLOW_UnscaledRev"));
while (retryCtr-- > 0 &&
@@ -186,11 +203,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Backup sealing state as for the NA region it may be unsealed
var displaySealingState =
RegisterConverter.ByteArrayToValue(Meter.ReadRegister("GENESISFLOW_SealDisplay"));
-
+
// Unseal accumulator reset capability
retValBol = WriteRegisterLogAndProcessCtr(new ProgrammingParameters("GENESISFLOW_SealDisplay",
new Byte[] { 0x00 }, ProgrammingSource.ProgramInternal));
-
+
// Reset accumulators again
retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("GENESISFLOW_ResetAccumulators",
new Byte[] { 0x01 }, ProgrammingSource.ProgramInternal));
@@ -201,7 +218,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// it doesn't have to be a change.
retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("GENESISFLOW_ForwardArrow",
new[] { forwardArrow }, ProgrammingSource.ProgramInternal));
-
+
// Seal accumulator reset capability
// ReSharper disable once RedundantAssignment as it is used for DEBUG
retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("GENESISFLOW_SealDisplay",
@@ -224,7 +241,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
EolProgress.RebootDoneChecked = EOLStatus.FAIL;
return StatusReturn.Failed;
}
-#endregion
+ #endregion
SuccessMsgDispatcher(Resources.StrSuccessMsgAlarmReset);
EolProgress.RebootDoneChecked = EOLStatus.OK;
return StatusReturn.Okay;
diff --git a/Common/Production/ProductionUiCordonel/Properties/Resources.Designer.cs b/Common/Production/ProductionUiCordonel/Properties/Resources.Designer.cs
index 9e1c3880..c7e5eb18 100644
--- a/Common/Production/ProductionUiCordonel/Properties/Resources.Designer.cs
+++ b/Common/Production/ProductionUiCordonel/Properties/Resources.Designer.cs
@@ -1050,6 +1050,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to ERROR: Hardware reboots higher than allowed threshold.
+ ///
+ internal static string StrErrorMsgTooManyReboots {
+ get {
+ return ResourceManager.GetString("StrErrorMsgTooManyReboots", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to ERROR: Firmware is not supported.
///
diff --git a/Common/Production/ProductionUiCordonel/Properties/Resources.de.resx b/Common/Production/ProductionUiCordonel/Properties/Resources.de.resx
index 3feb62b5..944704e0 100644
--- a/Common/Production/ProductionUiCordonel/Properties/Resources.de.resx
+++ b/Common/Production/ProductionUiCordonel/Properties/Resources.de.resx
@@ -681,6 +681,9 @@
WARNUNG: Ergebnis muß überprüft werden! Prozeß
+
+
+ FEHLER: Hardwareneustarts über der erlaubten Grenze
ACHTUNG
diff --git a/Common/Production/ProductionUiCordonel/Properties/Resources.resx b/Common/Production/ProductionUiCordonel/Properties/Resources.resx
index c7247541..83b62502 100644
--- a/Common/Production/ProductionUiCordonel/Properties/Resources.resx
+++ b/Common/Production/ProductionUiCordonel/Properties/Resources.resx
@@ -681,6 +681,9 @@
WARNING: Result needs inspection! Process
+
+
+ ERROR: Hardware reboots higher than allowed threshold
ATTENTION
diff --git a/Common/Ui/GenesisToolBox/FrmFwUpdate.cs b/Common/Ui/GenesisToolBox/FrmFwUpdate.cs
index a4d21598..d8d9088b 100644
--- a/Common/Ui/GenesisToolBox/FrmFwUpdate.cs
+++ b/Common/Ui/GenesisToolBox/FrmFwUpdate.cs
@@ -1486,33 +1486,6 @@ namespace Xylem.Common.Ui.GenesisToolBox
{
return;
}
-
-
-
- //_currentGenesis.WriteRegister("POWERMON_BatteryQuantity", 2, true, true);
- //_currentGenesis.WriteRegister("POWERMON_StoreConfiguration", 1, true, true);
- //var genesisStatus = new GenesisStatus();
- //if (GenesisStatusHandler.BuildLifeTimeInformation(_currentGenesis, genesisStatus))
- //{
-
- // var sbMSG = new StringBuilder();
- // sbMSG.AppendLine($"Pcb = {_currentGenesis.PcbId}");
-
- // sbMSG.AppendLine($"POWERMON_TotalUsedSeconds = {genesisStatus.ExceededLifeTime_s}");
- // sbMSG.AppendLine($"POWERMON_TotalUsedCharge = {genesisStatus.DrainedBatteryLoad_uAs}");
- // sbMSG.AppendLine($"POWERMON_BatteryQuantity = {genesisStatus.BatteryQuantity}");
- // sbMSG.AppendLine($"POWERMON_BatteryMilliAHrRating = {genesisStatus.InitialBatteryLoad_mAh}");
- // sbMSG.AppendLine("");
- // sbMSG.AppendLine($"Remaining lifetime in years {genesisStatus.RemainingLifeTimeYears:F2}");
- // sbMSG.AppendLine($"Totally drained battery load in % {genesisStatus.DrainedBatteryLoadPercent:F2}");
- // _currentGenesis.WriteLog(sbMSG.ToString());
- // MessageBox.Show(sbMSG.ToString(), $"Battery for {_currentGenesis.PcbId} has remaining life " +
- // $"time of {genesisStatus.RemainingLifeTimeYears:F2} years");
- //}
- //else
- //{
- // MessageBox.Show("Failed to get life time information");
- //}
_currentGenesis.RequestProtocol.AdditionalRetryTimeoutMs = addRetryTimeoutMs;
Task.Factory.StartNew(() =>