diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs
index 8256643e..a3ac134b 100644
--- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs
+++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs
@@ -145,6 +145,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
///
public Boolean UseOfflinePasswords { set; get; }
+ ///
+ /// Remind the offline password for comparison if this is actively used
+ ///
+ public String OfflinePassword { protected set; get; } = "";
+
///
/// Process configuration
///
@@ -1241,6 +1246,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
{
Logger.Info($"Slot:{Slot} - Got password from GenesisPasswordService, " +
$"URL({ServiceUrls.GenesisGetPasswordServiceUrl() + PcbId})");
+ OfflinePassword = "";
}
else
{
@@ -1261,6 +1267,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
if (!string.IsNullOrEmpty(password))
{
Logger.Info($"Slot:{Slot} - Got password for PcbId:{PcbId} from password file!");
+ OfflinePassword = password;
}
}
diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs
index 7cf28d83..92c9a772 100644
--- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs
+++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs
@@ -70,6 +70,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
///
/// List for un-reversed parameters which can be written, all others need to be swapped byte-wise
///
+ //TODO THW take configuration.json and use for String and Array type, see RegisterConverter
private static readonly List _unReversedParameters = new List
{
"SENSUSRADIO_Authentification", //UInt96
@@ -572,6 +573,23 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
}
// 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;
+ //}
+ //}
+
+
+
if (_unReversedParameters.Contains(proPar.RegisterName))
{
// Add parameter if it is not in the list
diff --git a/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs b/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs
index ff66f008..a30b219a 100644
--- a/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs
+++ b/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs
@@ -109,6 +109,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
SetCordonelAccessLocked();
tbxPcbId.Visible = false;
+ btnConnect.Focus();
}
private void FrmLowLevelTools_Load(Object sender, EventArgs e)
@@ -272,7 +273,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
try
{
var sb = new StringBuilder();
-
+
Invoke(new Action(() =>
{
Init();
@@ -304,6 +305,8 @@ namespace Xylem.Common.Ui.GenesisToolBox
Task.Factory.StartNew(() =>
{
+ // The password needs to be cleared for recurrent connections as otherwise the last password will be used.
+ _currentGenesis.ClearPassword();
_currentGenesis.Login();
if (!_currentGenesis.IsLoggedOn && String.IsNullOrEmpty(_currentGenesis.PcbId))
@@ -315,85 +318,132 @@ namespace Xylem.Common.Ui.GenesisToolBox
var retValPwdBuild = MeterPwdHandlerDb.RequestPwdFileFromDb(_currentGenesis.PcbId, out var pwdContainer);
- // Login failed and password cannot be acquired
+ // Login failed and password cannot be acquired, there isn't any chance to login without additional info
if (!_currentGenesis.IsLoggedOn &&
(pwdContainer?.ListOfPasswords == null ||
pwdContainer.ListOfPasswords.Count < 8 ||
string.IsNullOrEmpty(pwdContainer.Skeleton)))
{
LowLevelActionControl(false);
- LogErrorText("ERROR: Login failed and password file cannot be acquired from database!");
+ LogErrorText("ERROR: Login failed and passwords cannot be acquired from database!");
return;
}
- //TODO THW check all cases
if (_currentGenesis.IsLoggedOn)
{
- // The login succeeded with the 'SkeletonKey' or the password 'Lvl8' or the 'OfflinePassword'
- if (retValPwdBuild)
+ // The login succeeded with the 'SkeletonKey', the 'Lvl8 password' or the 'offline password'
+ if (retValPwdBuild) // Passwords exist in database
{
- if (pwdContainer.Password.Equals(Encoding.UTF8.GetString(pwdContainer.ListOfPasswords.Last())))
+ // Remind the 'Lvl8 password' from passwords
+ var pwdLvl8FromPasswords = Encoding.UTF8.GetString(pwdContainer.ListOfPasswords.Last());
+
+ // Check if the 'offline password' is in use
+ if (!string.IsNullOrWhiteSpace(_currentGenesis.OfflinePassword))
{
- // CASE 1: - The 'production password' is the 'Lvl8 password' as the login succeeded.
- LogText(@"Successfully logged in with password Lvl8 and password file okay!");
- }
- else if (pwdContainer.Skeleton.Equals(pwdContainer.Password))
+ LogText("Successfully logged in with the 'offline password'");
+
+ if (_currentGenesis.OfflinePassword.Equals(pwdLvl8FromPasswords))
+ {
+ LogText("The 'offline password' is the 'Lvl8 password'");
+ if (pwdLvl8FromPasswords.Equals(pwdContainer.Password))
+ {
+ // CASE 1: - The 'offline password' is valid and equals the 'Lvl8 password' and the
+ // 'production password'
+ LogText("The 'production password' is the 'Lvl8 password'\n" +
+ "Installed password file is valid and compared with database");
+ }
+ else
+ {
+ // CASE 2: - The 'offline password' is valid and equals the 'Lvl8 password' but the
+ // 'production password' is not correctly updated
+ ShowPasswordRepairMessage(
+ "The 'production password' is not correctly set to the 'Lvl8 password'\n" +
+ "Installed password file is valid and compared with database\n" +
+ "[Repair Password] enabled");
+ }
+ }
+ // CASE 3: - The 'offline password' is valid and equals the 'SkeletonKey'
+ else if (_currentGenesis.OfflinePassword.Equals(pwdContainer.Skeleton))
+ ShowPasswordRepairMessage(
+ "The 'offline password' is the 'SkeletonKey'\n" +
+ "Password exists on database but password file not installed'\n" +
+ "[Repair Password] enabled");
+ }// The 'offline password' is in use
+ else // The 'production password' is in use
{
- // CASE 2: - Passwords are generated in database but password file is not installed or doesn't work.
- // - The 'production password' is the 'SkeletonKey' as the login succeeded.
- //
- // If password file is initially not installed and the database password returned the SkeletonKey
- // the login has been successfully executed with this SkeletonKey, so a repair of the password
- // file needs to be enabled!
- ShowPasswordRepairMessage(@"Password exists on database but the SkeletonKey is valid" +
- " - [Repair Password] enabled");
+ if (pwdContainer.Password.Equals(pwdLvl8FromPasswords))
+ {
+ // CASE 4: - The 'production password' is the 'Lvl8 password' as the login succeeded.
+ LogText(
+ "Successfully logged in with the 'production password' which equals the 'Lvl8 password'\n" +
+ "Installed password file is valid and compared with database");
+ }
+ else if (pwdContainer.Password.Equals(pwdContainer.Skeleton))
+ {
+ // If the 'password file' is initially not installed and the 'production password' returned the
+ // 'SkeletonKey', then the login has been successfully executed with this 'SkeletonKey',
+ // a repair of the 'password file' needs to be enabled!
+
+ // CASE 5: - The 'production password' is the 'SkeletonKey' as the login succeeded.
+ ShowPasswordRepairMessage(
+ "Successfully logged in with the 'production password' which equals the 'SkeletonKey'\n" +
+ "Password exists on database but password file not installed'\n" +
+ "[Repair Password] enabled");
+ }
}
- }
+ }// Database returned valid passwords
else
{
- // CASE 3: - The login succeeded but the password file request from database failed
- LogText(@"Successfully logged in. Password file not generated!");
+ // CASE 6: - The login succeeded but the password file request from database failed
+ LogText("Successfully logged in with the 'offline password'.\n" +
+ "Passwords cannot be acquired from database and therefore not compared");
}
- }
+ }// Initial login succeeded
- if (!_currentGenesis.IsLoggedOn)
+ // Login can only be tried on valid database collection of passwords
+ if (!retValPwdBuild)
+ {
+ sb.AppendLine(@"Passwords cannot be acquired from database [E0]!");
+ }
+ // As the initial login wasn't successfully, try the acquired combinations from the database passwords
+ else if (!_currentGenesis.IsLoggedOn)
{
// This is needed from meter as an unsuccessful login requires a delay for the next trial
Thread.Sleep(2000);
// Try to log in with password level 8 which may not be published to the database
var retVal = _currentGenesis.Login(Encoding.UTF8.GetString(pwdContainer.ListOfPasswords.Last()));
- // CASE 4: - Passwords are generated in database and correctly installed. The login check will be done
+ // CASE 6: - Passwords are generated in database and correctly installed. The login check will be done
// with the generated password, but the 'production password' is still the 'SkeletonKey'.
// - The database update of the production password went wrong!
if (_currentGenesis.IsLoggedOn && retVal)
{
- ShowPasswordRepairMessage(@"Password file is installed as login Lvl8 works, password in database" +
- " not updated - [Repair Password] enabled");
+ ShowPasswordRepairMessage("Successfully logged in with 'Lvl8 password'\n" +
+ "Installed password file is valid and compared with database!\n" +
+ "'production password' in database not actual, update required\n" +
+ "[Repair Password] enabled");
}
else
{
- sb.AppendLine("Login with LVL8 failed [M1]!");
+ sb.AppendLine("Login with 'LVL8 password' failed [M1]!");
}
if (!_currentGenesis.IsLoggedOn)
{
// This is needed from meter as an unsuccessful login requires a delay for the next trial
Thread.Sleep(4000);
- // CASE 5: - The production password didn't work, so the SkeletonKey will be tried.
+ // CASE 7: - The production password didn't work, so the SkeletonKey will be tried.
if (_currentGenesis.Login(pwdContainer.Skeleton))
{
- ShowPasswordRepairMessage(@"Successfully logged in with SkeletonKey - [Repair Password] enabled");
+ ShowPasswordRepairMessage("Successfully logged in with 'SkeletonKey'\n" +
+ "'production password' in database not actual, update required\n" +
+ "[Repair Password] enabled");
}
else
{
- sb.AppendLine(@"Login with Skeleton failed [M2]!");
+ sb.AppendLine(@"Login with 'SkeletonKey' failed [M2]!");
}
- if (!retValPwdBuild)
- {
- sb.AppendLine(@"Unable to build password file [E0]!");
- }
- else if (_currentGenesis.Region.Equals("NA"))
+ if (_currentGenesis.Region.Equals("NA"))
{
var url = ServiceUrls.GetExportDataServiceUrl();
var retStr = LocalWebRequest.GetRequestWithError(url + _currentGenesis.PcbId,
@@ -422,15 +472,15 @@ namespace Xylem.Common.Ui.GenesisToolBox
{
if (item.PWD == pwdContainer.Password)
{
- sb.AppendLine($"{item.ID} is Password LVL 8");
+ sb.AppendLine($"{item.ID} is the 'Lvl8 password'");
}
else if (item.PWD == pwdContainer.Skeleton)
{
- sb.AppendLine($"{item.ID} is Skeleton [E3]");
+ sb.AppendLine($"{item.ID} is the 'SkeletonKey' [E3]");
}
else
{
- sb.AppendLine($"{item.ID} is not LVL 8 or Skeleton [E3]");
+ sb.AppendLine($"{item.ID} is neither the 'Lvl8 password' nor the 'SkeletonKey' [E3]");
}
}
}
diff --git a/Common/Ui/GenesisToolBox/FrmQsTool.Designer.cs b/Common/Ui/GenesisToolBox/FrmQsTool.Designer.cs
index c9ad20e4..2c2b9857 100644
--- a/Common/Ui/GenesisToolBox/FrmQsTool.Designer.cs
+++ b/Common/Ui/GenesisToolBox/FrmQsTool.Designer.cs
@@ -166,6 +166,7 @@
this.cbxUseOfflinePwds.TabIndex = 42;
this.cbxUseOfflinePwds.Text = "Use Offline Passwords";
this.cbxUseOfflinePwds.UseVisualStyleBackColor = true;
+ this.cbxUseOfflinePwds.CheckedChanged += new System.EventHandler(this.cbxUseOfflinePwds_CheckedChanged);
//
// tbxPcbId
//
diff --git a/Common/Ui/GenesisToolBox/FrmQsTool.cs b/Common/Ui/GenesisToolBox/FrmQsTool.cs
index 39eac73d..70e179ba 100644
--- a/Common/Ui/GenesisToolBox/FrmQsTool.cs
+++ b/Common/Ui/GenesisToolBox/FrmQsTool.cs
@@ -87,6 +87,7 @@ namespace Xylem.Common.Ui.GenesisToolBox
SetCordonelAccessLocked();
tbxPcbId.Visible = false;
+ btnConnect.Focus();
}
private void FrmQsTool_Load(Object sender, EventArgs e)
@@ -265,54 +266,66 @@ namespace Xylem.Common.Ui.GenesisToolBox
return;
}
- Invoke(new Action(() =>
+ if (_currentGenesis.IsLoggedOn)
{
- lblConnectPcb.Text = StrPartPcbConnected;
- tbxPcbId.Text = _currentGenesis.PcbId;
- tbxPcbId.Visible = true;
- tbxMeterFw.Text = _currentGenesis.FwVersion;
- tbxMeterMeterSize.Text = _currentGenesis.MeterSize;
- tbxMeterLutCrc.Text = _currentGenesis.LutCrc;
- tbxRegion.Text = _currentGenesis.Region;
- LogText("Meter FW Version:\t" + _currentGenesis.FwVersion);
- LogText("Meter LUT CRC:\t" + _currentGenesis.LutCrc);
- LogText("Meter Size:\t" + _currentGenesis.MeterSize);
- LogText("Meter Region:\t" + _currentGenesis.Region);
- if (_currentGenesis.RadioFrequencyMhz != null)
+ Invoke(new Action(() =>
{
- tbxRadio.Text = $@"{_currentGenesis.RadioFrequencyMhz}";
- LogText("Radio frequency:\t" + $"{_currentGenesis.RadioFrequencyMhz} MHz");
- }
+ lblConnectPcb.Text = StrPartPcbConnected;
+ tbxPcbId.Text = _currentGenesis.PcbId;
+ tbxPcbId.Visible = true;
+ tbxMeterFw.Text = _currentGenesis.FwVersion;
+ tbxMeterMeterSize.Text = _currentGenesis.MeterSize;
+ tbxMeterLutCrc.Text = _currentGenesis.LutCrc;
+ tbxRegion.Text = _currentGenesis.Region;
+ LogText("Meter FW Version:\t" + _currentGenesis.FwVersion);
+ LogText("Meter LUT CRC:\t" + _currentGenesis.LutCrc);
+ LogText("Meter Size:\t" + _currentGenesis.MeterSize);
+ LogText("Meter Region:\t" + _currentGenesis.Region);
+ if (_currentGenesis.RadioFrequencyMhz != null)
+ {
+ tbxRadio.Text = $@"{_currentGenesis.RadioFrequencyMhz}";
+ LogText("Radio frequency:\t" + $"{_currentGenesis.RadioFrequencyMhz} MHz");
+ }
- LogText("");
- LogText("'Configuration.json' version: " + _currentGenesis.InterfaceInfo.InterfaceVersion);
- lblConfigVersion.Text = @"Interface Version: " + _currentGenesis.InterfaceInfo.InterfaceVersion;
- lblConfigVersion.ForeColor = _currentGenesis.InterfaceSupportsFwVersion ? Color.Green : Color.Red;
- if (!_currentGenesis.InterfaceSupportsFwVersion)
- {
- var text = "INTERFACE VERSION OUTDATED!\n" +
- "The loaded \'configuration.json\' " +
- $"version: {_currentGenesis.InterfaceInfo.InterfaceVersion}\n" +
- $"does NOT support the Cordonel FW version: {_currentGenesis.FwVersion}!";
- MessageBox.Show(text, @"FAILED", MessageBoxButtons.OK, MessageBoxIcon.Error);
- LogText(text);
- }
- else
- {
- LogText($"\'Configuration.json\' supports installed FW version: {_currentGenesis.FwVersion}");
- }
+ LogText("");
+ LogText("'Configuration.json' version: " + _currentGenesis.InterfaceInfo.InterfaceVersion);
+ lblConfigVersion.Text = @"Interface Version: " + _currentGenesis.InterfaceInfo.InterfaceVersion;
+ lblConfigVersion.ForeColor = _currentGenesis.InterfaceSupportsFwVersion ? Color.Green : Color.Red;
+ if (!_currentGenesis.InterfaceSupportsFwVersion)
+ {
+ var text = "INTERFACE VERSION OUTDATED!\n" +
+ "The loaded \'configuration.json\' " +
+ $"version: {_currentGenesis.InterfaceInfo.InterfaceVersion}\n" +
+ $"does NOT support the Cordonel FW version: {_currentGenesis.FwVersion}!";
+ MessageBox.Show(text, @"FAILED", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ LogText(text);
+ }
+ else
+ {
+ LogText($"\'Configuration.json\' supports installed FW version: {_currentGenesis.FwVersion}");
+ }
- LogText("");
- lblConnectPcb.ForeColor = Color.Green;
- CheckUpdateEnabled();
+ LogText("");
+ lblConnectPcb.ForeColor = Color.Green;
+ CheckUpdateEnabled();
- LogPcAndCordonelTime();
- LogInstalledMeterFw();
- }));
+ LogPcAndCordonelTime();
+ LogInstalledMeterFw();
+ }));
+ }
}).ContinueWith(delegate
{
LowLevelActionControl(false);
- btnReadLifetime_Click(this, null);
+ _currentGenesis.ReLogin();
+ if (_currentGenesis.IsLoggedOn)
+ btnReadLifetime_Click(this, null);
+ else
+ {
+ Invoke(new Action(() =>
+ {
+ Init();
+ }));
+ }
});
}
catch (Exception ex)
@@ -688,13 +701,13 @@ namespace Xylem.Common.Ui.GenesisToolBox
tbxDrainedLoad_uAs.Text = $@"{genesisStatus.DrainedBatteryLoad_uAs:N0}";
tbxExpiredLifeTime.Text = $@"{genesisStatus.ExceededLifeTime_s:N0}";
tbxInitialBatteryLoad.Text = $@"{genesisStatus.InitialBatteryLoad_mAh:N0}";
-
+
tbxDrainedBatteryLoad_percent.Text = $@"{genesisStatus.DrainedBatteryLoadPercent:F2}";
tBxRemainingLifeTimeSw.Text = $@"{genesisStatus.RemainingLifeTimeYears:F2}";
tbxRemainingLifeTimeFw.Text = genesisStatus.FwCalculatedRemainingLifeTimeYears != null ?
- $@"{genesisStatus.DrainedBatteryLoadPercent:F2}" : "not supported";
+ $@"{genesisStatus.FwCalculatedRemainingLifeTimeYears:F2}" : "not supported";
tbxStorageMonths.Text = $@"{genesisStatus.StorageMonths:F1}";
- }
+ }
else
{
tbxDrainedBatteryLoad_percent.Text = "";