diff --git a/Common/.shared/SharedAssemblyInfo.cs b/Common/.shared/SharedAssemblyInfo.cs
index 5d4e6217..625b4677 100644
--- a/Common/.shared/SharedAssemblyInfo.cs
+++ b/Common/.shared/SharedAssemblyInfo.cs
@@ -13,4 +13,4 @@ using System.Reflection;
//
//[assembly: AssemblyVersion("1.2.*.0")]
-[assembly: AssemblyVersion("2.7.4.*")]
+[assembly: AssemblyVersion("2.7.5.*")]
diff --git a/Common/Common.sln.DotSettings b/Common/Common.sln.DotSettings
index fba34e5b..d76a8661 100644
--- a/Common/Common.sln.DotSettings
+++ b/Common/Common.sln.DotSettings
@@ -33,6 +33,7 @@
True
True
True
+ True
True
True
True
diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/configuration.json b/Common/Hardware/WaterMeter/Genesis/GenesisCore/configuration.json
index f81206a2..fe1e8e62 100644
--- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/configuration.json
+++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/configuration.json
@@ -18469,7 +18469,7 @@
},
"description": "",
"version": {
- "first": 69,
+ "first": 72,
"last": 72
},
"statictype": "dynamic",
diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatus.cs b/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatus.cs
index 75b3a16e..16fecc89 100644
--- a/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatus.cs
+++ b/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatus.cs
@@ -7,6 +7,16 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus
///
public class GenesisStatus
{
+ ///
+ /// Remaining lifetime for Cordonel in years based on FW calculation.
+ ///
+ public Double? FwCalculatedRemainingLifeTimeYears { get; set; }
+
+ ///
+ /// Remaining lifetime for Cordonel in seconds based on FW calculation.
+ ///
+ public UInt64? FwCalculatedRemainingLifeTime_s { get; set; }
+
///
/// Remaining lifetime for Cordonel in years based on battery drainage.
///
diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatusHandler.cs b/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatusHandler.cs
index 17648d2a..a6a2b075 100644
--- a/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatusHandler.cs
+++ b/Common/Hardware/WaterMeter/Genesis/GenesisStatus/GenesisStatusHandler.cs
@@ -280,6 +280,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus
///
/// - errorMsg.
///
+ ///
+ /// - Readout FW based calculation of remaining lifetime in seconds.
+ ///
public static Boolean BuildLifeTimeInformation(IGenesisMeter currentGenesis, GenesisStatus status, out String errorMsg)
{
Boolean retVal;
@@ -302,6 +305,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus
status.InitialBatteryLoad_mAh = RegisterConverter.ByteArrayToValue(
currentGenesis.ReadRegister(Register.Powermon.BatteryInitialLoad));
+ var nullCheck = currentGenesis.ReadRegister(Register.Powermon.RemainingSeconds);
+ if (nullCheck == null)
+ status.FwCalculatedRemainingLifeTime_s = null;
+ else
+ status.FwCalculatedRemainingLifeTime_s =
+ RegisterConverter.ByteArrayToValue(nullCheck);
+
currentGenesis.Logout();
retVal = CalculateLifeTime(status);
@@ -337,6 +347,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus
///
/// - Calculate storage months.
///
+ ///
+ /// - Calculate FW based calculation of remaining lifetime in years.
+ ///
public static Boolean CalculateLifeTime(GenesisStatus status)
{
// Mark as false if the basic inputs are missed
@@ -361,6 +374,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus
var estimatedLifeTime_s = status.ExceededLifeTime_s / drainedBatteryLoad_rel;
var remainingLifetime_s = estimatedLifeTime_s - status.ExceededLifeTime_s;
status.RemainingLifeTimeYears = remainingLifetime_s * YEARS_PER_SECONDS;
+ status.FwCalculatedRemainingLifeTimeYears = status.FwCalculatedRemainingLifeTime_s * YEARS_PER_SECONDS;
// Calculate an alternative threshold for remaining battery load based on the quiescent current and a supplement
// for production purpose. Those values can be assigned in the Cordonel requirements.
diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/Registers.cs b/Common/Hardware/WaterMeter/Genesis/Registers/Registers.cs
index 41799755..a6ba9035 100644
--- a/Common/Hardware/WaterMeter/Genesis/Registers/Registers.cs
+++ b/Common/Hardware/WaterMeter/Genesis/Registers/Registers.cs
@@ -94,6 +94,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers
public static readonly String BatteryInitialLoad = "POWERMON_BatteryMilliAHrRating";
public static readonly String BatteryExceededSeconds = "POWERMON_TotalUsedSeconds";
public static readonly String StoreConfiguration = "POWERMON_StoreConfiguration";
+ public static readonly String RemainingSeconds = "POWERMON_RemainingSeconds";
}
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckProductionState.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckProductionState.cs
index be95b8f7..247366b9 100644
--- a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckProductionState.cs
+++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckProductionState.cs
@@ -11,7 +11,6 @@ using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Logic.ProductionOrderCore.TestResults;
-using Xylem.Common.Production.ProductionUiCordonel.Model;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericModules;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
@@ -78,6 +77,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - CancellationToken.
///
+ ///
+ /// - Moved EOL creation to ExecPasswordFile.
+ ///
public override StatusReturn PreExecuteProcess()
{
if (Meter == null || string.IsNullOrEmpty(Meter.PcbId) || Meter.PcbId.Length < GenesisMeter.MinPcbIdLength)
@@ -89,13 +91,13 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Some statistics for GUI and internal processing
SignalRunningState(MaxActualProgressSteps);
- // Get new EOL progress from DB. All fields except the Id, StartDate of EOL and the PcbId are null!
- if (!EOLHandler.GetNewEolProgress(Meter.PcbId, EolProgress, out var error))
- {
- Meter.WriteLog(error);
- ErrorMsgDispatcher(Resources.StrErrorMsgCreateEolProgress);
- return StatusReturn.Failed;
- }
+ //// Get new EOL progress from DB. All fields except the Id, StartDate of EOL and the PcbId are null!
+ //if (!EOLHandler.GetNewEolProgress(Meter.PcbId, EolProgress, out var error))
+ //{
+ // Meter.WriteLog(error);
+ // ErrorMsgDispatcher(Resources.StrErrorMsgCreateEolProgress);
+ // return StatusReturn.Failed;
+ //}
// Exit if meanwhile cancellation is required
if (CancellationToken.IsCancellationRequested)
@@ -105,7 +107,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Get the requirement (Standard or special)
if (!GenesisStatusHandler.GetCordonelRequirementInfoFromDb(Meter.PcbId, ProductionRequirements,
- out error) || ProductionRequirements == null)
+ out var error) || ProductionRequirements == null)
{
Meter.WriteLog(error);
ErrorMsgDispatcher(Resources.StrErrorMsgProductionRequirements);
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/EolProcessStatesDef.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/EolProcessStatesDef.cs
index 1e5d3928..e164f9d3 100644
--- a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/EolProcessStatesDef.cs
+++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/EolProcessStatesDef.cs
@@ -104,16 +104,14 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
var stateContainer = new List
{
#region ----------------------------------- GENERIC-STATES---------------------------------------------
- // Detection of Cordonel has to be completed before assigning next state, so leave to automatic
- // to change the state after successfully execution. The detection is the base for all others.
new ProcessStateStruct(
productionProcess: new DetectCordonel(Resources.StrStateDetectCordonel),
processState: ProcessState.DetectCordonel,
processInfo: Resources.StrStateDetectCordonel,
productionProcessNo: 0,
+ // CheckNewMeter will exit with repeated detect or connect
nextStateOnSuccess: ProcessState.CheckNewMeter),
- // Precondition: - The detection process has to be completed as the PcbId is needed.
new ProcessStateStruct(
productionProcess: new ConnectCordonel(Resources.StrStateConnectCordonel),
processState: ProcessState.ConnectCordonel,
@@ -121,8 +119,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
productionProcessNo: 1,
nextStateOnSuccess: ProcessState.GetSerialNumberAndRadioAddress),
- // Precondition: - The detection process has to be completed as the PcbId is needed.
- // AVOID to change the process state on completion as parallel process is active!
new ProcessStateStruct(
productionProcess: new GetSerialNumberAndRadioAddress(Resources.StrStateGetSerialAndRadioAddress),
processState: ProcessState.GetSerialNumberAndRadioAddress,
@@ -133,10 +129,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Kick off parallel process execution
kickOffParallelState: ProcessState.GetProgrammingParameters),
- // Precondition: - The connection process has to be completed as a readout of some register
- // values from the Cordonel are needed to check the update capability:
- // - Wait on completed connection process before starting this process.
- // AVOID to change the process state on completion as parallel process is active!
new ProcessStateStruct(
productionProcess: new GetFinalParametrization(Resources.StrStateGetProgrammingParameters),
processState: ProcessState.GetProgrammingParameters,
@@ -145,29 +137,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Avoid automatic change after completion as parallel process is active
nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
// Kick off parallel process execution
- kickOffParallelState: ProcessState.CheckProductionState,
- // Wait until this process has been successfully completed
- waitForSingleProcess: ProcessState.ConnectCordonel),
+ kickOffParallelState: ProcessState.ProcessPasswordFile),
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
#region ----------------------------------- EOL-STATES ------------------------------------------------
- // Precondition: - The connection process has to be completed as a readout of some register
- // values from the Cordonel are needed to check the update capability:
- // - Wait on completed connection process before starting this process.
- // AVOID to change the process state on completion as parallel process is active!
- new ProcessStateStruct(
- productionProcess: new CheckProductionState(Resources.StrStateCheckProductionState),
- processState: ProcessState.CheckProductionState,
- processInfo: Resources.StrStateCheckProductionState,
- productionProcessNo: 4,
- // Avoid automatic change after completion as parallel process is active
- nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
- // Kick off parallel process execution
- kickOffParallelState: ProcessState.ProcessPasswordFile,
- // Wait until this process has been successfully completed
- waitForSingleProcess: ProcessState.ConnectCordonel),
-
// Precondition: - The connection process has to be completed as a password change in the DB
// will take place: Skeleton to Password Level 8. Not waiting for completion may cause side
// effects on login. Wait for all processes to complete.
@@ -177,27 +151,32 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
productionProcess: new ExecPasswordFile(Resources.StrStatePasswordFile),
processState: ProcessState.ProcessPasswordFile,
processInfo: Resources.StrStatePasswordFile,
- productionProcessNo: 5,
+ productionProcessNo: 4,
nextStateOnSuccess: ProcessState.ExecFinalParametrization,
+ // Wait for completion of all processes to avoid side effects
waitForAllProcesses: true),
- // This writes all setups to the device, it has to be executed exclusively with automatic
- new ProcessStateStruct(
+ new ProcessStateStruct(
productionProcess: new ExecFinalParametrization(Resources.StrStateFinalParametrization),
processState: ProcessState.ExecFinalParametrization,
processInfo: Resources.StrStateFinalParametrization,
- productionProcessNo: 6,
+ productionProcessNo: 5,
nextStateOnSuccess: ProcessState.ExecStoreConfiguration),
- // Precondition: - The final parametrization has to be finished as this shall be stored
- // to non-volatile memory and checked if remaining valid after the reboot.
- // Store configuration has to be executed exclusively with automatic
new ProcessStateStruct(
productionProcess: new ExecStoreConfiguration(Resources.StrStateStoreConfiguration),
processState: ProcessState.ExecStoreConfiguration,
processInfo: Resources.StrStateStoreConfiguration,
- productionProcessNo: 7,
- nextStateOnSuccess: ProcessState.RebootCordonel),
+ productionProcessNo: 6,
+ nextStateOnSuccess: ProcessState.CheckProductionState),
+
+ // Parametrization has to be completed as those needed to check e.g. the remaining FW based lifetime.
+ new ProcessStateStruct(
+ productionProcess: new CheckProductionState(Resources.StrStateCheckProductionState),
+ processState: ProcessState.CheckProductionState,
+ processInfo: Resources.StrStateCheckProductionState,
+ productionProcessNo: 7,
+ nextStateOnSuccess: ProcessState.RebootCordonel),
// Precondition: - The store configuration has to be executed to safe all settings
// to non-volatile memory and checked if remaining valid after the reboot.
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/ExecPasswordFile.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/ExecPasswordFile.cs
index 214570a5..13180fbd 100644
--- a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/ExecPasswordFile.cs
+++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/ExecPasswordFile.cs
@@ -8,6 +8,7 @@ using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Logic.ProductionOrderCore;
+using Xylem.Common.Production.ProductionUiCordonel.Model;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
using Xylem.Common.Production.ProductionUiCordonel.Properties;
using Xylem.Common.Production.ProductionUiCordonel.UserControls;
@@ -89,8 +90,19 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - Retries for installation of password file.
///
+ ///
+ /// - Moved EOL creation from CHeckProductionState as this is the first entry for the configuration.
+ ///
public override StatusReturn ExecuteProcess()
{
+ // Get new EOL progress from DB. All fields except the Id, StartDate of EOL and the PcbId are null!
+ if (!EOLHandler.GetNewEolProgress(Meter.PcbId, EolProgress, out var error))
+ {
+ Meter.WriteLog(error);
+ ErrorMsgDispatcher(Resources.StrErrorMsgCreateEolProgress);
+ return StatusReturn.Failed;
+ }
+
// Uncheck executed process to leave the result open needed for retries
EolProgress.PasswordFileInstalledCheck = null;
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs
index aeaf1622..74ba04a6 100644
--- a/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs
+++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs
@@ -32,6 +32,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
///
/// - Initial.
///
+ ///
+ /// - FW based calculation of remaining lifetime in years.
+ ///
public static StatusReturn CheckRemainingLifetime(IGenesisMeter meter, CordonelRequirements productionRequirements,
GenesisStatus productionStatus, out String feedbackMsg, Boolean assemblyLine = false)
{
@@ -58,11 +61,22 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
var strStation = assemblyLine
? $"{productionRequirements.RequiredLifeTimeYearsAssembly:F2} "
: $"{productionRequirements.RequiredLifeTimeYearsShipping:F2} ";
+ // Take the FW based calculation into account
+ var strFwCalculatedLifeTimeYears = "";
+ if (productionStatus.FwCalculatedRemainingLifeTimeYears != null)
+ {
+ strFwCalculatedLifeTimeYears =
+ $@" - {Resources.StrMsgRemainingLifeTime}: " +
+ $"{productionStatus.FwCalculatedRemainingLifeTimeYears:F2} " +
+ $"{Resources.StrMsgYears} (Firmware)";
+ }
// Build message for required versus calculated lifetime
var lifeTime = $"{Resources.StrMsgRemainingLifeTime}: " +
- // Actual calculated lifetime based on readings from meter
+ // Actual SW calculated lifetime based on readings from meter
$"{productionStatus.RemainingLifeTimeYears:F2} " +
- $"{Resources.StrMsgYears}" +
+ $"{Resources.StrMsgYears} (Software)" +
+ // Optional FW calculation
+ strFwCalculatedLifeTimeYears +
$" - {Resources.StrMsgRequiredLifeTime}: " +
// Required lifetime from special or standard requirement
strStation +
@@ -72,7 +86,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
if ((assemblyLine &&
productionRequirements.RequiredLifeTimeYearsAssembly > productionStatus.RemainingLifeTimeYears) ||
(!assemblyLine &&
- productionRequirements.RequiredLifeTimeYearsShipping > productionStatus.RemainingLifeTimeYears))
+ (productionRequirements.RequiredLifeTimeYearsShipping > productionStatus.RemainingLifeTimeYears ||
+ // internally in FW calculated remaining lifetime visual for customer in DIAVASO
+ productionRequirements.RequiredLifeTimeYearsShipping > productionStatus.FwCalculatedRemainingLifeTimeYears)))
{
feedbackMsg = $"{Resources.StrErrorMsg}: {lifeTime}";
return StatusReturn.Failed;
@@ -218,9 +234,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
// Create an output message addon for alternative power consumption calculation
var strAlternativeCalc = productionStatus.AlternativeRequiredBatteryLoadPercent == null
- ? ""
- : $" - {Resources.StrMsgRequirementAbsolutLimitDrainedBattery}: " + strStation +
- $" ({Resources.StrMsgAlternativeDrainedBatteryCalculation})";
+ ? "" : $" - {Resources.StrMsgRequirementAbsolutLimitDrainedBattery}: " + strStation ;
var strBatLoad = $"{Resources.StrMsgDrainedBattery}: " +
// Actual calculated battery load based on readings from meter
diff --git a/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs b/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs
index 85d04021..5a6c5005 100644
--- a/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs
+++ b/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs
@@ -991,6 +991,9 @@ namespace Xylem.Common.Ui.GenesisToolBox
///
/// - Initial
///
+ ///
+ /// - Added FW based calculation of lifetime in years.
+ ///
private Boolean BuildGenesisStatus(out String msg)
{
msg = "";
@@ -1017,6 +1020,8 @@ namespace Xylem.Common.Ui.GenesisToolBox
sbMSG.AppendLine("");
sbMSG.AppendLine($"Actual storage months: {genesisStatus.StorageMonths:F1}");
sbMSG.AppendLine($"Remaining life time in years: {genesisStatus.RemainingLifeTimeYears:F2}");
+ if (genesisStatus.FwCalculatedRemainingLifeTimeYears != null)
+ sbMSG.AppendLine($"Remaining life time in years (FW): {genesisStatus.FwCalculatedRemainingLifeTimeYears:F2}");
sbMSG.AppendLine($"Totally drained battery load in %: {genesisStatus.DrainedBatteryLoadPercent:F2}");
msg = sbMSG.ToString();