diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs index 2d14c473..9c6c62f2 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs @@ -59,7 +59,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// Register which shall be restored after change of FW or after register recovery /// - private readonly MeterRegisters _restoreRegisters = new MeterRegisters(); + private readonly MeterRegisters _recoveryRegisters = new MeterRegisters(); /// /// Register access event for message dispatcher to caller @@ -80,8 +80,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// private static readonly List _excludedFromCompareParameters = new List { - "SENSUSRADIO_UpgFWVersion", // After a FW-Update the FW version has changed and the compare will fail - "IRDA_MfgDate" // After a FW-Update the date has changed and the compare will fail + "SENSUSRADIO_UpgFWVersion" // After a FW-Update the FW version has changed and the compare will fail }; /// /// Pre programming parameters for all devices defined here, will be filled with radio parameters @@ -94,11 +93,20 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore }; /// - /// Pre programming parameters for all devices defined here, will be filled with radio parameters - /// if meter has radio + /// /// - // ReSharper disable once CollectionNeverQueried.Global IS FOR DEBUG - public readonly List FailedComparisonRegisters = new List(); + // 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(); + private readonly List _recoveryRegisterList = new List(); + private List _initialRegisterList = new List(); + private List _finalRegisterList = new List(); + /// /// Post programming parameters for radio only @@ -106,6 +114,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore private static readonly List _finalizeProgrammingRadioOnly = 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 }), // 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 @@ -119,6 +128,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore private static readonly List _finalizeProgramming = new List { new RecoveryRegisterItem("GENESISFLOW_SealDisplay", new Byte[] { 0x01 }), + // trigger idle 0 releases the display to normal operation new RecoveryRegisterItem("GENESISFLOW_TriggerIdle", new Byte[] { 0x00 }), }; @@ -128,7 +138,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore private static readonly List _finalizeProgrammingEol = new List { new RecoveryRegisterItem("GENESISFLOW_ResetAccumulators", new Byte[] { 0x01 }), - new RecoveryRegisterItem("NFC_EraseRMA", new Byte[] { 0x01 }) + new RecoveryRegisterItem("NFC_EraseRMA", new Byte[] { 0x01 }), + new RecoveryRegisterItem("CUSTOMER_RebootCount", new Byte[] {0x00}) }; /// @@ -386,6 +397,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore 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) @@ -400,7 +416,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore { finalizeProgrammingAll.AddRange(_finalizeProgrammingRadioOnly); } - // add EOL sequence if called + // add EOL (shipping reset of accumulators, alarms and setup of manufacturing date) if (eolProgramming) { finalizeProgrammingAll.AddRange(_finalizeProgrammingEol); @@ -480,7 +496,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore { strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, recReg.WriteValue); // replace value in _restoreRegister with the required recovery value - _restoreRegisters?.Set(regDef, recReg.WriteValue); + _recoveryRegisters?.Set(regDef, recReg.WriteValue); } catch (Exception ex) @@ -585,17 +601,17 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore public Boolean CompareRegisters() { if (_pcbIdFinalRegisterRead != _pcbIdInitialRegisterRead || - _restoreRegisters == null || + _recoveryRegisters == null || _finalReadRegisters == null) return false; StopRegisterAccess = false; ActualRegisterCtr = 0; var retVal = true; - FailedComparisonRegisters?.Clear(); + _failedComparisonRegisters?.Clear(); // build a string list of the registers being able to sort those - var registerNames = _restoreRegisters.MeterRegisterDic.Select(register => register.Key.GetIdent()).ToList(); + var registerNames = _recoveryRegisters.MeterRegisterDic.Select(register => register.Key.GetIdent()).ToList(); // Remove all excluded registers foreach (var regName in _excludedFromCompareParameters.Where(regName => registerNames.Any(reg => reg == regName))) { @@ -611,14 +627,14 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore { ActualRegisterCtr++; - var regDef = _restoreRegisters.GetRegisterDefinitionByName(regName); + var regDef = _recoveryRegisters.GetRegisterDefinitionByName(regName); var overallProcessCtrPercent = 100.0 * ActualRegisterCtr / registersCount; try { // Get the raw byte array of this register - var restorableRawRegister = _restoreRegisters.Get(regName); + var restorableRawRegister = _recoveryRegisters.Get(regName); var finalReadRawRegister = _finalReadRegisters.Get(regName); // take the size into account as a read value will be filled up to a chunk of 4 bytes @@ -702,7 +718,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore strRequiredRegisterValue += $" - {Resources.StrMeterValue}: ({strReadBackRegisterValue})" + $" - {Resources.StrRegisterCompareFailed}"; - FailedComparisonRegisters?.Add(new RecoveryRegisterItem(regName, restorableRawRegister, + _failedComparisonRegisters?.Add(new RecoveryRegisterItem(regName, restorableRawRegister, finalReadRawRegister)); retVal = false; } @@ -779,6 +795,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}", 0, Resources.StrReadRegistersAfterUpdate)); + // Build string list for debug + _finalRegisterList.Clear(); + _finalRegisterList = _finalReadRegisters.MeterRegisterDic.Select(register => register.Key.GetIdent()).ToList(); + _finalRegisterList.Sort(); + // executes login read logout return ReadRegistersSet(_finalReadRegisters); } @@ -819,13 +840,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore // deny update of registers if already done if (_pcbIdInitialRegisterRead == _currentGenesis.PcbId && _initialReadRegisters.MeterRegisterDic.Count > 0 && - _restoreRegisters.MeterRegisterDic.Count > 0) + _recoveryRegisters.MeterRegisterDic.Count > 0) return true; // remind the PCB ID before update for comparison _pcbIdInitialRegisterRead = _currentGenesis.PcbId; - _initialReadRegisters.MeterRegisterDic.Clear(); - _restoreRegisters.MeterRegisterDic.Clear(); // create the dictionaries out of the configuration.json if (!BuildInitialDictionaries()) @@ -835,7 +854,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}", 0, Resources.StrReadRegistersBeforeUpdate)); - return ReadRegistersSet(_initialReadRegisters, _restoreRegisters); + return ReadRegistersSet(_initialReadRegisters, _recoveryRegisters); } /// @@ -854,8 +873,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore if (_currentGenesis == null) return false; - _initialReadRegisters.MeterRegisterDic.Clear(); - _restoreRegisters.MeterRegisterDic.Clear(); + _recoveryRegisters.MeterRegisterDic.Clear(); + _recoveryRegisterList.Clear(); // create a dictionary for initial read being able to compare those with the final read and restored if (!BuildReadableRegisterDictionary(ref _initialReadRegisters)) @@ -867,10 +886,17 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore r.Key.RestoreCapability.CheckRestoreCapability() && r.Key.RegisterDetail.Privilege.Lvl8 == Access.RW)) { - _restoreRegisters.MeterRegisterDic.TryAdd(reg.Key, reg.Value); + _recoveryRegisters.MeterRegisterDic.TryAdd(reg.Key, reg.Value); + _recoveryRegisterList.Add(reg.Key.GetIdent()); } + _recoveryRegisterList.Sort(); - return _restoreRegisters.MeterRegisterDic.Count > 0 && _initialReadRegisters.MeterRegisterDic.Count > 0; + // Build string list for debug + _initialRegisterList.Clear(); + _initialRegisterList = _initialReadRegisters.MeterRegisterDic.Select(register => register.Key.GetIdent()).ToList(); + _initialRegisterList.Sort(); + + return _recoveryRegisters.MeterRegisterDic.Count > 0 && _initialReadRegisters.MeterRegisterDic.Count > 0; } /// @@ -885,7 +911,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// - Initial from . /// - public Boolean BuildReadableRegisterDictionary(ref MeterRegisters registers) + private Boolean BuildReadableRegisterDictionary(ref MeterRegisters registers) { if (_currentGenesis == null || registers?.MeterRegisterDic == null) return false;