From 8dd636922b859eaf4e045f79d14f37f079be5823 Mon Sep 17 00:00:00 2001 From: Thomas Wiedebusch Date: Mon, 17 Nov 2025 17:01:39 +0100 Subject: [PATCH] ProductionUiCordonel: - restore listed registers after reboot which didn't survive the reboot --- .../Genesis/GenesisCore/RegisterRestorer.cs | 215 ++++++++++++------ .../BaseProductionProcess.cs | 19 +- .../EolProcesses/CheckFinalParametrization.cs | 21 ++ .../Properties/Resources.Designer.cs | 11 +- .../Properties/Resources.de.resx | 5 +- .../Properties/Resources.resx | 9 +- .../EventArguments/ProcessExecEventArgs.cs | 10 +- 7 files changed, 218 insertions(+), 72 deletions(-) diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs index 92c9a772..eebd89ba 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs @@ -47,6 +47,16 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// public List RecoveryRegisters; + /// + /// Name of registers which should be restored after reboot if the compare failed. + /// + private List _restoreRegistersAfterReboot; + + /// + /// Marker for restore after reboot parameters + /// + public Boolean HasRestoreRegistersAfterRebootIfCompareFailed; + /// /// Register content on initial connect to keep those during update /// @@ -100,6 +110,16 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore "SENSUSRADIO_UpgFWVersion" // After a FW-Update the FW version has changed }; + /// + /// Registers manually explicit marked to be restored after reboot if compare failed. Those registers will + /// 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! + /// + private static readonly List _restoreAfterRebootIfCompareFailed = new List + { + "CUSTOMER_AlarmEnableMask" // Restored to hard coded value up to FW R1.4.22 + }; + /// /// Registers manually explicit excluded for in-field updatable parameters for the CUST to prevent inadvertent /// modifications resulting in potential MID violations. @@ -120,7 +140,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore "FLEXNETSERIAL_FwdlState", "FLEXNETSERIAL_UpgState", - + "GENESISFLOW_AmplitudePeakDetectEnd", // 1 "GENESISFLOW_ArrowThreshold", // 2 "GENESISFLOW_CalFactor1", // 3 @@ -206,7 +226,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore "PERIODICLOG_PeriodicLogLifeTimeCounter", "PERIODICLOG_ResetCounter", - "POWERMON_TotalUsedCharge", + "POWERMON_TotalUsedCharge", "POWERMON_TotalUsedSeconds", "SENSUSRADIO_AverageFlowPeriod", // 1 @@ -360,6 +380,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore _currentGenesis = currentGenesis; RecoveryRegisters = null; RecoveryRegisters = new List(); + _restoreRegistersAfterReboot = new List(); } /// @@ -556,7 +577,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore continue; } - // Fill DEBUG lists START with all registers even if they are multiple assigned + // Fill DEBUG lists START with all registers even if they are multiple assigned sortableRegisterList.Add(proPar.RegisterName); switch (proPar.Source) @@ -572,21 +593,21 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore break; } - // Take this parameter as is - //TODO THW take configuration.json and use for String and Array type, see RegisterConverter - //take the register properties from configuration.json - //get the pre-defined dictionary - //var meterRegisters = MockGenesis based on FW version .GetConfigRegistersDefinitions(); - //var regDef = meterRegisters.GetRegisterDefinitionByName(proPar.RegisterName); - //if (regDef.DataType.Name.Equals("Int32")) - //{ - // Add parameter if it is not in the list - //if (sortableProgrammingParameters.All(a => !proPar.RegisterName.Equals(a.RegisterName))) - //{ - // sortableProgrammingParameters.Add(proPar); - // continue; - //} - //} + // Take this parameter as is + //TODO THW take configuration.json and use for String and Array type, see RegisterConverter + //take the register properties from configuration.json + //get the pre-defined dictionary + //var meterRegisters = MockGenesis based on FW version .GetConfigRegistersDefinitions(); + //var regDef = meterRegisters.GetRegisterDefinitionByName(proPar.RegisterName); + //if (regDef.DataType.Name.Equals("Int32")) + //{ + // Add parameter if it is not in the list + //if (sortableProgrammingParameters.All(a => !proPar.RegisterName.Equals(a.RegisterName))) + //{ + // sortableProgrammingParameters.Add(proPar); + // continue; + //} + //} @@ -780,7 +801,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore return StatusReturn.Failed; } - return RawProgrammingParametersFilterAndSort(programmingParameters, recoveryRegistersDb, out errorMsg, + return RawProgrammingParametersFilterAndSort(programmingParameters, recoveryRegistersDb, out errorMsg, fieldUpdate); } catch (Exception) @@ -819,7 +840,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// - CancellationToken. /// - public StatusReturn EolProgrammingRegisters(List recoveryRegistersDb, + public StatusReturn EolProgrammingRegisters(List recoveryRegistersDb, CancellationToken cancellationToken) { // Mark field update as false to set EOL as true to force accu reset @@ -926,7 +947,10 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// - Remove '_fieldUpdateBlacklist' parameters for the CUST to prevent inadvertent modifications resulting in potential /// MID violations. /// - public StatusReturn WriteRegisters(List recoveryRegistersDb, CancellationToken cancellationToken, + /// + /// - Login/Logout moved to . + /// + public StatusReturn WriteRegisters(List recoveryRegistersDb, CancellationToken cancellationToken, Boolean fieldUpdate) { if (_currentGenesis == null || @@ -952,11 +976,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore _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(); @@ -991,11 +1010,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryPreparation, actualProcessMessage: Resources.StrRegisterRecoveryPreparation)); - if (StatusReturn.Failed == WriteRegisterParameterSet(_prepareProgramming, recRegistersCount, meterRegisters, + if (StatusReturn.Failed == WriteRegisterParameterSet(_prepareProgramming, recRegistersCount, meterRegisters, cancellationToken, fieldUpdate)) { - // the logout will force the radio app to activate the settings - _currentGenesis?.Logout(); return StatusReturn.Failed; } @@ -1003,32 +1020,25 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryExec, actualProcessMessage: Resources.StrRegisterRecoveryExec)); - if (StatusReturn.Failed == WriteRegisterParameterSet(recoveryRegistersDb, recRegistersCount, meterRegisters, + if (StatusReturn.Failed == WriteRegisterParameterSet(recoveryRegistersDb, recRegistersCount, meterRegisters, cancellationToken, fieldUpdate)) { - // the logout will force the radio app to activate the settings - _currentGenesis?.Logout(); - return StatusReturn.Failed; + return StatusReturn.Failed; } // finalize recovery OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryFinalization, actualProcessMessage: Resources.StrRegisterRecoveryFinalization)); - if (StatusReturn.Failed == WriteRegisterParameterSet(finalizeProgrammingAll, recRegistersCount, meterRegisters, + if (StatusReturn.Failed == WriteRegisterParameterSet(finalizeProgrammingAll, recRegistersCount, meterRegisters, cancellationToken, fieldUpdate)) { - // 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); @@ -1062,19 +1072,20 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// - Excluded un-comparable registers from write turned back on ('blind' writing enabled again). /// - private StatusReturn WriteRegisterParameterSet(List recoveryRegistersDb, Int32 recRegistersCount, - MeterRegisters meterRegisters, CancellationToken cancellationToken, Boolean fieldUpdate) + /// + /// - Login/Logout moved here. + /// + private StatusReturn WriteRegisterParameterSet(List recoveryRegistersDb, + Int32 recRegistersCount, MeterRegisters meterRegisters, CancellationToken cancellationToken, Boolean fieldUpdate) { + _currentGenesis.ReLogin(); + if (!_currentGenesis.IsLoggedOn) + return StatusReturn.Failed; + foreach (var recReg in recoveryRegistersDb) { - //TODO THW Check - // Temporary excluded un-comparable registers from write as this make no sense to write them blind being - // unable to read the correct value back. - //if (_excludedFromCompareParameters.Any( regName => recReg.RegisterIdent.Equals(regName))) - // continue; - // Remove all parameters from parameter list if used for field update - if (fieldUpdate && _fieldUpdateBlacklist.Any( regName => recReg.RegisterIdent.Equals(regName))) + if (fieldUpdate && _fieldUpdateBlacklist.Any(regName => recReg.RegisterIdent.Equals(regName))) continue; _actualRegisterCtr++; @@ -1099,6 +1110,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", overallProcessCtrPercent, Resources.StrErrorMsgRegisterNotFound + " Register: " + recReg.RegisterIdent)); + _currentGenesis?.Logout(); return StatusReturn.Failed; } @@ -1115,6 +1127,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs( $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", overallProcessCtrPercent, Resources.StrRegisterValueOutOfRange + " " + errorMessage)); + _currentGenesis?.Logout(); return StatusReturn.Failed; } @@ -1124,6 +1137,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", overallProcessCtrPercent, Resources.StrErrorMsgRegisterWrite + " Register: " + recReg.RegisterIdent)); + _currentGenesis?.Logout(); return StatusReturn.Failed; } @@ -1149,10 +1163,63 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore if (cancellationToken.IsCancellationRequested) break; } - + _currentGenesis?.Logout(); return StatusReturn.Okay; } + /// + /// Restore and compare all registers which did not survive a reboot and are listed in the + /// + /// - This is a workaround for a FW-bug in R1.4.22 and below. + /// + /// + /// + /// + /// - Initial. + /// + public Boolean RestoreAndCompareRegistersAfterReboot(CancellationToken cancellationToken) + { + if (!HasRestoreRegistersAfterRebootIfCompareFailed) + return false; + + HasRestoreRegistersAfterRebootIfCompareFailed = false; + + // Use preset recovery registers for check + RecoveryRegisters.Clear(); + RecoveryRegisters.AddRange(_restoreRegistersAfterReboot); + _failedComparisonRegisters.Clear(); + + // get the pre-defined dictionary + var meterRegisters = _currentGenesis.GetConfigRegistersDefinitions(); + + _actualRegisterCtr = 0; + // Expected access counter is 3 times the content for write, read and compare + var maxCounter = 3 * RecoveryRegisters.Count; + + // Write after reboot + if (StatusReturn.Failed == WriteRegisterParameterSet(RecoveryRegisters, maxCounter, + meterRegisters, cancellationToken, false)) + { + return false; + } + + // executes login read logout + if (!ReadPresetRegisters(cancellationToken)) + { + return false; + } + + // Compare register content + if (!CompareRegisters(cancellationToken)) + { + return false; + } + // Wait for completion as storing may need a certain time + Thread.Sleep(1000); + + return true; + } + /// /// Compare all registers which can be restored without new access to meter. /// Precondition: @@ -1203,6 +1270,12 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// - Take 'null' in readBack into account due to communication error. /// + /// + /// - _restoreAfterRebootIfCompareFailed. + /// + /// + /// - Made method static. + /// public Boolean CompareRegisters(CancellationToken cancellationToken) { if (_pcbIdFinalRegisterRead != _pcbIdWriteRegisters || @@ -1214,6 +1287,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore // DEBUG _failedComparisonRegisters?.Clear(); + _restoreRegistersAfterReboot.Clear(); // build a string list of the registers being able to sort those var registerNames = RecoveryRegisters.Select(register => register.RegisterIdent).ToList(); @@ -1263,14 +1337,14 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore var writtenValue = recReg.WriteValue; var readBackValue = recReg.ReadBackValue; var strRequiredRegisterValue = ""; + var isApproximated = false; + var isIdentical = false; try { // ATTENTION: The size of the writtenValue and readBackValue may deviate! var dataSize = writtenValue.Length; - var isApproximated = false; - var isIdentical = false; - + // Process values only if not 'null' if (writtenValue != null && readBackValue != null) { @@ -1331,15 +1405,21 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore } }// Process register values only if not 'null' - // convert register content to text with raw and converted value depending on data type - strRequiredRegisterValue = - RegisterConverter.GetRegisterContentText(regDef, writtenValue); + // 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 { + // Check registers which should be restored after reboot if failed + if (_restoreAfterRebootIfCompareFailed.Any(reg => reg.Equals(regName))) + { + HasRestoreRegistersAfterRebootIfCompareFailed = true; + _restoreRegistersAfterReboot.Add(recReg); + } var encryptRawData = regName.Contains("EncryptionKey") || regName.Contains("Password"); var strReadBackRegisterValue = RegisterConverter.GetRegisterRawText(regDef, readBackValue, @@ -1366,7 +1446,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore { OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrRegisterCompare}" + $@" {_actualRegisterCtr} / {registersCount}", - overallProcessCtrPercent, actualProcessMsg)); + overallProcessCtrPercent, actualProcessMsg, + statusReturn: isIdentical || isApproximated ? StatusReturn.Okay : StatusReturn.Failed)); } } @@ -1427,7 +1508,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore 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; @@ -1525,8 +1605,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore // remind the PCB ID before update for comparison _pcbIdInitialRegisterRead = _currentGenesis.PcbId; - // create the dictionaries out of the configuration.json - if (!BuildReadableRegisterDictionary(ref _initialRegisters)) + // 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 initial register read string @@ -1559,14 +1639,15 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// - Excluded registers which do not contain useful information. /// + /// + /// - Sequence resorted. + /// 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 @@ -1579,11 +1660,14 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore { 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)); + + // DEBUG information + _readableRegisterList.Clear(); + _readableRegisterList.AddRange(_finalRegisterList); + return registers.Count > 0; } @@ -1612,7 +1696,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore // temporary list of registers just for read and log without keeping them alive var registers = new List(); - if (!BuildReadableRegisterDictionary(ref registers)) + // 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 initial register read string @@ -1692,7 +1777,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// - Date size directly from register object. /// - private Boolean ReadRegistersSet(ref List registers, CancellationToken cancellationToken) + private Boolean ReadRegistersSet(ref List registers, CancellationToken cancellationToken) { if (_currentGenesis == null) return false; diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/BaseProductionProcess.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/BaseProductionProcess.cs index 1491b865..564548d4 100644 --- a/Common/Production/ProductionUiCordonel/ProductionProcesses/BaseProductionProcess.cs +++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/BaseProductionProcess.cs @@ -520,10 +520,27 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses /// /// - Initial /// + /// + /// - StatusReturn. + /// protected void ProcessUpdate_Handler(Object sender, ProcessExecEventArgs e) { ActualProcessProgress++; - LogNewStatusMsg(e.ActualProcessMessage); + switch (e.StatusReturn) + { + case StatusReturn.Okay: + SuccessMsgDispatcher(e.ActualProcessMessage); + break; + case StatusReturn.Warning: + WarningMsgDispatcher(e.ActualProcessMessage); + break; + case StatusReturn.Failed: + ErrorMsgDispatcher(e.ActualProcessMessage); + break; + default: + LogNewStatusMsg(e.ActualProcessMessage); + break; + } } /// diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckFinalParametrization.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckFinalParametrization.cs index 0597f89e..f21ab7c6 100644 --- a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckFinalParametrization.cs +++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckFinalParametrization.cs @@ -49,6 +49,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr /// /// - CancellationToken. /// + /// + /// - Restore registers after reboot if failed - temporary workaround for FW-bug. + /// public override StatusReturn ExecuteProcess() { // Uncheck executed process to leave the result open needed for retries @@ -98,6 +101,24 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr Meter?.Logout(); return StatusReturn.Okay; } + + // Restore registers after reboot if failed + if (RegisterRestorer.HasRestoreRegistersAfterRebootIfCompareFailed) + { + // 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; + } + } + + // No chance to repair anything EolProgress.ParametrizationCompareChecked = EOLStatus.FAIL; Meter?.Logout(); return StatusReturn.Failed; diff --git a/Common/Production/ProductionUiCordonel/Properties/Resources.Designer.cs b/Common/Production/ProductionUiCordonel/Properties/Resources.Designer.cs index 8e5ed948..9e1c3880 100644 --- a/Common/Production/ProductionUiCordonel/Properties/Resources.Designer.cs +++ b/Common/Production/ProductionUiCordonel/Properties/Resources.Designer.cs @@ -2509,7 +2509,16 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties { } /// - /// Looks up a localized string similar to WARNING: Inspect results. + /// Looks up a localized string similar to WARNING: Parameter restored after reboot as it does not survive it. + /// + internal static string StrWarningMsgParameterCompare { + get { + return ResourceManager.GetString("StrWarningMsgParameterCompare", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WARNING: Result needs inspection! Process. /// internal static string StrWarningMsgProcess { get { diff --git a/Common/Production/ProductionUiCordonel/Properties/Resources.de.resx b/Common/Production/ProductionUiCordonel/Properties/Resources.de.resx index 9c53f5a4..3feb62b5 100644 --- a/Common/Production/ProductionUiCordonel/Properties/Resources.de.resx +++ b/Common/Production/ProductionUiCordonel/Properties/Resources.de.resx @@ -660,6 +660,9 @@ FEHLER: Parametervergleich fehlgeschlagen + + + WARNUNG: Parameter überlebte den Neustart nicht und wurde danach wiederhergestellt FEHLER: Parameterschreiben fehlgeschlagen @@ -677,7 +680,7 @@ WARNUNG - WARNUNG: Ergebnis manuell überprüfen + WARNUNG: Ergebnis muß überprüft werden! Prozeß ACHTUNG diff --git a/Common/Production/ProductionUiCordonel/Properties/Resources.resx b/Common/Production/ProductionUiCordonel/Properties/Resources.resx index fb9a72cc..c7247541 100644 --- a/Common/Production/ProductionUiCordonel/Properties/Resources.resx +++ b/Common/Production/ProductionUiCordonel/Properties/Resources.resx @@ -660,6 +660,9 @@ ERROR: Parameter compare failed + + + WARNING: Parameter restored after reboot as it does not survive it ERROR: Parameter write failed @@ -675,12 +678,12 @@ WARNING + + + WARNING: Result needs inspection! Process ATTENTION - - - WARNING: Inspect results SPECIAL APPROVAL diff --git a/Common/Utils/ProcessExec/EventArguments/ProcessExecEventArgs.cs b/Common/Utils/ProcessExec/EventArguments/ProcessExecEventArgs.cs index fdb27941..8899e926 100644 --- a/Common/Utils/ProcessExec/EventArguments/ProcessExecEventArgs.cs +++ b/Common/Utils/ProcessExec/EventArguments/ProcessExecEventArgs.cs @@ -1,4 +1,5 @@ using System; +using Xylem.Common.CommonCore.Consts; namespace Xylem.Common.Utils.ProcessExec.EventArguments { @@ -28,6 +29,11 @@ namespace Xylem.Common.Utils.ProcessExec.EventArguments /// public Double? ActualProcessPercent { get; } + /// + /// Single process percentage 0..100 + /// + public StatusReturn StatusReturn { get; } + /// /// Ctor /// @@ -35,9 +41,10 @@ namespace Xylem.Common.Utils.ProcessExec.EventArguments /// /// /// + /// public ProcessExecEventArgs(String overallProcessMessage, Double? overallProcessPercent = null, String actualProcessMessage = null, - Double? actualProcessPercent = null) + Double? actualProcessPercent = null, StatusReturn statusReturn = StatusReturn.Unknown) { OverallProcessMessage = overallProcessMessage; ActualProcessMessage = actualProcessMessage; @@ -45,6 +52,7 @@ namespace Xylem.Common.Utils.ProcessExec.EventArguments OverallProcessPercent = OverallProcessPercent < 0 ? 0 : OverallProcessPercent; ActualProcessPercent = actualProcessPercent > 100.0 ? 100.0 : actualProcessPercent; ActualProcessPercent = ActualProcessPercent < 0 ? 0 : ActualProcessPercent; + StatusReturn = statusReturn; } } }