FwUpdateSw: - pulse mode stored in xxxx_RestoreSettings.json at initial connect exported, pulse mode set to OFF, read back if software was interrupted, restore at finalization

This commit is contained in:
Thomas Wiedebusch 2023-03-07 15:38:23 +01:00
parent 5e4865d8d0
commit e98d7cfac5
11 changed files with 244 additions and 83 deletions

View File

@ -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("");

View File

@ -1083,7 +1083,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// <remarks date="2023-Mar-06" author="Thomas Wiedebusch">
/// - Pulse module deactivated at login.
/// </remarks>
public Boolean Login(String password, Boolean runImmediately = true)
/// <remarks date="2023-Mar-07" author="Thomas Wiedebusch">
/// - REMOVED: Pulse module deactivated at login.
/// - Skip FW readout to quick connect being able to immediately switch off the pulse mode before App detection.
/// </remarks>
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
}
}
/// <summary>
/// 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.
/// </summary>
/// <remarks date="2023-Feb-13" author="Roland Drabesch/Thomas Wiedebusch">
/// - Initial.
/// </remarks>
private Boolean DeactivatePulseModule()
{
Boolean retVal;
try
{
var pulseMode = RegisterConverter.ConvertTo<Byte>(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;
}
/// <summary>
/// Automatic login to meter enabled if logged out by lost authentication
/// </summary>

View File

@ -104,7 +104,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus
/// <summary>
/// Drained capacity of all batteries in uAs.
/// </summary>
public UInt64 DrainedBatteryPower_uAs;
public UInt64 DrainedBatteryLoad_uAs;
/// <summary>
/// Comment for approval and permissions reasons:

View File

@ -72,7 +72,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus
status.ExceededLifeTime_s = RegisterConverter.ConvertTo<UInt32>(
currentGenesis.ReadRegister(Register.Powermon.BatteryExceededSeconds));
status.DrainedBatteryPower_uAs = RegisterConverter.ConvertTo<UInt64>(
status.DrainedBatteryLoad_uAs = RegisterConverter.ConvertTo<UInt64>(
currentGenesis.ReadRegister(Register.Powermon.BatteryDrainedLoad, 8));
status.BatteryQuantity = RegisterConverter.ConvertTo<Int32>(
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
{

View File

@ -121,7 +121,9 @@ namespace Xylem.Common.Hardware.WaterMeter.WaterMeterCore
/// </summary>
/// <param name="password">password for login</param>
/// <param name="runImmediately">execute immediately</param>
Boolean Login(String password, Boolean runImmediately = true);
/// <param name="skipReadMeterFwAndAssignRegisters">skip app readout and register generation to speed up
/// the initial connection process</param>
Boolean Login(String password, Boolean runImmediately = true, Boolean skipReadMeterFwAndAssignRegisters = false);
/// <summary>
/// set up measurement parameter and set meter into test-mode

View File

@ -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("");

View File

@ -24,6 +24,11 @@ namespace Xylem.ServiceFwUpdate.Common.FwUpdateConfig.Consts
"Firmware ist aktuell!"
};
/// <summary>
/// Name of settings file being able to restores settings on crashed update procedure on next login.
/// </summary>
public const String RestoreSettingsFileName = "RestoreSettings.json";
/// <summary>
/// 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

View File

@ -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<String, Byte[]> _pulseModeRegistersRestore = new Dictionary<String, Byte[]>();
// 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.
/// </summary>
/// <returns>true if meter size is approved</returns>
/// <remarks date="2023-Feb-23" author="Thomas Wiedebusch">
/// <remarks date="2023-Feb-23" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
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<Int32>(_currentGenesis.ReadRegister(Register.Sensusradio.SystemState)))
if (0x01 != RegisterConverter.ConvertTo<Int32>(_currentGenesis.ReadRegister(Register.Sensusradio.SystemState)))
{
LogSuccessText(Resources.StrRadioAlreadyActive);
retVal = true;
@ -1589,6 +1598,95 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw
return retVal;
}
/// <summary>
/// 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.
/// </summary>
/// <remarks date="2023-Mar-07" author="Roland Drabesch/Thomas Wiedebusch">
/// - Initial.
/// </remarks>
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<Byte>(_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<Dictionary<String, Byte[]>>(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;
}
/// <summary>
/// Restore all listed registers.
/// </summary>
/// <remarks date="2023-Mar-07" author="Roland Drabesch/Thomas Wiedebusch">
/// - Initial.
/// </remarks>
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;
}
/// <summary>
/// Store configurations with logging of success or failed.
/// </summary>
@ -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);
}
/// <summary>
/// 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.
/// </summary>
/// <param name="password">lvl8 or skeleton</param>
/// <param name="initialLogin">initial connection</param>
/// <returns>true if successfully executed</returns>
/// <remarks date="2023-Mar-07" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
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;
}
/// <summary>
/// Execution of connect to water-meter.
/// </summary>
@ -2692,15 +2832,19 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw
/// <remarks date="2023-Mar-01" author="Thomas Wiedebusch">
/// - "Release Display" before "Store Configuration".
/// </remarks>
/// <remarks date="2023-Mar-07" author="Thomas Wiedebusch">
/// - "Deactivate Pulse Mode" at initial login to avoid interference of pulses to IrDA communication.
/// </remarks>
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
/// <remarks date="2021-Apr-20" author="Thomas Wiedebusch">
/// - Final login message produced to log password file validation.
/// </remarks>
/// <remarks date="2023-Mar-07" author="Thomas Wiedebusch">
/// - Enable connect if error.
/// </remarks>
private void FinalConnect(Boolean success, IReadOnlyList<Object> 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 ---------------------------------------------------
}
}
}

View File

@ -853,6 +853,33 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Pulse mode is inactive..
/// </summary>
internal static string StrPulseModeInactive {
get {
return ResourceManager.GetString("StrPulseModeInactive", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Original pulse mode restored..
/// </summary>
internal static string StrPulseModeRestored {
get {
return ResourceManager.GetString("StrPulseModeRestored", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Pulse mode temporary deactivated..
/// </summary>
internal static string StrPulseModeTemporaryDeactivated {
get {
return ResourceManager.GetString("StrPulseModeTemporaryDeactivated", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to activate the radio in customer mode!.
/// </summary>

View File

@ -529,4 +529,13 @@
<data name="StrDisplayReleased" xml:space="preserve">
<value>Display freigegeben für Volumen- und Durchflußanzeige.</value>
</data>
</root>
<data name="StrPulseModeInactive" xml:space="preserve">
<value>Pulsmodus ist ausgeschaltet.</value>
</data>
<data name="StrPulseModeRestored" xml:space="preserve">
<value>Orginal Pulsmodus wiederhergestellt.</value>
</data>
<data name="StrPulseModeTemporaryDeactivated" xml:space="preserve">
<value>Pulsmodus vorrübergehend ausgeschaltet.</value>
</data>
</root>

View File

@ -529,4 +529,13 @@
<data name="StrDisplayReleased" xml:space="preserve">
<value>Display released to accumulator- and flow-display.</value>
</data>
<data name="StrPulseModeInactive" xml:space="preserve">
<value>Pulse mode is inactive.</value>
</data>
<data name="StrPulseModeRestored" xml:space="preserve">
<value>Original pulse mode restored.</value>
</data>
<data name="StrPulseModeTemporaryDeactivated" xml:space="preserve">
<value>Pulse mode temporary deactivated.</value>
</data>
</root>