diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/GenesisFile.csproj b/Common/Hardware/WaterMeter/Genesis/GenesisFile/GenesisFile.csproj index 3d8d216a..23096148 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/GenesisFile.csproj +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/GenesisFile.csproj @@ -194,6 +194,10 @@ {AC434B18-4D7B-49BA-9AD5-0527C79E8297} GenesisPwd + + {0F646872-D8DC-4EE5-989F-D4C73F0ACE3F} + GenesisStatus + {F4AAF7E6-7333-4284-B735-E32DEB076C64} Registers diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPowerCorrectionFile.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPowerCorrectionFile.cs index ad7b74b7..40fdcee5 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPowerCorrectionFile.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPowerCorrectionFile.cs @@ -45,7 +45,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile private const Int32 PulseEvenDistributionSize = sizeof(Boolean); // production data - private const Int32 ProdTimeIdx = FileDataIdx; + private const Int32 ProdDateTimeIdx = FileDataIdx; + private const Int32 ProdTimeIdx = ProdDateTimeIdx + TimeSize; private const Int32 ProdChargeIdx = ProdTimeIdx + TimeSize; private const Int32 ProdRadioStateIdx = ProdChargeIdx + ChargeSize; private const Int32 ProdPulseAdaptInstalledIdx = ProdRadioStateIdx + RadioStateSize; @@ -56,7 +57,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile // field data private const Int32 FieldFwVersionIdx = ProdPulseEvenDistributionIdx + PulseEvenDistributionSize; - private const Int32 FieldTimeIdx = FieldFwVersionIdx + FwVersionSize; + private const Int32 FieldDateTimeIdx = FieldFwVersionIdx + FwVersionSize; + private const Int32 FieldTimeIdx = FieldDateTimeIdx + TimeSize; private const Int32 FieldChargeIdx = FieldTimeIdx + TimeSize; private const Int32 FieldRadioStateIdx = FieldChargeIdx + ChargeSize; private const Int32 FieldPulseAdaptInstalledIdx = FieldRadioStateIdx + RadioStateSize; @@ -84,15 +86,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// /// Content of power correction meter file /// - public List FileContent = new List(); - - /// - /// Power correction data. - /// - public PowerCorrection PowerCorrectionData - { - get; set; - } + public readonly List FileContent = new List(); /// /// Ctor @@ -167,95 +161,94 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile fc.Clear(); fc.Add(Resources.StrPowCorrFileInfo); - if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, ProdTimeIdx)) - { - fc.Add($"{Resources.StrPowCorrFactoryValues} -{Resources.StrPowCorrDateTime}" + + if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, ProdDateTimeIdx)) + fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrDateTime}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(TimeT))}"); - fc.Add($"{Resources.StrPowCorrFactoryValues} -{Resources.StrPowCorrTime_s}" + + if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, ProdTimeIdx)) + fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrTime_s}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt32))}"); - } if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, ProdChargeIdx)) - fc.Add($"{Resources.StrPowCorrFactoryValues} -{Resources.StrPowCorrCharge_uAs}" + + fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrCharge_uAs}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}"); - if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, FieldTimeIdx)) - { - fc.Add($"{Resources.StrPowCorrActualValues} -{Resources.StrPowCorrDateTime}" + + if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, FieldDateTimeIdx)) + fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrDateTime}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(TimeT))}"); - fc.Add($"{Resources.StrPowCorrActualValues} -{Resources.StrPowCorrTime_s}" + + if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, FieldTimeIdx)) + fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrTime_s}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt32))}"); - } if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, FieldChargeIdx)) - fc.Add($"{Resources.StrPowCorrActualValues} -{Resources.StrPowCorrCharge_uAs}" + + fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrCharge_uAs}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}"); if (CopyByteArray(value_u8a = new Byte[RadioStateSize], bin, RadioStateSize, 0, ProdRadioStateIdx)) - fc.Add($"{Resources.StrPowCorrFactoryValues} -{Resources.StrPowCorrRadioSystemState}" + + fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrRadioSystemState}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}"); if (CopyByteArray(value_u8a = new Byte[RadioStateSize], bin, RadioStateSize, 0, FieldRadioStateIdx)) - fc.Add($"{Resources.StrPowCorrActualValues} -{Resources.StrPowCorrRadioSystemState}" + + fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrRadioSystemState}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}"); if (CopyByteArray(value_u8a = new Byte[PulseAdaptInstalledSize], bin, PulseAdaptInstalledSize, 0, ProdPulseAdaptInstalledIdx)) - fc.Add($"{Resources.StrPowCorrFactoryValues} -{Resources.StrPowCorrPulseAdapterInstallationState}" + + fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrPulseAdapterInstallationState}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(Boolean))}"); if (CopyByteArray(value_u8a = new Byte[PulseAdaptInstalledSize], bin, PulseAdaptInstalledSize, 0, FieldPulseAdaptInstalledIdx)) - fc.Add($"{Resources.StrPowCorrActualValues} -{Resources.StrPowCorrPulseAdapterAutoDetected}" + + fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrPulseAdapterAutoDetected}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(Boolean))}"); if (CopyByteArray(value_u8a = new Byte[PulseModeSize], bin, PulseModeSize, 0, ProdPulseModeIdx)) - fc.Add($"{Resources.StrPowCorrFactoryValues} -{Resources.StrPowCorrPulseMode}" + + fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrPulseMode}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}"); if (CopyByteArray(value_u8a = new Byte[PulseModeSize], bin, PulseModeSize, 0, FieldPulseModeIdx)) - fc.Add($"{Resources.StrPowCorrActualValues} -{Resources.StrPowCorrPulseMode}" + + fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrPulseMode}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}"); if (CopyByteArray(value_u8a = new Byte[PulseSequenceCtrSize], bin, PulseSequenceCtrSize, 0, ProdPulseSequenceCtrIdx)) - fc.Add($"{Resources.StrPowCorrFactoryValues} -{Resources.StrPowCorrPulseSequenceCounter}" + + fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrPulseSequenceCounter}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}"); if (CopyByteArray(value_u8a = new Byte[PulseSequenceCtrSize], bin, PulseSequenceCtrSize, 0, FieldPulseSequenceCtrIdx)) - fc.Add($"{Resources.StrPowCorrActualValues} -{Resources.StrPowCorrPulseSequenceCounter}" + + fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrPulseSequenceCounter}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(Byte))}"); if (CopyByteArray(value_u8a = new Byte[PulseEvenDistributionSize], bin, PulseEvenDistributionSize, 0, ProdPulseEvenDistributionIdx)) - fc.Add($"{Resources.StrPowCorrFactoryValues} -{Resources.StrPowCorrPulseEvenDistribution}" + + fc.Add($"{Resources.StrPowCorrFactoryValues} - {Resources.StrPowCorrPulseEvenDistribution}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(Boolean))}"); if (CopyByteArray(value_u8a = new Byte[PulseEvenDistributionSize], bin, PulseEvenDistributionSize, 0, FieldPulseEvenDistributionIdx)) - fc.Add($"{Resources.StrPowCorrActualValues} -{Resources.StrPowCorrPulseEvenDistribution}" + + fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrPulseEvenDistribution}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(Boolean))}"); - fc.Add($"{Resources.StrPowCorrActualValues} -{Resources.StrPowCorrOldFwVersion}" + - $": {_currentGenesis.FwVersion}"); + if (CopyByteArray(value_u8a = new Byte[FwVersionSize], bin, FwVersionSize, 0, FieldFwVersionIdx)) + fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrOldFwVersion}" + + $": {GenesisMeter.BuildFlexnetFwVersion(out _, null, value_u8a[1], value_u8a[0])}"); if (CopyByteArray(value_u8a = new Byte[FwVersionSize], bin, FwVersionSize, 0, RequiredFwVersionIdx)) - fc.Add($"{Resources.StrPowCorrActualValues} -{Resources.StrPowCorrNewFwVersion}" + + fc.Add($"{Resources.StrPowCorrActualValues} - {Resources.StrPowCorrNewFwVersion}" + $": {GenesisMeter.BuildFlexnetFwVersion(out _, null, value_u8a[1], value_u8a[0])}"); if (CopyByteArray(value_u8a = new Byte[CalcPulseReportLengthSize], bin, CalcPulseReportLengthSize, 0, CalcPulseReportLengthIdx)) - fc.Add($"{Resources.StrPowCorrCalculation}-{Resources.StrPowCorrPulseReportLength}" + + fc.Add($"{Resources.StrPowCorrPulseReportLength}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt32))}"); if (CopyByteArray(value_u8a = new Byte[TimeSize], bin, TimeSize, 0, CalcPostProdTimeIdx)) - fc.Add($"{Resources.StrPowCorrCalculation}-{Resources.StrPowCorrPostProdTime_s}" + + fc.Add($"{Resources.StrPowCorrPostProdTime_s}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt32))}"); if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, CalcOverestimatedChargeIdx)) - fc.Add($"{Resources.StrPowCorrCalculation}-{Resources.StrPowCorrOverestimate_uAs}" + + fc.Add($"{Resources.StrPowCorrOverestimate_uAs}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}"); if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, CalcFixedEstimatedChargeIdx)) - fc.Add($"{Resources.StrPowCorrCalculation}-{Resources.StrPowCorrFixedEstimateCharge_uAs}" + + fc.Add($"{Resources.StrPowCorrFixedEstimateCharge_uAs}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}"); if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, CalcMinimumChargeIdx)) - fc.Add($"{Resources.StrPowCorrCalculation}-{Resources.StrPowCorrOverestimateLimit_uAs}" + + fc.Add($"{Resources.StrPowCorrOverestimateLimit_uAs}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}"); if (CopyByteArray(value_u8a = new Byte[ChargeSize], bin, ChargeSize, 0, CalcCorrectedChargeIdx)) - fc.Add($"{Resources.StrPowCorrCalculation}-{Resources.StrPowCorrCorrectedCharge_uAs}" + + fc.Add($"{Resources.StrPowCorrCorrectedCharge_uAs}" + $": {RegisterConverter.ConvertToText(value_u8a, typeof(UInt64))}"); return true; @@ -270,12 +263,15 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// /// Copy byte arrays /// - /// - /// - /// + /// destination array to copy to + /// array to copy from /// + /// /// - /// + /// true: success + /// + /// - Initial + /// private Boolean CopyByteArray(Byte[] destination, Byte[] source, Int32 size, Int32 destinationStartIndex = 0, Int32 sourceStartIndex = 0) { @@ -306,23 +302,30 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// PRECONDITION: PowerCorrectionData has to be filled in advance! /// /// true: success - /// + /// /// - Initial /// - private Boolean BuildBinData() + /// power correction + /// if successfully copied + private Boolean BuildBinData(PowerCorrection powerCorrectionData) { - if (PowerCorrectionData == null || _currentGenesis == null) + if (powerCorrectionData == null || _currentGenesis == null) return false; try { - if (_meterBinData == null) _meterBinData = new Byte[FileSize]; - var pc = PowerCorrectionData; + var pc = powerCorrectionData; // production + var timeT = new TimeT(); + var dateTimeUtc = pc.ProductionDateTimeUtc ?? timeT.DateTimeUtc; + var secSince2000 = timeT.UtcAnyToSecondsSince2000(dateTimeUtc); + CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(secSince2000), + TimeSize, ProdDateTimeIdx); + CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ProductionTotalUsedSeconds_s), TimeSize, ProdTimeIdx); CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ProductionTotalUsedCharge_uAs), @@ -342,6 +345,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualFwVersion), FwVersionSize, FieldFwVersionIdx); + // reset timeT to 2000 + timeT.SecondsSince2000 = 0; + dateTimeUtc = pc.ActualDateTimeUtc ?? timeT.DateTimeUtc; + secSince2000 = timeT.UtcAnyToSecondsSince2000(dateTimeUtc); + CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(secSince2000), + TimeSize, FieldDateTimeIdx); + CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualTotalUsedSeconds_s), TimeSize, FieldTimeIdx); CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualTotalUsedCharge_uAs), @@ -349,7 +359,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualRadioSystemState), RadioStateSize, FieldRadioStateIdx); CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualPulseAdapterIsInstalled), - RadioStateSize, FieldPulseAdaptInstalledIdx, PulseAdaptInstalledSize); + PulseAdaptInstalledSize, FieldPulseAdaptInstalledIdx); CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualPulseMode), PulseModeSize, FieldPulseModeIdx); CopyByteArray(_meterBinData, RegisterConverter.ValueToByteArray(pc.ActualPulseSequenceCounter), @@ -394,18 +404,20 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile /// Write the meter power correction file. /// /// true successfully written - /// + /// /// - Initial. /// - public Boolean WritePowCorrMeterFile() + /// + /// true if successfully written + public Boolean WritePowCorrMeterFile(PowerCorrection powerCorrectionData) { - if (_currentGenesis == null || _meterFile == null) + if (_currentGenesis == null || _meterFile == null || powerCorrectionData == null) return false; try { - if (!BuildBinData()) + if (!BuildBinData(powerCorrectionData)) return false; BuildStringListOfPowCorrFileContent(); diff --git a/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs b/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs index e1d436d5..6869670e 100644 --- a/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs +++ b/Common/Ui/GenesisToolBox/FrmLowLevelTools.cs @@ -1494,7 +1494,7 @@ namespace Xylem.Common.Ui.GenesisToolBox /// - /// Cpllect life time information and production status. + /// Collect life time information and production status. /// /// /// - Initial diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs index 8e14d990..64b96520 100644 --- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs +++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs @@ -207,8 +207,8 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw ProcessState.FinalConnect, ProcessState.ReadEngineeringLogs, ProcessState.CorrectPowerOverestimation, - ProcessState.VerifyMeterFiles, ProcessState.CalculateLifeTime, + ProcessState.VerifyMeterFiles, ProcessState.CheckFwUpdateSuccess }; @@ -1413,7 +1413,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// /// /// - /// + /// /// - Initial. /// private void CorrectPowerOverestimation(ProcessState successExitState, @@ -1446,27 +1446,19 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // CASE 2: Power correction needed due to update of FW to corrected version regarding the // power calculation: // Check required versus installed FW versions and threshold version for power correction + // using the preset _fwUpdatePowerCorrection.ActualFwVersion on initial connect as after + // the FW update this is lost in _currentGenesis.InstalledFwVersion and overwritten by the + // new version after the FW update! if ((_currentGenesis.Region == "EMEA" && _cordonelFirmwarePackage.FwPackageInfo.Version >= PowCorrConst.EmeaFwThresholdForPowCorr && - _currentGenesis.InstalledFwVersion < PowCorrConst.EmeaFwThresholdForPowCorr) || + _fwUpdatePowerCorrection.ActualFwVersion < PowCorrConst.EmeaFwThresholdForPowCorr) || (_currentGenesis.Region == "NA" && _cordonelFirmwarePackage.FwPackageInfo.Version >= PowCorrConst.NaFNaFwThresholdForPowCorr && - _currentGenesis.InstalledFwVersion < PowCorrConst.NaFNaFwThresholdForPowCorr)) + _fwUpdatePowerCorrection.ActualFwVersion < PowCorrConst.NaFNaFwThresholdForPowCorr)) { // CASE 2.1: Missing power correction settings from FW update package - if (_fwUpdatePowerCorrection == null) - { - //do something - _fwUpdatePowerCorrection = new PowerCorrection(); - } - - // fill all currently known infos to power correction - _fwUpdatePowerCorrection.ActualPulseAdapterIsInstalled = _currentGenesis.PulseAdapterAutoDetected; - _fwUpdatePowerCorrection.ActualFwVersion = _currentGenesis.InstalledFwVersion; - _fwUpdatePowerCorrection.RequiredFwVersion = (UInt32?)_cordonelFirmwarePackage.FwPackageInfo.Version; - // preset meter power correction file - powCorrFile.PowerCorrectionData = _fwUpdatePowerCorrection; + _fwUpdatePowerCorrection.RequiredFwVersion = (UInt32?)_cordonelFirmwarePackage.FwPackageInfo.Version; // estimate the power correction values which includes the pulse adapter installation marker and // the readout of Cordonel registers to get the actual status @@ -1488,7 +1480,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw if (retVal) { // store results to "1\\powcorr" in the meter - powCorrFile.WritePowCorrMeterFile(); + powCorrFile.WritePowCorrMeterFile(_fwUpdatePowerCorrection); } } @@ -3714,7 +3706,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// /// - Added power correction on FW update to specific version. /// - private StatusReturn ExecConnect() + private StatusReturn ExecConnect() { // If the PCB ID is not set (read from meter) this is the first initial login. if (string.IsNullOrEmpty(_currentGenesis.PcbId)) @@ -3828,6 +3820,10 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw /// /// - Update app information on new connect. /// + /// + /// - Remind installed FW version on initial connect to _fwUpdatePowerCorrection as this will be lost + /// after FW update in _currentGenesis.InstalledFwVersion and set to the version after the update. + /// private Boolean LoginAndSpecialSetupProcedure(String password) { Boolean retVal; @@ -3876,6 +3872,16 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw // Set radio to customer mode (encryption active) if (_initialConnect && retVal) { + if (_fwUpdatePowerCorrection == null) + { + //do something + _fwUpdatePowerCorrection = new PowerCorrection(); + } + + // fill all currently known infos to power correction + _fwUpdatePowerCorrection.ActualPulseAdapterIsInstalled = _currentGenesis.PulseAdapterAutoDetected; + _fwUpdatePowerCorrection.ActualFwVersion = _currentGenesis.InstalledFwVersion; + if (_currentGenesis.RadioFrequencyMhz != null) { SetRadioToCustomerMode();