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:
parent
5e4865d8d0
commit
e98d7cfac5
@ -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("");
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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("");
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 ---------------------------------------------------
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
@ -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>
|
||||
Loading…
Reference in New Issue
Block a user