Merge branch 'Dev_ProdUiCord'
This commit is contained in:
commit
6cd904dc7e
@ -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.
|
||||
/// </summary>
|
||||
/// <remarks date="2024-Dec-01" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-19" author="Thomas Wiedebusch">
|
||||
/// - Avoid overwriting of list combined with valid register dictionary.
|
||||
/// </remarks>
|
||||
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");
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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<FilePart>();
|
||||
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.
|
||||
/// </remarks>
|
||||
/// <remarks date="2023-Jul-07" author="Thomas Wiedebusch">
|
||||
/// - Removed signals for <see cref="SingleProcessState.Error"/> and <see cref="SingleProcessState.Succeeded"/> as
|
||||
/// these will be automatically set based on return value in
|
||||
/// - Removed signals for <see cref="SingleProcessState.Error"/> and <see cref="SingleProcessState.Succeeded"/>
|
||||
/// as these will be automatically set based on return value in
|
||||
/// <see cref="BaseProductionProcess.FinalizeProcess"/>.
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-Jul-20" author="Thomas Wiedebusch">
|
||||
/// - 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.
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-Sep-03" author="Thomas Wiedebusch">
|
||||
/// - Get EOL progress model from DB,
|
||||
@ -326,8 +328,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// - Changed <see cref="CheckStorageMonths"/> from "StatusReturn" to "EOLStatus".
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Apr-09" author="Thomas Wiedebusch">
|
||||
/// - 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.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - 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
|
||||
/// <remarks date="2025-Jan-21" author="Thomas Wiedebusch">
|
||||
/// - New IsSpecialApproved and IsStandardApproved.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Modified for generic checks.
|
||||
/// </remarks>
|
||||
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
|
||||
/// <remarks date="2024-Nov-06" author="Thomas Wiedebusch">
|
||||
/// - Extracted from <see cref="ExecuteProcess"/> for better testability.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Modified for generic checks.
|
||||
/// </remarks>
|
||||
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
|
||||
/// <remarks date="2024-Nov-06" author="Thomas Wiedebusch">
|
||||
/// - Extracted from <see cref="ExecuteProcess"/> for better testability.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Modified for generic checks.
|
||||
/// </remarks>
|
||||
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
|
||||
/// <remarks date="2024-Nov-15" author="Thomas Wiedebusch">
|
||||
/// - Extracted from <see cref="ExecuteProcess"/> for better testability.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Modified for generic checks.
|
||||
/// </remarks>
|
||||
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
|
||||
/// <remarks date="2024-Nov-18" author="Thomas Wiedebusch">
|
||||
/// - Set result to null on error.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Modified for generic checks.
|
||||
/// </remarks>
|
||||
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
|
||||
/// <remarks date="2024-Nov-15" author="Thomas Wiedebusch">
|
||||
/// - Extracted from <see cref="ExecuteProcess"/> for better testability.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Modified for generic checks.
|
||||
/// </remarks>
|
||||
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
|
||||
/// <remarks date="2024-Nov-22" author="Thomas Wiedebusch">
|
||||
/// - Absolut maximal threshold even if alternative power consumption calculation.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Modified for generic checks.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1069,53 +995,27 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="2024-Nov-22" author="Thomas Wiedebusch">
|
||||
/// - Check required lifetime for unequal to 0.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Modified for generic checks.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1136,56 +1036,28 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="2025-Jan-16" author="Thomas Wiedebusch">
|
||||
/// - Changed from "StatusReturn" to "EOLStatus".
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-19" author="Thomas Wiedebusch">
|
||||
/// - Modified for generic checks.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Check the remaining lifetime
|
||||
/// </summary>
|
||||
/// <param name="productionStatus"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <param name="meter"></param>
|
||||
/// <param name="productionRequirements"></param>
|
||||
/// <param name="assemblyLine">true == assemblyLine, false == EOL</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check the months between first battery activation and now
|
||||
/// </summary>
|
||||
/// <param name="productionStatus"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <param name="meter"></param>
|
||||
/// <param name="productionRequirements"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="productionStatus"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <param name="meter"></param>
|
||||
/// <param name="productionRequirements"></param>
|
||||
/// <param name="assemblyLine">true == assemblyLine, false == EOL</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check meter size
|
||||
/// </summary>
|
||||
/// <param name="meter"></param>
|
||||
/// <param name="productionRequirements"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// <param name="productionRequirements"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <param name="meter"></param>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check production order number between meter and requirements.
|
||||
/// </summary>
|
||||
/// <param name="productionRequirements"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <param name="meter"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check region between meter and requirements
|
||||
/// </summary>
|
||||
/// <param name="productionRequirements"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <param name="meter"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
/// <summary>
|
||||
/// Check Look-Up-Table (LUT) for metrology calibration values for the checksum (CRC) of this table
|
||||
/// </summary>
|
||||
/// <param name="productionRequirements"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <param name="meter"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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!
|
||||
/// </summary>
|
||||
/// <param name="productionRequirements"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
/// <summary>
|
||||
/// Check the measurements from Kitron for this specific Cordonel if it is an EMEA region.
|
||||
/// </summary>
|
||||
@ -32,6 +472,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Import from CheckProductionState for common use.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-19" author="Thomas Wiedebusch">
|
||||
/// - Extended radio parameter.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Roland Drahbesh">
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check production order number between meter and requirements.
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_002]_Check_ProductionOrderNo
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check region between meter and requirements
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_004]_Check_Region
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check meter size
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_006]_Check_Meter_Size
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
private StatusReturn CheckKitronRadioSignalLevels(out String feedbackMsg)
|
||||
{
|
||||
return GenericChecks.CheckKitronRadioSignalLevels(Meter, RegisterRestorer, ProductionRequirements.SkipRadioCheck,
|
||||
out feedbackMsg);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 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 "<see cref="MeterFwUpdate"/> 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
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Exported to generic tests.
|
||||
/// </remarks>
|
||||
private String CheckFwAndApps(out String feedbackMsg)
|
||||
{
|
||||
return GenericChecks.CheckFwAndApps(Meter, ProductionRequirements, FwUpdatePackage, out feedbackMsg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check the remaining lifetime
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_010]_Check_Remaining_Lifetime
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check the months between first battery activation and now
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_011]_Check_Storage_Months
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user