diff --git a/Common/Hardware/WaterMeter/Genesis/MockGenesis/MockGenesis.cs b/Common/Hardware/WaterMeter/Genesis/MockGenesis/MockGenesis.cs
index 1e8e30ff..5ac3a4b2 100644
--- a/Common/Hardware/WaterMeter/Genesis/MockGenesis/MockGenesis.cs
+++ b/Common/Hardware/WaterMeter/Genesis/MockGenesis/MockGenesis.cs
@@ -426,12 +426,16 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.MockGenesis
/// Mock reading all applications from a predefined package description file instead from the Meter.
///
///
- /// - Initial
+ /// - Initial.
+ ///
+ ///
+ /// - Avoid overwriting of list combined with valid register dictionary.
///
protected override void ReadMeterFirmwareAndAssignRegisters()
{
// Avoid overwriting of list if this already exits
- if (MeterAppListVersion.Any() && MeterAppListVersion.All(f => f.Status != MeterAppState.Unknown))
+ if (MeterAppListVersion.Any() && MeterAppListVersion.All(f => f.Status != MeterAppState.Unknown) &&
+ ConfigRegister.MeterRegisterDic.Count != 0)
{
Logger.Warn($"Slot:{Slot} - Trying to overwride installed FW. Skipping generation of new " +
"App list and meter register dictionary");
diff --git a/Common/Hardware/WaterMeter/Genesis/MockGenesis/MockRawParamsExamples/EMEA_DN50_RawParamsExample.json b/Common/Hardware/WaterMeter/Genesis/MockGenesis/MockRawParamsExamples/EMEA_DN50_RawParamsExample.json
index 9a652317..7c5d0140 100644
--- a/Common/Hardware/WaterMeter/Genesis/MockGenesis/MockRawParamsExamples/EMEA_DN50_RawParamsExample.json
+++ b/Common/Hardware/WaterMeter/Genesis/MockGenesis/MockRawParamsExamples/EMEA_DN50_RawParamsExample.json
@@ -1 +1,417 @@
-[{"RegisterName":"SENSUSRADIO_RadioAddress","RegisterValue":"GI6fMA==","Source":0},{"RegisterName":"SENSUSRADIO_EncryptionKey","RegisterValue":"Dp+sxqDh7xw7J6SbrCFlNQ==","Source":0},{"RegisterName":"GENESISFLOW_MeterSize","RegisterValue":"AAAAAQ==","Source":0},{"RegisterName":"GENESISFLOW_DisplayUnits","RegisterValue":"AAAAAA==","Source":0},{"RegisterName":"METROLOGYASST_FlowUnits","RegisterValue":"AAAABA==","Source":0},{"RegisterName":"SENSUSRADIO_FrequencyIndicator","RegisterValue":"AAABsQ==","Source":0},{"RegisterName":"METROLOGYASST_PulseMode","RegisterValue":"AAAABQ==","Source":0},{"RegisterName":"METROLOGYASST_PulseLength","RegisterValue":"AAAACA==","Source":0},{"RegisterName":"METROLOGYASST_PressurePresent","RegisterValue":"AAAAAA==","Source":0},{"RegisterName":"METROLOGYASST_TemperatureUnits","RegisterValue":"AAAAAA==","Source":0},{"RegisterName":"METROLOGYASST_PressureRate","RegisterValue":"AAAAAA==","Source":0},{"RegisterName":"METROLOGYASST_PressureUnits","RegisterValue":"AAAAAA==","Source":0},{"RegisterName":"METROLOGYASST_PulseWeight","RegisterValue":"ADDUAA==","Source":0},{"RegisterName":"SENSUSRADIO_MbusState","RegisterValue":"AAAABw==","Source":0},{"RegisterName":"SENSUSRADIO_OmTxInterval","RegisterValue":"AAAOEA==","Source":0},{"RegisterName":"SENSUSRADIO_TxInterval","RegisterValue":"AAAADw==","Source":0},{"RegisterName":"SENSUSRADIO_WakeupInterval","RegisterValue":"AAAAAw==","Source":0},{"RegisterName":"SENSUSRADIO_LatInterval","RegisterValue":"AAAAAw==","Source":0},{"RegisterName":"GENESISFLOW_DisplayPow10","RegisterValue":"/f///w==","Source":0},{"RegisterName":"METROLOGYASST_FlowPoint","RegisterValue":"AgAAAA==","Source":0},{"RegisterName":"CUSTOMER_AlarmEnableMask","RegisterValue":"AACAUw==","Source":1},{"RegisterName":"CUSTOMER_AlarmBroadcastMask","RegisterValue":"AAAf3A==","Source":1},{"RegisterName":"CUSTOMER_AlarmVisualMask","RegisterValue":"AAAf3A==","Source":1},{"RegisterName":"CUSTOMER_LeakTimeThreshold","RegisterValue":"AABOwA==","Source":1},{"RegisterName":"CUSTOMER_ExcessFlowTimeThreshold","RegisterValue":"AAAABQ==","Source":1},{"RegisterName":"CUSTOMER_ReverseFlowTimeThreshold","RegisterValue":"AAAHCA==","Source":1},{"RegisterName":"CUSTOMER_TemperatureHighThreshold","RegisterValue":"AAAB9A==","Source":1},{"RegisterName":"CUSTOMER_TemperatureHighDelay","RegisterValue":"AAABLA==","Source":1},{"RegisterName":"CUSTOMER_TemperatureLowThreshold","RegisterValue":"AAAAFA==","Source":1},{"RegisterName":"CUSTOMER_TemperatureLowDelay","RegisterValue":"AAABLA==","Source":1},{"RegisterName":"CUSTOMER_PressureHighThreshold","RegisterValue":"ABhqAA==","Source":1},{"RegisterName":"CUSTOMER_PressureHighDelay","RegisterValue":"AAABLA==","Source":1},{"RegisterName":"CUSTOMER_PressureLowThreshold","RegisterValue":"AAB1MA==","Source":1},{"RegisterName":"CUSTOMER_PressureLowDelay","RegisterValue":"AAABLA==","Source":1},{"RegisterName":"METROLOGYASST_TemperatureUnits","RegisterValue":"AAAAAA==","Source":1},{"RegisterName":"METROLOGYASST_PressureOffset","RegisterValue":"AAAAAA==","Source":1},{"RegisterName":"PERIODICLOG_DataLogContents","RegisterValue":"DAAkAw==","Source":1},{"RegisterName":"PERIODICLOG_DataLogPeriod","RegisterValue":"AAAAPA==","Source":1},{"RegisterName":"PERIODICLOG_AverageFlowPeriod","RegisterValue":"AAU=","Source":1},{"RegisterName":"SENSUSRADIO_AverageFlowPeriod","RegisterValue":"AAU=","Source":1},{"RegisterName":"PERIODICLOG_PeriodicLogLifeTimeCounter","RegisterValue":"AAAAAA==","Source":1},{"RegisterName":"SENSUSRADIO_MetroRadioLifeTimeCounter","RegisterValue":"AAAAAA==","Source":1},{"RegisterName":"PERIODICLOG_FixedDateReadingContents","RegisterValue":"DAAkAw==","Source":1},{"RegisterName":"PERIODICLOG_FixedDateDayOfMonth","RegisterValue":"AAAAAQ==","Source":1},{"RegisterName":"POWERMON_WarnFromClamp","RegisterValue":"JZgGAA==","Source":1},{"RegisterName":"SYSTEM_UpgradePermissions","RegisterValue":"AAAA/g==","Source":1},{"RegisterName":"POWERMON_BatteryQuantity","RegisterValue":"AAAAAg==","Source":1},{"RegisterName":"GENESISFLOW_SampleRate","RegisterValue":"AAI=","Source":1},{"RegisterName":"GENESISFLOW_LedMode","RegisterValue":"AAAAAA==","Source":1},{"RegisterName":"GENESISFLOW_HardErrorLimit","RegisterValue":"AAQ=","Source":1},{"RegisterName":"IRDA_PulseReportRate","RegisterValue":"AAAAAA==","Source":1},{"RegisterName":"IRDA_AdapterPresenceLimit","RegisterValue":"AAM=","Source":1},{"RegisterName":"SENSUSRADIO_OTAControlFlags","RegisterValue":"AAA=","Source":1},{"RegisterName":"CUSTOMER_RebootCount","RegisterValue":"AAAAAA==","Source":1},{"RegisterName":"GENESISFLOW_LowFlowMaxPeriod","RegisterValue":"ADwAAA==","Source":1},{"RegisterName":"GENESISFLOW_LowFlowThreshold","RegisterValue":"AAAAyA==","Source":1},{"RegisterName":"GENESISFLOW_MaxValidAmplitude","RegisterValue":"rwAAAA==","Source":1},{"RegisterName":"GENESISFLOW_MaxValidDeltaToF","RegisterValue":"AAPGXg==","Source":1},{"RegisterName":"GENESISFLOW_MaxValidToF","RegisterValue":"AXl8ww==","Source":1},{"RegisterName":"GENESISFLOW_MeterSize","RegisterValue":"AAAAAQ==","Source":1},{"RegisterName":"GENESISFLOW_MinValidAmplitude","RegisterValue":"JYAAAA==","Source":1},{"RegisterName":"GENESISFLOW_MinValidToF","RegisterValue":"ANG3Fw==","Source":1},{"RegisterName":"GENESISFLOW_Timeout","RegisterValue":"AAE=","Source":1},{"RegisterName":"CUSTOMER_LeakFlowThreshold","RegisterValue":"AAF3AA==","Source":1},{"RegisterName":"CUSTOMER_ExcessFlowVolumeThreshold","RegisterValue":"AMNQAA==","Source":1},{"RegisterName":"CUSTOMER_AppArrangement","RegisterValue":"AAE=","Source":1},{"RegisterName":"METROLOGYASST_PressureUnits","RegisterValue":"AAA=","Source":1},{"RegisterName":"CUSTOMER_Locale","RegisterValue":"AAAA0A==","Source":1},{"RegisterName":"GENESISFLOW_MaxValidAmplitude","RegisterValue":"rwAAAA==","Source":1},{"RegisterName":"SENSUSRADIO_HistoricalAlarmsDays","RegisterValue":"AAAAWg==","Source":1},{"RegisterName":"SENSUSRADIO_OmTxInterval","RegisterValue":"AAADhA==","Source":1},{"RegisterName":"GENESISFLOW_ForwardArrow","RegisterValue":"AAAAAQ==","Source":1},{"RegisterName":"SENSUSRADIO_EncryptionKey","RegisterValue":"8L/KE0jHXszHydwgWg0KHQ==","Source":1},{"RegisterName":"GENESISFLOW_ArrowThreshold","RegisterValue":"HoSA","Source":1},{"RegisterName":"GENESISFLOW_StartHit","RegisterValue":"AAAABg==","Source":1},{"RegisterName":"CUSTOMER_InstallationTime","RegisterValue":"AAAAAA==","Source":1},{"RegisterName":"METROLOGYASST_PressureRate","RegisterValue":"AADqYA==","Source":1},{"RegisterName":"GENESISFLOW_MaxDeltaToFDeviation","RegisterValue":"AAGtfw==","Source":1},{"RegisterName":"SENSUSRADIO_TemperatureMeasurePeriod","RegisterValue":"AAAAPA==","Source":1}]
\ No newline at end of file
+[
+ {
+ "RegisterName": "SENSUSRADIO_RadioAddress",
+ "RegisterValue": "GI6fMA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_EncryptionKey",
+ "RegisterValue": "Dp+sxqDh7xw7J6SbrCFlNQ==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_PowerLevel",
+ "RegisterValue": "AAAALQ==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_PowerLevelOption",
+ "RegisterValue": "AAAALw==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_ImpedanceCodeNew",
+ "RegisterValue": "AAALLQ==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_ImpedanceCodeOption",
+ "RegisterValue": "AAALLw==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "GENESISFLOW_MeterSize",
+ "RegisterValue": "AAAAAQ==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "GENESISFLOW_DisplayUnits",
+ "RegisterValue": "AAAAAA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "METROLOGYASST_FlowUnits",
+ "RegisterValue": "AAAABA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_FrequencyIndicator",
+ "RegisterValue": "AAABsQ==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "METROLOGYASST_PulseMode",
+ "RegisterValue": "AAAABQ==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "METROLOGYASST_PulseLength",
+ "RegisterValue": "AAAACA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "METROLOGYASST_PressurePresent",
+ "RegisterValue": "AAAAAA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "METROLOGYASST_TemperatureUnits",
+ "RegisterValue": "AAAAAA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "METROLOGYASST_PressureRate",
+ "RegisterValue": "AAAAAA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "METROLOGYASST_PressureUnits",
+ "RegisterValue": "AAAAAA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "METROLOGYASST_PulseWeight",
+ "RegisterValue": "ADDUAA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_MbusState",
+ "RegisterValue": "AAAABw==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_OmTxInterval",
+ "RegisterValue": "AAAOEA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_TxInterval",
+ "RegisterValue": "AAAADw==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_WakeupInterval",
+ "RegisterValue": "AAAAAw==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "SENSUSRADIO_LatInterval",
+ "RegisterValue": "AAAAAw==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "GENESISFLOW_DisplayPow10",
+ "RegisterValue": "/f///w==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "METROLOGYASST_FlowPoint",
+ "RegisterValue": "AgAAAA==",
+ "Source": 0
+ },
+ {
+ "RegisterName": "CUSTOMER_AlarmEnableMask",
+ "RegisterValue": "AACAUw==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_AlarmBroadcastMask",
+ "RegisterValue": "AAAf3A==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_AlarmVisualMask",
+ "RegisterValue": "AAAf3A==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_LeakTimeThreshold",
+ "RegisterValue": "AABOwA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_ExcessFlowTimeThreshold",
+ "RegisterValue": "AAAABQ==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_ReverseFlowTimeThreshold",
+ "RegisterValue": "AAAHCA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_TemperatureHighThreshold",
+ "RegisterValue": "AAAB9A==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_TemperatureHighDelay",
+ "RegisterValue": "AAABLA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_TemperatureLowThreshold",
+ "RegisterValue": "AAAAFA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_TemperatureLowDelay",
+ "RegisterValue": "AAABLA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_PressureHighThreshold",
+ "RegisterValue": "ABhqAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_PressureHighDelay",
+ "RegisterValue": "AAABLA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_PressureLowThreshold",
+ "RegisterValue": "AAB1MA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_PressureLowDelay",
+ "RegisterValue": "AAABLA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "METROLOGYASST_TemperatureUnits",
+ "RegisterValue": "AAAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "METROLOGYASST_PressureOffset",
+ "RegisterValue": "AAAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "PERIODICLOG_DataLogContents",
+ "RegisterValue": "DAAkAw==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "PERIODICLOG_DataLogPeriod",
+ "RegisterValue": "AAAAPA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "PERIODICLOG_AverageFlowPeriod",
+ "RegisterValue": "AAU=",
+ "Source": 1
+ },
+ {
+ "RegisterName": "SENSUSRADIO_AverageFlowPeriod",
+ "RegisterValue": "AAU=",
+ "Source": 1
+ },
+ {
+ "RegisterName": "PERIODICLOG_PeriodicLogLifeTimeCounter",
+ "RegisterValue": "AAAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "SENSUSRADIO_MetroRadioLifeTimeCounter",
+ "RegisterValue": "AAAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "PERIODICLOG_FixedDateReadingContents",
+ "RegisterValue": "DAAkAw==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "PERIODICLOG_FixedDateDayOfMonth",
+ "RegisterValue": "AAAAAQ==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "POWERMON_WarnFromClamp",
+ "RegisterValue": "JZgGAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "SYSTEM_UpgradePermissions",
+ "RegisterValue": "AAAA/g==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "POWERMON_BatteryQuantity",
+ "RegisterValue": "AAAAAg==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_SampleRate",
+ "RegisterValue": "AAI=",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_LedMode",
+ "RegisterValue": "AAAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_HardErrorLimit",
+ "RegisterValue": "AAQ=",
+ "Source": 1
+ },
+ {
+ "RegisterName": "IRDA_PulseReportRate",
+ "RegisterValue": "AAAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "IRDA_AdapterPresenceLimit",
+ "RegisterValue": "AAM=",
+ "Source": 1
+ },
+ {
+ "RegisterName": "SENSUSRADIO_OTAControlFlags",
+ "RegisterValue": "AAA=",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_RebootCount",
+ "RegisterValue": "AAAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_LowFlowMaxPeriod",
+ "RegisterValue": "ADwAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_LowFlowThreshold",
+ "RegisterValue": "AAAAyA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_MaxValidAmplitude",
+ "RegisterValue": "rwAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_MaxValidDeltaToF",
+ "RegisterValue": "AAPGXg==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_MaxValidToF",
+ "RegisterValue": "AXl8ww==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_MeterSize",
+ "RegisterValue": "AAAAAQ==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_MinValidAmplitude",
+ "RegisterValue": "JYAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_MinValidToF",
+ "RegisterValue": "ANG3Fw==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_Timeout",
+ "RegisterValue": "AAE=",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_LeakFlowThreshold",
+ "RegisterValue": "AAF3AA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_ExcessFlowVolumeThreshold",
+ "RegisterValue": "AMNQAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_AppArrangement",
+ "RegisterValue": "AAE=",
+ "Source": 1
+ },
+ {
+ "RegisterName": "METROLOGYASST_PressureUnits",
+ "RegisterValue": "AAA=",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_Locale",
+ "RegisterValue": "AAAA0A==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_MaxValidAmplitude",
+ "RegisterValue": "rwAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "SENSUSRADIO_HistoricalAlarmsDays",
+ "RegisterValue": "AAAAWg==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "SENSUSRADIO_OmTxInterval",
+ "RegisterValue": "AAADhA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_ForwardArrow",
+ "RegisterValue": "AAAAAQ==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "SENSUSRADIO_EncryptionKey",
+ "RegisterValue": "8L/KE0jHXszHydwgWg0KHQ==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_ArrowThreshold",
+ "RegisterValue": "HoSA",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_StartHit",
+ "RegisterValue": "AAAABg==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "CUSTOMER_InstallationTime",
+ "RegisterValue": "AAAAAA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "METROLOGYASST_PressureRate",
+ "RegisterValue": "AADqYA==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "GENESISFLOW_MaxDeltaToFDeviation",
+ "RegisterValue": "AAGtfw==",
+ "Source": 1
+ },
+ {
+ "RegisterName": "SENSUSRADIO_TemperatureMeasurePeriod",
+ "RegisterValue": "AAAAPA==",
+ "Source": 1
+ }
+]
\ No newline at end of file
diff --git a/Common/Production/ProductionUiCordonel.UnitTests/Features/ProductionProcessCheckProductionState.feature b/Common/Production/ProductionUiCordonel.UnitTests/Features/ProductionProcessCheckProductionState.feature
index 0a7bcdf7..f1fdd772 100644
--- a/Common/Production/ProductionUiCordonel.UnitTests/Features/ProductionProcessCheckProductionState.feature
+++ b/Common/Production/ProductionUiCordonel.UnitTests/Features/ProductionProcessCheckProductionState.feature
@@ -466,7 +466,11 @@ OUTPUT: "StatusReturn" with results "Okay" or "Failed",
# Activate the entire equality EOL progress check between requirement and result
And Activate EOL progress check
- # The input initializations don't have a "TestNo" nor a result (EOLStatus, StringReturn or StatusReturn) as those are commonly used for
+ # Name one production process to be checked in advance to the real test. This can be done more than once to fill a list with
+ # all required preceding production processes to check an entire sequence of processes.
+ And Define production process for sequencing before test 'ExecFinalParametrization'
+
+# The input initializations don't have a "TestNo" nor a result (EOLStatus, StringReturn or StatusReturn) as those are commonly used for
# all tests specified in "Input matrix defining the test cases and results". All these inputs have a setup to pass the overall test with
# positive feedback (all are good).
And Input initializations for the test matrix and presets to pass the preceding tests
@@ -530,20 +534,20 @@ OUTPUT: "StatusReturn" with results "Okay" or "Failed",
# "Kill x" forces the test to fail to check if all tests are executed. REMIND: Set only ONE to "X" and leave all others as "-"! Otherwise the test will FAIL!
| TestNo | Kill EOL | Kill Requ | Kill Order | Kill PcbId | Kill Region | Kill LUT | Kill Size | Kill FW | Kill Load | Kill LifeTime | Kill StoreTime | Kill PreAdj | Kill FlowTest | Kill Calib | StatusReturn | Comment |
| 1 | - | - | - | - | - | - | - | - | - | - | - | - | - | - | Okay | Test sequence complete |
- | 2 | X | - | - | - | - | - | - | - | - | - | - | - | - | - | Failed | Detected kill EOL generation |
- | 3 | - | X | - | - | - | - | - | - | - | - | - | - | - | - | Failed | Detected kill requirement |
- | 4 | - | - | X | - | - | - | - | - | - | - | - | - | - | - | Failed | Detected kill production order check |
- | 5 | - | - | - | X | - | - | - | - | - | - | - | - | - | - | Failed | Detected kill PcbId check |
- | 6 | - | - | - | - | X | - | - | - | - | - | - | - | - | - | Failed | Detected kill region check |
- | 7 | - | - | - | - | - | X | - | - | - | - | - | - | - | - | Failed | Detected kill LUT check |
- | 8 | - | - | - | - | - | - | X | - | - | - | - | - | - | - | Failed | Detected kill meter size check |
- | 9 | - | - | - | - | - | - | - | X | - | - | - | - | - | - | Failed | Detected kill FW check |
- | 10 | - | - | - | - | - | - | - | - | X | - | - | - | - | - | Failed | Detected kill battery load check |
- | 11 | - | - | - | - | - | - | - | - | - | X | - | - | - | - | Failed | Detected kill life time check |
- | 12 | - | - | - | - | - | - | - | - | - | - | X | - | - | - | Failed | Detected kill storage time check |
- | 13 | - | - | - | - | - | - | - | - | - | - | - | X | - | - | Failed | Detected kill preadjustment check |
- | 14 | - | - | - | - | - | - | - | - | - | - | - | - | X | - | Failed | Detected kill flow test check |
- | 15 | - | - | - | - | - | - | - | - | - | - | - | - | - | X | Failed | Detected kill calibrations check |
+# | 2 | X | - | - | - | - | - | - | - | - | - | - | - | - | - | Failed | Detected kill EOL generation |
+# | 3 | - | X | - | - | - | - | - | - | - | - | - | - | - | - | Failed | Detected kill requirement |
+# | 4 | - | - | X | - | - | - | - | - | - | - | - | - | - | - | Failed | Detected kill production order check |
+# | 5 | - | - | - | X | - | - | - | - | - | - | - | - | - | - | Failed | Detected kill PcbId check |
+# | 6 | - | - | - | - | X | - | - | - | - | - | - | - | - | - | Failed | Detected kill region check |
+# | 7 | - | - | - | - | - | X | - | - | - | - | - | - | - | - | Failed | Detected kill LUT check |
+# | 8 | - | - | - | - | - | - | X | - | - | - | - | - | - | - | Failed | Detected kill meter size check |
+# | 9 | - | - | - | - | - | - | - | X | - | - | - | - | - | - | Failed | Detected kill FW check |
+# | 10 | - | - | - | - | - | - | - | - | X | - | - | - | - | - | Failed | Detected kill battery load check |
+# | 11 | - | - | - | - | - | - | - | - | - | X | - | - | - | - | Failed | Detected kill life time check |
+# | 12 | - | - | - | - | - | - | - | - | - | - | X | - | - | - | Failed | Detected kill storage time check |
+# | 13 | - | - | - | - | - | - | - | - | - | - | - | X | - | - | Failed | Detected kill preadjustment check |
+# | 14 | - | - | - | - | - | - | - | - | - | - | - | - | X | - | Failed | Detected kill flow test check |
+# | 15 | - | - | - | - | - | - | - | - | - | - | - | - | - | X | Failed | Detected kill calibrations check |
When Execute the generic tests
Then Check the generic test results
diff --git a/Common/Production/ProductionUiCordonel.UnitTests/Features/ProductionProcessCheckProductionState.feature.cs b/Common/Production/ProductionUiCordonel.UnitTests/Features/ProductionProcessCheckProductionState.feature.cs
index 1c996a06..1120f140 100644
--- a/Common/Production/ProductionUiCordonel.UnitTests/Features/ProductionProcessCheckProductionState.feature.cs
+++ b/Common/Production/ProductionUiCordonel.UnitTests/Features/ProductionProcessCheckProductionState.feature.cs
@@ -1877,6 +1877,9 @@ this.ScenarioInitialize(scenarioInfo);
#line hidden
#line 467
testRunner.And("Activate EOL progress check", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
+#line hidden
+#line 471
+ testRunner.And("Define production process for sequencing before test \'ExecFinalParametrization\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table16 = new TechTalk.SpecFlow.Table(new string[] {
"EOL Id",
@@ -1890,7 +1893,7 @@ this.ScenarioInitialize(scenarioInfo);
"182100041",
"182100041",
"EOL Progress successfully created"});
-#line 472
+#line 476
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table16, "And ");
#line hidden
@@ -1910,7 +1913,7 @@ this.ScenarioInitialize(scenarioInfo);
"null",
"null",
"Standard Requirement is active and approved"});
-#line 476
+#line 480
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table17, "And ");
#line hidden
@@ -1922,7 +1925,7 @@ this.ScenarioInitialize(scenarioInfo);
"3118323",
"3118323",
"Order number is identical"});
-#line 480
+#line 484
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table18, "And ");
#line hidden
@@ -1936,7 +1939,7 @@ this.ScenarioInitialize(scenarioInfo);
"182100041",
"182100041",
"PcbId is identical"});
-#line 484
+#line 488
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table19, "And ");
#line hidden
@@ -1948,7 +1951,7 @@ this.ScenarioInitialize(scenarioInfo);
"EMEA",
"EMEA",
"Region is identical"});
-#line 488
+#line 492
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table20, "And ");
#line hidden
@@ -1960,7 +1963,7 @@ this.ScenarioInitialize(scenarioInfo);
"0xEB7C",
"0xEB7C",
"LUT CRC is identical"});
-#line 492
+#line 496
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table21, "And ");
#line hidden
@@ -1972,7 +1975,7 @@ this.ScenarioInitialize(scenarioInfo);
"DN50",
"DN50",
"Meter size is identical"});
-#line 496
+#line 500
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table22, "And ");
#line hidden
@@ -1986,7 +1989,7 @@ this.ScenarioInitialize(scenarioInfo);
"R1.3.0B",
"R1.3.0B",
"FW Version is identical"});
-#line 500
+#line 504
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table23, "And ");
#line hidden
@@ -1996,7 +1999,7 @@ this.ScenarioInitialize(scenarioInfo);
table24.AddRow(new string[] {
"2.0",
"Normal threshold okay"});
-#line 504
+#line 508
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table24, "And ");
#line hidden
@@ -2010,7 +2013,7 @@ this.ScenarioInitialize(scenarioInfo);
"20.0",
"1.0",
"Remaining lifetime as required"});
-#line 508
+#line 512
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table25, "And ");
#line hidden
@@ -2022,7 +2025,7 @@ this.ScenarioInitialize(scenarioInfo);
"-3.0",
"3.0",
"Storage months in range"});
-#line 512
+#line 516
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table26, "And ");
#line hidden
@@ -2034,7 +2037,7 @@ this.ScenarioInitialize(scenarioInfo);
"5",
"21",
"Test bench preadjustment succeeded"});
-#line 516
+#line 520
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table27, "And ");
#line hidden
@@ -2046,7 +2049,7 @@ this.ScenarioInitialize(scenarioInfo);
"6",
"30",
"Test bench calibration succeeded"});
-#line 520
+#line 524
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table28, "And ");
#line hidden
@@ -2066,7 +2069,7 @@ this.ScenarioInitialize(scenarioInfo);
"20000",
"30000",
"Valid calib factors"});
-#line 524
+#line 528
testRunner.And("Input initializations for the test matrix and presets to pass the preceding tests" +
"", ((string)(null)), table29, "And ");
#line hidden
@@ -2106,265 +2109,13 @@ this.ScenarioInitialize(scenarioInfo);
"-",
"Okay",
"Test sequence complete"});
- table30.AddRow(new string[] {
- "2",
- "X",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill EOL generation"});
- table30.AddRow(new string[] {
- "3",
- "-",
- "X",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill requirement"});
- table30.AddRow(new string[] {
- "4",
- "-",
- "-",
- "X",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill production order check"});
- table30.AddRow(new string[] {
- "5",
- "-",
- "-",
- "-",
- "X",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill PcbId check"});
- table30.AddRow(new string[] {
- "6",
- "-",
- "-",
- "-",
- "-",
- "X",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill region check"});
- table30.AddRow(new string[] {
- "7",
- "-",
- "-",
- "-",
- "-",
- "-",
- "X",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill LUT check"});
- table30.AddRow(new string[] {
- "8",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "X",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill meter size check"});
- table30.AddRow(new string[] {
- "9",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "X",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill FW check"});
- table30.AddRow(new string[] {
- "10",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "X",
- "-",
- "-",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill battery load check"});
- table30.AddRow(new string[] {
- "11",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "X",
- "-",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill life time check"});
- table30.AddRow(new string[] {
- "12",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "X",
- "-",
- "-",
- "-",
- "Failed",
- "Detected kill storage time check"});
- table30.AddRow(new string[] {
- "13",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "X",
- "-",
- "-",
- "Failed",
- "Detected kill preadjustment check"});
- table30.AddRow(new string[] {
- "14",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "X",
- "-",
- "Failed",
- "Detected kill flow test check"});
- table30.AddRow(new string[] {
- "15",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "-",
- "X",
- "Failed",
- "Detected kill calibrations check"});
-#line 529
+#line 533
testRunner.And("Input matrix defining the test cases and results", ((string)(null)), table30, "And ");
#line hidden
-#line 547
+#line 551
testRunner.When("Execute the generic tests", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line hidden
-#line 548
+#line 552
testRunner.Then("Check the generic test results", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line hidden
}
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckProductionState.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckProductionState.cs
index 3f203e66..b820c57c 100644
--- a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckProductionState.cs
+++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckProductionState.cs
@@ -10,7 +10,6 @@ using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
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.OrderData;
using Xylem.Common.Logic.ProductionOrderCore.TestResults;
using Xylem.Common.Production.ProductionUiCordonel.Model;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
@@ -140,7 +139,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
ActualProcessProgress++;
- // Get the real content of the FW package including all binaries of each app and the application description file
+ // Get the real content of the FW package including all binaries of each app and the application
+ // description file
FwUpdatePackage = new List();
if (!MeterFwUpdate.GetFwPackageFromDb((Int32)parentFileId, FwUpdatePackage, out error) ||
FwUpdatePackage == null)
@@ -284,7 +284,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
/// - Region,
/// - FW,
/// - LUT CRC,
- /// - Meter size
+ /// - Meter size,
+ /// - Kitron radio parameter,
/// - Drained battery load versus required remaining battery load in percent,
/// - Remaining run time in years,
/// - Preadjustment is completed including correct values in registers,
@@ -298,12 +299,13 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
/// - Adapted to new production process.
///
///
- /// - Removed signals for and as
- /// these will be automatically set based on return value in
+ /// - Removed signals for and
+ /// as these will be automatically set based on return value in
/// .
///
///
- /// - Take cordonel requirements from DB as base for checks of drained battery load and eventually special requirements.
+ /// - Take cordonel requirements from DB as base for checks of drained battery load and eventually special
+ /// requirements.
///
///
/// - Get EOL progress model from DB,
@@ -326,8 +328,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
/// - Changed from "StatusReturn" to "EOLStatus".
///
///
- /// - Collect all requirement statuses before signalizing failed to summarize results starting with battery
- /// load.
+ /// - Collect all requirement statuses before signalizing failed to summarize results starting with
+ /// battery load.
///
///
/// - Check radio signal levels in parameter list.
@@ -421,22 +423,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
ActualProcessProgress++;
#endregion
- #region ----------------------------------- Check Kitron Radio Signal Levels ------------------------------
-
- var statusReturn = CheckKitronRadioSignalLevels(out feedbackMsg);
- if (StatusReturn.Failed == statusReturn)
- {
- ErrorMsgDispatcher(feedbackMsg);
- return StatusReturn.Failed;
- }
- if (StatusReturn.Okay == statusReturn)
- {
- SuccessMsgDispatcher(feedbackMsg);
- }
-
- ActualProcessProgress++;
- #endregion
-
#region ----------------------------------- Check Firmware and Apps ---------------------------------------
if (string.IsNullOrEmpty(CheckFwAndApps(out feedbackMsg)))
@@ -449,9 +435,34 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
ActualProcessProgress++;
#endregion
- #region ----------------------------------- Check Remaining Battery Load ----------------------------------
+ #region ----------------------------------- Check Kitron Radio Signal Levels ------------------------------
var erroneousSequenceStep = false;
+ var warningSequenceStep = false;
+ var statusReturn = CheckKitronRadioSignalLevels(out feedbackMsg);
+
+ if (StatusReturn.Failed == statusReturn)
+ {
+ ErrorMsgDispatcher(feedbackMsg);
+ //return StatusReturn.Failed;
+ // Do not return immediately to avoid multiple special-requirements on multiple errors
+ erroneousSequenceStep = true;
+ }
+ if (StatusReturn.Warning == statusReturn)
+ {
+ WarningMsgDispatcher(feedbackMsg);
+ warningSequenceStep = true;
+ }
+ if (StatusReturn.Okay == statusReturn)
+ {
+ SuccessMsgDispatcher(feedbackMsg);
+ }
+
+ ActualProcessProgress++;
+ #endregion
+
+ #region ----------------------------------- Check Remaining Battery Load ----------------------------------
+
if (EOLStatus.FAIL == CheckRemainingBatteryLoad(out feedbackMsg))
{
ErrorMsgDispatcher(feedbackMsg);
@@ -459,7 +470,10 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Do not return immediately to avoid multiple special-requirements on multiple errors
erroneousSequenceStep = true;
}
- SuccessMsgDispatcher(feedbackMsg);
+ else
+ {
+ SuccessMsgDispatcher(feedbackMsg);
+ }
ActualProcessProgress++;
#endregion
@@ -473,7 +487,10 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Do not return immediately to avoid multiple special-requirements on multiple errors
erroneousSequenceStep = true;
}
- SuccessMsgDispatcher(feedbackMsg);
+ else
+ {
+ SuccessMsgDispatcher(feedbackMsg);
+ }
ActualProcessProgress++;
#endregion
@@ -487,14 +504,16 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Do not return immediately to avoid multiple special-requirements on multiple errors
erroneousSequenceStep = true;
}
- SuccessMsgDispatcher(feedbackMsg);
+ else
+ {
+ SuccessMsgDispatcher(feedbackMsg);
+ }
ActualProcessProgress++;
#endregion
#region ----------------------------------- Check Preadjusment --------------------------------------------
- var warningSequenceStep = false;
eolStatus = CheckPreadjustment(out feedbackMsg);
if (EOLStatus.FAIL == eolStatus)
{
@@ -503,12 +522,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Do not return immediately to avoid multiple special-requirements on multiple errors
erroneousSequenceStep = true;
}
- if (EOLStatus.NA == eolStatus)
+ else if (EOLStatus.NA == eolStatus)
{
WarningMsgDispatcher(feedbackMsg);
warningSequenceStep = true;
}
- SuccessMsgDispatcher(feedbackMsg);
+ else
+ {
+ SuccessMsgDispatcher(feedbackMsg);
+ }
ActualProcessProgress++;
#endregion
@@ -523,12 +545,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
// Do not return immediately to avoid multiple special-requirements on multiple errors
erroneousSequenceStep = true;
}
- if (EOLStatus.NA == eolStatus)
+ else if (EOLStatus.NA == eolStatus)
{
WarningMsgDispatcher(feedbackMsg);
warningSequenceStep = true;
}
- SuccessMsgDispatcher(feedbackMsg);
+ else
+ {
+ SuccessMsgDispatcher(feedbackMsg);
+ }
ActualProcessProgress++;
#endregion
@@ -546,20 +571,24 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
warningSequenceStep = true;
//return StatusReturn.Skipped;
}
- if (StatusReturn.Failed == statusReturn)
+ else if (StatusReturn.Failed == statusReturn)
{
ErrorMsgDispatcher(feedbackMsg);
//return StatusReturn.Failed;
// Do not return immediately to avoid multiple special-requirements on multiple errors
erroneousSequenceStep = true;
}
- if (StatusReturn.Warning == statusReturn)
+ else if (StatusReturn.Warning == statusReturn)
{
WarningMsgDispatcher(feedbackMsg);
//return StatusReturn.Failed;//TODO THW return warning?
erroneousSequenceStep = true;
}
- #endregion -------------------------------- Check Calibration Values --------------------------------------
+ else
+ {
+ SuccessMsgDispatcher(feedbackMsg);
+ }
+ #endregion
#region ----------------------------------- Summarize Check Results ---------------------------------------
@@ -647,6 +676,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - New IsSpecialApproved and IsStandardApproved.
///
+ ///
+ /// - Modified for generic checks.
+ ///
private EOLStatus CheckRequirements(out String feedbackMsg)
{
feedbackMsg = "";
@@ -658,26 +690,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
return EOLStatus.FAIL;
}
- // Check if requirement is active (free for production) and approved by a second person. Priority special
- // requirement.
- var isSpecialActive = false;
- var isStandardActive = false;
- if (ProductionRequirements.IsSpecialActive != null && (Boolean)ProductionRequirements.IsSpecialActive &&
- ProductionRequirements.IsSpecialApproved != null && (Boolean)ProductionRequirements.IsSpecialApproved)
- isSpecialActive = true;
- if (ProductionRequirements.IsStandardActive != null && (Boolean)ProductionRequirements.IsStandardActive &&
- ProductionRequirements.IsStandardApproved != null && (Boolean)ProductionRequirements.IsStandardApproved)
- isStandardActive = true;
-
- // At least one requirement needs to be active and a requirement number and version has to be set
- if ((!isStandardActive && !isSpecialActive) ||
- // The standard Id and version have always to be set even if the special is active
- ProductionRequirements.StandardId == null || ProductionRequirements.StandardVersion == null ||
- // If the special is active the version and Id have to be defined
- (isSpecialActive && (ProductionRequirements.SpecialId == null ||
- ProductionRequirements.SpecialVersion == null)))
+ var statusReturn = GenericChecks.CheckRequirements(ProductionRequirements, out feedbackMsg);
+ if (StatusReturn.Failed == statusReturn)
{
- feedbackMsg = Resources.StrErrorMsgRequirementInactive;
EolProgress.RequirementRequestChecked = EOLStatus.FAIL;
}
else
@@ -689,14 +704,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
EolProgress.SpecialRequirementId = ProductionRequirements.SpecialId;
EolProgress.SpecialRequirementVersion = ProductionRequirements.SpecialVersion;
- feedbackMsg = isSpecialActive &&
- ProductionRequirements.SpecialId != null &&
- ProductionRequirements.SpecialVersion != null ?
- Resources.StrWarningMsgSpecialRequirementActive +
- $" Id.Ver: {ProductionRequirements.SpecialId}.{ProductionRequirements.SpecialVersion}" :
- Resources.StrSuccessMsgRequirementActive +
- $" Id.Ver {ProductionRequirements.StandardId}.{ProductionRequirements.StandardVersion}";
-
EolProgress.RequirementRequestChecked = EOLStatus.OK;
}
@@ -715,23 +722,22 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - Extracted from for better testability.
///
+ ///
+ /// - Modified for generic checks.
+ ///
private EOLStatus CheckProductionOrderNumber(out String feedbackMsg)
{
feedbackMsg = "";
- if (Meter == null ||
- ProductionRequirements == null ||
- EolProgress == null ||
- ProductionRequirements.ProductionOrderNr != Meter.OrderNumber)
+ if (EolProgress == null ||
+ StatusReturn.Failed == GenericChecks.CheckProductionOrderNumber(Meter, ProductionRequirements,
+ out feedbackMsg))
{
if (EolProgress != null)
EolProgress.RequirementOrderChecked = EOLStatus.FAIL;
- feedbackMsg = Resources.StrErrorMsgRequirementProductionOrder;
return EOLStatus.FAIL;
}
EolProgress.RequirementOrderChecked = EOLStatus.OK;
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementProductionOrder} - " +
- $"{Resources.StrLblOrderNumberTxt}: {Meter.OrderNumber}";
return EolProgress.RequirementOrderChecked;
}
@@ -749,38 +755,32 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - Extracted from for better testability.
///
+ ///
+ /// - Modified for generic checks.
+ ///
private EOLStatus CheckPcbId(out String feedbackMsg)
{
feedbackMsg = "";
- if (Meter == null ||
- ProductionRequirements == null ||
- EolProgress == null ||
- Meter.PcbId == null ||
- Meter.PcbId.Length < GenesisMeter.MinPcbIdLength)
+ if (EolProgress == null ||
+ StatusReturn.Failed == GenericChecks.CheckPcbId(Meter, ProductionRequirements, out feedbackMsg))
{
if (EolProgress != null)
EolProgress.RequirementPcbIdChecked = EOLStatus.FAIL;
- feedbackMsg = Resources.StrErrorMsgRequirementPcbId;
return EOLStatus.FAIL;
}
if (ProductionRequirements.PcbId == null)
{
EolProgress.RequirementPcbIdChecked = EOLStatus.NA;
- feedbackMsg = Resources.StrSuccessMsgOrderBasedRequirements;
return EolProgress.RequirementPcbIdChecked;
}
- if (Meter.PcbId.Equals(EolProgress.PcbId.ToString()) &&
- Meter.PcbId.Equals(ProductionRequirements.PcbId.ToString()))
+ if (Meter.PcbId.Equals(EolProgress.PcbId.ToString()))
{
EolProgress.RequirementPcbIdChecked = EOLStatus.OK;
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementPcbId} - PcbId: {Meter.PcbId}";
return EolProgress.RequirementPcbIdChecked;
}
EolProgress.RequirementPcbIdChecked = EOLStatus.FAIL;
- feedbackMsg = Resources.StrErrorMsgRequirementPcbId;
-
return EolProgress.RequirementPcbIdChecked;
}
@@ -796,23 +796,21 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - Extracted from for better testability.
///
+ ///
+ /// - Modified for generic checks.
+ ///
private EOLStatus CheckRegion(out String feedbackMsg)
{
feedbackMsg = "";
if (EolProgress == null ||
- ProductionRequirements == null ||
- string.IsNullOrEmpty(ProductionRequirements.Region) ||
- string.IsNullOrEmpty(Meter.Region) ||
- !Meter.Region.Equals(ProductionRequirements.Region))
+ StatusReturn.Failed == GenericChecks.CheckRegion(Meter, ProductionRequirements, out feedbackMsg))
{
if (EolProgress != null)
EolProgress.RequirementRegionChecked = EOLStatus.FAIL;
- feedbackMsg = Resources.StrErrorMsgRequirementRegion;
return EOLStatus.FAIL;
}
EolProgress.RequirementRegionChecked = EOLStatus.OK;
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementRegion} - Region: {Meter.Region}";
return EolProgress.RequirementRegionChecked;
}
@@ -831,25 +829,21 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - Set result to null on error.
///
+ ///
+ /// - Modified for generic checks.
+ ///
private String CheckLutCrc(out String feedbackMsg)
{
feedbackMsg = "";
if (EolProgress == null ||
- Meter == null ||
- ProductionRequirements == null ||
- string.IsNullOrEmpty(ProductionRequirements.LutCrc) ||
- string.IsNullOrEmpty(Meter.LutCrc) ||
- !Meter.LutCrc.Equals(ProductionRequirements.LutCrc))
+ string.IsNullOrEmpty(GenericChecks.CheckLutCrc(Meter, ProductionRequirements, out feedbackMsg)))
{
- feedbackMsg = Resources.StrErrorMsgRequirementLut;
if (EolProgress != null)
EolProgress.ProductionStatusLutCrc = null;
return "";
}
EolProgress.ProductionStatusLutCrc = Meter.LutCrc;
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementLut} - LUT CRC: {Meter.LutCrc}";
-
return EolProgress.ProductionStatusLutCrc;
}
@@ -865,26 +859,21 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - Extracted from for better testability.
///
+ ///
+ /// - Modified for generic checks.
+ ///
private String CheckMeterSize(out String feedbackMsg)
{
feedbackMsg = "";
if (EolProgress == null ||
- Meter == null ||
- ProductionRequirements == null || string.IsNullOrEmpty(ProductionRequirements.MeterSize) ||
- string.IsNullOrEmpty(Meter.MeterSize) ||
- MeterSizeConverter.ConvertMeterSizeNameToEnum(Meter.MeterSize) !=
- MeterSizeConverter.ConvertMeterSizeNameToEnum(ProductionRequirements.MeterSize))
+ string.IsNullOrEmpty(GenericChecks.CheckMeterSize(Meter, ProductionRequirements, out feedbackMsg)))
{
if (EolProgress != null)
EolProgress.ProductionStatusMeterSize = null;
- feedbackMsg = Resources.StrErrorMsgRequirementMeterSize;
return "";
}
EolProgress.ProductionStatusMeterSize = ProductionRequirements.MeterSize;
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementMeterSize} - " +
- $"{Resources.StrLblMeterSizeTxt}: {Meter.MeterSize}";
-
return EolProgress.ProductionStatusMeterSize;
}
@@ -968,90 +957,27 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - Absolut maximal threshold even if alternative power consumption calculation.
///
+ ///
+ /// - Modified for generic checks.
+ ///
private EOLStatus CheckRemainingBatteryLoad(out String feedbackMsg)
{
+ feedbackMsg = "";
if (EolProgress == null ||
- Meter == null ||
- ProductionRequirements?.MaxDrainedBatteryLoadPercentShipping == null ||
- ProductionStatus == null)
+ StatusReturn.Failed == GenericChecks.CheckRemainingBatteryLoad(Meter, ProductionRequirements,
+ ProductionStatus, out feedbackMsg))
{
if (EolProgress != null)
+ {
+ EolProgress.ProductionStatusDrainedBatteryLoad = ProductionStatus.DrainedBatteryLoadPercent;
EolProgress.ProductionStatusBatteryLoadChecked = EOLStatus.FAIL;
- feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
+ }
return EOLStatus.FAIL;
}
- // If the values for calculation of drained battery load and exceeded lifetime are not accessible
- if (ProductionStatus.DrainedBatteryLoad_uAs == 0 || ProductionStatus.ExceededLifeTime_s == 0)
- {
- EolProgress.ProductionStatusBatteryLoadChecked = EOLStatus.FAIL;
- feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
- return EolProgress.ProductionStatusBatteryLoadChecked;
- }
-
- // Set up the alternative calculation values needed for given current and supplement for production.
- // These values will be set by the requirement and have a higher priority than the standard calculation
- // based on the drained battery load and the estimated prediction based on this and the time of operation.
- if (ProductionRequirements.QuiescentCurrent_uA > GenesisMeter.QuiescentCurrent_uA &&
- ProductionRequirements.EstimatedProductionBatteryLoadPercent > 0)
- {
- ProductionStatus.QuiescentCurrent_uA = ProductionRequirements.QuiescentCurrent_uA;
- ProductionStatus.EstimatedProductionBatteryLoadPercent =
- ProductionRequirements.EstimatedProductionBatteryLoadPercent;
- }
-
- // Calculate the power consumption
- if (!GenesisStatusHandler.CalculateLifeTime(ProductionStatus))
- {
- EolProgress.ProductionStatusBatteryLoadChecked = EOLStatus.FAIL;
- feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
- return EolProgress.ProductionStatusBatteryLoadChecked;
- }
-
- // Check battery load in percent and compare with requirements for limits for drained battery load
- // For the alternative calculation based quiescent current and production supplement this will be used.
- // Build message for required versus calculated lifetime
- var threshold = ProductionStatus.AlternativeRequiredBatteryLoadPercent ??
- ProductionRequirements.MaxDrainedBatteryLoadPercentShipping;
-
- // Create an output message addon for alternative power consumption calculation
- var strAlternativeCalc = ProductionStatus.AlternativeRequiredBatteryLoadPercent == null
- ? ""
- : $" - {Resources.StrMsgRequirementAbsolutLimitDrainedBattery}: " +
- $"{ProductionRequirements.MaxDrainedBatteryLoadPercentShipping:F2} %" +
- $" ({Resources.StrMsgAlternativeDrainedBatteryCalculation})";
-
- var batteryLoad = $"{Resources.StrMsgDrainedBattery}: " +
- // Actual calculated battery load based on readings from meter
- $"{ProductionStatus.DrainedBatteryLoadPercent:F2} %" +
- $" - {Resources.StrMsgRequirementLimitDrainedBattery}: " +
- // Required battery load from standard or special requirement
- $"{threshold:F2} % {strAlternativeCalc}";
-
EolProgress.ProductionStatusDrainedBatteryLoad = ProductionStatus.DrainedBatteryLoadPercent;
-
- // This is the absolut limit even if the "AlternativeRequiredBatteryLoadPercent" will be used
- if (ProductionStatus.DrainedBatteryLoadPercent >
- ProductionRequirements.MaxDrainedBatteryLoadPercentShipping)
- {
- EolProgress.ProductionStatusBatteryLoadChecked = EOLStatus.FAIL;
- feedbackMsg = $"{Resources.StrErrorMsg}: {batteryLoad}";
- return EolProgress.ProductionStatusBatteryLoadChecked;
- }
-
- // This is the limit given by the "AlternativeRequiredBatteryLoadPercent"
- if (ProductionStatus.AlternativeRequiredBatteryLoadPercent != null &&
- ProductionStatus.DrainedBatteryLoadPercent > ProductionStatus.AlternativeRequiredBatteryLoadPercent)
- {
- EolProgress.ProductionStatusBatteryLoadChecked = EOLStatus.FAIL;
- feedbackMsg = $"{Resources.StrErrorMsg}: {batteryLoad}";
- return EolProgress.ProductionStatusBatteryLoadChecked;
- }
-
EolProgress.ProductionStatusBatteryLoadChecked = EOLStatus.OK;
- feedbackMsg = $"{Resources.StrSuccessMsg}: {batteryLoad}";
-
- return EolProgress.ProductionStatusBatteryLoadChecked;
+ return EOLStatus.OK;
}
///
@@ -1069,53 +995,27 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - Check required lifetime for unequal to 0.
///
+ ///
+ /// - Modified for generic checks.
+ ///
private EOLStatus CheckRemainingLifetime(out String feedbackMsg)
{
+ feedbackMsg = "";
if (EolProgress == null ||
- Meter == null ||
- ProductionRequirements?.RequiredLifeTimeYearsShipping == null ||
- ProductionRequirements.RequiredLifeTimeYearsShipping <= 0 ||
- ProductionStatus == null)
+ StatusReturn.Failed == GenericChecks.CheckRemainingLifetime(Meter, ProductionRequirements,
+ ProductionStatus, out feedbackMsg))
{
if (EolProgress != null)
+ {
+ EolProgress.ProductionStatusRemainingLifeTime = ProductionStatus.RemainingLifeTimeYears;
EolProgress.ProductionStatusRemainingLifeTimeChecked = EOLStatus.FAIL;
- feedbackMsg = Resources.StrErrorMsgLifeTimeCalculation;
+ }
return EOLStatus.FAIL;
}
- // Calculate the power consumption
- if (!GenesisStatusHandler.CalculateLifeTime(ProductionStatus))
- {
- EolProgress.ProductionStatusRemainingLifeTimeChecked = EOLStatus.FAIL;
- feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
- return EolProgress.ProductionStatusBatteryLoadChecked;
- }
-
- // Build message for required versus calculated lifetime
- var lifeTime = $"{Resources.StrMsgRemainingLifeTime}: " +
- // Actual calculated lifetime based on readings from meter
- $"{ProductionStatus.RemainingLifeTimeYears:F2} " +
- $"{Resources.StrMsgYears}" +
- $" - {Resources.StrMsgRequiredLifeTime}: " +
- // Required lifetime from special or standard requirement
- $"{ProductionRequirements.RequiredLifeTimeYearsShipping:F2} " +
- $"{Resources.StrMsgYears}";
-
EolProgress.ProductionStatusRemainingLifeTime = ProductionStatus.RemainingLifeTimeYears;
-
- // Check required years for shipping
- if (ProductionRequirements.RequiredLifeTimeYearsShipping > ProductionStatus.RemainingLifeTimeYears)
- {
- EolProgress.ProductionStatusRemainingLifeTimeChecked = EOLStatus.FAIL;
- feedbackMsg = $"{Resources.StrErrorMsg}: {lifeTime}";
- }
- else
- {
- feedbackMsg = $"{Resources.StrSuccessMsg}: {lifeTime}";
- EolProgress.ProductionStatusRemainingLifeTimeChecked = EOLStatus.OK;
- }
-
- return EolProgress.ProductionStatusRemainingLifeTimeChecked;
+ EolProgress.ProductionStatusRemainingLifeTimeChecked = EOLStatus.OK;
+ return EOLStatus.OK;
}
///
@@ -1136,56 +1036,28 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
///
/// - Changed from "StatusReturn" to "EOLStatus".
///
+ ///
+ /// - Modified for generic checks.
+ ///
private EOLStatus CheckStorageMonths(out String feedbackMsg)
{
- // Based on first attached battery and the POWEMON_TotalUsedSeconds (Kitron production date) and actual date
+ feedbackMsg = "";
if (EolProgress == null ||
- Meter == null ||
- ProductionRequirements?.MaxStorageMonths == null ||
- ProductionRequirements.MaxStorageMonths < 0.0 ||
- ProductionStatus == null ||
- ProductionStatus.DrainedBatteryLoad_uAs == 0 ||
- ProductionStatus.ExceededLifeTime_s == 0)
+ StatusReturn.Failed == GenericChecks.CheckStorageMonths(Meter, ProductionRequirements,
+ ProductionStatus, out feedbackMsg))
{
if (EolProgress != null)
+ {
EolProgress.MaxStorageMonthsChecked = EOLStatus.FAIL;
- // Storage months requirement or Kitron production date unknown
- feedbackMsg = Resources.StrErrorMsgRequirementMaximumStorageMonthUnknown;
+ EolProgress.MaxStorageMonths = ProductionRequirements.MaxStorageMonths;
+ }
+
return EOLStatus.FAIL;
}
- // Calculate the power consumption
- if (!GenesisStatusHandler.CalculateLifeTime(ProductionStatus) || ProductionStatus.BatteryAssemblyDateTimeUtc == null)
- {
- EolProgress.MaxStorageMonthsChecked = EOLStatus.FAIL;
- feedbackMsg = Resources.StrErrorMsgRequirementMaximumStorageMonthUnknown;
- return EOLStatus.FAIL;
- }
-
- var actualDate = DateTime.UtcNow.Date;
- var batteryAssemblyDate = ProductionStatus.BatteryAssemblyDateTimeUtc.Value.Date;
- // Give one day more as rounding issue
- var expirationDate = batteryAssemblyDate.AddDays((Double)ProductionRequirements.MaxStorageMonths * GenesisStatusHandler.DAYS_PER_MONTH + 1.0);
- var strStorageProduction = $"{Resources.StrLblKitronProductionDate}: " +
- $"{ProductionStatus.BatteryAssemblyDateTimeUtc.Value:dd-MMM-yyyy} - " +
- $"{Resources.StrLblExpirationDate}: {expirationDate:dd-MMM-yyyy} - " +
- $"{Resources.StrLblMaxStorageMonths}: " +
- $"{(Int32)ProductionRequirements.MaxStorageMonths} {Resources.StrLblMonths}";
-
+ EolProgress.MaxStorageMonthsChecked = EOLStatus.OK;
EolProgress.MaxStorageMonths = ProductionRequirements.MaxStorageMonths;
- if (actualDate >= expirationDate)
- {
- // Storage months exceeded
- feedbackMsg = $"{Resources.StrErrorMsgRequirementMaximumStorageMonth} - " + strStorageProduction;
- EolProgress.MaxStorageMonthsChecked = EOLStatus.FAIL;
- }
- else
- {
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementMaximumStorageMonth} - " + strStorageProduction;
- EolProgress.MaxStorageMonthsChecked = EOLStatus.OK;
- }
-
- return EolProgress.MaxStorageMonthsChecked;
+ return EOLStatus.OK;
}
///
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs
index 37a1a667..69eb76c5 100644
--- a/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs
+++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs
@@ -1,15 +1,17 @@
using LaaPackages.Features.Cordonel.Models;
using Logic.ProductionToProductMapper.Files.Fw;
+using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
-using Newtonsoft.Json;
using Xylem.Common.CommonCore.Configuration;
using Xylem.Common.CommonCore.Consts;
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications;
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Const;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
+using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
+using Xylem.Common.Logic.ProductionOrderCore.OrderData;
using Xylem.Common.Logic.ProductionOrderCore.Vako;
using Xylem.Common.Logic.SoftwareAccessHelper;
using Xylem.Common.Production.ProductionUiCordonel.Properties;
@@ -18,6 +20,444 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
{
internal static class GenericChecks
{
+ ///
+ /// Check the remaining lifetime
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// true == assemblyLine, false == EOL
+ ///
+ ///
+ /// - Initial.
+ ///
+ public static StatusReturn CheckRemainingLifetime(IGenesisMeter meter, CordonelRequirements productionRequirements,
+ GenesisStatus productionStatus, out String feedbackMsg, Boolean assemblyLine = false)
+ {
+ if (meter == null ||
+ productionRequirements == null ||
+ (assemblyLine && productionRequirements.RequiredLifeTimeYearsAssembly == null) ||
+ (assemblyLine && productionRequirements.RequiredLifeTimeYearsAssembly <= 0) ||
+ (!assemblyLine && productionRequirements.RequiredLifeTimeYearsShipping == null) ||
+ (!assemblyLine && productionRequirements.RequiredLifeTimeYearsShipping <= 0) ||
+ productionStatus == null)
+ {
+ feedbackMsg = Resources.StrErrorMsgLifeTimeCalculation;
+ return StatusReturn.Failed;
+ }
+
+ // Calculate the power consumption
+ if (!GenesisStatusHandler.CalculateLifeTime(productionStatus))
+ {
+ feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
+ return StatusReturn.Failed;
+ }
+
+ // Decide which station Assembly-Line or Shipping-Line (EOL)
+ var strStation = assemblyLine
+ ? $"{productionRequirements.RequiredLifeTimeYearsAssembly:F2} %"
+ : $"{productionRequirements.RequiredLifeTimeYearsShipping:F2} %";
+ // Build message for required versus calculated lifetime
+ var lifeTime = $"{Resources.StrMsgRemainingLifeTime}: " +
+ // Actual calculated lifetime based on readings from meter
+ $"{productionStatus.RemainingLifeTimeYears:F2} " +
+ $"{Resources.StrMsgYears}" +
+ $" - {Resources.StrMsgRequiredLifeTime}: " +
+ // Required lifetime from special or standard requirement
+ strStation +
+ $"{Resources.StrMsgYears}";
+
+ // Check required years for assembly
+ if ((assemblyLine &&
+ productionRequirements.RequiredLifeTimeYearsAssembly > productionStatus.RemainingLifeTimeYears) ||
+ (!assemblyLine &&
+ productionRequirements.RequiredLifeTimeYearsShipping > productionStatus.RemainingLifeTimeYears))
+ {
+ feedbackMsg = $"{Resources.StrErrorMsg}: {lifeTime}";
+ return StatusReturn.Failed;
+ }
+
+ feedbackMsg = $"{Resources.StrSuccessMsg}: {lifeTime}";
+ return StatusReturn.Okay;
+ }
+
+ ///
+ /// Check the months between first battery activation and now
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// - Initial.
+ ///
+ public static StatusReturn CheckStorageMonths(IGenesisMeter meter, CordonelRequirements productionRequirements,
+ GenesisStatus productionStatus, out String feedbackMsg)
+ {
+ // Based on first attached battery and the POWEMON_TotalUsedSeconds (Kitron production date) and actual date
+ if (meter == null ||
+ productionRequirements?.MaxStorageMonths == null ||
+ productionRequirements.MaxStorageMonths < 0.0 ||
+ productionStatus == null ||
+ productionStatus.DrainedBatteryLoad_uAs == 0 ||
+ productionStatus.ExceededLifeTime_s == 0)
+ {
+ // Storage months requirement or Kitron production date unknown
+ feedbackMsg = Resources.StrErrorMsgRequirementMaximumStorageMonthUnknown;
+ return StatusReturn.Failed;
+ }
+
+ // Calculate the power consumption
+ if (!GenesisStatusHandler.CalculateLifeTime(productionStatus) || productionStatus.BatteryAssemblyDateTimeUtc == null)
+ {
+ feedbackMsg = Resources.StrErrorMsgRequirementMaximumStorageMonthUnknown;
+ return StatusReturn.Failed;
+ }
+
+ var actualDate = DateTime.UtcNow.Date;
+ var batteryAssemblyDate = productionStatus.BatteryAssemblyDateTimeUtc.Value.Date;
+ // Give one day more as rounding issue
+ var expirationDate = batteryAssemblyDate.AddDays((Double)productionRequirements.MaxStorageMonths *
+ GenesisStatusHandler.DAYS_PER_MONTH + 1.0);
+ var strStorageProduction = $"{Resources.StrLblKitronProductionDate}: " +
+ $"{productionStatus.BatteryAssemblyDateTimeUtc.Value:dd-MMM-yyyy} - " +
+ $"{Resources.StrLblExpirationDate}: {expirationDate:dd-MMM-yyyy} - " +
+ $"{Resources.StrLblMaxStorageMonths}: " +
+ $"{(Int32)productionRequirements.MaxStorageMonths} {Resources.StrLblMonths}";
+
+ if (actualDate >= expirationDate)
+ {
+ // Storage months exceeded
+ feedbackMsg = $"{Resources.StrErrorMsgRequirementMaximumStorageMonth} - " + strStorageProduction;
+ return StatusReturn.Failed;
+ }
+
+ feedbackMsg = $"{Resources.StrSuccessMsgRequirementMaximumStorageMonth} - " + strStorageProduction;
+ return StatusReturn.Okay;
+ }
+ ///
+ /// Check the remaining battery load based on the thresholds which can be either:
+ /// - The AlternativeRequiredBatteryLoadPercent if the QuiescentCurrent_uA is set to a value greater than 50 uA
+ /// and the EstimatedProductionBatteryLoadPercent is greater than 0.0 %
+ /// and
+ /// - the MaxDrainedBatteryLoadPercentAssembly limits the threshold,
+ /// or only
+ /// - the MaxDrainedBatteryLoadPercentAssembly/Shipping limits the threshold as absolut limit.
+ ///
+ /// ATTENTION: The MaxDrainedBatteryLoadPercentAssembly/Shipping forces the absolut limit even if the alternative
+ /// calculation is being used.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// true == assemblyLine, false == EOL
+ ///
+ ///
+ /// - Initial.
+ ///
+ public static StatusReturn CheckRemainingBatteryLoad(IGenesisMeter meter, CordonelRequirements productionRequirements,
+ GenesisStatus productionStatus, out String feedbackMsg, Boolean assemblyLine = false)
+ {
+ if (meter == null ||
+ productionRequirements == null ||
+ (assemblyLine && productionRequirements.MaxDrainedBatteryLoadPercentAssembly == null) ||
+ (!assemblyLine && productionRequirements.MaxDrainedBatteryLoadPercentShipping == null) ||
+ productionStatus == null)
+ {
+ feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
+ return StatusReturn.Failed;
+ }
+
+ // If the values for calculation of drained battery load and exceeded lifetime are not accessible
+ if (productionStatus.DrainedBatteryLoad_uAs == 0 || productionStatus.ExceededLifeTime_s == 0)
+ {
+ feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
+ return StatusReturn.Failed;
+ }
+
+ // Set up the alternative calculation values needed for given current and supplement for production.
+ // These values will be set by the requirement and have a higher priority than the standard calculation
+ // based on the drained battery load and the estimated prediction based on this and the time of operation.
+ if (productionRequirements.QuiescentCurrent_uA > GenesisMeter.QuiescentCurrent_uA &&
+ productionRequirements.EstimatedProductionBatteryLoadPercent > 0)
+ {
+ productionStatus.QuiescentCurrent_uA = productionRequirements.QuiescentCurrent_uA;
+ productionStatus.EstimatedProductionBatteryLoadPercent =
+ productionRequirements.EstimatedProductionBatteryLoadPercent;
+ }
+
+ // Calculate the power consumption
+ if (!GenesisStatusHandler.CalculateLifeTime(productionStatus))
+ {
+ feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
+ return StatusReturn.Failed;
+ }
+
+ // Check battery load in percent and compare with requirements for limits for drained battery load
+ // For the alternative calculation based quiescent current and production supplement this will be used.
+ // Build message for required versus calculated lifetime
+ Double? threshold;
+ if (assemblyLine)
+ {
+ threshold = productionStatus.AlternativeRequiredBatteryLoadPercent ??
+ productionRequirements.MaxDrainedBatteryLoadPercentAssembly;
+ }
+ else
+ {
+ threshold = productionStatus.AlternativeRequiredBatteryLoadPercent ??
+ productionRequirements.MaxDrainedBatteryLoadPercentShipping;
+ }
+
+ // Decide which station Assembly-Line or Shipping-Line (EOL)
+ var strStation = assemblyLine
+ ? $"{productionRequirements.MaxDrainedBatteryLoadPercentAssembly:F2} %"
+ : $"{productionRequirements.MaxDrainedBatteryLoadPercentShipping:F2} %";
+
+ // Create an output message addon for alternative power consumption calculation
+ var strAlternativeCalc = productionStatus.AlternativeRequiredBatteryLoadPercent == null
+ ? ""
+ : $" - {Resources.StrMsgRequirementAbsolutLimitDrainedBattery}: " + strStation +
+ $" ({Resources.StrMsgAlternativeDrainedBatteryCalculation})";
+
+ var strBatLoad = $"{Resources.StrMsgDrainedBattery}: " +
+ // Actual calculated battery load based on readings from meter
+ $"{productionStatus.DrainedBatteryLoadPercent:F2} %" +
+ $" - {Resources.StrMsgRequirementLimitDrainedBattery}: " +
+ // Required battery load from standard or special requirement
+ $"{threshold:F2} % {strAlternativeCalc}";
+
+
+ // This is the absolut limit even if the "AlternativeRequiredBatteryLoadPercent" will be used
+ if ((assemblyLine && productionStatus.DrainedBatteryLoadPercent >
+ productionRequirements.MaxDrainedBatteryLoadPercentAssembly) ||
+ (!assemblyLine && productionStatus.DrainedBatteryLoadPercent >
+ productionRequirements.MaxDrainedBatteryLoadPercentShipping))
+ {
+ feedbackMsg = $"{Resources.StrErrorMsg}: {strBatLoad}";
+ return StatusReturn.Failed;
+ }
+
+ // This is the limit given by the "AlternativeRequiredBatteryLoadPercent"
+ if (productionStatus.AlternativeRequiredBatteryLoadPercent != null &&
+ productionStatus.DrainedBatteryLoadPercent > productionStatus.AlternativeRequiredBatteryLoadPercent)
+ {
+ feedbackMsg = $"{Resources.StrErrorMsg}: {strBatLoad}";
+ return StatusReturn.Failed;
+ }
+
+ feedbackMsg = $"{Resources.StrSuccessMsg}: {strBatLoad}";
+
+ return StatusReturn.Okay;
+ }
+
+ ///
+ /// Check meter size
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// - Initial.
+ ///
+ public static String CheckMeterSize(IGenesisMeter meter, CordonelRequirements productionRequirements,
+ out String feedbackMsg)
+ {
+ feedbackMsg = "";
+ if (meter == null ||
+ productionRequirements == null || string.IsNullOrEmpty(productionRequirements.MeterSize) ||
+ string.IsNullOrEmpty(meter.MeterSize) ||
+ MeterSizeConverter.ConvertMeterSizeNameToEnum(meter.MeterSize) !=
+ MeterSizeConverter.ConvertMeterSizeNameToEnum(productionRequirements.MeterSize))
+ {
+ feedbackMsg = Resources.StrErrorMsgRequirementMeterSize;
+ return "";
+ }
+
+ feedbackMsg = $"{Resources.StrSuccessMsgRequirementMeterSize} - " +
+ $"{Resources.StrLblMeterSizeTxt}: {meter.MeterSize}";
+
+ return productionRequirements.MeterSize;
+ }
+
+ ///
+ /// Check PcbId of meter and requirements. Mark PcbId as skipped if
+ /// production requirements PcbId is null as this is the indication that all Cordonels
+ /// assigned to this production order are produced according to this requirement.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// - Initial.
+ ///
+ public static StatusReturn CheckPcbId(IGenesisMeter meter, CordonelRequirements productionRequirements,
+ out String feedbackMsg)
+ {
+ feedbackMsg = "";
+ if (meter == null ||
+ productionRequirements == null ||
+ meter.PcbId == null ||
+ meter.PcbId.Length < GenesisMeter.MinPcbIdLength)
+ {
+ feedbackMsg = Resources.StrErrorMsgRequirementPcbId;
+ return StatusReturn.Failed;
+ }
+
+ if (productionRequirements.PcbId == null)
+ {
+ feedbackMsg = Resources.StrSuccessMsgOrderBasedRequirements;
+ return StatusReturn.Okay;
+ }
+ if (meter.PcbId.Equals(productionRequirements.PcbId.ToString()))
+ {
+ feedbackMsg = $"{Resources.StrSuccessMsgRequirementPcbId} - PcbId: {meter.PcbId}";
+ return StatusReturn.Okay;
+ }
+
+ feedbackMsg = Resources.StrErrorMsgRequirementPcbId;
+ return StatusReturn.Failed;
+ }
+
+ ///
+ /// Check production order number between meter and requirements.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// - Initial.
+ ///
+ public static StatusReturn CheckProductionOrderNumber(IGenesisMeter meter, CordonelRequirements productionRequirements,
+ out String feedbackMsg)
+ {
+ feedbackMsg = "";
+ if (meter == null ||
+ productionRequirements == null ||
+ productionRequirements.ProductionOrderNr != meter.OrderNumber)
+ {
+ feedbackMsg = Resources.StrErrorMsgRequirementProductionOrder;
+ return StatusReturn.Failed;
+ }
+
+ feedbackMsg = $"{Resources.StrSuccessMsgRequirementProductionOrder} - " +
+ $"{Resources.StrLblOrderNumberTxt}: {meter.OrderNumber}";
+ return StatusReturn.Okay;
+ }
+
+ ///
+ /// Check region between meter and requirements
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// - Initial.
+ ///
+ public static StatusReturn CheckRegion(IGenesisMeter meter, CordonelRequirements productionRequirements, out String feedbackMsg)
+ {
+ feedbackMsg = "";
+ if (productionRequirements == null ||
+ string.IsNullOrEmpty(productionRequirements.Region) ||
+ string.IsNullOrEmpty(meter.Region) ||
+ !meter.Region.Equals(productionRequirements.Region))
+ {
+ feedbackMsg = Resources.StrErrorMsgRequirementRegion;
+ return StatusReturn.Failed;
+ }
+
+ feedbackMsg = $"{Resources.StrSuccessMsgRequirementRegion} - Region: {meter.Region}";
+ return StatusReturn.Okay;
+ }
+ ///
+ /// Check Look-Up-Table (LUT) for metrology calibration values for the checksum (CRC) of this table
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// - Initial.
+ ///
+ public static String CheckLutCrc(IGenesisMeter meter, CordonelRequirements productionRequirements, out String feedbackMsg)
+ {
+ feedbackMsg = "";
+ if (meter == null ||
+ productionRequirements == null ||
+ string.IsNullOrEmpty(productionRequirements.LutCrc) ||
+ string.IsNullOrEmpty(meter.LutCrc) ||
+ !meter.LutCrc.Equals(productionRequirements.LutCrc))
+ {
+ feedbackMsg = Resources.StrErrorMsgRequirementLut;
+ return "";
+ }
+
+ feedbackMsg = $"{Resources.StrSuccessMsgRequirementLut} - LUT CRC: {meter.LutCrc}";
+
+ return meter.LutCrc;
+ }
+
+ ///
+ /// Check for requirement permission special or standard or none:
+ /// - If the special requirement is active all fields a filled with the according values from this "special"
+ /// requirement,
+ /// - Else those fields contain the "standard" requirements!
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// - Initial.
+ ///
+ public static StatusReturn CheckRequirements(CordonelRequirements productionRequirements, out String feedbackMsg)
+ {
+ feedbackMsg = "";
+ if (productionRequirements == null)
+ {
+ feedbackMsg = Resources.StrErrorMsgProductionRequirements;
+ return StatusReturn.Failed;
+ }
+
+ // Check if requirement is active (free for production) and approved by a second person. Priority special
+ // requirement.
+ var isSpecialActive = false;
+ var isStandardActive = false;
+ if (productionRequirements.IsSpecialActive != null && (Boolean)productionRequirements.IsSpecialActive &&
+ productionRequirements.IsSpecialApproved != null && (Boolean)productionRequirements.IsSpecialApproved)
+ isSpecialActive = true;
+ if (productionRequirements.IsStandardActive != null && (Boolean)productionRequirements.IsStandardActive &&
+ productionRequirements.IsStandardApproved != null && (Boolean)productionRequirements.IsStandardApproved)
+ isStandardActive = true;
+
+ // At least one requirement needs to be active and a requirement number and version has to be set
+ if ((!isStandardActive && !isSpecialActive) ||
+ // The standard Id and version have always to be set even if the special is active
+ productionRequirements.StandardId == null || productionRequirements.StandardVersion == null ||
+ // If the special is active the version and Id have to be defined
+ (isSpecialActive && (productionRequirements.SpecialId == null ||
+ productionRequirements.SpecialVersion == null)))
+ {
+ feedbackMsg = Resources.StrErrorMsgRequirementInactive;
+ return StatusReturn.Failed;
+ }
+
+ feedbackMsg = isSpecialActive &&
+ productionRequirements.SpecialId != null &&
+ productionRequirements.SpecialVersion != null ?
+ Resources.StrWarningMsgSpecialRequirementActive +
+ $" Id.Ver: {productionRequirements.SpecialId}.{productionRequirements.SpecialVersion}" :
+ Resources.StrSuccessMsgRequirementActive +
+ $" Id.Ver {productionRequirements.StandardId}.{productionRequirements.StandardVersion}";
+
+
+ return StatusReturn.Okay;
+ }
///
/// Check the measurements from Kitron for this specific Cordonel if it is an EMEA region.
///
@@ -32,6 +472,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
///
/// - Import from CheckProductionState for common use.
///
+ ///
+ /// - Extended radio parameter.
+ ///
public static StatusReturn CheckKitronRadioSignalLevels(IGenesisMeter meter, RegisterRestorer registerRestorer,
Boolean skipRadioCheck, out String feedbackMsg)
{
@@ -43,11 +486,17 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
return StatusReturn.Failed;
}
- // The NA region has no radio or radio check should be ignored
- if (meter.Region.Equals("NA") || skipRadioCheck)
+ // The NA region has no radio
+ if (meter.Region.Equals("NA"))
{
return StatusReturn.Skipped;
}
+ // The radio check should be ignored
+ if (skipRadioCheck)
+ {
+ feedbackMsg = Resources.StrSkippedMsgRadioCheckSpecialPermission;
+ return StatusReturn.Warning;
+ }
var pressureSensorAssembled =
meter.PressureSensorAssembled ? $", {Resources.StrLblPressureSensorAssembledTxt}" : "";
var meterInfo = $"{Resources.StrLblRadioFrequencyTxt}: {meter.RadioFrequencyMhz} MHz," +
@@ -55,13 +504,16 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
$"{Resources.StrLblMeterLengthTxt}: {meter.MeterLength} mm" +
$"{pressureSensorAssembled}";
// On unknown radio signal level parameters from Kitron those are not in the list of the programming parameters
- if (!registerRestorer.RecoveryRegisters.Any(x => x.RegisterIdent.Equals("SENSUSRADIO_PowerLevel")))
- {
- feedbackMsg = Resources.StrErrorMsgRadioSignalLevels + " " + meterInfo;
- return StatusReturn.Failed;
+ if (!registerRestorer.RecoveryRegisters.Any(x => x.RegisterIdent.Equals("SENSUSRADIO_PowerLevel")) ||
+ !registerRestorer.RecoveryRegisters.Any(x => x.RegisterIdent.Equals("SENSUSRADIO_PowerLevelOption")) ||
+ !registerRestorer.RecoveryRegisters.Any(x => x.RegisterIdent.Equals("SENSUSRADIO_ImpedanceCodeNew")) ||
+ !registerRestorer.RecoveryRegisters.Any(x => x.RegisterIdent.Equals("SENSUSRADIO_ImpedanceCodeOption")) )
+ {
+ feedbackMsg = Resources.StrErrorMsgRadioSignalLevels + " " + meterInfo;
+ return StatusReturn.Failed;
}
- feedbackMsg = Resources.StrSuccessMsgRadioSignalLevels + ". " + meterInfo;
+ feedbackMsg = Resources.StrSuccessMsgRadioSignalLevels + " - " + meterInfo;
return StatusReturn.Okay;
}
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/PickingProcesses/CheckProductionState.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/PickingProcesses/CheckProductionState.cs
index 7e4efa18..36b539c8 100644
--- a/Common/Production/ProductionUiCordonel/ProductionProcesses/PickingProcesses/CheckProductionState.cs
+++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/PickingProcesses/CheckProductionState.cs
@@ -6,7 +6,6 @@ using Xylem.Common.CommonCore.Consts;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
-using Xylem.Common.Logic.ProductionOrderCore.OrderData;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericModules;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
using Xylem.Common.Production.ProductionUiCordonel.Properties;
@@ -149,19 +148,20 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
/// - Region,
/// - FW,
/// - LUT CRC,
- /// - Meter size
+ /// - Meter size,
+ /// - Kitron radio parameter,
/// - Drained battery load versus required remaining battery load in percent,
/// - Remaining run time in years,
///
///
- ///
+ ///
/// - Initial.
///
public override StatusReturn ExecuteProcess()
{
#region ----------------------------------- Check Requirements --------------------------------------------
- var statusReturn = CheckRequirements(out var feedbackMsg);
+ var statusReturn = GenericChecks.CheckRequirements(ProductionRequirements, out var feedbackMsg);
if (StatusReturn.Failed == statusReturn)
{
ErrorMsgDispatcher(feedbackMsg);
@@ -175,7 +175,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#region ----------------------------------- Check Production Order ----------------------------------------
// Production order
- if (StatusReturn.Failed == CheckProductionOrderNumber(out feedbackMsg))
+ if (StatusReturn.Failed == GenericChecks.CheckProductionOrderNumber(Meter, ProductionRequirements,
+ out feedbackMsg))
{
ErrorMsgDispatcher(feedbackMsg);
return StatusReturn.Failed;
@@ -187,7 +188,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#region ----------------------------------- Check PCBID ---------------------------------------------------
// PCBID read from meter compared with requirement PcbIds
- statusReturn = CheckPcbId(out feedbackMsg);
+ statusReturn = GenericChecks.CheckPcbId(Meter, ProductionRequirements, out feedbackMsg);
// Exit here with error
if (StatusReturn.Failed == statusReturn)
@@ -202,7 +203,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#region ----------------------------------- Check Region --------------------------------------------------
- if (StatusReturn.Failed == CheckRegion(out feedbackMsg))
+ if (StatusReturn.Failed == GenericChecks.CheckRegion(Meter, ProductionRequirements, out feedbackMsg))
{
ErrorMsgDispatcher(feedbackMsg);
return StatusReturn.Failed;
@@ -214,7 +215,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#region ----------------------------------- Check LUT CRC -------------------------------------------------
- if (string.IsNullOrEmpty(CheckLutCrc(out feedbackMsg)))
+ if (string.IsNullOrEmpty(GenericChecks.CheckLutCrc(Meter, ProductionRequirements, out feedbackMsg)))
{
ErrorMsgDispatcher(feedbackMsg);
return StatusReturn.Failed;
@@ -226,7 +227,20 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#region ----------------------------------- Check Meter Size ----------------------------------------------
- if (string.IsNullOrEmpty(CheckMeterSize(out feedbackMsg)))
+ if (string.IsNullOrEmpty(GenericChecks.CheckMeterSize(Meter, ProductionRequirements, out feedbackMsg)))
+ {
+ ErrorMsgDispatcher(feedbackMsg);
+ return StatusReturn.Failed;
+ }
+
+ SuccessMsgDispatcher(feedbackMsg);
+ ActualProcessProgress++;
+ #endregion
+
+ #region ----------------------------------- Check Firmware and Apps ---------------------------------------
+
+ if (string.IsNullOrEmpty(GenericChecks.CheckFwAndApps(Meter, ProductionRequirements, FwUpdatePackage,
+ out feedbackMsg)))
{
ErrorMsgDispatcher(feedbackMsg);
return StatusReturn.Failed;
@@ -238,13 +252,24 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#region ----------------------------------- Check Kitron Radio Signal Levels ------------------------------
- statusReturn = CheckKitronRadioSignalLevels(out feedbackMsg);
+ var erroneousSequenceStep = false;
+ var warningSequenceStep = false;
+ statusReturn = GenericChecks.CheckKitronRadioSignalLevels(Meter, RegisterRestorer, ProductionRequirements.SkipRadioCheck,
+ out feedbackMsg);
+
if (StatusReturn.Failed == statusReturn)
{
ErrorMsgDispatcher(feedbackMsg);
- return StatusReturn.Failed;
+ //return StatusReturn.Failed;
+ // Do not return immediately to avoid multiple special-requirements on multiple errors
+ erroneousSequenceStep = true;
}
- if (StatusReturn.Okay == statusReturn)
+ else if (StatusReturn.Warning == statusReturn)
+ {
+ WarningMsgDispatcher(feedbackMsg);
+ warningSequenceStep = true;
+ }
+ else
{
SuccessMsgDispatcher(feedbackMsg);
}
@@ -252,57 +277,56 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
ActualProcessProgress++;
#endregion
- #region ----------------------------------- Check Firmware and Apps ---------------------------------------
-
- if (string.IsNullOrEmpty(CheckFwAndApps(out feedbackMsg)))
- {
- ErrorMsgDispatcher(feedbackMsg);
- return StatusReturn.Failed;
- }
-
- SuccessMsgDispatcher(feedbackMsg);
- ActualProcessProgress++;
- #endregion
-
#region ----------------------------------- Check Remaining Battery Load ----------------------------------
- var erroneousSequenceStep = false;
- if (StatusReturn.Failed == CheckRemainingBatteryLoad(out feedbackMsg))
+ if (StatusReturn.Failed == GenericChecks.CheckRemainingBatteryLoad(Meter, ProductionRequirements,
+ ProductionStatus, out feedbackMsg, true))
{
ErrorMsgDispatcher(feedbackMsg);
//return StatusReturn.Failed;
// Do not return immediately to avoid multiple special-requirements on multiple errors
erroneousSequenceStep = true;
}
- SuccessMsgDispatcher(feedbackMsg);
+ else
+ {
+ SuccessMsgDispatcher(feedbackMsg);
+ }
ActualProcessProgress++;
#endregion
#region ----------------------------------- Check Remaining Life Time -------------------------------------
- if (StatusReturn.Failed == CheckRemainingLifetime(out feedbackMsg))
+ if (StatusReturn.Failed == GenericChecks.CheckRemainingLifetime(Meter, ProductionRequirements,
+ ProductionStatus, out feedbackMsg, true))
{
ErrorMsgDispatcher(feedbackMsg);
//return StatusReturn.Failed;
// Do not return immediately to avoid multiple special-requirements on multiple errors
erroneousSequenceStep = true;
}
- SuccessMsgDispatcher(feedbackMsg);
+ else
+ {
+ SuccessMsgDispatcher(feedbackMsg);
+ }
ActualProcessProgress++;
#endregion
#region ----------------------------------- Check Storage Months ------------------------------------------
- if (StatusReturn.Failed == CheckStorageMonths(out feedbackMsg))
+ if (StatusReturn.Failed == GenericChecks.CheckStorageMonths(Meter, ProductionRequirements,
+ ProductionStatus, out feedbackMsg))
{
ErrorMsgDispatcher(feedbackMsg);
//return StatusReturn.Failed;
// Do not return immediately to avoid multiple special-requirements on multiple errors
erroneousSequenceStep = true;
}
- SuccessMsgDispatcher(feedbackMsg);
+ else
+ {
+ SuccessMsgDispatcher(feedbackMsg);
+ }
ActualProcessProgress++;
#endregion
@@ -313,6 +337,10 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
if (erroneousSequenceStep)
return StatusReturn.Failed;
+ // One or more checks generated a warning
+ if (warningSequenceStep)
+ return StatusReturn.Skipped;
+
// Here everything went fine
SuccessMsgDispatcher(feedbackMsg);
@@ -336,473 +364,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
MessageBox.Show(errorMsg, Resources.StrProcessStateError, MessageBoxButton.OK, MessageBoxImage.Error);
return StatusReturn.Failed;
}
-
- ///
- /// Check for requirement permission special or standard or none:
- /// - If the special requirement is active all fields a filled with the according values from this "special"
- /// requirement,
- /// - Else those fields contain the "standard" requirements!
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_001]_Check_Requirements
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- private StatusReturn CheckRequirements(out String feedbackMsg)
- {
- feedbackMsg = "";
- if (ProductionRequirements == null)
- {
- feedbackMsg = Resources.StrErrorMsgProductionRequirements;
- return StatusReturn.Failed;
- }
-
- // Check if requirement is active (free for production) and approved by a second person. Priority special
- // requirement.
- var isSpecialActive = false;
- var isStandardActive = false;
- if (ProductionRequirements.IsSpecialActive != null && (Boolean)ProductionRequirements.IsSpecialActive &&
- ProductionRequirements.IsSpecialApproved != null && (Boolean)ProductionRequirements.IsSpecialApproved)
- isSpecialActive = true;
- if (ProductionRequirements.IsStandardActive != null && (Boolean)ProductionRequirements.IsStandardActive &&
- ProductionRequirements.IsStandardApproved != null && (Boolean)ProductionRequirements.IsStandardApproved)
- isStandardActive = true;
-
- // At least one requirement needs to be active and a requirement number and version has to be set
- if ((!isStandardActive && !isSpecialActive) ||
- // The standard Id and version have always to be set even if the special is active
- ProductionRequirements.StandardId == null || ProductionRequirements.StandardVersion == null ||
- // If the special is active the version and Id have to be defined
- (isSpecialActive && (ProductionRequirements.SpecialId == null ||
- ProductionRequirements.SpecialVersion == null)))
- {
- feedbackMsg = Resources.StrErrorMsgRequirementInactive;
- return StatusReturn.Failed;
- }
-
- feedbackMsg = isSpecialActive &&
- ProductionRequirements.SpecialId != null &&
- ProductionRequirements.SpecialVersion != null ?
- Resources.StrWarningMsgSpecialRequirementActive +
- $" Id.Ver: {ProductionRequirements.SpecialId}.{ProductionRequirements.SpecialVersion}" :
- Resources.StrSuccessMsgRequirementActive +
- $" Id.Ver {ProductionRequirements.StandardId}.{ProductionRequirements.StandardVersion}";
-
-
- return StatusReturn.Okay;
- }
-
- ///
- /// Check production order number between meter and requirements.
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_002]_Check_ProductionOrderNo
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- private StatusReturn CheckProductionOrderNumber(out String feedbackMsg)
- {
- feedbackMsg = "";
- if (Meter == null ||
- ProductionRequirements == null ||
- ProductionRequirements.ProductionOrderNr != Meter.OrderNumber)
- {
- feedbackMsg = Resources.StrErrorMsgRequirementProductionOrder;
- return StatusReturn.Failed;
- }
-
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementProductionOrder} - " +
- $"{Resources.StrLblOrderNumberTxt}: {Meter.OrderNumber}";
- return StatusReturn.Okay;
- }
-
- ///
- /// Check PcbId of meter and requirements. Mark PcbId as skipped if
- /// production requirements PcbId is null as this is the indication that all Cordonels
- /// assigned to this production order are produced according to this requirement.
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_003]_Check_PcbId
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- private StatusReturn CheckPcbId(out String feedbackMsg)
- {
- feedbackMsg = "";
- if (Meter == null ||
- ProductionRequirements == null ||
- Meter.PcbId == null ||
- Meter.PcbId.Length < GenesisMeter.MinPcbIdLength)
- {
- feedbackMsg = Resources.StrErrorMsgRequirementPcbId;
- return StatusReturn.Failed;
- }
-
- if (ProductionRequirements.PcbId == null)
- {
- feedbackMsg = Resources.StrSuccessMsgOrderBasedRequirements;
- return StatusReturn.Okay;
- }
- if (Meter.PcbId.Equals(ProductionRequirements.PcbId.ToString()))
- {
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementPcbId} - PcbId: {Meter.PcbId}";
- return StatusReturn.Okay;
- }
-
- feedbackMsg = Resources.StrErrorMsgRequirementPcbId;
- return StatusReturn.Failed;
- }
-
- ///
- /// Check region between meter and requirements
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_004]_Check_Region
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- private StatusReturn CheckRegion(out String feedbackMsg)
- {
- feedbackMsg = "";
- if (ProductionRequirements == null ||
- string.IsNullOrEmpty(ProductionRequirements.Region) ||
- string.IsNullOrEmpty(Meter.Region) ||
- !Meter.Region.Equals(ProductionRequirements.Region))
- {
- feedbackMsg = Resources.StrErrorMsgRequirementRegion;
- return StatusReturn.Failed;
- }
-
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementRegion} - Region: {Meter.Region}";
- return StatusReturn.Okay;
- }
-
- ///
- /// Check Look-Up-Table (LUT) for metrology calibration values for the checksum (CRC) of this table
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_005]_Check_LUT_CRC
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- private String CheckLutCrc(out String feedbackMsg)
- {
- feedbackMsg = "";
- if (Meter == null ||
- ProductionRequirements == null ||
- string.IsNullOrEmpty(ProductionRequirements.LutCrc) ||
- string.IsNullOrEmpty(Meter.LutCrc) ||
- !Meter.LutCrc.Equals(ProductionRequirements.LutCrc))
- {
- feedbackMsg = Resources.StrErrorMsgRequirementLut;
- return "";
- }
-
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementLut} - LUT CRC: {Meter.LutCrc}";
-
- return Meter.LutCrc;
- }
-
- ///
- /// Check meter size
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_006]_Check_Meter_Size
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- private String CheckMeterSize(out String feedbackMsg)
- {
- feedbackMsg = "";
- if (Meter == null ||
- ProductionRequirements == null || string.IsNullOrEmpty(ProductionRequirements.MeterSize) ||
- string.IsNullOrEmpty(Meter.MeterSize) ||
- MeterSizeConverter.ConvertMeterSizeNameToEnum(Meter.MeterSize) !=
- MeterSizeConverter.ConvertMeterSizeNameToEnum(ProductionRequirements.MeterSize))
- {
- feedbackMsg = Resources.StrErrorMsgRequirementMeterSize;
- return "";
- }
-
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementMeterSize} - " +
- $"{Resources.StrLblMeterSizeTxt}: {Meter.MeterSize}";
-
- return ProductionRequirements.MeterSize;
- }
-
- ///
- /// Check the measurements from Kitron for this specific Cordonel if it is an EMEA region.
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_007]_Check_Kitron_Radio_Levels
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- private StatusReturn CheckKitronRadioSignalLevels(out String feedbackMsg)
- {
- return GenericChecks.CheckKitronRadioSignalLevels(Meter, RegisterRestorer, ProductionRequirements.SkipRadioCheck,
- out feedbackMsg);
- }
-
-
- ///
- /// Check the installed firmware (FW) and all individual applications (Apps) installed to the meter:
- /// - Take the FLEXNETVERSION as base information which FW is installed in the Cordonel and compare this with
- /// the production-requirement,
- /// - The downloaded FW package containing all Apps as application-binary-container (ABC) will be compared with
- /// the reported Apps by the Cordonel for their version and CRC using the " class,
- /// - Crosscheck if the application-description-file (ADF) states all Apps which are installed in the Cordonel,
- /// - Check the Core-Revision of the Cordonel against the ADF to guarantee that this FW is supported by the
- /// Cordonel operational system (Breeze).
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_008]_Check_FW_and_Apps
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- ///
- /// - Exported to generic tests.
- ///
- private String CheckFwAndApps(out String feedbackMsg)
- {
- return GenericChecks.CheckFwAndApps(Meter, ProductionRequirements, FwUpdatePackage, out feedbackMsg);
- }
-
- ///
- /// Check the remaining battery load based on the thresholds which can be either:
- /// - The AlternativeRequiredBatteryLoadPercent if the QuiescentCurrent_uA is set to a value greater than 50 uA
- /// and the EstimatedProductionBatteryLoadPercent is greater than 0.0 %
- /// and
- /// - the MaxDrainedBatteryLoadPercentAssembly limits the threshold,
- /// or only
- /// - the MaxDrainedBatteryLoadPercentAssembly limits the threshold as absolut limit.
- ///
- /// ATTENTION: The MaxDrainedBatteryLoadPercentAssembly forces the absolut limit even if the alternative
- /// calculation is being used.
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_009]_Check_Remaining_Battery_Load
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- private StatusReturn CheckRemainingBatteryLoad(out String feedbackMsg)
- {
- if (Meter == null ||
- ProductionRequirements?.MaxDrainedBatteryLoadPercentAssembly == null ||
- ProductionStatus == null)
- {
- feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
- return StatusReturn.Failed;
- }
-
- // If the values for calculation of drained battery load and exceeded lifetime are not accessible
- if (ProductionStatus.DrainedBatteryLoad_uAs == 0 || ProductionStatus.ExceededLifeTime_s == 0)
- {
- feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
- return StatusReturn.Failed;
- }
-
- // Set up the alternative calculation values needed for given current and supplement for production.
- // These values will be set by the requirement and have a higher priority than the standard calculation
- // based on the drained battery load and the estimated prediction based on this and the time of operation.
- if (ProductionRequirements.QuiescentCurrent_uA > GenesisMeter.QuiescentCurrent_uA &&
- ProductionRequirements.EstimatedProductionBatteryLoadPercent > 0)
- {
- ProductionStatus.QuiescentCurrent_uA = ProductionRequirements.QuiescentCurrent_uA;
- ProductionStatus.EstimatedProductionBatteryLoadPercent =
- ProductionRequirements.EstimatedProductionBatteryLoadPercent;
- }
-
- // Calculate the power consumption
- if (!GenesisStatusHandler.CalculateLifeTime(ProductionStatus))
- {
- feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
- return StatusReturn.Failed;
- }
-
- // Check battery load in percent and compare with requirements for limits for drained battery load
- // For the alternative calculation based quiescent current and production supplement this will be used.
- // Build message for required versus calculated lifetime
- var threshold = ProductionStatus.AlternativeRequiredBatteryLoadPercent ??
- ProductionRequirements.MaxDrainedBatteryLoadPercentAssembly;
-
- // Create an output message addon for alternative power consumption calculation
- var strAlternativeCalc = ProductionStatus.AlternativeRequiredBatteryLoadPercent == null
- ? ""
- : $" - {Resources.StrMsgRequirementAbsolutLimitDrainedBattery}: " +
- $"{ProductionRequirements.MaxDrainedBatteryLoadPercentAssembly:F2} %" +
- $" ({Resources.StrMsgAlternativeDrainedBatteryCalculation})";
-
- var batteryLoad = $"{Resources.StrMsgDrainedBattery}: " +
- // Actual calculated battery load based on readings from meter
- $"{ProductionStatus.DrainedBatteryLoadPercent:F2} %" +
- $" - {Resources.StrMsgRequirementLimitDrainedBattery}: " +
- // Required battery load from standard or special requirement
- $"{threshold:F2} % {strAlternativeCalc}";
-
-
- // This is the absolut limit even if the "AlternativeRequiredBatteryLoadPercent" will be used
- if (ProductionStatus.DrainedBatteryLoadPercent >
- ProductionRequirements.MaxDrainedBatteryLoadPercentAssembly)
- {
- feedbackMsg = $"{Resources.StrErrorMsg}: {batteryLoad}";
- return StatusReturn.Failed;
- }
-
- // This is the limit given by the "AlternativeRequiredBatteryLoadPercent"
- if (ProductionStatus.AlternativeRequiredBatteryLoadPercent != null &&
- ProductionStatus.DrainedBatteryLoadPercent > ProductionStatus.AlternativeRequiredBatteryLoadPercent)
- {
- feedbackMsg = $"{Resources.StrErrorMsg}: {batteryLoad}";
- return StatusReturn.Failed;
- }
-
- feedbackMsg = $"{Resources.StrSuccessMsg}: {batteryLoad}";
-
- return StatusReturn.Okay;
- }
-
- ///
- /// Check the remaining lifetime
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_010]_Check_Remaining_Lifetime
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- private StatusReturn CheckRemainingLifetime(out String feedbackMsg)
- {
- if (Meter == null ||
- ProductionRequirements?.RequiredLifeTimeYearsAssembly == null ||
- ProductionRequirements.RequiredLifeTimeYearsAssembly <= 0 ||
- ProductionStatus == null)
- {
- feedbackMsg = Resources.StrErrorMsgLifeTimeCalculation;
- return StatusReturn.Failed;
- }
-
- // Calculate the power consumption
- if (!GenesisStatusHandler.CalculateLifeTime(ProductionStatus))
- {
- feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
- return StatusReturn.Failed;
- }
-
- // Build message for required versus calculated lifetime
- var lifeTime = $"{Resources.StrMsgRemainingLifeTime}: " +
- // Actual calculated lifetime based on readings from meter
- $"{ProductionStatus.RemainingLifeTimeYears:F2} " +
- $"{Resources.StrMsgYears}" +
- $" - {Resources.StrMsgRequiredLifeTime}: " +
- // Required lifetime from special or standard requirement
- $"{ProductionRequirements.RequiredLifeTimeYearsAssembly:F2} " +
- $"{Resources.StrMsgYears}";
-
- // Check required years for assembly
- if (ProductionRequirements.RequiredLifeTimeYearsAssembly > ProductionStatus.RemainingLifeTimeYears)
- {
- feedbackMsg = $"{Resources.StrErrorMsg}: {lifeTime}";
- return StatusReturn.Failed;
- }
-
- feedbackMsg = $"{Resources.StrSuccessMsg}: {lifeTime}";
- return StatusReturn.Okay;
- }
-
- ///
- /// Check the months between first battery activation and now
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_011]_Check_Storage_Months
- ///
- ///
- ///
- ///
- ///
- /// - Initial.
- ///
- private StatusReturn CheckStorageMonths(out String feedbackMsg)
- {
- // Based on first attached battery and the POWEMON_TotalUsedSeconds (Kitron production date) and actual date
- if (Meter == null ||
- ProductionRequirements?.MaxStorageMonths == null ||
- ProductionRequirements.MaxStorageMonths < 0.0 ||
- ProductionStatus == null ||
- ProductionStatus.DrainedBatteryLoad_uAs == 0 ||
- ProductionStatus.ExceededLifeTime_s == 0)
- {
- // Storage months requirement or Kitron production date unknown
- feedbackMsg = Resources.StrErrorMsgRequirementMaximumStorageMonthUnknown;
- return StatusReturn.Failed;
- }
-
- // Calculate the power consumption
- if (!GenesisStatusHandler.CalculateLifeTime(ProductionStatus) || ProductionStatus.BatteryAssemblyDateTimeUtc == null)
- {
- feedbackMsg = Resources.StrErrorMsgRequirementMaximumStorageMonthUnknown;
- return StatusReturn.Failed;
- }
-
- var actualDate = DateTime.UtcNow.Date;
- var batteryAssemblyDate = ProductionStatus.BatteryAssemblyDateTimeUtc.Value.Date;
- // Give one day more as rounding issue
- var expirationDate = batteryAssemblyDate.AddDays((Double)ProductionRequirements.MaxStorageMonths * GenesisStatusHandler.DAYS_PER_MONTH + 1.0);
- var strStorageProduction = $"{Resources.StrLblKitronProductionDate}: " +
- $"{ProductionStatus.BatteryAssemblyDateTimeUtc.Value:dd-MMM-yyyy} - " +
- $"{Resources.StrLblExpirationDate}: {expirationDate:dd-MMM-yyyy} - " +
- $"{Resources.StrLblMaxStorageMonths}: " +
- $"{(Int32)ProductionRequirements.MaxStorageMonths} {Resources.StrLblMonths}";
-
- if (actualDate >= expirationDate)
- {
- // Storage months exceeded
- feedbackMsg = $"{Resources.StrErrorMsgRequirementMaximumStorageMonth} - " + strStorageProduction;
- return StatusReturn.Failed;
- }
-
- feedbackMsg = $"{Resources.StrSuccessMsgRequirementMaximumStorageMonth} - " + strStorageProduction;
- return StatusReturn.Okay;
- }
}
}