diff --git a/Common/CordonelAssemblyLine/Model/PickingModel.cs b/Common/CordonelAssemblyLine/Model/PickingModel.cs index bf7aaa6b..a67ef117 100644 --- a/Common/CordonelAssemblyLine/Model/PickingModel.cs +++ b/Common/CordonelAssemblyLine/Model/PickingModel.cs @@ -594,7 +594,7 @@ namespace CordonelAssemblyLine.Model sbMSG.AppendLine($"Pcb = {meter.PcbId}"); sbMSG.AppendLine($"POWERMON_TotalUsedSeconds = {genesisStatus.ExceededLifeTime_s}"); - sbMSG.AppendLine($"POWERMON_TotalUsedCharge = {genesisStatus.DrainedBatteryPower_uAs}"); + sbMSG.AppendLine($"POWERMON_TotalUsedCharge = {genesisStatus.DrainedBatteryLoad_uAs}"); sbMSG.AppendLine($"POWERMON_BatteryQuantity = {genesisStatus.BatteryQuantity}"); sbMSG.AppendLine($"POWERMON_BatteryMilliAHrRating = {genesisStatus.InitialBatteryLoad_mAh}"); sbMSG.AppendLine(""); diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs index 4b0becc3..1a91853d 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs @@ -1083,7 +1083,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// - Pulse module deactivated at login. /// - public Boolean Login(String password, Boolean runImmediately = true) + /// + /// - REMOVED: Pulse module deactivated at login. + /// - Skip FW readout to quick connect being able to immediately switch off the pulse mode before App detection. + /// + public Boolean Login(String password, Boolean runImmediately = true, Boolean skipReadMeterFwAndAssignRegisters = false) { var backupRetries = CommunicationConfig.RequestRetries; @@ -1113,13 +1117,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore IsDevelopmentUsage = true; } - if (!DeactivatePulseModule()) - { - _logger.Warn($"Slot:{Slot} - Pulse module deactivation failed!"); - } - - ReadMeterFirmwareAndAssignRegisters(); - + if (!skipReadMeterFwAndAssignRegisters) ReadMeterFirmwareAndAssignRegisters(); } else { @@ -1473,38 +1471,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore } } - /// - /// The pulse module interrupts and disturbs the IrDA communication. As quick fix the pulse module can be switched off, - /// as soon as a communication could be established. As the pulse output will only be switched on again, if a pulse - /// module is attached to the device, this pulse mode can be switched active instantaneously after deactivation. - /// - /// - /// - Initial. - /// - private Boolean DeactivatePulseModule() - { - Boolean retVal; - try - { - var pulseMode = RegisterConverter.ConvertTo(ReadRegister(Register.Mertrologyasst.PulseMode)); - // if pulse mode is already set to 0 (OFF) return true - if (pulseMode == 0) - return true; - - // write pulse mode temporary to 0 (OFF) and wait for result - retVal = WriteRegister(Register.Mertrologyasst.PulseMode, 0); - Thread.Sleep(500); - // instantaneously restore pulse mode to original value - retVal &= WriteRegister(Register.Mertrologyasst.PulseMode, pulseMode); - Thread.Sleep(500); - } - catch (Exception) - { - retVal = false; - } - - return retVal; - } /// /// Automatic login to meter enabled if logged out by lost authentication /// diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatus.cs b/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatus.cs index ba9d2aa9..52abad0e 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatus.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatus.cs @@ -104,7 +104,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus /// /// Drained capacity of all batteries in uAs. /// - public UInt64 DrainedBatteryPower_uAs; + public UInt64 DrainedBatteryLoad_uAs; /// /// Comment for approval and permissions reasons: diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatusHandler.cs b/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatusHandler.cs index 4afc1dfb..85acd281 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatusHandler.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatusHandler.cs @@ -72,7 +72,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus status.ExceededLifeTime_s = RegisterConverter.ConvertTo( currentGenesis.ReadRegister(Register.Powermon.BatteryExceededSeconds)); - status.DrainedBatteryPower_uAs = RegisterConverter.ConvertTo( + status.DrainedBatteryLoad_uAs = RegisterConverter.ConvertTo( currentGenesis.ReadRegister(Register.Powermon.BatteryDrainedLoad, 8)); status.BatteryQuantity = RegisterConverter.ConvertTo( currentGenesis.ReadRegister(Register.Powermon.BatteryQuantity)); @@ -105,7 +105,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus var drainedBatteryLoad_rel = 1.0; if (initialBatteryLoad_uAs != 0) { - drainedBatteryLoad_rel = (Double)status.DrainedBatteryPower_uAs / initialBatteryLoad_uAs; + drainedBatteryLoad_rel = (Double)status.DrainedBatteryLoad_uAs / initialBatteryLoad_uAs; } else { diff --git a/Common/Hardware/WaterMeter/WaterMeterCore/IMeter.cs b/Common/Hardware/WaterMeter/WaterMeterCore/IMeter.cs index 929bc228..9819f466 100644 --- a/Common/Hardware/WaterMeter/WaterMeterCore/IMeter.cs +++ b/Common/Hardware/WaterMeter/WaterMeterCore/IMeter.cs @@ -121,7 +121,9 @@ namespace Xylem.Common.Hardware.WaterMeter.WaterMeterCore /// /// password for login /// execute immediately - Boolean Login(String password, Boolean runImmediately = true); + /// skip app readout and register generation to speed up + /// the initial connection process + Boolean Login(String password, Boolean runImmediately = true, Boolean skipReadMeterFwAndAssignRegisters = false); /// /// set up measurement parameter and set meter into test-mode diff --git a/Common/Ui/GenesisToolBox/frmRegisterStore.cs b/Common/Ui/GenesisToolBox/frmRegisterStore.cs index c65d1305..3221651a 100644 --- a/Common/Ui/GenesisToolBox/frmRegisterStore.cs +++ b/Common/Ui/GenesisToolBox/frmRegisterStore.cs @@ -2224,7 +2224,7 @@ namespace Xylem.Common.Ui.GenesisToolBox sbMSG.AppendLine($"Pcb = {_currentGenesis.PcbId}"); sbMSG.AppendLine($"POWERMON_TotalUsedSeconds = {genesisStatus.ExceededLifeTime_s}"); - sbMSG.AppendLine($"POWERMON_TotalUsedCharge = {genesisStatus.DrainedBatteryPower_uAs}"); + sbMSG.AppendLine($"POWERMON_TotalUsedCharge = {genesisStatus.DrainedBatteryLoad_uAs}"); sbMSG.AppendLine($"POWERMON_BatteryQuantity = {genesisStatus.BatteryQuantity}"); sbMSG.AppendLine($"POWERMON_BatteryMilliAHrRating = {genesisStatus.InitialBatteryLoad_mAh}"); sbMSG.AppendLine(""); diff --git a/ServiceFwUpdate/Common/FwUpdateConfig/Consts/FwUpdateConfig.cs b/ServiceFwUpdate/Common/FwUpdateConfig/Consts/FwUpdateConfig.cs index bf071da6..2cd5b465 100644 --- a/ServiceFwUpdate/Common/FwUpdateConfig/Consts/FwUpdateConfig.cs +++ b/ServiceFwUpdate/Common/FwUpdateConfig/Consts/FwUpdateConfig.cs @@ -24,6 +24,11 @@ namespace Xylem.ServiceFwUpdate.Common.FwUpdateConfig.Consts "Firmware ist aktuell!" }; + /// + /// Name of settings file being able to restores settings on crashed update procedure on next login. + /// + public const String RestoreSettingsFileName = "RestoreSettings.json"; + /// /// Name of the file which contains the meter file names that can be erased before the FW-Update /// to free disk space and have to be restored after the FW-Update diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs index 6862f01e..d7f31565 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs @@ -145,6 +145,11 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // path and name of the installed applications private String _pathNameCordonelAppVersionFile; + // path and name of the restore settings file on crashed application or interrupted update + private String _pathNameCordonelRegisterRestoreSettingsFile; + // Register subset needed to adjust for update performance content before update + private Dictionary _pulseModeRegistersRestore = new Dictionary(); + // loading the lists of meter files which shall be erased before the FW-Update and restored after. private MeterFilesEraseRestore _meterFilesEraseRestore; @@ -370,6 +375,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw case ProcessState.FirmwareUpdateSuccess: ReleaseDisplay(); + RestoreRegisters(); FwUpdateSuccessMessage(); _processState = ProcessState.Idle; break; @@ -979,9 +985,9 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw try { - if (_cordonelDeviceInfos == null + if (_cordonelDeviceInfos == null || _cordonelFirmwarePackage?.FwPackageInfo == null - || _cordonelFirmwarePackage.BinaryApplicationFiles == null + || _cordonelFirmwarePackage.BinaryApplicationFiles == null || _cordonelFirmwarePackage.BinaryApplicationFiles.Count == 0 || _cordonelFirmwarePackage.PackageDescriptionFile == null) { @@ -997,7 +1003,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw { // here the firmware package is valid, encode content var encoding = new ASCIIEncoding(); - var packageFile = + var packageFile = encoding.GetString(_cordonelFirmwarePackage.PackageDescriptionFile.FileContent.ToArray()); // setup package description file in FwUpdate class @@ -1211,8 +1217,8 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // set information of required and detected versions, check failed! LogText(StrSeparator); LogErrorText(Resources.StrCoreRevision); - LogErrorText(@"Minimum :" + _meterFwUpdate.CoreRevisionMinimum/100 + ":" + _meterFwUpdate.CoreRevisionMinimum%100); - LogErrorText(@"Maximum :" + _meterFwUpdate.CoreRevisionMaximum/100 + "." + _meterFwUpdate.CoreRevisionMaximum%100 ); + LogErrorText(@"Minimum :" + _meterFwUpdate.CoreRevisionMinimum / 100 + ":" + _meterFwUpdate.CoreRevisionMinimum % 100); + LogErrorText(@"Maximum :" + _meterFwUpdate.CoreRevisionMaximum / 100 + "." + _meterFwUpdate.CoreRevisionMaximum % 100); LogErrorText(@"Cordonel :" + GenesisMeter.BuildFwVersionString(_currentGenesis.CoreRevision)); InfoProcessFailed(lblCordonelUpdateCapability, Resources.StrCordonelUpdateCapabilityCoreFailed); _processState = ProcessState.Error; @@ -1279,12 +1285,12 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // extract the package information var fwPackRegion = _cordonelFirmwarePackage.FwPackageInfo.Region; var fwPackRadioFrequencyMhz = _cordonelFirmwarePackage.FwPackageInfo.RadioFrequencyMhz; - + // region if (!string.IsNullOrEmpty(fwPackRegion)) { // accept region if identical, on undefined installed region or support for all regions - if (_currentGenesis.Region == fwPackRegion + if (_currentGenesis.Region == fwPackRegion || Constants.StrWildcard == fwPackRegion || Constants.StrUnknown == _currentGenesis.Region) { @@ -1303,7 +1309,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // if radio frequency is null the region is "NA" or the fw package serves all frequencies, // if the radio frequency is explicit set, it has to be verified against the preset value in the Cordonel - if (fwPackRadioFrequencyMhz == null || fwPackRadioFrequencyMhz == _currentGenesis.RadioFrequencyMhz + if (fwPackRadioFrequencyMhz == null || fwPackRadioFrequencyMhz == _currentGenesis.RadioFrequencyMhz || _currentGenesis.RadioFrequencyMhz == null) { InfoProcessSuccess(null, Resources.StrCordonelUpdateCapabilityRadioSucceeded); @@ -1317,8 +1323,9 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw LogErrorText(@"Cordonel: " + _currentGenesis.RadioFrequencyMhz + " MHz"); InfoProcessFailed(lblCordonelUpdateCapability, Resources.StrCordonelUpdateCapabilityRadioFailed); } - - if (!retVal) _processState = ProcessState.Error; + + if (!retVal) + _processState = ProcessState.Error; return retVal; } @@ -1331,7 +1338,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// for this update capability check. /// /// true if meter size is approved - /// + /// /// - Initial. /// private Boolean MeterSizeUpdateCapability() @@ -1343,7 +1350,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // extract the package information var fwPackMeterSizes = _cordonelFirmwarePackage.FwPackageInfo.MeterSizes; - + // meter size if (fwPackMeterSizes != null && fwPackMeterSizes.Count > 0) { @@ -1351,7 +1358,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // if fw package supports all meter sizes or the meter size is unknown if (fwPackMeterSizes.Any(size => size == _currentGenesis.MeterSize) || fwPackMeterSizes.Any(size => size == Constants.StrWildcard) - || Constants.StrUnknown == _currentGenesis.MeterSize ) + || Constants.StrUnknown == _currentGenesis.MeterSize) { InfoProcessSuccess(null, Resources.StrCordonelUpdateCapabilityMeterSizeSucceeded); } @@ -1365,7 +1372,8 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw foreach (var size in fwPackMeterSizes) { msg += size; - if (--cnt > 0) msg += ", "; + if (--cnt > 0) + msg += ", "; } LogErrorText(Resources.StrFwPackageInfo + msg); LogErrorText(@"Cordonel: " + _currentGenesis.MeterSize); @@ -1373,7 +1381,8 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw } } - if (!retVal) _processState = ProcessState.Error; + if (!retVal) + _processState = ProcessState.Error; return retVal; } @@ -1550,7 +1559,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw try { // read initially if radio is NOT in production mode (0x01), where it sends unencrypted radio telegrams - if ( 0x01 != RegisterConverter.ConvertTo(_currentGenesis.ReadRegister(Register.Sensusradio.SystemState))) + if (0x01 != RegisterConverter.ConvertTo(_currentGenesis.ReadRegister(Register.Sensusradio.SystemState))) { LogSuccessText(Resources.StrRadioAlreadyActive); retVal = true; @@ -1589,6 +1598,95 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw return retVal; } + /// + /// The pulse module interrupts and disturbs the IrDA communication. As quick fix the pulse module can be switched off, + /// as soon as a communication could be established. As the pulse output will only be switched on again, if a pulse + /// module is attached to the device, this pulse mode can be switched active instantaneously after deactivation. + /// + /// + /// - Initial. + /// + private Boolean DeactivatePulseModule() + { + var retVal = false; + try + { + if (!_currentGenesis.IsLoggedOn) + _currentGenesis.ReLogin(); + + // create path and name for register setup reminder for this PcbId + _pathNameCordonelRegisterRestoreSettingsFile = Path.Combine(FwUpdateConfig.ReportedPath, + $"{_currentGenesis.PcbId}_" + FwUpdateConfig.RestoreSettingsFileName); + + var pulseMode = + RegisterConverter.ConvertTo(_currentGenesis.ReadRegister(Register.Mertrologyasst.PulseMode)); + // if pulse mode is already set to 0 (OFF) this could be initial setup or a indication of a crashed update + if (pulseMode == 0) + { + LogText(Resources.StrPulseModeInactive); + // check if a file exists with settings from a previous update + if (File.Exists(_pathNameCordonelRegisterRestoreSettingsFile)) + { + var fileData = File.ReadAllText(_pathNameCordonelRegisterRestoreSettingsFile); + _pulseModeRegistersRestore = JsonConvert.DeserializeObject>(fileData); + } + retVal = true; + } + + //if retVal is true, the pulse mode is switched OFF, no further action is required + if (!retVal) + { + // safe the pulse setting + _pulseModeRegistersRestore.Add(Register.Mertrologyasst.PulseMode, new[] { pulseMode }); + // Create new file as for report only one version is allowed + var serializedData = JsonConvert.SerializeObject(_pulseModeRegistersRestore); + var asciiStream = Encoding.UTF8.GetBytes(serializedData); + File.WriteAllBytes(_pathNameCordonelRegisterRestoreSettingsFile, asciiStream); + + // write pulse mode temporary to 0 (OFF) and wait for result + retVal = _currentGenesis.WriteRegister(Register.Mertrologyasst.PulseMode, 0); + LogText(Resources.StrPulseModeTemporaryDeactivated); + } + } + catch (Exception ex) + { + retVal = false; + } + + _currentGenesis.Logout(); + return retVal; + } + /// + /// Restore all listed registers. + /// + /// + /// - Initial. + /// + private Boolean RestoreRegisters() + { + var retVal = true; + try + { + if (!_currentGenesis.IsLoggedOn) + _currentGenesis.ReLogin(); + + foreach (var item in _pulseModeRegistersRestore) + { + retVal &= _currentGenesis.WriteRegister(item.Key, item.Value); + + } + if (retVal && _pulseModeRegistersRestore.Any(x => x.Key == Register.Mertrologyasst.PulseMode)) + LogText(Resources.StrPulseModeRestored); + } + catch (Exception ex) + { + retVal = false; + } + + _currentGenesis.Logout(); + return retVal; + } + /// /// Store configurations with logging of success or failed. /// @@ -1601,7 +1699,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw return false; _currentGenesis.ReLogin(); Boolean retVal; - if ( _currentGenesis.StoreAllConfigurations()) + if (_currentGenesis.StoreAllConfigurations()) { LogSuccessText(Resources.StrStoreConfigSuccess); retVal = true; @@ -1635,7 +1733,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // deactivate LED, not needed to get measurements during the update or on repeated start after system // failure. This overwrites the settings in _meterFwUpdate. _currentGenesis.WriteRegister(Register.Genesisflow.LedMode, new[] { (Byte)LedMode.Off }); - _currentGenesis.WriteRegister(Register.Genesisflow.StoreConfiguration, 1); + _currentGenesis.WriteRegister(Register.Genesisflow.StoreConfiguration, 1); LogText(Resources.StrDisplayReleased); _currentGenesis.Logout(); } @@ -2435,7 +2533,6 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // try to login to check if meter is ready after reboot procedure _currentGenesis.ReLogin(); - _processState = _currentGenesis.IsLoggedOn ? successExitState : errorExitState; // change first the process state, otherwise the timer may switch the bar on again @@ -2654,6 +2751,49 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw SetOverallProgressDisplayOn(Resources.StrConnecting); } + /// + /// Common login and special setup procedure, as this is needed for login with password level 8 + /// and for login with skeleton key: + /// - Initial login without register readout being able to quick switch off the pulse mode, + /// - Switch off the pulse mode on initial connection, + /// - Activate the radio, + /// - Release the display to normal operation, + /// - Store all configurations on initial connection. + /// + /// lvl8 or skeleton + /// initial connection + /// true if successfully executed + /// + /// - Initial + /// + private Boolean LoginAndSpecialSetupProcedure(String password, Boolean initialLogin) + { + // login without reading all registers and FW keeping the communication to a minimum to switch + // the pulse mode OFF before reading all installed apps, which will be unpredictable on activated + // pulse module + var retVal = _currentGenesis.Login(password, skipReadMeterFwAndAssignRegisters: initialLogin); + if (!retVal) + return false; + + // switch the pulse module inactive + if (initialLogin) + DeactivatePulseModule(); + + // login with reading out all installed applications + retVal = _currentGenesis.Login(password); + + if (_currentGenesis.RadioFrequencyMhz != null) + ActivateRadio(); + + // display to normal operation + ReleaseDisplay(); + + // safe all settings from RAM to FLASH to keep those for reboot + if (initialLogin) + StoreConfigurations(); + + return retVal; + } /// /// Execution of connect to water-meter. /// @@ -2692,15 +2832,19 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// /// - "Release Display" before "Store Configuration". /// + /// + /// - "Deactivate Pulse Mode" at initial login to avoid interference of pulses to IrDA communication. + /// private Boolean ExecConnect() { - // logout if already logged in into meter - if (_currentGenesis.IsLoggedOn) - _currentGenesis.Logout(); - - //read out the PCB ID from water-meter to open the password container of this device + var initialLogin = false; + // read out the PCB ID from water-meter to open the password container of this device if (string.IsNullOrEmpty(_currentGenesis.PcbId)) + { + // if the PcbId is unknown, it is an initial login + initialLogin = true; _currentGenesis.GetPcbId(); + } // search the PCB ID and extract password for login String password = null; @@ -2729,11 +2873,8 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // this login may be time consuming on readout of application information // first try to login with password Level 8, this is needed if the password file is installed - if (_currentGenesis.Login(password)) + if (LoginAndSpecialSetupProcedure(password, initialLogin)) { - if (_currentGenesis.RadioFrequencyMhz != null) ActivateRadio(); - ReleaseDisplay(); - StoreConfigurations(); _passwordFileIsCorrupted = false; return true; } @@ -2752,11 +2893,9 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // wait that long, otherwise the Cordonel locks for 2s, 4s, 8s, 16s and so on on every retry! Thread.Sleep(5000); - if (_currentGenesis.Login(skeletonKey)) + // use the skeleton key for login as the password file may not be installed or invalid + if (LoginAndSpecialSetupProcedure(skeletonKey, initialLogin)) { - if (_currentGenesis.RadioFrequencyMhz != null) ActivateRadio(); - ReleaseDisplay(); - StoreConfigurations(); return true; } @@ -2812,6 +2951,9 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// /// - Final login message produced to log password file validation. /// + /// + /// - Enable connect if error. + /// private void FinalConnect(Boolean success, IReadOnlyList exitProcessStateObjects) { ObjectsToProcessStates(exitProcessStateObjects, out var successExitState, out var errorExitState, @@ -2833,6 +2975,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw _processState = errorExitState; // change first the process state, otherwise the timer may switch the bar on again SetOverallProgressDisplayOff(); + SetDisableDownloadAndEnableConnect(); return; } @@ -2847,15 +2990,15 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // if authentication succeeded, the cordonel port detection must have succeeded in advance, // this information might get lost on Connect() without previous port scan. InfoProcessSuccess(lblCordonelDetection, Resources.StrCordonelDetectSucceeded); - InfoProcessSuccess(lblCordonelAuthentication, _finalLoginAfterUpdate - ? Resources.StrPasswordFileValid + InfoProcessSuccess(lblCordonelAuthentication, _finalLoginAfterUpdate + ? Resources.StrPasswordFileValid : Resources.StrCordonelAuthenticationSucceeded); // use here direct text assignment to avoid x or v before label UiInvoker.ControlInvoker(lblConnectPcb, ColorSuccess, Resources.StrPartPcbConnected + @" " + _currentGenesis.PcbId); UiInvoker.ControlInvoker(lblCoreRevision, ColorDefault, - Resources.StrCoreRevision + @" " + + Resources.StrCoreRevision + @" " + $"{GenesisMeter.BuildFwVersionString(_currentGenesis.CoreRevision)}"); // avoid report again on final login after update if (!_finalLoginAfterUpdate && BuildReportFiles()) @@ -3753,6 +3896,6 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw #endregion --------------------------------------- Language --------------------------------------------------- - } + } } diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs index c1183707..1ea45c06 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs @@ -853,6 +853,33 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw.Properties { } } + /// + /// Looks up a localized string similar to Pulse mode is inactive.. + /// + internal static string StrPulseModeInactive { + get { + return ResourceManager.GetString("StrPulseModeInactive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Original pulse mode restored.. + /// + internal static string StrPulseModeRestored { + get { + return ResourceManager.GetString("StrPulseModeRestored", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pulse mode temporary deactivated.. + /// + internal static string StrPulseModeTemporaryDeactivated { + get { + return ResourceManager.GetString("StrPulseModeTemporaryDeactivated", resourceCulture); + } + } + /// /// Looks up a localized string similar to Failed to activate the radio in customer mode!. /// diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx index 5ce3c33b..818975f4 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx @@ -529,4 +529,13 @@ Display freigegeben für Volumen- und Durchflußanzeige. - \ No newline at end of file + + Pulsmodus ist ausgeschaltet. + + + Orginal Pulsmodus wiederhergestellt. + + + Pulsmodus vorrübergehend ausgeschaltet. + + \ No newline at end of file diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx index adcaa2c2..9c3649a3 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx @@ -529,4 +529,13 @@ Display released to accumulator- and flow-display. + + Pulse mode is inactive. + + + Original pulse mode restored. + + + Pulse mode temporary deactivated. + \ No newline at end of file