diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckProductionState.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/EolProcesses/CheckProductionState.cs
index a96975d6..4906d74a 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;
@@ -693,23 +692,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;
}
@@ -727,38 +725,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;
}
@@ -774,23 +766,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;
}
@@ -809,25 +799,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;
}
@@ -843,26 +829,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;
}
@@ -946,90 +927,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;
}
///
@@ -1047,53 +965,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;
}
///
@@ -1114,56 +1006,23 @@ 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;
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.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;
+ EolProgress.MaxStorageMonthsChecked = EOLStatus.OK;
+ return EOLStatus.OK;
}
///
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs
index 08a69bbe..c0894307 100644
--- a/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs
+++ b/Common/Production/ProductionUiCordonel/ProductionProcesses/GenericModules/GenericChecks.cs
@@ -1,16 +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 System.Threading;
-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;
@@ -19,15 +20,394 @@ 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!
- ///
- /// Software Requirement Specification:
- /// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_001]_Check_Requirements
- ///
///
///
///
@@ -48,7 +428,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
// requirement.
var isSpecialActive = false;
var isStandardActive = false;
- if (productionRequirements.IsSpecialActive != null && (Boolean)productionRequirements.IsSpecialActive &&
+ if (productionRequirements.IsSpecialActive != null && (Boolean)productionRequirements.IsSpecialActive &&
productionRequirements.IsSpecialApproved != null && (Boolean)productionRequirements.IsSpecialApproved)
isSpecialActive = true;
if (productionRequirements.IsStandardActive != null && (Boolean)productionRequirements.IsStandardActive &&
@@ -78,7 +458,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
return StatusReturn.Okay;
}
- ///
+ ///
/// Check the measurements from Kitron for this specific Cordonel if it is an EMEA region.
///
///
@@ -117,8 +497,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
// 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;
+ feedbackMsg = Resources.StrErrorMsgRadioSignalLevels + " " + meterInfo;
+ return StatusReturn.Failed;
}
feedbackMsg = Resources.StrSuccessMsgRadioSignalLevels + " - " + meterInfo;
diff --git a/Common/Production/ProductionUiCordonel/ProductionProcesses/PickingProcesses/CheckProductionState.cs b/Common/Production/ProductionUiCordonel/ProductionProcesses/PickingProcesses/CheckProductionState.cs
index c53d57ff..1a0dd36d 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;
@@ -175,7 +174,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 +187,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 +202,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 +214,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 +226,7 @@ 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;
@@ -238,7 +238,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#region ----------------------------------- Check Kitron Radio Signal Levels ------------------------------
- statusReturn = CheckKitronRadioSignalLevels(out feedbackMsg);
+ statusReturn = GenericChecks.CheckKitronRadioSignalLevels(Meter, RegisterRestorer,
+ ProductionRequirements.SkipRadioCheck,out feedbackMsg);
if (StatusReturn.Failed == statusReturn)
{
ErrorMsgDispatcher(feedbackMsg);
@@ -254,7 +255,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#region ----------------------------------- Check Firmware and Apps ---------------------------------------
- if (string.IsNullOrEmpty(CheckFwAndApps(out feedbackMsg)))
+ if (string.IsNullOrEmpty(GenericChecks.CheckFwAndApps(Meter, ProductionRequirements, FwUpdatePackage,
+ out feedbackMsg)))
{
ErrorMsgDispatcher(feedbackMsg);
return StatusReturn.Failed;
@@ -267,7 +269,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#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;
@@ -281,7 +284,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#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;
@@ -295,7 +299,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
#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;
@@ -336,473 +341,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;
- }
}
}