Merge branch 'main' of https://slm.sms-esaap.com/la_operations/laa_production
This commit is contained in:
@@ -13,4 +13,4 @@ using System.Reflection;
|
||||
//
|
||||
//[assembly: AssemblyVersion("1.2.*.0")]
|
||||
|
||||
[assembly: AssemblyVersion("2.8.11.*")]
|
||||
[assembly: AssemblyVersion("2.8.12.*")]
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
</site>
|
||||
<site name="MeterProcessState(3)" id="6">
|
||||
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
||||
<virtualDirectory path="/" physicalPath="C:\Users\SZLATEV\source\repos\laa_production\Common\Service\MeterProcessState" />
|
||||
<virtualDirectory path="/" physicalPath="D:\Projekte\SENSUS_GitLab\LAA_PRODUCTION\Common\Service\MeterProcessState" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:50075:localhost" />
|
||||
|
||||
@@ -1,16 +1,40 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeEditing/ContextActionTable/DisabledContextActions/=JetBrains_002EReSharper_002EAI_002ECore_002EContextActions_002EOpenAIAssistantContextAction/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/ParenthesesInsertType/@EntryValue">Left</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMissingParentheses/@EntryIndexedValue">HINT</s:String>
|
||||
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeRedundantParentheses/@EntryIndexedValue">SUGGESTION</s:String>
|
||||
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedLocalFunction/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedLocalFunction_002ECompiler/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMember_002ELocal/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedType_002ELocal/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/PARENTHESES_GROUP_NON_OBVIOUS_OPERATIONS/@EntryValue">Arithmetic, Relational, Conditional</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/PARENTHESES_NON_OBVIOUS_OPERATIONS/@EntryValue">Arithmetic, Shift, Relational, Equality, Bitwise, Conditional, NullCoalescing, Lowest</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/PARENTHESES_REDUNDANCY_STYLE/@EntryValue">Remove</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/PREFER_ROSLYN_RULES_FOR_PARENTHESES_CLARITY/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ACCESSOR_OWNER_DECLARATION_BRACES/@EntryValue">NEXT_LINE</s:String>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">120</s:Int64>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DN/@EntryIndexedValue">DN</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FW/@EntryIndexedValue">FW</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LUT/@EntryIndexedValue">LUT</s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/AIAssistantOptions/AiRenameSuggestions/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/AIAssistantOptions/IsAccessToCodeEnabled/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/AIAssistantOptions/IsContextActionsEnabled/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/AIAssistantOptions/IsContextSlidingWindowEnabled/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/AIAssistantOptions/IsExplainExceptionEnabled/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/AIInplaceSuggestionHintsOptions/ShowInPlaceSuggestionHints/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/GrayCodeCompletion/IsEnabled/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/MemoryUsageIndicator/IsVisible/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SearchAndNavigation/SaveExtendedSearch/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SearchAndNavigation/UseReSharperMouseBackForwardNavigation/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/GrammarAndSpelling/GrammarChecking/Exceptions/=na2walarms/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/GrammarAndSpelling/GrammarChecking/LanguagesStates/=Asturianu/@EntryIndexedValue">Disabled</s:String>
|
||||
|
||||
|
||||
|
||||
@@ -48,6 +72,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Flowrate/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fwdl/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=GENESISFLOW/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Gensis/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=GENSISFLOW/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Irda/@EntryIndexedValue">True</s:Boolean>
|
||||
@@ -59,6 +84,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Milli/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Modbus/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=MOXA/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=naproduct/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=OPTICALINTERFACE/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=PCBID/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=perc/@EntryIndexedValue">True</s:Boolean>
|
||||
@@ -70,6 +96,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pwds/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=restorable/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=RFID/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=rowproduct/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sensus/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=SENSUSRADIO/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sirt/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMissingParentheses/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMember_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/PREFER_ROSLYN_RULES_FOR_PARENTHESES_CLARITY/@EntryValue">True</s:Boolean>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/Naming/CSharpAutoNaming/AutoNamingCompletedVersion/@EntryValue">2</s:Int64>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Naming/CSharpAutoNaming/IsNamingAutoDetectionCompleted/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Naming/CSharpAutoNaming/IsNotificationDisabled/@EntryValue">True</s:Boolean>
|
||||
@@ -36,7 +38,12 @@
|
||||
|
||||
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=d5d84997_002D9b95_002D490a_002Da9a3_002Da461c5e0d514/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<Solution />
|
||||
<Not>
|
||||
<TestAncestor>
|
||||
<TestId>VsTest::48DA0272-9B14-4CC8-976F-A91E42DE4680::.NETFramework,Version=v4.8.1::executor://nunit3testexecutor/#Xylem.Common.Production.ProductionUiCordonel.UnitTests.Features.CheckProductionStateFeature</TestId>
|
||||
<TestId>VsTest::48DA0272-9B14-4CC8-976F-A91E42DE4680::.NETFramework,Version=v4.8.1::executor://nunit3testexecutor/#Xylem.Common.Production.ProductionUiCordonel.UnitTests.Features.FinalParamSequence_Write_Store_Reboot_Read_VerifyFeature</TestId>
|
||||
</TestAncestor>
|
||||
</Not>
|
||||
</SessionState></s:String>
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<s:Boolean x:Key="/Default/Environment/Hierarchy/EntityFrameworkOptions/IsAlreadyNotifiedAboutEntityFramework/@EntryValue">True</s:Boolean>
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
<s:String x:Key="/Default/Environment/Highlighting/HighlightingSourceSnapshotLocation/@EntryValue">C:\Users\Thomas Müller\AppData\Local\Temp\JetBrains\ReSharperPlatformVs17\vAny_ab6433f6\CoverageData\_Common.-1885154465\Snapshot\snapshot.utdcvr</s:String>
|
||||
<s:String x:Key="/Default/Environment/Highlighting/HighlightingSourceSnapshotLocation/@EntryValue">C:\Users\Thomas\AppData\Local\Temp\JetBrains\ReSharperPlatformVs17\vAny_ab6433f6\CoverageData\_Common.-1885154465\Snapshot\snapshot.utdcvr</s:String>
|
||||
>>>>>>> origin/main
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Xylem.Common.CommonCore.Configuration
|
||||
public static class ServiceUrls
|
||||
{
|
||||
//#if URI_OLD_DNS // this is defined in build configuration 'VPN_Debug' as the new DNS cannot be reached via VPN
|
||||
// private const String ServerDns = "http://sla12iis01.emea.sensus.net";
|
||||
// private const String ServerDns = "http://sla12iis01.emea.sensus.net";
|
||||
//#else
|
||||
private const String ServerDns = "http://delaz1web01.world.fluidtechnology.net";
|
||||
//#endif
|
||||
|
||||
@@ -619,7 +619,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
try
|
||||
{
|
||||
Logger.Trace($"Slot:{Slot} - Registers definitions loaded from {location}");
|
||||
if (Configuration.AutoUpdateFiles)
|
||||
if (Configuration != null && Configuration.AutoUpdateFiles)
|
||||
{
|
||||
Logger.Trace($"Slot:{Slot} - Check for updates of {configFilePath}");
|
||||
var fi = new FileInfo(configFilePath);
|
||||
@@ -2608,7 +2608,14 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <inheritdoc />
|
||||
public void WriteLog(String text)
|
||||
{
|
||||
Logger.Info($"Slot:{Slot} - {text}");
|
||||
try
|
||||
{
|
||||
Logger.Info($"Slot:{Slot} - {text}");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -43,9 +43,14 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
private String _pcbIdFinalRegisterRead = Constants.StrUnknown;
|
||||
|
||||
/// <summary>
|
||||
/// Collection of recovery registers and values
|
||||
/// Collection of recovery registers - programming parameters
|
||||
/// </summary>
|
||||
public List<RecoveryRegisterItem> RecoveryRegisters;
|
||||
public List<RecoveryRegisterItem> RecoveryRegisters { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// Marker for restore after reboot parameters
|
||||
/// </summary>
|
||||
public Boolean HasRestoreRegistersAfterRebootIfCompareFailed { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// Register content on initial connect to keep those during update
|
||||
@@ -100,6 +105,19 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
"SENSUSRADIO_UpgFWVersion" // After a FW-Update the FW version has changed
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Registers manually explicit marked to be restored after reboot if compare failed. Those registers will
|
||||
/// temporary setup values which do not survive a reboot. This is done to overcome a FW-bug which overwrites
|
||||
/// those values after the reboot procedure!
|
||||
/// </summary>
|
||||
/// <remarks date="2025-Nov-17" author="Thomas Wiedebusch">
|
||||
/// - Initial to restore values which do not survive the reboot as workaround for R1.4.22 and below.
|
||||
/// </remarks>
|
||||
private static readonly List<String> _restoreAfterRebootIfCompareFailed = new List<String>
|
||||
{
|
||||
"CUSTOMER_AlarmEnableMask" // Restored to hard coded value up to FW R1.4.22
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Registers manually explicit excluded for in-field updatable parameters for the CUST to prevent inadvertent
|
||||
/// modifications resulting in potential MID violations.
|
||||
@@ -109,6 +127,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// All commands defined here will not be accepted from 'external' to adjust. Program internally, those
|
||||
/// commands are potentially allowed if those do not change any MID dependent 'values'.
|
||||
/// </summary>
|
||||
/// <remarks date="2025-Nov-18" author="Thomas Wiedebusch">
|
||||
/// - SENSUSRADIO_WakeupInterval added to keep radio active after field update if it was active before.
|
||||
/// </remarks>
|
||||
private static readonly List<String> _fieldUpdateBlacklist = new List<String>
|
||||
{
|
||||
"CUSTOMER_AlarmVisualMask",
|
||||
@@ -120,7 +141,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
|
||||
"FLEXNETSERIAL_FwdlState",
|
||||
"FLEXNETSERIAL_UpgState",
|
||||
|
||||
|
||||
"GENESISFLOW_AmplitudePeakDetectEnd", // 1
|
||||
"GENESISFLOW_ArrowThreshold", // 2
|
||||
"GENESISFLOW_CalFactor1", // 3
|
||||
@@ -206,7 +227,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
"PERIODICLOG_PeriodicLogLifeTimeCounter",
|
||||
"PERIODICLOG_ResetCounter",
|
||||
|
||||
"POWERMON_TotalUsedCharge",
|
||||
"POWERMON_TotalUsedCharge",
|
||||
"POWERMON_TotalUsedSeconds",
|
||||
|
||||
"SENSUSRADIO_AverageFlowPeriod", // 1
|
||||
@@ -232,6 +253,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
"SENSUSRADIO_Tfx_Structure", //21
|
||||
"SENSUSRADIO_UpgFWVersion", //22
|
||||
"SENSUSRADIO_UtcTimeOffset", //23
|
||||
"SENSUSRADIO_WakeupInterval", //24
|
||||
|
||||
"SYSTEM_CalendarSeconds", // 1
|
||||
"SYSTEM_CheckPresence", // 2
|
||||
@@ -276,8 +298,16 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
new RecoveryRegisterItem("GENESISFLOW_SealDisplay", new Byte[] { 0x00 })
|
||||
};
|
||||
|
||||
// ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG
|
||||
private readonly List<RecoveryRegisterItem> _failedComparisonRegisters = new List<RecoveryRegisterItem>();
|
||||
/// <summary>
|
||||
/// Registers which failed the comparison
|
||||
/// </summary>
|
||||
public List<RecoveryRegisterItem> FailedComparisonRegisters { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of registers which should be restored after reboot if the compare failed.
|
||||
/// </summary>
|
||||
public List<RecoveryRegisterItem> RestoreRegistersAfterReboot { get; }
|
||||
|
||||
// ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG
|
||||
private List<String> _dbParameterRegisterList = new List<String>();
|
||||
// ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG
|
||||
@@ -302,13 +332,21 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// Post programming parameters for EMEA region as NA region doesn't have radio and seal display shouldn't
|
||||
/// be executed.
|
||||
/// </summary>
|
||||
/// <remarks date="2025-Nov-20" author="Thomas Wiedebusch">
|
||||
/// - Removed 'SENSUSRADIO_SystemState' as this will synchronize all parameters between this app and the
|
||||
/// 'PERIODICLOG' app. Meaning, the 'SENSUSRADIO' app will overwrite the previously adjusted parameters of
|
||||
/// the 'PERIODICLOG'. After writing the last 'PERIODICLOG' parameter a delay timer between finish exec-
|
||||
/// parametrization and store all configs needs at least 20 s to update contents.
|
||||
/// </remarks>
|
||||
private static readonly List<RecoveryRegisterItem> _finalizeProgrammingEmea = new List<RecoveryRegisterItem>
|
||||
{
|
||||
// Set counter to 0 as this is a value how often the radio detected a reset
|
||||
new RecoveryRegisterItem("SENSUSRADIO_ResetCounter", new Byte[] { 0x00 }),
|
||||
// System state 0xFF will force a storage of all parameters and reset, followed by system state 0x02
|
||||
// for customer mode, the reset needs only a few milliseconds
|
||||
// Attention logout-delay-login required after this step!
|
||||
// ATTENTION: logout-delay-login required after this step!
|
||||
// ATTENTION: 'PERIODICLOG' parameters which will be saved after at least 20 s and the 'SENSUSRADIO' will
|
||||
// synchronize all parameters and therefore overwrite the previously written values.
|
||||
new RecoveryRegisterItem("SENSUSRADIO_SystemState", new Byte[] { 0xFF }),
|
||||
// Seal the display to lock against changes
|
||||
new RecoveryRegisterItem("GENESISFLOW_SealDisplay", new Byte[] { 0x01 }),
|
||||
@@ -358,8 +396,18 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
public RegisterRestorer(IGenesisMeter currentGenesis)
|
||||
{
|
||||
_currentGenesis = currentGenesis;
|
||||
RecoveryRegisters = null;
|
||||
RecoveryRegisters = new List<RecoveryRegisterItem>();
|
||||
RestoreRegistersAfterReboot = new List<RecoveryRegisterItem>();
|
||||
FailedComparisonRegisters = new List<RecoveryRegisterItem>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renew meter for Unit tests based on different meter
|
||||
/// </summary>
|
||||
/// <param name="currentGenesis"></param>
|
||||
public void RenewMeter(IGenesisMeter currentGenesis)
|
||||
{
|
||||
_currentGenesis = currentGenesis;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -556,7 +604,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
continue;
|
||||
}
|
||||
|
||||
// Fill DEBUG lists START with all registers even if they are multiple assigned
|
||||
// Fill DEBUG lists START with all registers even if they are multiple assigned
|
||||
sortableRegisterList.Add(proPar.RegisterName);
|
||||
|
||||
switch (proPar.Source)
|
||||
@@ -572,21 +620,21 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
break;
|
||||
}
|
||||
|
||||
// Take this parameter as is
|
||||
//TODO THW take configuration.json and use for String and Array type, see RegisterConverter
|
||||
//take the register properties from configuration.json
|
||||
//get the pre-defined dictionary
|
||||
//var meterRegisters = MockGenesis based on FW version .GetConfigRegistersDefinitions();
|
||||
//var regDef = meterRegisters.GetRegisterDefinitionByName(proPar.RegisterName);
|
||||
//if (regDef.DataType.Name.Equals("Int32"))
|
||||
//{
|
||||
// Add parameter if it is not in the list
|
||||
//if (sortableProgrammingParameters.All(a => !proPar.RegisterName.Equals(a.RegisterName)))
|
||||
//{
|
||||
// sortableProgrammingParameters.Add(proPar);
|
||||
// continue;
|
||||
//}
|
||||
//}
|
||||
// Take this parameter as is
|
||||
//TODO THW take configuration.json and use for String and Array type, see RegisterConverter
|
||||
//take the register properties from configuration.json
|
||||
//get the pre-defined dictionary
|
||||
//var meterRegisters = MockGenesis based on FW version .GetConfigRegistersDefinitions();
|
||||
//var regDef = meterRegisters.GetRegisterDefinitionByName(proPar.RegisterName);
|
||||
//if (regDef.DataType.Name.Equals("Int32"))
|
||||
//{
|
||||
// Add parameter if it is not in the list
|
||||
//if (sortableProgrammingParameters.All(a => !proPar.RegisterName.Equals(a.RegisterName)))
|
||||
//{
|
||||
// sortableProgrammingParameters.Add(proPar);
|
||||
// continue;
|
||||
//}
|
||||
//}
|
||||
|
||||
|
||||
|
||||
@@ -780,7 +828,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
return RawProgrammingParametersFilterAndSort(programmingParameters, recoveryRegistersDb, out errorMsg,
|
||||
return RawProgrammingParametersFilterAndSort(programmingParameters, recoveryRegistersDb, out errorMsg,
|
||||
fieldUpdate);
|
||||
}
|
||||
catch (Exception)
|
||||
@@ -789,21 +837,21 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Avoid doubling of register restore on subsequent FW-Update trials.
|
||||
/// </summary>
|
||||
/// <returns>true if registers already backed up</returns>
|
||||
/// <remarks date="2020-Dec-21" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
public Boolean RegisterRestoreExecuted()
|
||||
{
|
||||
if (_currentGenesis == null)
|
||||
return false;
|
||||
if (_currentGenesis.PcbId != _pcbIdFinalRegisterRead)
|
||||
return false;
|
||||
return _finalRegisters.Count > 0;
|
||||
}
|
||||
///// <summary>
|
||||
///// Avoid doubling of register restore on subsequent FW-Update trials.
|
||||
///// </summary>
|
||||
///// <returns>true if registers already backed up</returns>
|
||||
///// <remarks date="2020-Dec-21" author="Thomas Wiedebusch">
|
||||
///// - Initial.
|
||||
///// </remarks>
|
||||
//public Boolean RegisterRestoreExecuted()
|
||||
//{
|
||||
// if (_currentGenesis == null)
|
||||
// return false;
|
||||
// if (_currentGenesis.PcbId != _pcbIdFinalRegisterRead)
|
||||
// return false;
|
||||
// return _finalRegisters.Count > 0;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// EOL (end of line) programming contains a reset of the accumulators. Else it is identical with recover
|
||||
@@ -819,7 +867,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <remarks date="2025-Apr-07" author="Thomas Wiedebusch">
|
||||
/// - CancellationToken.
|
||||
/// </remarks>
|
||||
public StatusReturn EolProgrammingRegisters(List<RecoveryRegisterItem> recoveryRegistersDb,
|
||||
public StatusReturn EolProgrammingRegisters(List<RecoveryRegisterItem> recoveryRegistersDb,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// Mark field update as false to set EOL as true to force accu reset
|
||||
@@ -926,7 +974,10 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// - Remove '_fieldUpdateBlacklist' parameters for the CUST to prevent inadvertent modifications resulting in potential
|
||||
/// MID violations.
|
||||
/// </remarks>
|
||||
public StatusReturn WriteRegisters(List<RecoveryRegisterItem> recoveryRegistersDb, CancellationToken cancellationToken,
|
||||
/// <remarks date="2025-Nov-17" author="Thomas Wiedebusch">
|
||||
/// - Login/Logout moved to <see cref="WriteRegisterParameterSet"/>.
|
||||
/// </remarks>
|
||||
public StatusReturn WriteRegisters(List<RecoveryRegisterItem> recoveryRegistersDb, CancellationToken cancellationToken,
|
||||
Boolean fieldUpdate)
|
||||
{
|
||||
if (_currentGenesis == null ||
|
||||
@@ -935,7 +986,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
recoveryRegistersDb.Count == 0)
|
||||
return StatusReturn.Failed;
|
||||
|
||||
// preset recovery registers if not already set
|
||||
//TODO THW preset recovery registers if not already set
|
||||
if (RecoveryRegisters == null)
|
||||
{
|
||||
RecoveryRegisters = new List<RecoveryRegisterItem>();
|
||||
@@ -952,11 +1003,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
_dbParameterRegisterList = recoveryRegistersDb.Select(register => register.RegisterIdent).ToList();
|
||||
_dbParameterRegisterList.Sort();
|
||||
|
||||
// write values to Genesis
|
||||
_currentGenesis.ReLogin();
|
||||
if (!_currentGenesis.IsLoggedOn)
|
||||
return StatusReturn.Failed;
|
||||
|
||||
// get the pre-defined dictionary
|
||||
var meterRegisters = _currentGenesis.GetConfigRegistersDefinitions();
|
||||
|
||||
@@ -991,11 +1037,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryPreparation,
|
||||
actualProcessMessage: Resources.StrRegisterRecoveryPreparation));
|
||||
|
||||
if (StatusReturn.Failed == WriteRegisterParameterSet(_prepareProgramming, recRegistersCount, meterRegisters,
|
||||
if (StatusReturn.Failed == WriteRegisterParameterSet(_prepareProgramming, recRegistersCount, meterRegisters,
|
||||
cancellationToken, fieldUpdate))
|
||||
{
|
||||
// the logout will force the radio app to activate the settings
|
||||
_currentGenesis?.Logout();
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
@@ -1003,32 +1047,25 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryExec,
|
||||
actualProcessMessage: Resources.StrRegisterRecoveryExec));
|
||||
|
||||
if (StatusReturn.Failed == WriteRegisterParameterSet(recoveryRegistersDb, recRegistersCount, meterRegisters,
|
||||
if (StatusReturn.Failed == WriteRegisterParameterSet(recoveryRegistersDb, recRegistersCount, meterRegisters,
|
||||
cancellationToken, fieldUpdate))
|
||||
{
|
||||
// the logout will force the radio app to activate the settings
|
||||
_currentGenesis?.Logout();
|
||||
return StatusReturn.Failed;
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
// finalize recovery
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryFinalization,
|
||||
actualProcessMessage: Resources.StrRegisterRecoveryFinalization));
|
||||
|
||||
if (StatusReturn.Failed == WriteRegisterParameterSet(finalizeProgrammingAll, recRegistersCount, meterRegisters,
|
||||
if (StatusReturn.Failed == WriteRegisterParameterSet(finalizeProgrammingAll, recRegistersCount, meterRegisters,
|
||||
cancellationToken, fieldUpdate))
|
||||
{
|
||||
// the logout will force the radio app to activate the settings
|
||||
_currentGenesis?.Logout();
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
// remind pcbId of this run to avoid endless repetition
|
||||
_pcbIdWriteRegisters = _currentGenesis.PcbId;
|
||||
|
||||
// the logout will force the radio app to activate the settings
|
||||
_currentGenesis?.Logout();
|
||||
|
||||
// Wait for completion as storing may need a certain time
|
||||
Thread.Sleep(1000);
|
||||
|
||||
@@ -1062,19 +1099,20 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <remarks date="2025-Jul-22" author="Thomas Wiedebusch">
|
||||
/// - Excluded un-comparable registers from write turned back on ('blind' writing enabled again).
|
||||
/// </remarks>
|
||||
private StatusReturn WriteRegisterParameterSet(List<RecoveryRegisterItem> recoveryRegistersDb, Int32 recRegistersCount,
|
||||
MeterRegisters meterRegisters, CancellationToken cancellationToken, Boolean fieldUpdate)
|
||||
/// <remarks date="2025-Nov-17" author="Thomas Wiedebusch">
|
||||
/// - Login/Logout moved here.
|
||||
/// </remarks>
|
||||
private StatusReturn WriteRegisterParameterSet(List<RecoveryRegisterItem> recoveryRegistersDb,
|
||||
Int32 recRegistersCount, MeterRegisters meterRegisters, CancellationToken cancellationToken, Boolean fieldUpdate)
|
||||
{
|
||||
_currentGenesis.ReLogin();
|
||||
if (!_currentGenesis.IsLoggedOn)
|
||||
return StatusReturn.Failed;
|
||||
|
||||
foreach (var recReg in recoveryRegistersDb)
|
||||
{
|
||||
//TODO THW Check
|
||||
// Temporary excluded un-comparable registers from write as this make no sense to write them blind being
|
||||
// unable to read the correct value back.
|
||||
//if (_excludedFromCompareParameters.Any( regName => recReg.RegisterIdent.Equals(regName)))
|
||||
// continue;
|
||||
|
||||
// Remove all parameters from parameter list if used for field update
|
||||
if (fieldUpdate && _fieldUpdateBlacklist.Any( regName => recReg.RegisterIdent.Equals(regName)))
|
||||
if (fieldUpdate && _fieldUpdateBlacklist.Any(regName => recReg.RegisterIdent.Equals(regName)))
|
||||
continue;
|
||||
|
||||
_actualRegisterCtr++;
|
||||
@@ -1099,6 +1137,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
$@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}",
|
||||
overallProcessCtrPercent, Resources.StrErrorMsgRegisterNotFound + " Register: " +
|
||||
recReg.RegisterIdent));
|
||||
_currentGenesis?.Logout();
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
@@ -1115,6 +1154,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(
|
||||
$@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}",
|
||||
overallProcessCtrPercent, Resources.StrRegisterValueOutOfRange + " " + errorMessage));
|
||||
_currentGenesis?.Logout();
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
@@ -1124,6 +1164,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
$@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}",
|
||||
overallProcessCtrPercent, Resources.StrErrorMsgRegisterWrite + " Register: " +
|
||||
recReg.RegisterIdent));
|
||||
_currentGenesis?.Logout();
|
||||
return StatusReturn.Failed;
|
||||
|
||||
}
|
||||
@@ -1149,17 +1190,68 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
break;
|
||||
}
|
||||
|
||||
_currentGenesis?.Logout();
|
||||
return StatusReturn.Okay;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare all registers which can be restored without new access to meter.
|
||||
/// Precondition:
|
||||
/// - The _restoreRegisters has to be filled with all registers being able to restore (RW),
|
||||
/// - The _finalReadRegisters has to be filled.
|
||||
/// Restore and compare all registers which did not survive a reboot and are listed in the
|
||||
/// <see cref="_restoreAfterRebootIfCompareFailed"/>
|
||||
/// - This is a workaround for a FW-bug in R1.4.22 and below.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Nov-17" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-19" author="Thomas Wiedebusch">
|
||||
/// - Leave the initial 'RecoveryRegisters' intact.
|
||||
/// </remarks>
|
||||
public Boolean RestoreAndCompareRegistersAfterReboot(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!HasRestoreRegistersAfterRebootIfCompareFailed)
|
||||
return false;
|
||||
|
||||
HasRestoreRegistersAfterRebootIfCompareFailed = false;
|
||||
|
||||
FailedComparisonRegisters.Clear();
|
||||
|
||||
// get the pre-defined dictionary
|
||||
var meterRegisters = _currentGenesis.GetConfigRegistersDefinitions();
|
||||
|
||||
_actualRegisterCtr = 0;
|
||||
// Expected access counter is 3 times the content for write, read and compare
|
||||
var maxCounter = 3 * RecoveryRegisters.Count;
|
||||
|
||||
// Write after reboot
|
||||
if (StatusReturn.Failed == WriteRegisterParameterSet(RestoreRegistersAfterReboot, maxCounter,
|
||||
meterRegisters, cancellationToken, false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// executes login read logout
|
||||
if (!ReadPresetRegisters(RestoreRegistersAfterReboot, cancellationToken))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare register content
|
||||
if (!CompareRegisters(RestoreRegistersAfterReboot, cancellationToken))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Wait for completion as storing may need a certain time
|
||||
Thread.Sleep(1000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare all registers which can be restored without new access to meter.
|
||||
/// </summary>
|
||||
/// <param name="recoveryRegisters"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>true if equal</returns>
|
||||
/// <remarks date="2023-Nov-20" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
@@ -1203,20 +1295,31 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <remarks date="2025-Aug-12" author="Thomas Wiedebusch">
|
||||
/// - Take 'null' in readBack into account due to communication error.
|
||||
/// </remarks>
|
||||
public Boolean CompareRegisters(CancellationToken cancellationToken)
|
||||
/// <remarks date="2025-Nov-17" author="Thomas Wiedebusch">
|
||||
/// - _restoreAfterRebootIfCompareFailed.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-17" author="Thomas Wiedebusch">
|
||||
/// - Made method static.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-19" author="Thomas Wiedebusch">
|
||||
/// - Avoid clearing of failed registers
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-19" author="Thomas Wiedebusch">
|
||||
/// - Leave the initial 'RecoveryRegisters' intact.
|
||||
/// </remarks>
|
||||
public Boolean CompareRegisters(List<RecoveryRegisterItem> recoveryRegisters, CancellationToken cancellationToken)
|
||||
{
|
||||
if (_pcbIdFinalRegisterRead != _pcbIdWriteRegisters ||
|
||||
RecoveryRegisters == null)
|
||||
recoveryRegisters == null)
|
||||
return false;
|
||||
|
||||
_actualRegisterCtr = 0;
|
||||
var retVal = true;
|
||||
|
||||
// DEBUG
|
||||
_failedComparisonRegisters?.Clear();
|
||||
|
||||
// build a string list of the registers being able to sort those
|
||||
var registerNames = RecoveryRegisters.Select(register => register.RegisterIdent).ToList();
|
||||
//var registerNames = RecoveryRegisters.Select(register => register.RegisterIdent).ToList();
|
||||
var registerNames = recoveryRegisters.Select(register => register.RegisterIdent).ToList();
|
||||
|
||||
// Remove all excluded registers
|
||||
foreach (var regName in _excludedFromCompareParameters.Where(regName => registerNames.Any(reg => reg == regName)))
|
||||
{
|
||||
@@ -1259,18 +1362,19 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
try
|
||||
{
|
||||
// Get the raw byte array of this register
|
||||
var recReg = RecoveryRegisters.First(reg => reg.RegisterIdent.Equals(regName));
|
||||
//var recReg = RecoveryRegisters.First(reg => reg.RegisterIdent.Equals(regName));
|
||||
var recReg = recoveryRegisters.First(reg => reg.RegisterIdent.Equals(regName));
|
||||
var writtenValue = recReg.WriteValue;
|
||||
var readBackValue = recReg.ReadBackValue;
|
||||
var strRequiredRegisterValue = "";
|
||||
var isApproximated = false;
|
||||
var isIdentical = false;
|
||||
|
||||
try
|
||||
{
|
||||
// ATTENTION: The size of the writtenValue and readBackValue may deviate!
|
||||
var dataSize = writtenValue.Length;
|
||||
var isApproximated = false;
|
||||
var isIdentical = false;
|
||||
|
||||
|
||||
// Process values only if not 'null'
|
||||
if (writtenValue != null && readBackValue != null)
|
||||
{
|
||||
@@ -1331,15 +1435,21 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
}
|
||||
}// Process register values only if not 'null'
|
||||
|
||||
// convert register content to text with raw and converted value depending on data type
|
||||
strRequiredRegisterValue =
|
||||
RegisterConverter.GetRegisterContentText(regDef, writtenValue);
|
||||
// Convert register content to text with raw and converted value depending on data type
|
||||
strRequiredRegisterValue = RegisterConverter.GetRegisterContentText(regDef, writtenValue);
|
||||
|
||||
if (readBackValue != null && (isIdentical || isApproximated))
|
||||
{
|
||||
strRequiredRegisterValue += $" - {Resources.StrRegisterCompareSucceeded}";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check registers which should be restored after reboot if failed
|
||||
if (_restoreAfterRebootIfCompareFailed.Any(reg => reg.Equals(regName)))
|
||||
{
|
||||
HasRestoreRegistersAfterRebootIfCompareFailed = true;
|
||||
RestoreRegistersAfterReboot.Add(recReg);
|
||||
}
|
||||
var encryptRawData = regName.Contains("EncryptionKey") || regName.Contains("Password");
|
||||
|
||||
var strReadBackRegisterValue = RegisterConverter.GetRegisterRawText(regDef, readBackValue,
|
||||
@@ -1347,7 +1457,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
|
||||
strRequiredRegisterValue += $" - {Resources.StrMeterValue} ({strReadBackRegisterValue})h" +
|
||||
$" - {Resources.StrRegisterCompareFailed}";
|
||||
_failedComparisonRegisters?.Add(new RecoveryRegisterItem(regName, writtenValue,
|
||||
FailedComparisonRegisters?.Add(new RecoveryRegisterItem(regName, writtenValue,
|
||||
readBackValue));
|
||||
retVal = false;
|
||||
}
|
||||
@@ -1366,7 +1476,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
{
|
||||
OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrRegisterCompare}" +
|
||||
$@" {_actualRegisterCtr} / {registersCount}",
|
||||
overallProcessCtrPercent, actualProcessMsg));
|
||||
overallProcessCtrPercent, actualProcessMsg,
|
||||
statusReturn: isIdentical || isApproximated ? StatusReturn.Okay : StatusReturn.Failed));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1419,6 +1530,10 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <remarks date="2025-Apr-07" author="Thomas Wiedebusch">
|
||||
/// - CancellationToken.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-19" author="Thomas Wiedebusch">
|
||||
/// - Cleared all failed compare registers and the restore after reboot registers as a new reading
|
||||
/// will give it a new chance to compare it.
|
||||
/// </remarks>
|
||||
public Boolean FinalReadRegisters(CancellationToken cancellationToken)
|
||||
{
|
||||
if (_currentGenesis == null)
|
||||
@@ -1427,6 +1542,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
Boolean retVal;
|
||||
try
|
||||
{
|
||||
// Clear all preceding failed register lists
|
||||
RestoreRegistersAfterReboot.Clear();
|
||||
FailedComparisonRegisters.Clear();
|
||||
|
||||
// create a dictionary for final read being able to compare those with the initial read and restored
|
||||
if (!BuildReadableRegisterDictionary(ref _finalRegisters))
|
||||
@@ -1525,8 +1643,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
// remind the PCB ID before update for comparison
|
||||
_pcbIdInitialRegisterRead = _currentGenesis.PcbId;
|
||||
|
||||
// create the dictionaries out of the configuration.json
|
||||
if (!BuildReadableRegisterDictionary(ref _initialRegisters))
|
||||
// create a dictionary for final read being able to compare those with the initial read and restored
|
||||
if (!BuildReadableRegisterDictionary(ref _finalRegisters))
|
||||
return false;
|
||||
|
||||
// log to report file the initial register read string
|
||||
@@ -1559,14 +1677,15 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <remarks date="2024-Feb-23" author="Thomas Wiedebusch">
|
||||
/// - Excluded registers which do not contain useful information.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-17" author="Thomas Wiedebusch">
|
||||
/// - Sequence resorted.
|
||||
/// </remarks>
|
||||
public Boolean BuildReadableRegisterDictionary(ref List<RecoveryRegisterItem> registers)
|
||||
{
|
||||
if (_currentGenesis == null || registers == null)
|
||||
return false;
|
||||
|
||||
registers.Clear();
|
||||
_readableRegisterList.Clear();
|
||||
|
||||
// get the pre-defined dictionary
|
||||
var meterRegisters = _currentGenesis.GetConfigRegistersDefinitions();
|
||||
// extract all registers which can be read and create two dictionaries for before update to safe program
|
||||
@@ -1579,11 +1698,14 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
{
|
||||
var registerIdent = reg.Key.GetIdent();
|
||||
registers.Add(new RecoveryRegisterItem(registerIdent, reg.Value));
|
||||
_readableRegisterList.Add(registerIdent);
|
||||
}
|
||||
|
||||
_readableRegisterList.Sort();
|
||||
registers.Sort((a, b) => String.Compare(a.RegisterIdent, b.RegisterIdent, StringComparison.Ordinal));
|
||||
|
||||
// DEBUG information
|
||||
_readableRegisterList.Clear();
|
||||
_readableRegisterList.AddRange(_finalRegisterList);
|
||||
|
||||
return registers.Count > 0;
|
||||
}
|
||||
|
||||
@@ -1612,7 +1734,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
// temporary list of registers just for read and log without keeping them alive
|
||||
var registers = new List<RecoveryRegisterItem>();
|
||||
|
||||
if (!BuildReadableRegisterDictionary(ref registers))
|
||||
// create a dictionary for final read being able to compare those with the initial read and restored
|
||||
if (!BuildReadableRegisterDictionary(ref _finalRegisters))
|
||||
return false;
|
||||
|
||||
// log to report file the initial register read string
|
||||
@@ -1625,6 +1748,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <summary>
|
||||
/// Read predefined registers from RecoveryRegisters.
|
||||
/// </summary>
|
||||
/// <param name="recoveryRegisters"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>true if registers could be read</returns>
|
||||
/// <remarks date="2024-Sep-25" author="Thomas Wiedebusch">
|
||||
@@ -1633,9 +1757,12 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <remarks date="2025-Apr-07" author="Thomas Wiedebusch">
|
||||
/// - CancellationToken.
|
||||
/// </remarks>
|
||||
public Boolean ReadPresetRegisters(CancellationToken cancellationToken)
|
||||
/// <remarks date="2025-Nov-19" author="Thomas Wiedebusch">
|
||||
/// - Leave the initial 'RecoveryRegisters' intact.
|
||||
/// </remarks>
|
||||
public Boolean ReadPresetRegisters(List<RecoveryRegisterItem> recoveryRegisters, CancellationToken cancellationToken)
|
||||
{
|
||||
if (_currentGenesis == null || RecoveryRegisters == null || RecoveryRegisters.Count == 0)
|
||||
if (_currentGenesis == null || recoveryRegisters == null || recoveryRegisters.Count == 0)
|
||||
return false;
|
||||
|
||||
// Assume that this meter shall be used for comparison even if nothing has been written.
|
||||
@@ -1644,7 +1771,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
_pcbIdWriteRegisters = _currentGenesis.PcbId;
|
||||
_pcbIdFinalRegisterRead = _currentGenesis.PcbId;
|
||||
|
||||
return ReadRegistersSet(ref RecoveryRegisters, cancellationToken);
|
||||
return ReadRegistersSet(ref recoveryRegisters, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1692,7 +1819,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
||||
/// <remarks date="2025-Oct-13" author="Thomas Wiedebusch">
|
||||
/// - Date size directly from register object.
|
||||
/// </remarks>
|
||||
private Boolean ReadRegistersSet(ref List<RecoveryRegisterItem> registers, CancellationToken cancellationToken)
|
||||
private Boolean ReadRegistersSet(ref List<RecoveryRegisterItem> registers, CancellationToken cancellationToken)
|
||||
{
|
||||
if (_currentGenesis == null)
|
||||
return false;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -74,7 +74,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
// position of version string
|
||||
private const Int32 FlexVersionStringIndex = 0x66;
|
||||
|
||||
|
||||
private Int32 _processRetryCtr;
|
||||
|
||||
private IGenesisMeter _genesisMeter;
|
||||
@@ -101,6 +100,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
|
||||
/// </summary>
|
||||
public Boolean StoreConfigEnable = true;
|
||||
|
||||
/// <summary>
|
||||
/// Threshold to waste the HW if reboots too high
|
||||
/// </summary>
|
||||
public const Int32 MAX_REBOOTS_FOR_HEALTHY_HW = 4;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
@@ -8,6 +8,14 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes
|
||||
/// </summary>
|
||||
public class TimeT
|
||||
{
|
||||
/// <summary>
|
||||
/// Ctor:
|
||||
/// - Takes actual date time as preset value
|
||||
/// </summary>
|
||||
public TimeT()
|
||||
{
|
||||
DateTimeUtc = DateTime.UtcNow;
|
||||
}
|
||||
/// <summary>
|
||||
/// 1. Get seconds since 01. Jan 2000 00:00:00 UTC previously set by any call by
|
||||
/// <see cref="UtcNowToSecondsSince2000"/> or <see cref="UtcAnyToSecondsSince2000"/>
|
||||
@@ -96,7 +104,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes
|
||||
{
|
||||
private set;
|
||||
get;
|
||||
} = _fixedDateTime2000;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get string of UTC date and time universal language with 24 hours format
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
*=======================================================================================\n
|
||||
*/
|
||||
|
||||
using NLog;
|
||||
//using NLog;
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
@@ -52,10 +52,10 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
|
||||
/// <summary>
|
||||
/// Logger for raw data output
|
||||
/// </summary>
|
||||
protected ILogger Logger
|
||||
{
|
||||
get;
|
||||
}
|
||||
//protected ILogger Logger
|
||||
//{
|
||||
// get;
|
||||
//}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public String SerialNumber
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using NLog;
|
||||
//using NLog;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
|
||||
namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
|
||||
|
||||
+1
-1
Submodule Common/LaaPackages updated: a9ef9051ca...8bda7ec658
+14
-24
@@ -1,8 +1,8 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by SpecFlow (https://www.specflow.org/).
|
||||
// SpecFlow Version:3.3.0.0
|
||||
// SpecFlow Generator Version:3.1.0.0
|
||||
// SpecFlow Version:3.9.0.0
|
||||
// SpecFlow Generator Version:3.9.0.0
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
@@ -17,7 +17,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Features
|
||||
using System.Linq;
|
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.3.0.0")]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.9.0.0")]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[NUnit.Framework.TestFixtureAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("FinalParamSequence_Write_Store_Reboot_Read_Verify")]
|
||||
@@ -26,7 +26,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Features
|
||||
|
||||
private TechTalk.SpecFlow.ITestRunner testRunner;
|
||||
|
||||
private string[] _featureTags = ((string[])(null));
|
||||
private static string[] featureTags = ((string[])(null));
|
||||
|
||||
#line 1 "FinalParamSequence_Write_Store_Reboot_Verify.feature"
|
||||
#line hidden
|
||||
@@ -35,11 +35,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Features
|
||||
public virtual void FeatureSetup()
|
||||
{
|
||||
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
|
||||
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "FinalParamSequence_Write_Store_Reboot_Read_Verify", @"Test the sequence of execute final parametrization, store all settings to FLASH memory, reboot the Cordonel and finally read back
|
||||
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Features", "FinalParamSequence_Write_Store_Reboot_Read_Verify", @"Test the sequence of execute final parametrization, store all settings to FLASH memory, reboot the Cordonel and finally read back
|
||||
and verify the parameters which should remain persistent in non-volatile memory. This should avoid loosing of the parametrization
|
||||
if the Cordonel accidentally reboots in the field. With the reboot it loads all values from FLASH, if those cannot be loaded, it
|
||||
presets these values with defaults.This test used a MockGenesis and real data stored as MockRawParamsExamples for the DN50, the
|
||||
DN80 and the US2.", ProgrammingLanguage.CSharp, ((string[])(null)));
|
||||
DN80 and the US2.", ProgrammingLanguage.CSharp, featureTags);
|
||||
testRunner.OnFeatureStart(featureInfo);
|
||||
}
|
||||
|
||||
@@ -51,28 +51,28 @@ DN80 and the US2.", ProgrammingLanguage.CSharp, ((string[])(null)));
|
||||
}
|
||||
|
||||
[NUnit.Framework.SetUpAttribute()]
|
||||
public virtual void TestInitialize()
|
||||
public void TestInitialize()
|
||||
{
|
||||
}
|
||||
|
||||
[NUnit.Framework.TearDownAttribute()]
|
||||
public virtual void TestTearDown()
|
||||
public void TestTearDown()
|
||||
{
|
||||
testRunner.OnScenarioEnd();
|
||||
}
|
||||
|
||||
public virtual void ScenarioInitialize(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
|
||||
public void ScenarioInitialize(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
|
||||
{
|
||||
testRunner.OnScenarioInitialize(scenarioInfo);
|
||||
testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs<NUnit.Framework.TestContext>(NUnit.Framework.TestContext.CurrentContext);
|
||||
}
|
||||
|
||||
public virtual void ScenarioStart()
|
||||
public void ScenarioStart()
|
||||
{
|
||||
testRunner.OnScenarioStart();
|
||||
}
|
||||
|
||||
public virtual void ScenarioCleanup()
|
||||
public void ScenarioCleanup()
|
||||
{
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
@@ -80,7 +80,7 @@ DN80 and the US2.", ProgrammingLanguage.CSharp, ((string[])(null)));
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("[SRS_TBF_EOL_PP_CHECK_FINAL_PARAM_001]_Check_Param_Sequence")]
|
||||
[NUnit.Framework.CategoryAttribute("CheckFinalParamSequence")]
|
||||
public virtual void SRS_TBF_EOL_PP_CHECK_FINAL_PARAM_001_Check_Param_Sequence()
|
||||
public void SRS_TBF_EOL_PP_CHECK_FINAL_PARAM_001_Check_Param_Sequence()
|
||||
{
|
||||
string[] tagsOfScenario = new string[] {
|
||||
"CheckFinalParamSequence"};
|
||||
@@ -113,21 +113,11 @@ DN80 and the US2.", ProgrammingLanguage.CSharp, ((string[])(null)));
|
||||
"\". \r\nCOMMENT: NCrunch needs programming parameters in a specific folder \r\n " +
|
||||
" \"[SolutionPath]\\Hardware\\WaterMeter\\Genesis\\MockGenesis\\MockRawParameterExa" +
|
||||
"mples\" as it copies all assemblies to a \r\n special NCrunch working fold" +
|
||||
"er which is total separated from the project specific \"\\bin\\Debug\" folder!", tagsOfScenario, argumentsOfScenario);
|
||||
"er which is total separated from the project specific \"\\bin\\Debug\" folder!", tagsOfScenario, argumentsOfScenario, featureTags);
|
||||
#line 11
|
||||
this.ScenarioInitialize(scenarioInfo);
|
||||
#line hidden
|
||||
bool isScenarioIgnored = default(bool);
|
||||
bool isFeatureIgnored = default(bool);
|
||||
if ((tagsOfScenario != null))
|
||||
{
|
||||
isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any();
|
||||
}
|
||||
if ((this._featureTags != null))
|
||||
{
|
||||
isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any();
|
||||
}
|
||||
if ((isScenarioIgnored || isFeatureIgnored))
|
||||
if ((TagHelper.ContainsIgnoreTag(tagsOfScenario) || TagHelper.ContainsIgnoreTag(featureTags)))
|
||||
{
|
||||
testRunner.SkipScenario();
|
||||
}
|
||||
|
||||
+48
-14
@@ -76,7 +76,37 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckProductionProperties
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_003]_Check_ProductionOrderNo
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_003]_Check_CSD_Status
|
||||
FUNCTION: Check the Customer Specific Document (CSD) for its status.
|
||||
PRESETS: none
|
||||
INPUTS: "CSD ID" the identification number of the CSD,
|
||||
"CSD Name" a string for verbose identification,
|
||||
"CSD Code" the code in SAP,
|
||||
"CSD Status" giving the status "Null", "New", "Blocked", "Known" or "Released".
|
||||
OUTPUT: "StatusReturn" with results "Okay", "Failed" or "Warning"
|
||||
#--------------------------------- Prepare Tests ----------------------------------------------------------------------------
|
||||
Given Initialize new test scenario for production process 'CheckProductionState'
|
||||
And Name the object type holding the property 'StatusReturn'
|
||||
And Name the private function to be checked for functionality 'ValidateCsd'
|
||||
|
||||
#--------------------------------- Define Test-Cases -------------------------------------------------------------------------
|
||||
And Input matrix defining the test cases and results
|
||||
| TestNo | CSD ID | CSD Name | CSD Code | CSD Status | StatusReturn | Comment |
|
||||
| 1 | 3100782 | CSD 767978 Canal de Isabel | O1 | Released | Okay | Released CSD approved for production |
|
||||
| 2 | 3100782 | CSD 767978 Canal de Isabel | O1 | Known | Warning | Known CSD temporary for production |
|
||||
| 3 | 3100782 | CSD 767978 Canal de Isabel | O1 | New | Failed | New CSD invalid for production |
|
||||
| 4 | 3100782 | CSD 767978 Canal de Isabel | O1 | Blocked | Failed | Blocked CSD invalid for production |
|
||||
| 5 | null | CSD 767978 Canal de Isabel | O1 | Released | Failed | Invalid CSD ID invalid for production |
|
||||
| 6 | 3100782 | null | O1 | Released | Failed | Invalid CSD Name invalid for production |
|
||||
| 7 | 3100782 | CSD 767978 Canal de Isabel | null | Released | Failed | Invalid CSD Code invalid for production |
|
||||
|
||||
When Execute the generic tests
|
||||
Then Check the generic test results
|
||||
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckProductionProperties
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_004]_Check_ProductionOrderNo
|
||||
FUNCTION: Compare the Cordonel production-order with the production-order from the requirement to validate that the correct requirements
|
||||
going to be used for the check of the actual production state.
|
||||
PRESETS: none
|
||||
@@ -100,7 +130,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckCordonelProperties
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_004]_Check_PcbId
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_005]_Check_PcbId
|
||||
FUNCTION: Compare the PcbId from Cordonel, EOL-progress and requirement.
|
||||
PRESETS: none
|
||||
INPUTS: "Cordonel PcbId", EOL PcbId and "Requirement PcbId". If the requirement-PcbId id is "null" then the requirement is order based
|
||||
@@ -129,7 +159,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckCordonelProperties
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_005]_Check_Region
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_006]_Check_Region
|
||||
FUNCTION: Compare the Region from Cordonel and requirement.
|
||||
PRESETS: none
|
||||
INPUTS: "Cordonel Region" and "Requirement Region".
|
||||
@@ -155,7 +185,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckCordonelProperties
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_006]_Check_LUT_CRC
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_007]_Check_LUT_CRC
|
||||
FUNCTION: Check for the checksum (cyclic redundancy check - CRC) of the metrology lookup-table.
|
||||
PRESETS: none
|
||||
INPUTS: "Cordonel LUT CRC" and "Requirement LUT CRC" just a string representing a number in hex e.g. "0xEB7C.
|
||||
@@ -182,7 +212,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckCordonelProperties
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_007]_Check_Meter_Size
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_008]_Check_Meter_Size
|
||||
FUNCTION: Compare the Meter Size from Cordonel and requirement.
|
||||
PRESETS: none
|
||||
INPUTS: "Cordonel Meter Size" and "Requirement Meter Size" as strings naming the size as e.g. "DN50", "US1_5" or "1 1/2 INC".
|
||||
@@ -209,7 +239,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckCordonelProperties
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_008]_Check_FW_and_Apps
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_009]_Check_FW_and_Apps
|
||||
FUNCTION: Compare Cordonel installed Firmware and Apps with required Firmware.
|
||||
All Apps will be verified for their versions and CRC.
|
||||
The Core-Revision will be validated.
|
||||
@@ -255,7 +285,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckKitronRadioSignalLevels
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_009]_Check_Kitron_Radio_Signal_Levels
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_010]_Check_Kitron_Radio_Signal_Levels
|
||||
FUNCTION: Check if radio signal levels have been defined (contained in parameter list) FOR THIS cORDONEL SIZE AND LENGHT.
|
||||
PRESETS: none
|
||||
INPUTS: .
|
||||
@@ -283,7 +313,7 @@ Then Check the generic test results
|
||||
|
||||
# ================================================================================================================================
|
||||
@CheckLifetimes
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_010]_Check_Remaining_Battery_Load
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_011]_Check_Remaining_Battery_Load
|
||||
FUNCTION: Compare the remaining battery load from Cordonel and the requirement.
|
||||
PRESETS: none
|
||||
INPUTS: "Normal Current [uA]" multiplied with exceeded lifetime together with "Production Drained [%] for an alternative threshold,
|
||||
@@ -319,7 +349,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckLifetimes
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_011]_Check_Remaining_Lifetime
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_012]_Check_Remaining_Lifetime
|
||||
FUNCTION: Compare the remaining life time reported by the Cordonel and the requirement.
|
||||
PRESETS: none
|
||||
INPUTS: "Actual Lifetime [days]" is the time in days the Cordonel after Kitron production,
|
||||
@@ -347,7 +377,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckLifetimeS
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_012]_Check_Storage_Months
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_013]_Check_Storage_Months
|
||||
FUNCTION: Compare the production date reported by the Cordonel with the actual date and check the requirement.
|
||||
PRESETS: none
|
||||
INPUTS: "Assembly Months before Now" as zero or negative floating point number or invalid if set to "null".
|
||||
@@ -375,7 +405,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckCalibrations
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_013]_Check_Preadjustment
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_014]_Check_Preadjustment
|
||||
FUNCTION: Check the database content reporting a flow-test preadjustment.
|
||||
PRESETS: none
|
||||
INPUTS: "Test Bench Fields" the array of test bench fields
|
||||
@@ -405,7 +435,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckCalibrations
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_014]_Check_Flow_Test_State
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_015]_Check_Flow_Test_State
|
||||
FUNCTION: Check the database content reporting the flow-test state.
|
||||
PRESETS: none
|
||||
INPUTS: "Test Bench Fields" the array of test bench fields
|
||||
@@ -436,7 +466,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckCalibrations
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_015]_Check_Calib_Factors
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_016]_Check_Calib_Factors
|
||||
FUNCTION: Compare the calibration values reported by the Cordonel with the flow-test calibration values reported by the database.
|
||||
PRESETS: All calibration values not covered by this test in valid range.
|
||||
INPUTS: "Meter Calib Fact 1/2/3" Meter calibration factors 1, 2 and 3 stored in and read out from the Cordonel,
|
||||
@@ -466,7 +496,7 @@ Then Check the generic test results
|
||||
# ================================================================================================================================
|
||||
|
||||
@CheckProductionStateProcess
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_016]_Check_Complete_Flow_Production_State
|
||||
Scenario: [SRS_TBF_EOL_PP_CHECK_PROD_STATE_017]_Check_Complete_Flow_Production_State
|
||||
FUNCTION: Check the entire production process sequence except the database calls with all underlaying sub-processes.
|
||||
PRESETS: Preset all values with valid parameters to pass the test as "Okay" needed to successfully pass all underlaying tests:
|
||||
- EOL Id | EOL StartDate | Cordonel PcbId | EOL PcbId
|
||||
@@ -512,6 +542,10 @@ And Input initializations for the test matrix and presets to pass the preceding
|
||||
| Standard Id | Standard Version | Standard IsActive | Standard IsApproved | Special Id | Special Version | Comment |
|
||||
| 10 | 5 | X | X | null | null | Standard Requirement is active and approved |
|
||||
|
||||
And Input initializations for the test matrix and presets to pass the preceding tests
|
||||
| CSD ID | CSD Name | CSD Code | CSD Status | Comment |
|
||||
| 3100782 | CSD 767978 Canal de Isabel | O1 | Released | Released CSD approved for production |
|
||||
|
||||
And Input initializations for the test matrix and presets to pass the preceding tests
|
||||
| Cordonel ProdOrderNo | Requirement ProdOrderNo | Comment |
|
||||
| 3118323 | 3118323 | Order number is identical |
|
||||
|
||||
+805
-838
File diff suppressed because it is too large
Load Diff
+21
-3
@@ -10,13 +10,31 @@
|
||||
<StartupObject />
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Configurations>Debug;Release;VPN_Debug</Configurations>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<Optimize>False</Optimize>
|
||||
<IsPublishable>False</IsPublishable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<IsPublishable>False</IsPublishable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VPN_Debug|AnyCPU'">
|
||||
<IsPublishable>False</IsPublishable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="8.3.0" />
|
||||
<PackageReference Include="Cucumber.Messages" Version="31.0.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="8.8.0" />
|
||||
<PackageReference Include="Moq" Version="4.20.72" />
|
||||
<PackageReference Include="NCrunch.Framework" Version="5.11.0" />
|
||||
<PackageReference Include="NUnit" Version="4.3.2" />
|
||||
<PackageReference Include="SpecFlow.NUnit" Version="3.3.57" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.2.0" />
|
||||
<PackageReference Include="SpecFlow.NUnit" Version="3.9.74" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+237
-66
@@ -5,9 +5,11 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using FluentAssertions;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Logic.ProductionToProductMapper.Files.Fw;
|
||||
using NUnit.Framework;
|
||||
using NCrunch.Framework;
|
||||
using Newtonsoft.Json;
|
||||
using TechTalk.SpecFlow;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
@@ -33,37 +35,55 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
/// - This will be used to assign dynamic a function to be checked,
|
||||
/// - If it is null or empty, it is not assigned.
|
||||
/// </summary>
|
||||
private String MethodToTest { set; get; }
|
||||
private String MethodToTest
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marker for a private method.
|
||||
/// </summary>
|
||||
private Boolean IsPrivateMethod { set; get; }
|
||||
private Boolean IsPrivateMethod
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Name of the property to be checked:
|
||||
/// - This will be used to assign dynamic a property to be checked.
|
||||
/// </summary>
|
||||
private String PropertyToCheck { set; get; }
|
||||
private String PropertyToCheck
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Name the object type holding the results of the test including the property:
|
||||
/// - This will be used to assign dynamic a property to be checked.
|
||||
/// </summary>
|
||||
private String ObjectTypeName { set; get; }
|
||||
private String ObjectTypeName
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Required to test the EOL progress and combine it with the individual result:
|
||||
/// - The required EOL progress will be crosschecked with the result of the EOL progress by eventually
|
||||
/// several individual methods or by preceding production processes.
|
||||
/// </summary>
|
||||
private Boolean TestEolProgress { set; get; }
|
||||
private Boolean TestEolProgress
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the production process to test. This is needed to call the correct type in the
|
||||
/// <see cref="ExecTests"></see>
|
||||
/// </summary>
|
||||
private String TestName { set; get; }
|
||||
private String TestName
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The exec path of the assembly for debug in environment.
|
||||
@@ -87,19 +107,31 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
/// </summary>
|
||||
private struct TestResult
|
||||
{
|
||||
public Int32 TestNo { set; get; }
|
||||
public Int32 TestNo
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
public EOLProgressModel EOLProgress { set; get; }
|
||||
public EOLProgressModel EOLProgress
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used if property cannot be checked by an EOL progress.
|
||||
/// </summary>
|
||||
public StatusReturn StatusReturn { set; get; }
|
||||
public StatusReturn StatusReturn
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Feedback message from tested routines
|
||||
/// </summary>
|
||||
public String FeedbackMsg { set; get; }
|
||||
public String FeedbackMsg
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -107,63 +139,102 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
/// </summary>
|
||||
private struct TestRequirement
|
||||
{
|
||||
public Int32 TestNo { set; get; }
|
||||
public Int32 TestNo
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
public String Comment { set; get; }
|
||||
public String Comment
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
|
||||
public MockGenesis? Meter { set; get; }
|
||||
public MockGenesis? Meter
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Production requirements for check of production status and special requirements
|
||||
/// </summary>
|
||||
public CordonelRequirements ProductionRequirements { set; get; }
|
||||
public CordonelRequirements ProductionRequirements
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EOL Progress as input where every single EOL property will be used to set the expected feedback
|
||||
/// to fulfill the single test.
|
||||
/// </summary>
|
||||
public EOLProgressModel RequiredEOLProgress { set; get; }
|
||||
public EOLProgressModel RequiredEOLProgress
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Status of the Cordonel
|
||||
/// </summary>
|
||||
public GenesisStatus CordonelDeviceStatus { set; get; }
|
||||
public GenesisStatus CordonelDeviceStatus
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calibration register restorer of Cordonel
|
||||
/// </summary>
|
||||
public RegisterRestorer CalibCheckRegisterRestorer { set; get; }
|
||||
public RegisterRestorer CalibCheckRegisterRestorer
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register restorer of Cordonel for parametrization
|
||||
/// </summary>
|
||||
public RegisterRestorer RegisterRestorer { set; get; }
|
||||
public RegisterRestorer RegisterRestorer
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Production status of the Cordonel
|
||||
/// </summary>
|
||||
public List<String> TestBenchState { set; get; }
|
||||
public List<String> TestBenchState
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used for partially or full compare on string result return
|
||||
/// </summary>
|
||||
public Boolean PartiallyCompareStringResult { set; get; }
|
||||
public Boolean PartiallyCompareStringResult
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loaded FW package from local disk
|
||||
/// </summary>
|
||||
public List<FilePart> FwUpdatePackage { set; get; }
|
||||
public List<FilePart> FwUpdatePackage
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used if property cannot be checked by an EOL progress.
|
||||
/// </summary>
|
||||
public StatusReturn RequiredStatusReturn { set; get; }
|
||||
public StatusReturn RequiredStatusReturn
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Control to fail the Kitron radio param test
|
||||
/// </summary>
|
||||
public Boolean KillRadioParam { set; get; }
|
||||
public Boolean KillRadioParam
|
||||
{
|
||||
set; get;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -184,7 +255,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
/// <summary>
|
||||
/// Presets needed to pass preceding tests or initialize some properties to a defined state
|
||||
/// </summary>
|
||||
private TestRequirement _presets;
|
||||
private String _presetTestCaseJson = "";
|
||||
/// <summary>
|
||||
/// Presets needed to pass preceding tests or initialize some properties to a defined state
|
||||
/// </summary>
|
||||
private TestRequirement _presetTestCase;
|
||||
|
||||
#endregion ----------------------------- Production State Properties ------------------------------------------
|
||||
|
||||
@@ -240,11 +315,10 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
// As here a new test step will be initialized and possibly the test-case table needs to be pre-filled for
|
||||
// more complex tests of a huge routine to keep running until the real test to be executed will be reached,
|
||||
// the test-cases and results have to be cleared here!
|
||||
_presets.Meter = null;
|
||||
_testCases.Clear();
|
||||
_testResults.Clear();
|
||||
_ppNamesExecSequence.Clear();
|
||||
|
||||
_presetTestCaseJson = "";
|
||||
}
|
||||
|
||||
[Given(@"Name the property to be checked for '(.*)'")]
|
||||
@@ -739,6 +813,31 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change naming string to CSD Status
|
||||
/// </summary>
|
||||
/// <param name="strCsdStatusReturn"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Nov-25" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
private static CSDStatus GetCsdStatusReturnFromName(String strCsdStatusReturn)
|
||||
{
|
||||
switch (strCsdStatusReturn)
|
||||
{
|
||||
case "Blocked":
|
||||
return CSDStatus.Blocked;
|
||||
case "New":
|
||||
return CSDStatus.New;
|
||||
case "Known":
|
||||
return CSDStatus.Known;
|
||||
case "Released":
|
||||
return CSDStatus.Released;
|
||||
default:
|
||||
return CSDStatus.Null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change EOLStatus enum to string
|
||||
/// </summary>
|
||||
@@ -797,34 +896,54 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
/// <remarks date="2024-Dec-10" author="Thomas Wiedebusch">
|
||||
/// - Login to build App list and registers.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-21" author="Thomas Wiedebusch">
|
||||
/// - New object with deep copy of presetTestCase using the Json serializer.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-22" author="Thomas Wiedebusch">
|
||||
/// - Moved meter login for new test requirement and register restorers modification to
|
||||
/// <see cref="NewTestRequirement"/>.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-25" author="Thomas Wiedebusch">
|
||||
/// - Init register restorers.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-26" author="Thomas Wiedebusch">
|
||||
/// - CSD parsing.
|
||||
/// </remarks>
|
||||
private void ReadTestTable(Table table)
|
||||
{
|
||||
// Generate list of tests out of the "Given" table and create test-cases
|
||||
foreach (var row in table.Rows)
|
||||
{
|
||||
var testCase = NewTestRequirement();
|
||||
|
||||
// Check if presets are required, if so copy all properties
|
||||
if (_presets.Meter != null)
|
||||
TestRequirement testCase;
|
||||
// Check if presets are required, if so copy all properties using the Json.Deserializer to create a
|
||||
// new object as deep copy!!!
|
||||
if (_presetTestCase.Meter != null)
|
||||
{
|
||||
ClassAccess.CopyAllProperties(testCase.Meter, _presets.Meter);
|
||||
ClassAccess.CopyAllProperties(testCase.ProductionRequirements, _presets.ProductionRequirements);
|
||||
ClassAccess.CopyAllProperties(testCase.RequiredEOLProgress, _presets.RequiredEOLProgress);
|
||||
ClassAccess.CopyAllProperties(testCase.CalibCheckRegisterRestorer,
|
||||
_presets.CalibCheckRegisterRestorer);
|
||||
ClassAccess.CopyAllProperties(testCase.RegisterRestorer, _presets.RegisterRestorer);
|
||||
ClassAccess.CopyAllProperties(testCase.CordonelDeviceStatus, _presets.CordonelDeviceStatus);
|
||||
testCase.FwUpdatePackage.AddRange(_presets.FwUpdatePackage);
|
||||
testCase.TestBenchState.AddRange(_presets.TestBenchState);
|
||||
if (string.IsNullOrEmpty(_presetTestCaseJson))
|
||||
{
|
||||
_presetTestCaseJson = JsonConvert.SerializeObject(_presetTestCase);
|
||||
}
|
||||
// Create a new object with a deep copy of the _presetTestCase
|
||||
testCase = JsonConvert.DeserializeObject<TestRequirement>(_presetTestCaseJson);
|
||||
|
||||
// Special meter properties which are not include in the deep copy
|
||||
ClassAccess.CopyAllProperties(testCase.Meter, _presetTestCase.Meter);
|
||||
|
||||
testCase.RegisterRestorer = new RegisterRestorer(testCase.Meter);
|
||||
testCase.CalibCheckRegisterRestorer = new RegisterRestorer(testCase.Meter);
|
||||
// Enable register compare even if not physically read from meter
|
||||
testCase.RegisterRestorer.EnableCompareExternalSetRegisters();
|
||||
testCase.CalibCheckRegisterRestorer.EnableCompareExternalSetRegisters();
|
||||
|
||||
// Login is needed for building the MeterAppListVersion and generating the accessible register list.
|
||||
// This register list will be used to check for valid ranges.
|
||||
testCase.Meter?.Login();
|
||||
}
|
||||
// Preset is not required, a single testCase has to be created
|
||||
else
|
||||
{
|
||||
testCase = NewTestRequirement();
|
||||
}
|
||||
|
||||
// Enable register compare even if not physically read from meter
|
||||
testCase.RegisterRestorer.EnableCompareExternalSetRegisters();
|
||||
testCase.CalibCheckRegisterRestorer.EnableCompareExternalSetRegisters();
|
||||
|
||||
// Login is needed for building the MeterAppListVersion and generating the accessible register list.
|
||||
// This register list will be used to check for valid ranges.
|
||||
testCase.Meter?.Login();
|
||||
|
||||
// This is the multiple row test table defining individual test cases
|
||||
ReadTable(row, ref testCase);
|
||||
@@ -844,18 +963,19 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
/// <remarks date="2024-Dec-10" author="Thomas Wiedebusch">
|
||||
/// - Login to build App list and registers.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-22" author="Thomas Wiedebusch">
|
||||
/// - Moved meter login to <see cref="NewTestRequirement"/>.
|
||||
/// </remarks>
|
||||
private void ReadPresetTable(Table table)
|
||||
{
|
||||
if (_presets.Meter == null)
|
||||
_presets = NewTestRequirement();
|
||||
|
||||
// Login is needed for building the MeterAppListVersion and generating the accessible register list.
|
||||
// This register list will be used to check for valid ranges.
|
||||
_presets.Meter?.Login();
|
||||
if (_presetTestCase.Meter == null)
|
||||
{
|
||||
_presetTestCase = NewTestRequirement();
|
||||
}
|
||||
|
||||
// A preset table is limited to exclusively one row, those settings will be used for every test of the
|
||||
// test-cases!
|
||||
ReadTable(table.Rows[0], ref _presets);
|
||||
ReadTable(table.Rows[0], ref _presetTestCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -899,7 +1019,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
|
||||
if (ParseInt(tableRow, "EOL Id", out strValue, out var intValue))
|
||||
{
|
||||
if (intValue != null) parsedTableRow.RequiredEOLProgress.Id = (Int32)intValue;
|
||||
if (intValue != null)
|
||||
parsedTableRow.RequiredEOLProgress.Id = (Int32)intValue;
|
||||
}
|
||||
|
||||
var strHeader = "EOL StartDate";
|
||||
@@ -976,17 +1097,44 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
|
||||
if (ParseInt(tableRow, "Requirement ProdOrderNo", out strValue, out intValue))
|
||||
{
|
||||
if (intValue != null) parsedTableRow.ProductionRequirements.ProductionOrderNr = (Int32)intValue;
|
||||
if (intValue != null)
|
||||
parsedTableRow.ProductionRequirements.ProductionOrderNr = (Int32)intValue;
|
||||
parsedTableRow.RequiredEOLProgress.RequirementOrderChecked = EOLStatus.OK;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Parse CSD -----------------------------------------------------
|
||||
|
||||
if (ParseInt(tableRow, "CSD ID", out strValue, out intValue))
|
||||
{
|
||||
if (intValue != null)
|
||||
parsedTableRow.ProductionRequirements.CSD.IdentId = (Int32)intValue;
|
||||
}
|
||||
|
||||
if (ParseString(tableRow, "CSD Name", out strValue))
|
||||
{
|
||||
parsedTableRow.ProductionRequirements.CSD.Name = strValue;
|
||||
}
|
||||
|
||||
if (ParseString(tableRow, "CSD Code", out strValue))
|
||||
{
|
||||
parsedTableRow.ProductionRequirements.CSD.Code = strValue;
|
||||
}
|
||||
|
||||
if (ParseString(tableRow, "CSD Status", out strValue))
|
||||
{
|
||||
parsedTableRow.ProductionRequirements.CSD.Status = GetCsdStatusReturnFromName(strValue);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Parse PcbId ---------------------------------------------------
|
||||
|
||||
if (ParseInt(tableRow, "Cordonel PcbId", out strValue, out intValue))
|
||||
{
|
||||
if (parsedTableRow.Meter != null) parsedTableRow.Meter.PcbId = strValue;
|
||||
if (parsedTableRow.Meter != null)
|
||||
parsedTableRow.Meter.PcbId = strValue;
|
||||
}
|
||||
|
||||
if (ParseInt(tableRow, "Requirement PcbId", out strValue, out intValue))
|
||||
@@ -997,7 +1145,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
|
||||
if (ParseInt(tableRow, "EOL PcbId", out strValue, out intValue))
|
||||
{
|
||||
if (intValue != null) parsedTableRow.RequiredEOLProgress.PcbId = (Int32)intValue;
|
||||
if (intValue != null)
|
||||
parsedTableRow.RequiredEOLProgress.PcbId = (Int32)intValue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -1006,7 +1155,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
|
||||
if (ParseString(tableRow, "Cordonel LUT CRC", out strValue))
|
||||
{
|
||||
if (parsedTableRow.Meter != null) parsedTableRow.Meter.LutCrc = strValue;
|
||||
if (parsedTableRow.Meter != null)
|
||||
parsedTableRow.Meter.LutCrc = strValue;
|
||||
}
|
||||
|
||||
if (ParseString(tableRow, "Requirement LUT CRC", out strValue))
|
||||
@@ -1021,7 +1171,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
|
||||
if (ParseString(tableRow, "Cordonel Region", out strValue))
|
||||
{
|
||||
if (parsedTableRow.Meter != null) parsedTableRow.Meter.Region = strValue;
|
||||
if (parsedTableRow.Meter != null)
|
||||
parsedTableRow.Meter.Region = strValue;
|
||||
}
|
||||
|
||||
if (ParseString(tableRow, "Requirement Region", out strValue))
|
||||
@@ -1104,7 +1255,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
if (parsedTableRow.Meter != null)
|
||||
{
|
||||
parsedTableRow.Meter.Login();
|
||||
if (floatValue != null) parsedTableRow.Meter.CoreRevision = (Int32)(floatValue * 100);
|
||||
if (floatValue != null)
|
||||
parsedTableRow.Meter.CoreRevision = (Int32)(floatValue * 100);
|
||||
parsedTableRow.Meter.StrCoreRevision = strValue;
|
||||
}
|
||||
}
|
||||
@@ -1173,7 +1325,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
|
||||
if (ParseFloat(tableRow, "Actual Lifetime [days]", out strValue, out floatValue))
|
||||
{
|
||||
if (floatValue != null) parsedTableRow.CordonelDeviceStatus.ExceededLifeTime_s =
|
||||
if (floatValue != null)
|
||||
parsedTableRow.CordonelDeviceStatus.ExceededLifeTime_s =
|
||||
(UInt64)(floatValue * 24 * 3600);
|
||||
parsedTableRow.RequiredEOLProgress.ProductionStatusBatteryLoadChecked = EOLStatus.OK;
|
||||
parsedTableRow.RequiredEOLProgress.ProductionStatusRemainingLifeTimeChecked = EOLStatus.OK;
|
||||
@@ -1399,7 +1552,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
if (!string.IsNullOrEmpty(strValue) && strValue.Equals("X") && !singleSelectionLock)
|
||||
{
|
||||
singleSelectionLock = true;
|
||||
if (parsedTableRow.Meter != null) parsedTableRow.Meter.OrderNumber = 0;
|
||||
if (parsedTableRow.Meter != null)
|
||||
parsedTableRow.Meter.OrderNumber = 0;
|
||||
parsedTableRow.RequiredEOLProgress.RequirementOrderChecked = EOLStatus.FAIL;
|
||||
}
|
||||
}
|
||||
@@ -1429,7 +1583,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
if (!string.IsNullOrEmpty(strValue) && strValue.Equals("X"))
|
||||
{
|
||||
singleSelectionLock = true;
|
||||
if (parsedTableRow.Meter != null) parsedTableRow.Meter.Region = "?";
|
||||
if (parsedTableRow.Meter != null)
|
||||
parsedTableRow.Meter.Region = "?";
|
||||
parsedTableRow.RequiredEOLProgress.RequirementRegionChecked = EOLStatus.FAIL;
|
||||
}
|
||||
}
|
||||
@@ -1444,7 +1599,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
if (!string.IsNullOrEmpty(strValue) && strValue.Equals("X"))
|
||||
{
|
||||
singleSelectionLock = true;
|
||||
if (parsedTableRow.Meter != null) parsedTableRow.Meter.LutCrc = "?";
|
||||
if (parsedTableRow.Meter != null)
|
||||
parsedTableRow.Meter.LutCrc = "?";
|
||||
parsedTableRow.RequiredEOLProgress.ProductionStatusLutCrc = "";
|
||||
}
|
||||
}
|
||||
@@ -1560,7 +1716,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
{
|
||||
if (!string.IsNullOrEmpty(strValue) && strValue.Equals("X") && !singleSelectionLock)
|
||||
{
|
||||
if (parsedTableRow.Meter != null) parsedTableRow.Meter.ReLogin();
|
||||
if (parsedTableRow.Meter != null)
|
||||
parsedTableRow.Meter.ReLogin();
|
||||
PresetRegisterRestorer(parsedTableRow.CalibCheckRegisterRestorer, "GENESISFLOW_CalFactor1",
|
||||
RegisterConverter.ValueToByteArray((UInt16)0), RegisterConverter.ValueToByteArray((UInt16)1));
|
||||
parsedTableRow.RequiredEOLProgress.ProductionStatusCalibrationChecked = EOLStatus.FAIL;
|
||||
@@ -1649,6 +1806,12 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
/// <remarks date="2024-Nov-19" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-22" author="Thomas Wiedebusch">
|
||||
/// - Init meter and enable change of values for register restorers.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-26" author="Thomas Wiedebusch">
|
||||
/// - CSD.
|
||||
/// </remarks>
|
||||
private static TestRequirement NewTestRequirement()
|
||||
{
|
||||
var testCase = new TestRequirement
|
||||
@@ -1664,8 +1827,16 @@ namespace Xylem.Common.Production.ProductionUiCordonel.UnitTests.Steps
|
||||
BatteryQuantity = 2
|
||||
}
|
||||
};
|
||||
testCase.ProductionRequirements.CSD = new CordonelCSD();
|
||||
testCase.RegisterRestorer = new RegisterRestorer(testCase.Meter);
|
||||
testCase.CalibCheckRegisterRestorer = new RegisterRestorer(testCase.Meter);
|
||||
// Enable register compare even if not physically read from meter
|
||||
testCase.RegisterRestorer.EnableCompareExternalSetRegisters();
|
||||
testCase.CalibCheckRegisterRestorer.EnableCompareExternalSetRegisters();
|
||||
|
||||
// Login is needed for building the MeterAppListVersion and generating the accessible register list.
|
||||
// This register list will be used to check for valid ranges.
|
||||
testCase.Meter?.Login();
|
||||
|
||||
return testCase;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Newtonsoft.Json;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
|
||||
+19
-2
@@ -122,7 +122,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// <inheritdoc />
|
||||
public IGenesisMeter Meter
|
||||
{
|
||||
protected get; set;
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -520,10 +520,27 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// <remarks date="2024-Jan-17" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-17" author="Thomas Wiedebusch">
|
||||
/// - StatusReturn.
|
||||
/// </remarks>
|
||||
protected void ProcessUpdate_Handler(Object sender, ProcessExecEventArgs e)
|
||||
{
|
||||
ActualProcessProgress++;
|
||||
LogNewStatusMsg(e.ActualProcessMessage);
|
||||
switch (e.StatusReturn)
|
||||
{
|
||||
case StatusReturn.Okay:
|
||||
SuccessMsgDispatcher(e.ActualProcessMessage);
|
||||
break;
|
||||
case StatusReturn.Warning:
|
||||
WarningMsgDispatcher(e.ActualProcessMessage);
|
||||
break;
|
||||
case StatusReturn.Failed:
|
||||
ErrorMsgDispatcher(e.ActualProcessMessage);
|
||||
break;
|
||||
default:
|
||||
LogNewStatusMsg(e.ActualProcessMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Newtonsoft.Json;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
|
||||
+30
-4
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
//using Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes;
|
||||
@@ -14,7 +14,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// </summary>
|
||||
public CheckFinalParametrization(String name) : base( name)
|
||||
public CheckFinalParametrization(String name) : base(name)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -49,6 +49,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="2025-Apr-07" author="Thomas Wiedebusch">
|
||||
/// - CancellationToken.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-17..19" author="Thomas Wiedebusch">
|
||||
/// - Restore registers after reboot if failed - temporary workaround for FW-bug.
|
||||
/// </remarks>
|
||||
public override StatusReturn ExecuteProcess()
|
||||
{
|
||||
// Uncheck executed process to leave the result open needed for retries
|
||||
@@ -83,13 +86,13 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
RegisterRestorer.OnProcessUpdate += ProcessUpdate_Handler;
|
||||
var retValBol = RegisterRestorer.FinalReadRegisters(CancellationToken);
|
||||
RegisterRestorer.OnProcessUpdate -= ProcessUpdate_Handler;
|
||||
|
||||
|
||||
// Exit if meanwhile cancellation is required
|
||||
if (CancellationToken.IsCancellationRequested)
|
||||
return CancellationProcedure();
|
||||
|
||||
RegisterRestorer.OnProcessUpdate += ProcessUpdate_Handler;
|
||||
retValBol &= RegisterRestorer.CompareRegisters(CancellationToken);
|
||||
retValBol &= RegisterRestorer.CompareRegisters(RegisterRestorer.RecoveryRegisters, CancellationToken);
|
||||
RegisterRestorer.OnProcessUpdate -= ProcessUpdate_Handler;
|
||||
|
||||
if (retValBol)
|
||||
@@ -98,6 +101,29 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
Meter?.Logout();
|
||||
return StatusReturn.Okay;
|
||||
}
|
||||
|
||||
// Restore registers after reboot if failed
|
||||
if (RegisterRestorer.HasRestoreRegistersAfterRebootIfCompareFailed)
|
||||
{
|
||||
WarningMsgDispatcher(Resources.StrWarningMsgParameterCompare);
|
||||
// Write and compare those registers
|
||||
RegisterRestorer.OnProcessUpdate += ProcessUpdate_Handler;
|
||||
retValBol = RegisterRestorer.RestoreAndCompareRegistersAfterReboot(CancellationToken);
|
||||
RegisterRestorer.OnProcessUpdate -= ProcessUpdate_Handler;
|
||||
if (retValBol)
|
||||
{
|
||||
if (RegisterRestorer.RestoreRegistersAfterReboot.Count ==
|
||||
RegisterRestorer.FailedComparisonRegisters.Count)
|
||||
{
|
||||
EolProgress.ParametrizationCompareChecked = EOLStatus.OK;
|
||||
Meter?.Logout();
|
||||
// Display a warning for the 'after reboot' parameter recovery
|
||||
return StatusReturn.Warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No chance to repair anything
|
||||
EolProgress.ParametrizationCompareChecked = EOLStatus.FAIL;
|
||||
Meter?.Logout();
|
||||
return StatusReturn.Failed;
|
||||
|
||||
+63
-23
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Logic.ProductionToProductMapper.Files.Fw;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
@@ -26,7 +26,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <summary>
|
||||
/// Maximum of expected processing steps for this process to feed the GUI progress bar.
|
||||
/// </summary>
|
||||
private const Int32 MaxActualProgressSteps = 23;
|
||||
private const Int32 MaxActualProgressSteps = 24;
|
||||
|
||||
/// <summary>
|
||||
/// Successfully test on flow test bench will return this const value.
|
||||
@@ -82,8 +82,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// </remarks>
|
||||
public override StatusReturn PreExecuteProcess()
|
||||
{
|
||||
if (Meter == null ||
|
||||
string.IsNullOrEmpty(Meter.PcbId) ||
|
||||
if (Meter == null ||
|
||||
string.IsNullOrEmpty(Meter.PcbId) ||
|
||||
Meter.PcbId.Length < GenesisMeter.MinPcbIdLength ||
|
||||
EolProgress == null)
|
||||
{
|
||||
@@ -248,7 +248,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Activate logging to output
|
||||
CalibCheckRegisterRestorer.OnProcessUpdate += ProcessUpdate_Handler;
|
||||
// Read out all parameters from meter and compare it
|
||||
if (!CalibCheckRegisterRestorer.ReadPresetRegisters(CancellationToken))
|
||||
if (!CalibCheckRegisterRestorer.ReadPresetRegisters(CalibCheckRegisterRestorer.RecoveryRegisters,
|
||||
CancellationToken))
|
||||
{
|
||||
// Stop logging
|
||||
CalibCheckRegisterRestorer.OnProcessUpdate -= ProcessUpdate_Handler;
|
||||
@@ -276,6 +277,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// be completed as the PcbId and the order number is needed.
|
||||
/// Checks:
|
||||
/// - Requirements are collected,
|
||||
/// - Validate CSD,
|
||||
/// - EOL progress for Sentinel can be generated,
|
||||
/// - PcbId,
|
||||
/// - Region,
|
||||
@@ -331,8 +333,14 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Check radio signal levels in parameter list.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-21" author="Thomas Wiedebusch">
|
||||
/// - Validate CSD.
|
||||
/// </remarks>
|
||||
public override StatusReturn ExecuteProcess()
|
||||
{
|
||||
var erroneousSequenceStep = false;
|
||||
var warningSequenceStep = false;
|
||||
|
||||
#region ----------------------------------- Check EOL Progress --------------------------------------------
|
||||
if (string.IsNullOrEmpty(CheckEolProgress(out var feedbackMsg)))
|
||||
{
|
||||
@@ -344,7 +352,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Requirements --------------------------------------------
|
||||
|
||||
var eolStatus = CheckRequirements(out feedbackMsg);
|
||||
if (EOLStatus.FAIL == eolStatus)
|
||||
{
|
||||
@@ -356,8 +363,30 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
ActualProcessProgress++;
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Production Order ----------------------------------------
|
||||
#region ----------------------------------- Validate CSD -------------------------------------------------
|
||||
var statusReturn = ValidateCsd(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);
|
||||
//TODO THW removed until 'CSDStatus.Released' is the only valid status
|
||||
//warningSequenceStep = true;
|
||||
}
|
||||
if (StatusReturn.Okay == statusReturn)
|
||||
{
|
||||
SuccessMsgDispatcher(feedbackMsg);
|
||||
}
|
||||
|
||||
ActualProcessProgress++;
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Production Order ----------------------------------------
|
||||
// Production order
|
||||
if (EOLStatus.FAIL == CheckProductionOrderNumber(out feedbackMsg))
|
||||
{
|
||||
@@ -385,7 +414,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Region --------------------------------------------------
|
||||
|
||||
if (EOLStatus.FAIL == CheckRegion(out feedbackMsg))
|
||||
{
|
||||
ErrorMsgDispatcher(feedbackMsg);
|
||||
@@ -397,7 +425,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check LUT CRC -------------------------------------------------
|
||||
|
||||
if (string.IsNullOrEmpty(CheckLutCrc(out feedbackMsg)))
|
||||
{
|
||||
ErrorMsgDispatcher(feedbackMsg);
|
||||
@@ -409,7 +436,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Meter Size ----------------------------------------------
|
||||
|
||||
if (string.IsNullOrEmpty(CheckMeterSize(out feedbackMsg)))
|
||||
{
|
||||
ErrorMsgDispatcher(feedbackMsg);
|
||||
@@ -421,7 +447,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Firmware and Apps ---------------------------------------
|
||||
|
||||
if (string.IsNullOrEmpty(CheckFwAndApps(out feedbackMsg)))
|
||||
{
|
||||
ErrorMsgDispatcher(feedbackMsg);
|
||||
@@ -433,10 +458,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Kitron Radio Signal Levels ------------------------------
|
||||
|
||||
var erroneousSequenceStep = false;
|
||||
var warningSequenceStep = false;
|
||||
var statusReturn = CheckKitronRadioSignalLevels(out feedbackMsg);
|
||||
statusReturn = CheckKitronRadioSignalLevels(out feedbackMsg);
|
||||
|
||||
if (StatusReturn.Failed == statusReturn)
|
||||
{
|
||||
@@ -459,7 +481,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Remaining Battery Load ----------------------------------
|
||||
|
||||
if (EOLStatus.FAIL == CheckRemainingBatteryLoad(out feedbackMsg))
|
||||
{
|
||||
ErrorMsgDispatcher(feedbackMsg);
|
||||
@@ -476,7 +497,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Remaining Life Time -------------------------------------
|
||||
|
||||
if (EOLStatus.FAIL == CheckRemainingLifetime(out feedbackMsg))
|
||||
{
|
||||
ErrorMsgDispatcher(feedbackMsg);
|
||||
@@ -493,7 +513,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Storage Months ------------------------------------------
|
||||
|
||||
if (EOLStatus.FAIL == CheckStorageMonths(out feedbackMsg))
|
||||
{
|
||||
ErrorMsgDispatcher(feedbackMsg);
|
||||
@@ -510,7 +529,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Preadjusment --------------------------------------------
|
||||
|
||||
eolStatus = CheckPreadjustment(out feedbackMsg);
|
||||
if (EOLStatus.FAIL == eolStatus)
|
||||
{
|
||||
@@ -533,7 +551,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Flow Test State -----------------------------------------
|
||||
|
||||
eolStatus = CheckFlowTestState(out feedbackMsg);
|
||||
if (EOLStatus.FAIL == eolStatus)
|
||||
{
|
||||
@@ -556,7 +573,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Calibration Values --------------------------------------
|
||||
|
||||
// ATTENTION:
|
||||
// This step may exit with "skipped" here if "special-requirement" forces to skip the check of calibration.
|
||||
// All following checks will be skipped as well.
|
||||
@@ -588,7 +604,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Summarize Check Results ---------------------------------------
|
||||
|
||||
// One or more checks failed
|
||||
if (erroneousSequenceStep)
|
||||
return StatusReturn.Failed;
|
||||
@@ -707,6 +722,30 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
return EolProgress.RequirementRequestChecked;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate the CSD
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_016]_Validate_CSD
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Nov-21..26" author="Thomas Wiedebusch">
|
||||
/// - initial.
|
||||
/// </remarks>
|
||||
private StatusReturn ValidateCsd(out String feedbackMsg)
|
||||
{
|
||||
feedbackMsg = "";
|
||||
if (ProductionRequirements == null )
|
||||
{
|
||||
feedbackMsg = Resources.StrErrorMsgProductionRequirements;
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
return GenericChecks.ValidateCsd(ProductionRequirements, out feedbackMsg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check production order number between meter and requirements.
|
||||
///
|
||||
@@ -1142,7 +1181,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
CalibCheckRegisterRestorer.OnProcessUpdate += ProcessUpdate_Handler;
|
||||
|
||||
// Compare the database value and the meter value (read in advance in the PreExecuteProcess)
|
||||
if (!CalibCheckRegisterRestorer.CompareRegisters(CancellationToken))
|
||||
if (!CalibCheckRegisterRestorer.CompareRegisters(CalibCheckRegisterRestorer.RecoveryRegisters,
|
||||
CancellationToken))
|
||||
{
|
||||
// Stop logging
|
||||
CalibCheckRegisterRestorer.OnProcessUpdate -= ProcessUpdate_Handler;
|
||||
|
||||
+32
-12
@@ -1,5 +1,4 @@
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SIRTCOM;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -8,6 +7,7 @@ using System.Net;
|
||||
using System.Threading;
|
||||
using System.Windows.Threading;
|
||||
using System.Xml.Linq;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig;
|
||||
@@ -189,6 +189,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="2025-Oct-13..14" author="Thomas Wiedebusch">
|
||||
/// - Service SIRT verbose output and additional error handling and warning.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-26" author="Thomas Wiedebusch">
|
||||
/// - Exit with error if database content for RSSI cannot be loaded.
|
||||
/// </remarks>
|
||||
public override StatusReturn ExecuteProcess()
|
||||
{
|
||||
// This will force to reset all values, Sentinel and Prepare shipping will fail based on EOL Progress
|
||||
@@ -292,12 +295,12 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
}
|
||||
|
||||
var ServicePorts = new List<Int32>();
|
||||
if (sirtConfig.ServiceSirtComport433MHz != null &&
|
||||
if (sirtConfig.ServiceSirtComport433MHz != null &&
|
||||
int.TryParse(sirtConfig.ServiceSirtComport433MHz.Replace("COM", ""), out var serviceSirtComport))
|
||||
{
|
||||
ServicePorts.Add(serviceSirtComport);
|
||||
}
|
||||
if (sirtConfig.ServiceSirtComport868MHz != null &&
|
||||
if (sirtConfig.ServiceSirtComport868MHz != null &&
|
||||
int.TryParse(sirtConfig.ServiceSirtComport868MHz.Replace("COM", ""), out serviceSirtComport))
|
||||
{
|
||||
ServicePorts.Add(serviceSirtComport);
|
||||
@@ -351,7 +354,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Clear the measurement as on a retry started from main control the old values will be displayed
|
||||
ClearRssiMeasurement();
|
||||
// kick off RSSI test
|
||||
StartRssiMeasurement();
|
||||
if (!StartRssiMeasurement(out var errorMsg))
|
||||
return SetTestFailed(errorMsg);
|
||||
|
||||
// Exit if meanwhile cancellation is required
|
||||
if (CancellationToken.IsCancellationRequested)
|
||||
@@ -525,7 +529,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
private void UpdateUc()
|
||||
{
|
||||
_checkRadioUserControl.SetUi(new UcRadioCheck.UiContainer(_rssiPamSirtDbMin, _rssiSemiCordonelDbMin,
|
||||
_rssiPamSirtMeasuredByCordonel, _rssiSemiCordonelMeasuredBySirt, _rssiPamSirtDbMax, _rssiSemiCordonelDbMax));
|
||||
_rssiPamSirtMeasuredByCordonel, _rssiSemiCordonelMeasuredBySirt, _rssiPamSirtDbMax,
|
||||
_rssiSemiCordonelDbMax));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -535,8 +540,12 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="????" author="Roland Drabesch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
private void StartRssiMeasurement()
|
||||
/// <remarks date="2025-Nov-26" author="Thomas Wiedebusch">
|
||||
/// - Exit with error if database content for RSSI cannot be loaded.
|
||||
/// </remarks>
|
||||
private Boolean StartRssiMeasurement(out String errorMsg)
|
||||
{
|
||||
errorMsg = "";
|
||||
// disable all buttons during ongoing measurement process
|
||||
DisableAllButtons();
|
||||
UpdateUc();
|
||||
@@ -544,7 +553,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
try
|
||||
{
|
||||
ActualProcessProgress++;
|
||||
GetRssiMinMaxValuesFromDb(_sirtBoxNr, Meter.OrderNumber);
|
||||
if (!GetRssiMinMaxValuesFromDb(_sirtBoxNr, Meter.OrderNumber, out errorMsg))
|
||||
return false;
|
||||
SendPamListenSemi((Int32)_radioAddressCordonel, _rssiSirtComport, _radioEncryptionKey);
|
||||
UpdateUc();
|
||||
ActualProcessProgress++;
|
||||
@@ -554,7 +564,10 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
_testFinished = true;
|
||||
Meter?.WriteLog(ex.Message);
|
||||
LogNewStatusMsg(Resources.StrErrorMsgRadioCheck);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -675,8 +688,12 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="????" author="Roland Drabesch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
private void GetRssiMinMaxValuesFromDb(Byte BoxNr, Int32 productionOrderNo)
|
||||
/// <remarks date="2025-Nov-26" author="Thomas Wiedebusch">
|
||||
/// - Exit with error if database content for RSSI cannot be loaded.
|
||||
/// </remarks>
|
||||
private Boolean GetRssiMinMaxValuesFromDb(Byte BoxNr, Int32 productionOrderNo, out String errorMsg)
|
||||
{
|
||||
errorMsg = "";
|
||||
try
|
||||
{
|
||||
if (_dataContainer != null)
|
||||
@@ -685,8 +702,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
var body = LocalWebRequest.GetRequest(url, 300000, out var httpStatus);
|
||||
if (httpStatus != HttpStatusCode.OK || string.IsNullOrEmpty(body))
|
||||
{
|
||||
ErrorMsgDispatcher(Resources.StrErrorMsgGetRadioRssiLimitsFromDb);
|
||||
return;
|
||||
errorMsg = Resources.StrErrorMsgGetRadioRssiLimitsFromDb;
|
||||
return false;
|
||||
}
|
||||
var o = JObject.Parse(body);
|
||||
|
||||
@@ -707,8 +724,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
catch (Exception ex)
|
||||
{
|
||||
Meter?.WriteLog(ex.Message);
|
||||
ErrorMsgDispatcher(Resources.StrErrorMsgGetRadioRssiLimitsFromDb);
|
||||
errorMsg = Resources.StrErrorMsgGetRadioRssiLimitsFromDb;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+23
-26
@@ -130,7 +130,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
productionProcessNo: 0,
|
||||
// CheckNewMeter will exit with repeated detect or connect
|
||||
nextStateOnSuccess: ProcessState.CheckNewMeter),
|
||||
|
||||
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ConnectCordonel(Resources.StrStateConnectCordonel),
|
||||
processState: ProcessState.ConnectCordonel,
|
||||
@@ -147,17 +147,14 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState: ProcessState.GetProgrammingParameters),
|
||||
|
||||
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new GetFinalParametrization(Resources.StrStateGetProgrammingParameters),
|
||||
processState: ProcessState.GetProgrammingParameters,
|
||||
processInfo: Resources.StrStateGetProgrammingParameters,
|
||||
productionProcessNo: 3,
|
||||
// Avoid automatic change after completion as parallel process is active
|
||||
nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState: ProcessState.CreateEolProgress),
|
||||
|
||||
nextStateOnSuccess: ProcessState.CreateEolProgress),
|
||||
|
||||
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
|
||||
|
||||
#region ----------------------------------- EOL-STATES ------------------------------------------------
|
||||
@@ -168,7 +165,16 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
processState: ProcessState.CreateEolProgress,
|
||||
processInfo: Resources.StrStateCreateEolProgress,
|
||||
productionProcessNo: null,
|
||||
nextStateOnSuccess: ProcessState.ProcessPasswordFile),
|
||||
nextStateOnSuccess: ProcessState.ExecFinalParametrization),
|
||||
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ExecFinalParametrization(Resources.StrStateFinalParametrization),
|
||||
processState: ProcessState.ExecFinalParametrization,
|
||||
processInfo: Resources.StrStateFinalParametrization,
|
||||
productionProcessNo: 4,
|
||||
nextStateOnSuccess: ProcessState.ProcessPasswordFile,
|
||||
// Wait for completion of all processes to avoid side effects
|
||||
waitForAllProcesses: true),
|
||||
|
||||
// Precondition: - The connection process has to be completed as a password change in the DB
|
||||
// will take place: Skeleton to Password Level 8. Not waiting for completion may cause side
|
||||
@@ -179,23 +185,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
productionProcess: new ExecPasswordFile(Resources.StrStatePasswordFile),
|
||||
processState: ProcessState.ProcessPasswordFile,
|
||||
processInfo: Resources.StrStatePasswordFile,
|
||||
productionProcessNo: 4,
|
||||
nextStateOnSuccess: ProcessState.ExecFinalParametrization,
|
||||
// Wait for completion of all processes to avoid side effects
|
||||
waitForAllProcesses: true),
|
||||
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ExecFinalParametrization(Resources.StrStateFinalParametrization),
|
||||
processState: ProcessState.ExecFinalParametrization,
|
||||
processInfo: Resources.StrStateFinalParametrization,
|
||||
productionProcessNo: 5,
|
||||
nextStateOnSuccess: ProcessState.ExecStoreConfiguration),
|
||||
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ExecStoreConfiguration(Resources.StrStateStoreConfiguration),
|
||||
processState: ProcessState.ExecStoreConfiguration,
|
||||
processInfo: Resources.StrStateStoreConfiguration,
|
||||
productionProcessNo: 6,
|
||||
nextStateOnSuccess: ProcessState.CheckProductionState),
|
||||
|
||||
// Parametrization has to be completed as those needed to check e.g. the remaining FW based lifetime.
|
||||
@@ -203,8 +193,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
productionProcess: new CheckProductionState(Resources.StrStateCheckProductionState),
|
||||
processState: ProcessState.CheckProductionState,
|
||||
processInfo: Resources.StrStateCheckProductionState,
|
||||
productionProcessNo: 7,
|
||||
nextStateOnSuccess: ProcessState.RebootCordonel),
|
||||
productionProcessNo: 6,
|
||||
nextStateOnSuccess: ProcessState.ExecStoreConfiguration),
|
||||
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ExecStoreConfiguration(Resources.StrStateStoreConfiguration),
|
||||
processState: ProcessState.ExecStoreConfiguration,
|
||||
processInfo: Resources.StrStateStoreConfiguration,
|
||||
productionProcessNo: 7,
|
||||
nextStateOnSuccess: ProcessState.RebootCordonel),
|
||||
|
||||
// Precondition: - The store configuration has to be executed to safe all settings
|
||||
// to non-volatile memory and checked if remaining valid after the reboot.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd;
|
||||
|
||||
+12
-10
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
@@ -77,7 +77,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
}
|
||||
var ale = Meter.ReadRegister("CUSTOMER_AlarmEnableMask");
|
||||
// Read and automatically log it to database if logging is active
|
||||
Meter.ReadRegister("CUSTOMER_AlarmEnableMask");
|
||||
|
||||
#region ----------------------------------- Reboot ----------------------------------------------------
|
||||
// reboot the meter and avoid doubled storage of configurations
|
||||
var _meterResetPsu = new MeterResetPsu(Meter)
|
||||
@@ -123,7 +125,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
ProgrammingSource.ProgramInternal));
|
||||
ActualProcessProgress++;
|
||||
// Reset reboot counter
|
||||
retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("CUSTOMER_RebootCount",
|
||||
retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("CUSTOMER_RebootCount",
|
||||
new Byte[] { 0x00 }, ProgrammingSource.ProgramInternal));
|
||||
// Reset alarms Customer
|
||||
retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("CUSTOMER_TriggerAlarmCancel",
|
||||
@@ -173,11 +175,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
var retryCtr = 2;
|
||||
|
||||
// Check all values for 0 after reset and followed reboot which may use the
|
||||
var readBackScaledBilling =
|
||||
var readBackScaledBilling =
|
||||
RegisterConverter.ByteArrayToValue<Int64>(Meter.ReadRegister("GENESISFLOW_ScaledBilling"));
|
||||
var readBackUnscaledFwd =
|
||||
var readBackUnscaledFwd =
|
||||
RegisterConverter.ByteArrayToValue<UInt64>(Meter.ReadRegister("GENESISFLOW_UnscaledFwd"));
|
||||
var readBackUnscaledRev =
|
||||
var readBackUnscaledRev =
|
||||
RegisterConverter.ByteArrayToValue<UInt64>(Meter.ReadRegister("GENESISFLOW_UnscaledRev"));
|
||||
|
||||
while (retryCtr-- > 0 &&
|
||||
@@ -186,11 +188,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Backup sealing state as for the NA region it may be unsealed
|
||||
var displaySealingState =
|
||||
RegisterConverter.ByteArrayToValue<Byte>(Meter.ReadRegister("GENESISFLOW_SealDisplay"));
|
||||
|
||||
|
||||
// Unseal accumulator reset capability
|
||||
retValBol = WriteRegisterLogAndProcessCtr(new ProgrammingParameters("GENESISFLOW_SealDisplay",
|
||||
new Byte[] { 0x00 }, ProgrammingSource.ProgramInternal));
|
||||
|
||||
|
||||
// Reset accumulators again
|
||||
retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("GENESISFLOW_ResetAccumulators",
|
||||
new Byte[] { 0x01 }, ProgrammingSource.ProgramInternal));
|
||||
@@ -201,7 +203,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// it doesn't have to be a change.
|
||||
retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("GENESISFLOW_ForwardArrow",
|
||||
new[] { forwardArrow }, ProgrammingSource.ProgramInternal));
|
||||
|
||||
|
||||
// Seal accumulator reset capability
|
||||
// ReSharper disable once RedundantAssignment as it is used for DEBUG
|
||||
retValBol &= WriteRegisterLogAndProcessCtr(new ProgrammingParameters("GENESISFLOW_SealDisplay",
|
||||
@@ -224,7 +226,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
EolProgress.RebootDoneChecked = EOLStatus.FAIL;
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
SuccessMsgDispatcher(Resources.StrSuccessMsgAlarmReset);
|
||||
EolProgress.RebootDoneChecked = EOLStatus.OK;
|
||||
return StatusReturn.Okay;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
|
||||
|
||||
+90
-28
@@ -4,6 +4,7 @@ using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LaaPackages.Features.Cordonel.Models.Values;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications;
|
||||
@@ -40,10 +41,10 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
{
|
||||
if (meter == null ||
|
||||
productionRequirements == null ||
|
||||
(assemblyLine && productionRequirements.RequiredLifeTimeYearsAssembly == null) ||
|
||||
(assemblyLine && productionRequirements.RequiredLifeTimeYearsAssembly <= 0) ||
|
||||
(!assemblyLine && productionRequirements.RequiredLifeTimeYearsShipping == null) ||
|
||||
(!assemblyLine && productionRequirements.RequiredLifeTimeYearsShipping <= 0) ||
|
||||
assemblyLine && productionRequirements.RequiredLifeTimeYearsAssembly == null ||
|
||||
assemblyLine && productionRequirements.RequiredLifeTimeYearsAssembly <= 0 ||
|
||||
!assemblyLine && productionRequirements.RequiredLifeTimeYearsShipping == null ||
|
||||
!assemblyLine && productionRequirements.RequiredLifeTimeYearsShipping <= 0 ||
|
||||
productionStatus == null)
|
||||
{
|
||||
feedbackMsg = Resources.StrErrorMsgLifeTimeCalculation;
|
||||
@@ -65,16 +66,16 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
var strFwCalculatedLifeTimeYears = "";
|
||||
if (productionStatus.FwCalculatedRemainingLifeTimeYears != null)
|
||||
{
|
||||
strFwCalculatedLifeTimeYears =
|
||||
strFwCalculatedLifeTimeYears =
|
||||
$@" - {Resources.StrMsgRemainingLifeTime}: " +
|
||||
$"{productionStatus.FwCalculatedRemainingLifeTimeYears:F2} " +
|
||||
$"{productionStatus.FwCalculatedRemainingLifeTimeYears:F2} " +
|
||||
$"{Resources.StrMsgYears} (Firmware)";
|
||||
}
|
||||
// Build message for required versus calculated lifetime
|
||||
var lifeTime = $"{Resources.StrMsgRemainingLifeTime}: " +
|
||||
// Actual SW calculated lifetime based on readings from meter
|
||||
$"{productionStatus.RemainingLifeTimeYears:F2} " +
|
||||
$"{Resources.StrMsgYears} (Software)" +
|
||||
$"{Resources.StrMsgYears} (Software)" +
|
||||
// Optional FW calculation
|
||||
strFwCalculatedLifeTimeYears +
|
||||
$" - {Resources.StrMsgRequiredLifeTime}: " +
|
||||
@@ -83,12 +84,12 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
$"{Resources.StrMsgYears}";
|
||||
|
||||
// Check required years for assembly
|
||||
if ((assemblyLine &&
|
||||
productionRequirements.RequiredLifeTimeYearsAssembly > productionStatus.RemainingLifeTimeYears) ||
|
||||
(!assemblyLine &&
|
||||
(productionRequirements.RequiredLifeTimeYearsShipping > productionStatus.RemainingLifeTimeYears ||
|
||||
// internally in FW calculated remaining lifetime visual for customer in DIAVASO
|
||||
productionRequirements.RequiredLifeTimeYearsShipping > productionStatus.FwCalculatedRemainingLifeTimeYears)))
|
||||
if (assemblyLine &&
|
||||
productionRequirements.RequiredLifeTimeYearsAssembly > productionStatus.RemainingLifeTimeYears ||
|
||||
!assemblyLine &&
|
||||
(productionRequirements.RequiredLifeTimeYearsShipping > productionStatus.RemainingLifeTimeYears ||
|
||||
// internally in FW calculated remaining lifetime visual for customer in DIAVASO
|
||||
productionRequirements.RequiredLifeTimeYearsShipping > productionStatus.FwCalculatedRemainingLifeTimeYears))
|
||||
{
|
||||
feedbackMsg = $"{Resources.StrErrorMsg}: {lifeTime}";
|
||||
return StatusReturn.Failed;
|
||||
@@ -134,8 +135,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
|
||||
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 *
|
||||
// Allow 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} - " +
|
||||
@@ -179,8 +180,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
{
|
||||
if (meter == null ||
|
||||
productionRequirements == null ||
|
||||
(assemblyLine && productionRequirements.MaxDrainedBatteryLoadPercentAssembly == null) ||
|
||||
(!assemblyLine && productionRequirements.MaxDrainedBatteryLoadPercentShipping == null) ||
|
||||
assemblyLine && productionRequirements.MaxDrainedBatteryLoadPercentAssembly == null ||
|
||||
!assemblyLine && productionRequirements.MaxDrainedBatteryLoadPercentShipping == null ||
|
||||
productionStatus == null)
|
||||
{
|
||||
feedbackMsg = Resources.StrErrorMsgBatteryLoadCalculation;
|
||||
@@ -231,10 +232,10 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
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.StrMsgRequirementAbsolutLimitDrainedBattery}: " + strStation;
|
||||
|
||||
var strBatLoad = $"{Resources.StrMsgDrainedBattery}: " +
|
||||
// Actual calculated battery load based on readings from meter
|
||||
@@ -245,10 +246,10 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
|
||||
|
||||
// This is the absolut limit even if the "AlternativeRequiredBatteryLoadPercent" will be used
|
||||
if ((assemblyLine && productionStatus.DrainedBatteryLoadPercent >
|
||||
productionRequirements.MaxDrainedBatteryLoadPercentAssembly) ||
|
||||
(!assemblyLine && productionStatus.DrainedBatteryLoadPercent >
|
||||
productionRequirements.MaxDrainedBatteryLoadPercentShipping))
|
||||
if (assemblyLine && productionStatus.DrainedBatteryLoadPercent >
|
||||
productionRequirements.MaxDrainedBatteryLoadPercentAssembly ||
|
||||
!assemblyLine && productionStatus.DrainedBatteryLoadPercent >
|
||||
productionRequirements.MaxDrainedBatteryLoadPercentShipping)
|
||||
{
|
||||
feedbackMsg = $"{Resources.StrErrorMsg}: {strBatLoad}";
|
||||
return StatusReturn.Failed;
|
||||
@@ -450,12 +451,12 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
isStandardActive = true;
|
||||
|
||||
// At least one requirement needs to be active and a requirement number and version has to be set
|
||||
if ((!isStandardActive && !isSpecialActive) ||
|
||||
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)))
|
||||
isSpecialActive && (productionRequirements.SpecialId == null ||
|
||||
productionRequirements.SpecialVersion == null))
|
||||
{
|
||||
feedbackMsg = Resources.StrErrorMsgRequirementInactive;
|
||||
return StatusReturn.Failed;
|
||||
@@ -472,6 +473,67 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
|
||||
return StatusReturn.Okay;
|
||||
}
|
||||
/// <summary>
|
||||
/// Validate the CSD:
|
||||
/// - A CSD number is needed,
|
||||
/// - The CSD status has to allow production:
|
||||
/// - <see cref="CSDStatus.Blocked"/> are not allowed for production
|
||||
/// - <see cref="CSDStatus.New"/> are not allowed for production
|
||||
/// - <see cref="CSDStatus.Known"/> are all the today's CSD for production 2025-Nov-21 (but not released)
|
||||
/// - <see cref="CSDStatus.Released"/> are all the today's CSD for production 2025-Nov-21 (but not released)
|
||||
/// </summary>
|
||||
/// <param name="productionRequirements"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Nov-21" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
public static StatusReturn ValidateCsd(CordonelRequirements productionRequirements, out String feedbackMsg)
|
||||
{
|
||||
feedbackMsg = "";
|
||||
if (productionRequirements == null)
|
||||
{
|
||||
feedbackMsg = Resources.StrErrorMsgProductionRequirements;
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
// Extract CSD information.
|
||||
var csd = productionRequirements.CSD;
|
||||
if (csd == null ||
|
||||
csd.Status == CSDStatus.Null ||
|
||||
string.IsNullOrEmpty(csd.Name) ||
|
||||
string.IsNullOrEmpty(csd.Code) ||
|
||||
csd.IdentId == 0)
|
||||
{
|
||||
feedbackMsg = Resources.StrErrorMsgCsdNotReceived;
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
var csdId = $"{csd.Name} - Code: {csd.Code} - ID: {csd.IdentId}";
|
||||
|
||||
// Released is the best case
|
||||
if (csd.Status == CSDStatus.Released)
|
||||
{
|
||||
feedbackMsg = $"{Resources.StrSuccessMsgCsdValid} - {csdId}";
|
||||
return StatusReturn.Okay;
|
||||
}
|
||||
// Known are all the today's CSD for production 2025-Nov-21 (but not released)
|
||||
if (csd.Status == CSDStatus.Known)
|
||||
{
|
||||
feedbackMsg = $"{Resources.StrWarningMsgCsdKnown} - {csdId}";
|
||||
return StatusReturn.Warning;
|
||||
}
|
||||
|
||||
if (csd.Status == CSDStatus.New)
|
||||
{
|
||||
feedbackMsg = $"{Resources.StrErrorMsgCsdNewNotApproved} - {csdId}";
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
feedbackMsg = $"{Resources.StrErrorMsgCsdBlocked} - {csdId}";
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check the measurements from Kitron for this specific Cordonel if it is an EMEA region.
|
||||
/// </summary>
|
||||
@@ -521,8 +583,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
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")) )
|
||||
{
|
||||
!registerRestorer.RecoveryRegisters.Any(x => x.RegisterIdent.Equals("SENSUSRADIO_ImpedanceCodeOption")))
|
||||
{
|
||||
feedbackMsg = Resources.StrErrorMsgRadioSignalLevels + " " + meterInfo;
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
+16
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
|
||||
@@ -35,6 +37,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
/// <remarks date="2025-Sep-01" author="Thomas Wiedebusch">
|
||||
/// - Early return if login failed.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-18" author="Thomas Wiedebusch">
|
||||
/// - Threshold for allowed reboots to detect erroneous hardware.
|
||||
/// </remarks>
|
||||
public override StatusReturn ExecuteProcess()
|
||||
{
|
||||
Boolean retVal;
|
||||
@@ -61,6 +66,17 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
|
||||
ErrorMsgDispatcher(Resources.StrErrorMsgCordonelLogin);
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
// Read reboot count and compare with hardcoded maximum value
|
||||
var rebootCount =
|
||||
RegisterConverter.ByteArrayToValue<UInt32>(Meter.ReadRegister("CUSTOMER_RebootCount"));
|
||||
if (rebootCount > MeterResetPsu.MAX_REBOOTS_FOR_HEALTHY_HW)
|
||||
{
|
||||
ErrorMsgDispatcher(Resources.StrErrorMsgTooManyReboots +
|
||||
$" - {Resources.StrProcessStateAllowed}: {MeterResetPsu.MAX_REBOOTS_FOR_HEALTHY_HW}" +
|
||||
$" - {Resources.StrProcessStateDetected}: {rebootCount}");
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
// If interface is outdated
|
||||
if (!Meter.InterfaceSupportsFwVersion)
|
||||
|
||||
@@ -101,6 +101,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
IGenesisMeter Meter
|
||||
{
|
||||
set;
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+24
-3
@@ -20,7 +20,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
/// <summary>
|
||||
/// Maximum of expected processing steps for this process to feed the GUI progress bar.
|
||||
/// </summary>
|
||||
private const Int32 MaxActualProgressSteps = 14;
|
||||
private const Int32 MaxActualProgressSteps = 15;
|
||||
|
||||
/// <summary>
|
||||
/// FW update package containing the ABC and the ADF.
|
||||
@@ -157,8 +157,13 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-21" author="Thomas Wiedebusch">
|
||||
/// - Validate CSD.
|
||||
/// </remarks>
|
||||
public override StatusReturn ExecuteProcess()
|
||||
{
|
||||
var erroneousSequenceStep = false;
|
||||
var warningSequenceStep = false;
|
||||
#region ----------------------------------- Check Requirements --------------------------------------------
|
||||
|
||||
var statusReturn = GenericChecks.CheckRequirements(ProductionRequirements, out var feedbackMsg);
|
||||
@@ -172,6 +177,24 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
ActualProcessProgress++;
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Validate CSD --------------------------------------------------
|
||||
|
||||
statusReturn = GenericChecks.ValidateCsd(ProductionRequirements, out feedbackMsg);
|
||||
if (StatusReturn.Failed == statusReturn)
|
||||
{
|
||||
ErrorMsgDispatcher(feedbackMsg);
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
if (StatusReturn.Warning == statusReturn)
|
||||
{
|
||||
WarningMsgDispatcher(feedbackMsg);
|
||||
}
|
||||
|
||||
SuccessMsgDispatcher(feedbackMsg);
|
||||
ActualProcessProgress++;
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Production Order ----------------------------------------
|
||||
|
||||
// Production order
|
||||
@@ -252,8 +275,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
|
||||
#region ----------------------------------- Check Kitron Radio Signal Levels ------------------------------
|
||||
|
||||
var erroneousSequenceStep = false;
|
||||
var warningSequenceStep = false;
|
||||
statusReturn = GenericChecks.CheckKitronRadioSignalLevels(Meter, RegisterRestorer,
|
||||
ProductionRequirements.SkipRadioCheck, out feedbackMsg);
|
||||
|
||||
|
||||
-1
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
|
||||
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.UserControls;
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
using System;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using System.Windows.Threading;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EventArgs;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
using Timer = System.Threading.Timer;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
@@ -98,6 +101,17 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
private Timer _processCtrlTimer;
|
||||
private const Int32 ProcessTimerCycleMs = 250;
|
||||
|
||||
// Delay timer between finish exec-parametrization and 'StoreConfiguration' as 'PERIODICLOG' doesn't
|
||||
// have 'StoreConfiguration' and needs at least 20 s to update contents before 'StoreConfiguration'
|
||||
// can be dispatched to 'SENSUSRADIO'.
|
||||
private DispatcherTimer _paramExeFinishedToStoreConfigDelayTimer;
|
||||
// Cycle time in milliseconds
|
||||
private const Int32 ParamExeFinishedToStoreConfigDelayCycleMs = 1000;
|
||||
// Time to keep in seconds
|
||||
private const Int32 ParamExeFinishedToStoreConfigTimeS = 22;
|
||||
private Boolean _paramExeFinishedToStoreConfigDelayTimerExceeded;
|
||||
private DateTimeOffset _paramExeFinishedToStoreConfigDelayTimerStartTime;
|
||||
|
||||
/// <summary>
|
||||
/// Avoid waiting for a single process completion.
|
||||
/// </summary>
|
||||
@@ -126,9 +140,18 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// - Always RegisterWatchService on,
|
||||
/// - Always MinMaxCHeck on.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-20" author="Thomas Wiedebusch">
|
||||
/// - _paramExeFinishedToStoreConfigurationDelayTimer.
|
||||
/// </remarks>
|
||||
public ProcessController(Int32 slot, IProcessStateDef processSateDef)
|
||||
{
|
||||
// Timer for cyclic call of state machine
|
||||
_processCtrlTimer = new Timer(TmrProcessCtrlCycle_Elapsed, null, ProcessTimerCycleMs, ProcessTimerCycleMs);
|
||||
|
||||
// Delay timer between final-param-exec finished and start of 'StoreConfiguration'
|
||||
_paramExeFinishedToStoreConfigDelayTimer = new DispatcherTimer();
|
||||
_paramExeFinishedToStoreConfigDelayTimer.Tick += TmrParamExeFinishedToStoreConfigCycle_Tick;
|
||||
_paramExeFinishedToStoreConfigDelayTimer.Interval = TimeSpan.FromMilliseconds(ParamExeFinishedToStoreConfigDelayCycleMs);
|
||||
_slot = slot;
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
_cancellationToken = _cancellationTokenSource.Token;
|
||||
@@ -204,6 +227,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
{
|
||||
_processCtrlTimer?.Dispose();
|
||||
_processCtrlTimer = null;
|
||||
_paramExeFinishedToStoreConfigDelayTimer?.Stop();
|
||||
_paramExeFinishedToStoreConfigDelayTimer = null;
|
||||
_processStateDef = null;
|
||||
KillProcesses();
|
||||
RemoveMeter();
|
||||
@@ -226,6 +251,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// <remarks date="2023-Jul-17" author="Thomas Wiedebusch">
|
||||
/// - Remove process events if process is finished or skipped.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-20" author="Thomas Wiedebusch">
|
||||
/// - Init and start the delay timer between finish exec-parametrization and 'StoreConfiguration
|
||||
/// to all apps as 'PERIODICLOG' doesn't have 'StoreConfiguration' and needs at least 20 s to
|
||||
/// update contents before 'SENSUSRADIO' tries to synchronize all settings.
|
||||
/// </remarks>
|
||||
private void ProcessStateChanged_Handler(Object sender, SingleProcessStateArgs e)
|
||||
{
|
||||
IProductionProcess pp = null;
|
||||
@@ -250,6 +280,22 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
case SingleProcessState.Running:
|
||||
break;
|
||||
}
|
||||
// Delay timer init and start if parametrization exec finished but only for 'EMEA' region
|
||||
if (pp != null &&
|
||||
pp.ProcessName != null &&
|
||||
pp.Meter != null &&
|
||||
pp.Meter.Region.Equals("EMEA") &&
|
||||
pp.ProcessName.Equals(Resources.StrStateFinalParametrization) &&
|
||||
e.SingleProcessState == SingleProcessState.Succeeded)
|
||||
{
|
||||
var teaTime = new TimeT();
|
||||
_paramExeFinishedToStoreConfigDelayTimerExceeded = false;
|
||||
_paramExeFinishedToStoreConfigDelayTimerStartTime = teaTime.DateTimeUtc;
|
||||
_paramExeFinishedToStoreConfigDelayTimer.Start();
|
||||
var msg = $"{Resources.StrMsgRebootDelayTimerStarted} {ParamExeFinishedToStoreConfigTimeS} s" +
|
||||
$" - {teaTime}";
|
||||
OnProcessLogRequest?.Invoke(sender, new ProcessLogArgs(msg));
|
||||
}
|
||||
// signal state change to GUI
|
||||
OnProcessStateChanged?.Invoke(sender, e);
|
||||
}
|
||||
@@ -300,6 +346,30 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
StateMachine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delay timer between parametrization exec finished and store config to support the 'PERIODICLOG' update
|
||||
/// which needs at least 20 s after writing to update the internal contents. Not holding this time will cause
|
||||
/// to take the value before the writing access as 'SENSUSRADIO' will synchronize all parameters if it receives
|
||||
/// the 'StoreConfiguration' command.
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <remarks date="2025-Nov-20" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
private void TmrParamExeFinishedToStoreConfigCycle_Tick(Object state, System.EventArgs e)
|
||||
{
|
||||
var teaTime = new TimeT();
|
||||
var timeSpan = teaTime.DateTimeUtc - _paramExeFinishedToStoreConfigDelayTimerStartTime;
|
||||
if (timeSpan.Seconds >= ParamExeFinishedToStoreConfigTimeS)
|
||||
{
|
||||
_paramExeFinishedToStoreConfigDelayTimerExceeded = true;
|
||||
_paramExeFinishedToStoreConfigDelayTimer.Stop();
|
||||
var msg = $"{Resources.StrMsgRebootDelayTimerExceeded} {ParamExeFinishedToStoreConfigTimeS} s - {teaTime}";
|
||||
OnProcessLogRequest?.Invoke(this, new ProcessLogArgs(msg));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion --------------------------------------- Events -----------------------------------------------------
|
||||
#region ------------------------------------------ State Machine ----------------------------------------------
|
||||
|
||||
@@ -732,25 +802,52 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// <remarks date="2025-Aug-11" author="Thomas Wiedebusch">
|
||||
/// - Removed cancellationToken assignment.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-20" author="Thomas Wiedebusch">
|
||||
/// Delay timer between finish exec-parametrization and 'StoreConfiguration' as 'PERIODICLOG' doesn't
|
||||
/// have 'StoreConfiguration' and needs at least 20 s to update contents before 'StoreConfiguration'
|
||||
/// can be dispatched to 'SENSUSRADIO'.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Nov-21" author="Thomas Wiedebusch">
|
||||
/// Abort enabled during waiting loop.
|
||||
/// </remarks>
|
||||
private void StartProcess(ProcessStateStruct processStateStruct)
|
||||
{
|
||||
// deny access if uninitialized
|
||||
// Deny access if uninitialized
|
||||
if (Processes == null || processStateStruct.ProductionProcess == null)
|
||||
return;
|
||||
|
||||
// do not start a new process if any error or abort request is signaled
|
||||
// Do not start a new process if any error or abort request is signaled
|
||||
if (AnyProcessRequiresAbortion() && !processStateStruct.StartAlways)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// process is waiting for execution after init, this overrides the eventually abort state
|
||||
// Process is waiting for execution after init, this overrides the eventually abort state
|
||||
processStateStruct.ProductionProcess.InitProcess();
|
||||
|
||||
// wait for a single process to complete before start of new depending on process
|
||||
// Wait for '_paramExeFinishedToRebootDelayTimerExceeded' before 'StoreConfiguration' to all apps
|
||||
while (processStateStruct.ProcessState == ProcessState.ExecStoreConfiguration &&
|
||||
_paramExeFinishedToStoreConfigDelayTimer != null &&
|
||||
_paramExeFinishedToStoreConfigDelayTimer.IsEnabled &&
|
||||
!_paramExeFinishedToStoreConfigDelayTimerExceeded &&
|
||||
!AnyProcessRequiresAbortion())
|
||||
{
|
||||
var teaTime = new TimeT();
|
||||
var timeSpan = teaTime.DateTimeUtc - _paramExeFinishedToStoreConfigDelayTimerStartTime;
|
||||
var msg = $"{Resources.StrMsgRebootDelayTimerActive} " +
|
||||
$"{timeSpan.Seconds}/{ParamExeFinishedToStoreConfigTimeS} s - {teaTime}";
|
||||
OnProcessLogRequest?.Invoke(this, new ProcessLogArgs(msg));
|
||||
OnProcessProgressChanged?.Invoke(this, new ProcessProgressArgs(ParamExeFinishedToStoreConfigTimeS,
|
||||
ProcessProgressArgs.ProcessProgressType.MaxActualProcessSteps));
|
||||
OnProcessProgressChanged?.Invoke(this, new ProcessProgressArgs(timeSpan.Seconds,
|
||||
ProcessProgressArgs.ProcessProgressType.ActualProcessSteps));
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
// Wait for a single process to complete before start of new depending on process
|
||||
if (processStateStruct.WaitForSingleProcess != null)
|
||||
{
|
||||
// each process will have its own timer until a timeout will change the state
|
||||
// Each process will have its own timer until a timeout will change the state
|
||||
while (Processes.Any(pp => !AnyProcessRequiresAbortion()
|
||||
&& _processStateDef.GetStateOfProcess(pp) == processStateStruct.WaitForSingleProcess
|
||||
&& WaitForProcess(pp)))
|
||||
@@ -759,10 +856,10 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
}
|
||||
}
|
||||
|
||||
// wait for all initialized processes to complete before start the new process
|
||||
// Wait for all initialized processes to complete before start the new process
|
||||
if (processStateStruct.WaitForAllProcesses)
|
||||
{
|
||||
// each process will have its own timer until a timeout will change the state,
|
||||
// Each process will have its own timer until a timeout will change the state,
|
||||
// avoid checking the new process, which is not started due to this waiting loop
|
||||
while (Processes.Any(pp => pp.ProcessName != processStateStruct.ProductionProcess.ProcessName
|
||||
&& WaitForProcess(pp)
|
||||
@@ -772,7 +869,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
}
|
||||
}
|
||||
|
||||
// if any process exits meanwhile with an error or abort request avoid a start of this process
|
||||
// If any process exits meanwhile with an error or abort request avoid a start of this process
|
||||
if ((!processStateStruct.StartAlways && AnyProcessRequiresAbortion())
|
||||
|| processStateStruct.ProductionProcess.SingleProcessState == SingleProcessState.Idle
|
||||
|| processStateStruct.ProductionProcess.SingleProcessState == SingleProcessState.Abort)
|
||||
@@ -789,12 +886,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
processStateStruct.ProductionProcess.ProductionStatus = _productionStatus;
|
||||
processStateStruct.ProductionProcess.ProductionRequirements = _cordonelRequirements;
|
||||
processStateStruct.ProductionProcess.EolProgress = _cordonelEolProgress;
|
||||
// processStateStruct.ProductionProcess.CancellationToken = _cancellationToken;
|
||||
|
||||
// kick off process execution, the breakExitState will not be used
|
||||
// Kick off process execution, the breakExitState will not be used
|
||||
processStateStruct.ProductionProcess.StartProcess(processStateStruct.NextStateOnSuccess,
|
||||
processStateStruct.ErrorExitState, processStateStruct.BreakExitState);
|
||||
// connect process events to actual process
|
||||
// Connect process events to actual process
|
||||
AddProcessEvents(processStateStruct.ProductionProcess);
|
||||
}
|
||||
|
||||
|
||||
@@ -845,7 +845,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
!string.IsNullOrEmpty(genesisMeter.MeterSize) ? genesisMeter.MeterSize : "?");
|
||||
|
||||
UpdateContentControl(lblMeterLengthValue,
|
||||
(!string.IsNullOrEmpty(genesisMeter.MeterLength) && !genesisMeter.MeterLength.Equals("?")) ?
|
||||
!string.IsNullOrEmpty(genesisMeter.MeterLength) && !genesisMeter.MeterLength.Equals("?") ?
|
||||
genesisMeter.MeterLength + " mm" : "?");
|
||||
|
||||
UpdateContentControl(lblInterfaceVersionValue,
|
||||
|
||||
@@ -492,6 +492,33 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: CSD is blocked for production.
|
||||
/// </summary>
|
||||
internal static string StrErrorMsgCsdBlocked {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMsgCsdBlocked", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: CSD is new and not approved for production.
|
||||
/// </summary>
|
||||
internal static string StrErrorMsgCsdNewNotApproved {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMsgCsdNewNotApproved", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: CSD status and number are unknown.
|
||||
/// </summary>
|
||||
internal static string StrErrorMsgCsdNotReceived {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMsgCsdNotReceived", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Data base access failed.
|
||||
/// </summary>
|
||||
@@ -1050,6 +1077,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Hardware reboots higher than allowed threshold.
|
||||
/// </summary>
|
||||
internal static string StrErrorMsgTooManyReboots {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMsgTooManyReboots", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Firmware is not supported.
|
||||
/// </summary>
|
||||
@@ -1635,6 +1671,33 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Expired delay timer between parametrization and store config.
|
||||
/// </summary>
|
||||
internal static string StrMsgRebootDelayTimerActive {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMsgRebootDelayTimerActive", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Stop: Delay timer between parametrization and store config after.
|
||||
/// </summary>
|
||||
internal static string StrMsgRebootDelayTimerExceeded {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMsgRebootDelayTimerExceeded", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Start: Delay timer between parametrization and store config for.
|
||||
/// </summary>
|
||||
internal static string StrMsgRebootDelayTimerStarted {
|
||||
get {
|
||||
return ResourceManager.GetString("StrMsgRebootDelayTimerStarted", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Estimated remaining lifetime.
|
||||
/// </summary>
|
||||
@@ -1734,6 +1797,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Allowed.
|
||||
/// </summary>
|
||||
internal static string StrProcessStateAllowed {
|
||||
get {
|
||||
return ResourceManager.GetString("StrProcessStateAllowed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ATTENTION.
|
||||
/// </summary>
|
||||
@@ -1752,6 +1824,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detected.
|
||||
/// </summary>
|
||||
internal static string StrProcessStateDetected {
|
||||
get {
|
||||
return ResourceManager.GetString("StrProcessStateDetected", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Success.
|
||||
/// </summary>
|
||||
@@ -2265,6 +2346,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Success: CSD is approved for production.
|
||||
/// </summary>
|
||||
internal static string StrSuccessMsgCsdValid {
|
||||
get {
|
||||
return ResourceManager.GetString("StrSuccessMsgCsdValid", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Success: Database with Cordonel radio encryption key successfully crosschecked.
|
||||
/// </summary>
|
||||
@@ -2509,7 +2599,25 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to WARNING: Inspect results.
|
||||
/// Looks up a localized string similar to WARNING: CSD is known and temporary used for production.
|
||||
/// </summary>
|
||||
internal static string StrWarningMsgCsdKnown {
|
||||
get {
|
||||
return ResourceManager.GetString("StrWarningMsgCsdKnown", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to WARNING: Parameter restored after reboot as it does not survive it.
|
||||
/// </summary>
|
||||
internal static string StrWarningMsgParameterCompare {
|
||||
get {
|
||||
return ResourceManager.GetString("StrWarningMsgParameterCompare", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to WARNING: Result needs inspection! Process.
|
||||
/// </summary>
|
||||
internal static string StrWarningMsgProcess {
|
||||
get {
|
||||
@@ -2527,7 +2635,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to WARNING: Service SIRT alarm mask setup skipped .
|
||||
/// Looks up a localized string similar to WARNING: Service SIRT alarm mask check skipped .
|
||||
/// </summary>
|
||||
internal static string StrWarningMsgServiceSirtSkipped {
|
||||
get {
|
||||
|
||||
@@ -437,7 +437,7 @@
|
||||
<value>FEHLER: Service SIRT Start des Messageserves fehlgeschlagen </value>
|
||||
</data>
|
||||
<data name="StrWarningMsgServiceSirtSkipped" xml:space="preserve">
|
||||
<value>WARNUNG: Service SIRT Alarmmaskeneinstellung übersprungen </value>
|
||||
<value>WARNUNG: Service SIRT Alarmmaskenüberprüfung ausgelassen </value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRadioKey" xml:space="preserve">
|
||||
<value>FEHLER: Funkverschlüsselungscode fehlerhaft</value>
|
||||
@@ -660,6 +660,9 @@
|
||||
</data>
|
||||
<data name="StrErrorMsgParameterCompare" xml:space="preserve">
|
||||
<value>FEHLER: Parametervergleich fehlgeschlagen</value>
|
||||
</data>
|
||||
<data name="StrWarningMsgParameterCompare" xml:space="preserve">
|
||||
<value>WARNUNG: Parameter überlebte den Neustart nicht und wurde danach wiederhergestellt</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgParameterWrite" xml:space="preserve">
|
||||
<value>FEHLER: Parameterschreiben fehlgeschlagen</value>
|
||||
@@ -677,10 +680,43 @@
|
||||
<value>WARNUNG</value>
|
||||
</data>
|
||||
<data name="StrWarningMsgProcess" xml:space="preserve">
|
||||
<value>WARNUNG: Ergebnis manuell überprüfen</value>
|
||||
<value>WARNUNG: Ergebnis muß überprüft werden! Prozeß </value>
|
||||
</data>
|
||||
<data name="StrErrorMsgTooManyReboots" xml:space="preserve">
|
||||
<value>FEHLER: Hardwareneustarts über der erlaubten Grenze</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgCsdBlocked" xml:space="preserve">
|
||||
<value>FEHLER: CSD ist für die Production gesperrt</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgCsdNewNotApproved" xml:space="preserve">
|
||||
<value>ERROR: CSD ist neu aber für die Production gesperrt</value>
|
||||
</data>
|
||||
<data name="StrSuccessMsgCsdValid" xml:space="preserve">
|
||||
<value>Erfolg: CSD ist zur Produktion freigegeben</value>
|
||||
</data>
|
||||
<data name="StrWarningMsgCsdKnown" xml:space="preserve">
|
||||
<value>WARNUNG: CSD ist bekannt und temporär zur Produktion freigegeben</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgCsdNotReceived" xml:space="preserve">
|
||||
<value>WARNUNG: CSD Status und Nummer sind unbekannt</value>
|
||||
</data>
|
||||
<data name="StrProcessStateAttention" xml:space="preserve">
|
||||
<value>ACHTUNG</value>
|
||||
</data>
|
||||
<data name="StrMsgRebootDelayTimerStarted" xml:space="preserve">
|
||||
<value>Start: Verzögerungszeit zwischen Parameterschreiben und Wertespeicherung für</value>
|
||||
</data>
|
||||
<data name="StrMsgRebootDelayTimerExceeded" xml:space="preserve">
|
||||
<value>Stop: Verzögerungszeit zwischen Parameterschreiben und Wertespeicherung nach</value>
|
||||
</data>
|
||||
<data name="StrMsgRebootDelayTimerActive" xml:space="preserve">
|
||||
<value>Abgelaufene Verzögerungszeit zwischen Parameterschreiben und Wertespeicherung</value>
|
||||
</data>
|
||||
<data name="StrProcessStateAllowed" xml:space="preserve">
|
||||
<value>Erlaubt</value>
|
||||
</data>
|
||||
<data name="StrProcessStateDetected" xml:space="preserve">
|
||||
<value>Erkannt</value>
|
||||
</data>
|
||||
<data name="StrLblSpecialRequirement" xml:space="preserve">
|
||||
<value>SONDERFREIGABE</value>
|
||||
|
||||
@@ -437,7 +437,7 @@
|
||||
<value>ERROR: Service SIRT message server start failed </value>
|
||||
</data>
|
||||
<data name="StrWarningMsgServiceSirtSkipped" xml:space="preserve">
|
||||
<value>WARNING: Service SIRT alarm mask setup skipped </value>
|
||||
<value>WARNING: Service SIRT alarm mask check skipped </value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRadioKey" xml:space="preserve">
|
||||
<value>ERROR: Radio encryption code wrong</value>
|
||||
@@ -660,6 +660,9 @@
|
||||
</data>
|
||||
<data name="StrErrorMsgParameterCompare" xml:space="preserve">
|
||||
<value>ERROR: Parameter compare failed</value>
|
||||
</data>
|
||||
<data name="StrWarningMsgParameterCompare" xml:space="preserve">
|
||||
<value>WARNING: Parameter restored after reboot as it does not survive it</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgParameterWrite" xml:space="preserve">
|
||||
<value>ERROR: Parameter write failed</value>
|
||||
@@ -675,12 +678,45 @@
|
||||
</data>
|
||||
<data name="StrProcessStateWarning" xml:space="preserve">
|
||||
<value>WARNING</value>
|
||||
</data>
|
||||
<data name="StrWarningMsgProcess" xml:space="preserve">
|
||||
<value>WARNING: Result needs inspection! Process</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgTooManyReboots" xml:space="preserve">
|
||||
<value>ERROR: Hardware reboots higher than allowed threshold</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgCsdBlocked" xml:space="preserve">
|
||||
<value>ERROR: CSD is blocked for production</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgCsdNewNotApproved" xml:space="preserve">
|
||||
<value>ERROR: CSD is new and not approved for production</value>
|
||||
</data>
|
||||
<data name="StrSuccessMsgCsdValid" xml:space="preserve">
|
||||
<value>Success: CSD is approved for production</value>
|
||||
</data>
|
||||
<data name="StrWarningMsgCsdKnown" xml:space="preserve">
|
||||
<value>WARNING: CSD is known and temporary used for production</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgCsdNotReceived" xml:space="preserve">
|
||||
<value>ERROR: CSD status and number are unknown</value>
|
||||
</data>
|
||||
<data name="StrProcessStateAttention" xml:space="preserve">
|
||||
<value>ATTENTION</value>
|
||||
</data>
|
||||
<data name="StrMsgRebootDelayTimerStarted" xml:space="preserve">
|
||||
<value>Start: Delay timer between parametrization and store config for</value>
|
||||
</data>
|
||||
<data name="StrWarningMsgProcess" xml:space="preserve">
|
||||
<value>WARNING: Inspect results</value>
|
||||
<data name="StrMsgRebootDelayTimerExceeded" xml:space="preserve">
|
||||
<value>Stop: Delay timer between parametrization and store config after</value>
|
||||
</data>
|
||||
<data name="StrMsgRebootDelayTimerActive" xml:space="preserve">
|
||||
<value>Expired delay timer between parametrization and store config</value>
|
||||
</data>
|
||||
<data name="StrProcessStateAllowed" xml:space="preserve">
|
||||
<value>Allowed</value>
|
||||
</data>
|
||||
<data name="StrProcessStateDetected" xml:space="preserve">
|
||||
<value>Detected</value>
|
||||
</data>
|
||||
<data name="StrLblSpecialRequirement" xml:space="preserve">
|
||||
<value>SPECIAL APPROVAL</value>
|
||||
|
||||
@@ -1486,33 +1486,6 @@ namespace Xylem.Common.Ui.GenesisToolBox
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//_currentGenesis.WriteRegister("POWERMON_BatteryQuantity", 2, true, true);
|
||||
//_currentGenesis.WriteRegister("POWERMON_StoreConfiguration", 1, true, true);
|
||||
//var genesisStatus = new GenesisStatus();
|
||||
//if (GenesisStatusHandler.BuildLifeTimeInformation(_currentGenesis, genesisStatus))
|
||||
//{
|
||||
|
||||
// var sbMSG = new StringBuilder();
|
||||
// sbMSG.AppendLine($"Pcb = {_currentGenesis.PcbId}");
|
||||
|
||||
// sbMSG.AppendLine($"POWERMON_TotalUsedSeconds = {genesisStatus.ExceededLifeTime_s}");
|
||||
// sbMSG.AppendLine($"POWERMON_TotalUsedCharge = {genesisStatus.DrainedBatteryLoad_uAs}");
|
||||
// sbMSG.AppendLine($"POWERMON_BatteryQuantity = {genesisStatus.BatteryQuantity}");
|
||||
// sbMSG.AppendLine($"POWERMON_BatteryMilliAHrRating = {genesisStatus.InitialBatteryLoad_mAh}");
|
||||
// sbMSG.AppendLine("");
|
||||
// sbMSG.AppendLine($"Remaining lifetime in years {genesisStatus.RemainingLifeTimeYears:F2}");
|
||||
// sbMSG.AppendLine($"Totally drained battery load in % {genesisStatus.DrainedBatteryLoadPercent:F2}");
|
||||
// _currentGenesis.WriteLog(sbMSG.ToString());
|
||||
// MessageBox.Show(sbMSG.ToString(), $"Battery for {_currentGenesis.PcbId} has remaining life " +
|
||||
// $"time of {genesisStatus.RemainingLifeTimeYears:F2} years");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// MessageBox.Show("Failed to get life time information");
|
||||
//}
|
||||
_currentGenesis.RequestProtocol.AdditionalRetryTimeoutMs = addRetryTimeoutMs;
|
||||
|
||||
Task.Factory.StartNew(() =>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
|
||||
namespace Xylem.Common.Utils.ProcessExec.EventArguments
|
||||
{
|
||||
@@ -28,6 +29,11 @@ namespace Xylem.Common.Utils.ProcessExec.EventArguments
|
||||
/// </summary>
|
||||
public Double? ActualProcessPercent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Single process percentage 0..100
|
||||
/// </summary>
|
||||
public StatusReturn StatusReturn { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// </summary>
|
||||
@@ -35,9 +41,10 @@ namespace Xylem.Common.Utils.ProcessExec.EventArguments
|
||||
/// <param name="overallProcessPercent"></param>
|
||||
/// <param name="actualProcessMessage"></param>
|
||||
/// <param name="actualProcessPercent"></param>
|
||||
/// <param name="statusReturn"></param>
|
||||
public ProcessExecEventArgs(String overallProcessMessage,
|
||||
Double? overallProcessPercent = null, String actualProcessMessage = null,
|
||||
Double? actualProcessPercent = null)
|
||||
Double? actualProcessPercent = null, StatusReturn statusReturn = StatusReturn.Unknown)
|
||||
{
|
||||
OverallProcessMessage = overallProcessMessage;
|
||||
ActualProcessMessage = actualProcessMessage;
|
||||
@@ -45,6 +52,7 @@ namespace Xylem.Common.Utils.ProcessExec.EventArguments
|
||||
OverallProcessPercent = OverallProcessPercent < 0 ? 0 : OverallProcessPercent;
|
||||
ActualProcessPercent = actualProcessPercent > 100.0 ? 100.0 : actualProcessPercent;
|
||||
ActualProcessPercent = ActualProcessPercent < 0 ? 0 : ActualProcessPercent;
|
||||
StatusReturn = statusReturn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4218,7 +4218,8 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw
|
||||
{
|
||||
SetOverallProgressDisplayOn(Resources.StrRegisterReadoutActive);
|
||||
InfoProcessActive(lblRegisterReadout, Resources.StrRegisterCompareActive);
|
||||
retVal = _registerRestorer.CompareRegisters(_cancellationToken);
|
||||
retVal = _registerRestorer.CompareRegisters(_registerRestorer.RecoveryRegisters,
|
||||
_cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user