diff --git a/Common/CommonCore/Consts/StatusReturn.cs b/Common/CommonCore/Consts/StatusReturn.cs index fedb4c2d..04722a29 100644 --- a/Common/CommonCore/Consts/StatusReturn.cs +++ b/Common/CommonCore/Consts/StatusReturn.cs @@ -6,17 +6,25 @@ public enum StatusReturn { /// - /// undefined status + /// undefined status does not fit in any other status defined below /// Unknown, + + /// + /// skipped test and therefore the return identifies this + /// + Skipped, + /// /// successfully executed without any restrictions /// Okay, + /// /// execution failed /// Failed, + /// /// inspection needed as warning returns /// diff --git a/Common/Hardware/WaterMeter/Genesis/Applications/Applications.v3.ncrunchproject b/Common/Hardware/WaterMeter/Genesis/Applications/Applications.v3.ncrunchproject new file mode 100644 index 00000000..c87a742f --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/Applications/Applications.v3.ncrunchproject @@ -0,0 +1,11 @@ + + + False + + + + + False + True + + \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/Genesis/DataPackages/EventArguments/BaseDataEventArgs.cs b/Common/Hardware/WaterMeter/Genesis/DataPackages/EventArguments/BaseDataEventArgs.cs new file mode 100644 index 00000000..b95fe97a --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/DataPackages/EventArguments/BaseDataEventArgs.cs @@ -0,0 +1,33 @@ +using System; + +namespace Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.EventArguments +{ + + /// + /// + /// abstract for set structure for BaseDataEventArgs + /// + public abstract class BaseDataEventArgs : EventArgs + { + /// + /// 'Base' get event record form real child. + /// + /// + public Object GetData() + { + return GetEventData(); + } + + /// + /// get real Event record + /// + /// + public abstract Object GetEventData(); + + /// + /// Holds the record before decoding, for logging + /// + public String RawData; + } +} + diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/Consts/Alarm.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/Consts/Alarm.cs new file mode 100644 index 00000000..60ea72bc --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/Consts/Alarm.cs @@ -0,0 +1,31 @@ +using System; + +namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Consts +{ + /// + /// Alarm messages + /// + [Flags] + public enum Alarm + { + // ReSharper disable InconsistentNaming +#pragma warning disable CS1591 + REBOOT = 1 << 0, + LOW_BATTERY = 1 << 1, + EMPTY_PIPE = 1 << 4, + REVERSE_FLOW = 1 << 6, + SUSPECT_LEAK = 1 << 7, + BROKEN_PIPE = 1 << 8, + LOW_PRESSURE = 1 << 9, + HIGH_PRESSURE = 1 << 10, + LOW_TEMPERATURE = 1 << 11, + HIGH_TEMPERATURE = 1 << 12, + RADIO_ERROR = 1 << 13, + METROLOGY_PARAMS = 1 << 14, + METROLOGY_MEASURE = 1 << 15, + + ALL = 0xFFFFFF, +#pragma warning restore CS1591 + // ReSharper restore InconsistentNaming + } +} diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisConfigReader.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisConfigReader.cs index 518c6571..e309cc15 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisConfigReader.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisConfigReader.cs @@ -1,15 +1,17 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore { - using Applications; using Newtonsoft.Json; using Newtonsoft.Json.Converters; - using Registers; - using Registers.DataTypes; - using Registers.Json; + using System; using System.Collections.Generic; using System.Globalization; using System.IO; + + using Applications; + using Registers; + using Registers.DataTypes; + using Registers.Json; using WaterMeterRegisters; /// @@ -32,7 +34,7 @@ /// /// Ctor /// - public GenesisConfigurationReader() { } + public GenesisConfigurationReader() {} /// /// Ctor @@ -68,7 +70,7 @@ .DeserializeObject>(configurationJson, SerializerSettings) ?? new Dictionary(); } - catch (Exception) + catch (Exception ) { sections = new Dictionary(); } @@ -151,35 +153,29 @@ private static Type GetType(String value) { - try + switch (value.ToLower()) { - switch (value.ToLower()) - { - case "bool_t": return typeof(Boolean); - case "rpc": return typeof(Rpc); - case "string": return typeof(String); - case "uint32_t": return typeof(UInt32); - case "time_t": return typeof(TimeT); - case "status_t": return typeof(StatusT); - case "uint16_t": return typeof(UInt16); - case "uint8_t": return typeof(Byte); - case "enum8": return typeof(Enum8); - case "uint64_t": return typeof(UInt64); - case "uint96_t": return typeof(UInt96); - case "uint128_t": return typeof(UInt128); - case "int8_t": return typeof(SByte); - case "int32_t": return typeof(Int32); - case "int64_t": return typeof(Int64); - case "int16_t": return typeof(Int16); - default: throw new Exception($"Type {value} not recognized!"); - } + case "bool_t": return typeof(Boolean); + case "rpc": return typeof(Rpc); + case "string": return typeof(String); + case "uint32_t": return typeof(UInt32); + case "time_t": return typeof(TimeT); + case "status_t": return typeof(StatusT); + case "uint16_t": return typeof(UInt16); + case "uint8_t": return typeof(Byte); + case "enum8": return typeof(Enum8); + case "uint64_t": return typeof(UInt64); + case "uint96_t": return typeof(UInt96); + case "uint128_t": return typeof(UInt128); + case "int8_t": return typeof(SByte); + case "int32_t": return typeof(Int32); + case "int64_t": return typeof(Int64); + case "int16_t": return typeof(Int16); + case "uint72_t": return typeof(UInt72); + case "uint48_t": return typeof(UInt48); + case "uint88_t": return typeof(UInt88); + default: throw new Exception($"Type {value} not recognized!"); } - catch (Exception ex) - { - //throw ex; - return typeof(Boolean); - } - } } diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisConfigReader.cs.bak b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisConfigReader.cs.bak new file mode 100644 index 00000000..518c6571 --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisConfigReader.cs.bak @@ -0,0 +1,241 @@ +namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore +{ + using Applications; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using Registers; + using Registers.DataTypes; + using Registers.Json; + using System; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using WaterMeterRegisters; + + /// + /// JSON filer reader for generation of register lists + /// + public class GenesisConfigurationReader + { + /// + /// Registers defined in configuration.json file + /// + public List ConfigRegistersDefinitions { get; } + = new List(); + + /// + /// Applications defined in configuration.json file + /// + public List ConfigApplicationDefinitions { get; } + = new List(); + + /// + /// Ctor + /// + public GenesisConfigurationReader() { } + + /// + /// Ctor + /// + /// the file path for configuration.json as interface description to the meter + public GenesisConfigurationReader(String configFilePath) + { + if (string.IsNullOrEmpty(configFilePath)) + { + throw new ApplicationException("JsonFileRegisterReader needs at least one file path"); + } + if (!File.Exists(configFilePath)) + { + throw new ApplicationException($" {configFilePath} doesn't exists"); + } + + BuildRegisterList(File.ReadAllText(configFilePath)); + } + + /// + /// Convert file content to register list + /// + /// + /// + /// + public void BuildRegisterList(String configurationJson) + { + IDictionary sections; + + try + { + sections = JsonConvert + .DeserializeObject>(configurationJson, SerializerSettings) + ?? new Dictionary(); + } + catch (Exception) + { + sections = new Dictionary(); + } + + foreach (var sectionKVP in sections) + { + var appId = sectionKVP.Value.Id; + var appName = sectionKVP.Key; + + ConfigApplicationDefinitions.Add(new ApplicationDefinition + { + AppId = appId, + AppName = appName + }); + + var section = sectionKVP.Value; + + var registers = section.Registers; + + if (registers is null) + { + continue; + } + + foreach (var registerKVP in registers) + { + var register = registerKVP.Value; + + if (register is null) + { + continue; + } + + var details = register.Details; + + if (details is null) + { + continue; + } + + var regId = register.Id; + + foreach (var detail in details) + { + var values = detail.Values; + + ConfigRegistersDefinitions.Add(new RegisterDefinition + { + AppAddress = appId, + AppName = appName, + DataType = GetType(detail.Type), + Default = values?.Default is Int64 d ? d : default(Int64?), + IsAvailable = default(Boolean), + Maximum = values?.Maximum is Int64 max ? max : default(Int64?), + Minimum = values?.Minimum is Int64 min ? min : default(Int64?), + RegAddressInApp = regId, + // RegisterAddress = new byte[] { appId, regId }, + RegisterDetail = detail, + RegisterName = registerKVP.Key, + RestoreCapability = new StaticType(detail.StaticType) + }); + } + } + } + } + + /// + /// Settings + /// + private static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = + { + AccessConverter.Singleton, + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + + private static Type GetType(String value) + { + try + { + switch (value.ToLower()) + { + case "bool_t": return typeof(Boolean); + case "rpc": return typeof(Rpc); + case "string": return typeof(String); + case "uint32_t": return typeof(UInt32); + case "time_t": return typeof(TimeT); + case "status_t": return typeof(StatusT); + case "uint16_t": return typeof(UInt16); + case "uint8_t": return typeof(Byte); + case "enum8": return typeof(Enum8); + case "uint64_t": return typeof(UInt64); + case "uint96_t": return typeof(UInt96); + case "uint128_t": return typeof(UInt128); + case "int8_t": return typeof(SByte); + case "int32_t": return typeof(Int32); + case "int64_t": return typeof(Int64); + case "int16_t": return typeof(Int16); + default: throw new Exception($"Type {value} not recognized!"); + } + } + catch (Exception ex) + { + //throw ex; + return typeof(Boolean); + } + + } + } + + /// + /// + /// + public class AccessConverter : JsonConverter + { + /// + /// + /// + /// + /// + public override Boolean CanConvert(Type t) => t == typeof(Access) || t == typeof(Access?); + + /// + /// + /// + /// + /// + /// + /// + /// + public override Object ReadJson(JsonReader reader, Type t, Object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + { + return null; + } + + var value = serializer.Deserialize(reader); + + return Enum.TryParse(value, true, out Access access) ? access : default(Access); + } + + /// + /// + /// + /// + /// + /// + public override void WriteJson(JsonWriter writer, Object untypedValue, JsonSerializer serializer) + { + if (untypedValue is Access access) + { + writer.WriteValue(access.ToString()); + } + else + { + throw new Exception("Cannot marshal type Lvl"); + } + } + + /// + /// + /// + public static readonly AccessConverter Singleton = new AccessConverter(); + } +} diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.Designer.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.Designer.cs index a824b71b..afb85796 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.Designer.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.Designer.cs @@ -60,6 +60,33 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties { } } + /// + /// Looks up a localized string similar to ERROR: Could not find a CSD parameter in register list!. + /// + internal static string StrErrorMsgCsdMissing { + get { + return ResourceManager.GetString("StrErrorMsgCsdMissing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ERROR: Could not find register in register list! Check configuration.json for latest version!. + /// + internal static string StrErrorMsgRegisterNotFound { + get { + return ResourceManager.GetString("StrErrorMsgRegisterNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ERROR: Could not write register!. + /// + internal static string StrErrorMsgRegisterWrite { + get { + return ResourceManager.GetString("StrErrorMsgRegisterWrite", resourceCulture); + } + } + /// /// Looks up a localized string similar to Read back. /// @@ -169,7 +196,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties { } /// - /// Looks up a localized string similar to Recovery configuration..... + /// Looks up a localized string similar to Execute configuration sequence..... /// internal static string StrRegisterRecoveryExec { get { @@ -178,7 +205,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties { } /// - /// Looks up a localized string similar to Finalize configuration recovery sequence..... + /// Looks up a localized string similar to Finalize configuration sequence..... /// internal static string StrRegisterRecoveryFinalization { get { @@ -187,7 +214,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties { } /// - /// Looks up a localized string similar to Prepare configuration recovery sequence..... + /// Looks up a localized string similar to Prepare configuration sequence..... /// internal static string StrRegisterRecoveryPreparation { get { @@ -196,7 +223,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties { } /// - /// Looks up a localized string similar to ERROR: Register value is out of range. + /// Looks up a localized string similar to ERROR: Register value is out of range!. /// internal static string StrRegisterValueOutOfRange { get { @@ -223,7 +250,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties { } /// - /// Looks up a localized string similar to Set register value to default. + /// Looks up a localized string similar to WARNING: Register value set to default. /// internal static string StrSetRegisterToDefault { get { diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.de.resx b/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.de.resx index 7e6add5e..7c3ba37c 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.de.resx +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.de.resx @@ -154,13 +154,13 @@ Lese Register nach der Wartung - Ausführung Konfigurationswiederherstellungssequenz.... + Ausführung der Konfigurationsequenz.... - Abschließen Konfigurationswiederherstellungssequenz.... + Abschließen der Konfigurationsequenz.... - Vorbereitung Konfigurationswiederherstellungssequenz.... + Vorbereitung der Konfigurationsequenz.... FEHLER: Vergleich fehlgeschlagen! @@ -172,9 +172,18 @@ Zurückgelesen - Registerwert auf Standardwert gesetzt + WARNUNG: Registerwert auf Standardwert gesetzt - FEHLER: Registerwert ungültig + FEHLER: Registerwert außerhalb des zulässigen Bereiches! + + + FEHLER: Kein CSD Parameter in Parameterliste gefunden! + + + FEHLER: Register nicht in Registerliste gefunden! Version der Configuration.json prüfen! + + + FEHLER: Register konnte nicht geschrieben werden! \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.resx b/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.resx index aecdd20e..247a1699 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.resx +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/Properties/Resources.resx @@ -154,13 +154,13 @@ Write register - Recovery configuration.... + Execute configuration sequence.... - Finalize configuration recovery sequence.... + Finalize configuration sequence.... - Prepare configuration recovery sequence.... + Prepare configuration sequence.... ERROR: Comparison failed! @@ -172,9 +172,18 @@ Read back - Set register value to default + WARNING: Register value set to default - ERROR: Register value is out of range + ERROR: Register value is out of range! + + + ERROR: Could not find a CSD parameter in register list! + + + ERROR: Could not find register in register list! Check configuration.json for latest version! + + + ERROR: Could not write register! \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs index b0e2ea9f..7e9caf6a 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using Newtonsoft.Json; @@ -34,7 +35,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// PCB ID for pre update write for comparison /// - private String _pcbIdWriteRegisters = Constants.StrUnknown; + private String _pcbIdWriteRegisters; /// /// PCB ID for post update for comparison @@ -71,15 +72,20 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// private static readonly List _unReversedParameters = new List { - "SENSUSRADIO_EncryptionKey", //UInt128 - "GENESISFLOW_DisplayPow10", //SInt8 - "METROLOGYASST_FlowPoint", //Enum8 - "CUSTOMER_SerialNumber", //String - "SYSTEM_CustomerSerialNumber0", //String - "SYSTEM_CustomerSerialNumber1", //String - "SYSTEM_CustomerSerialNumber2", //String - "SYSTEM_CustomerSerialNumber3", //String - "TESTMANAGER_OutputFile" //String + "SENSUSRADIO_Authentification", //UInt96 + "SENSUSRADIO_EncryptionKey", //UInt128 + "SENSUSRADIO_TfxSecondaryChannelInfo_1", //UInt48 + "SENSUSRADIO_TfxSecondaryChannelInfo_2", //UInt48 + "SENSUSRADIO_CustomerText", //UInt72 + "SENSUSRADIO_Tfx_Structure", //UInt88 + "GENESISFLOW_DisplayPow10", //SInt8 + "METROLOGYASST_FlowPoint", //Enum8 + "CUSTOMER_SerialNumber", //String + "SYSTEM_CustomerSerialNumber0", //String + "SYSTEM_CustomerSerialNumber1", //String + "SYSTEM_CustomerSerialNumber2", //String + "SYSTEM_CustomerSerialNumber3", //String + "TESTMANAGER_OutputFile" //String }; /// @@ -88,12 +94,10 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// private static readonly List _excludedFromCompareParameters = new List { - //THW 15-Aug-2024 reactivated "SYSTEM_UpgradePermissions", - //// Once set to deviating from 0xFF it will maintain this after reboot, - //// it only can be overwritten temporary in RAM! - - "CUSTOMER_AlarmVisualMask", // Will be cyclically overwritten by SENSUSRADIO - "SENSUSRADIO_UpgFWVersion" // After a FW-Update the FW version has changed + "CUSTOMER_AlarmVisualMask", // Fully hard coded, cannot be overwritten + "CUSTOMER_AlarmEnableMask", // Will be overwritten by SENSUSRADIO if set System state to 0xFF + "CUSTOMER_AppArrangement", // Is read only, makes no sense to compare anything + "SENSUSRADIO_UpgFWVersion" // After a FW-Update the FW version has changed }; /// @@ -102,22 +106,22 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// private static readonly List _excludedFromReadParameters = new List { - "CUSTOMER_AlarmVisualAutoClearMask",// Does NOT respond - "SYSTEM_CustomerSerialNumber0", // Does NOT respond - "SYSTEM_CustomerSerialNumber1", // Does NOT respond - "SYSTEM_CustomerSerialNumber2", // Does NOT respond - "SYSTEM_CustomerSerialNumber3", // Does NOT respond - "SYSTEM_CRC", // Needs application number written to it - "SYSTEM_ExitReason", // Needs application number written to it - "SYSTEM_DriveCapacity", // Needs drive number written to it - "GENESISFLOW_TriggerActive", // Does NOT respond - "SENSUSRADIO_CurrentLoopMax", // Does NOT respond - "SENSUSRADIO_CurrentLoopSource", // Does NOT respond - "SENSUSRADIO_CustomerText" // Does NOT respond + "CUSTOMER_InternalLoginTest", // Does NOT respond + "CUSTOMER_AlarmVisualAutoClearMask", // Does NOT respond + "SYSTEM_CRC", // Needs application number written to it + "SYSTEM_CRC32", // Needs application number written to it + "SYSTEM_ExitReason", // Needs application number written to it + "SYSTEM_DriveCapacity", // Needs drive number written to it + "GENESISFLOW_TriggerActive", // Does NOT respond + "SENSUSRADIO_CurrentLoopMax", // Does NOT respond + "SENSUSRADIO_CurrentLoopSource", // Does NOT respond + "SENSUSRADIO_CustomerText", // Does NOT respond + "SENSUSRADIO_TfxSecondaryChannelInfo_1",// Does NOT respond + "SENSUSRADIO_TfxSecondaryChannelInfo_2" // Does NOT respond }; /// - /// Pre programming parameters for all devices defined here, will be filled with radio parameters + /// Pre-programming parameters for all devices defined here, will be filled with radio parameters /// if meter has radio /// private static readonly List _prepareProgramming = new List @@ -128,9 +132,13 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG private readonly List _failedComparisonRegisters = new List(); + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG private List _dbParameterRegisterList = new List(); + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG private List _initialRegisterList = new List(); + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG private List _finalRegisterList = new List(); + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG private readonly List _readableRegisterList = new List(); /// @@ -146,7 +154,7 @@ 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 + /// Post programming parameters for EMEA region as NA region doesn't have radio and seal display shouldn't /// be executed. /// private static readonly List _finalizeProgrammingEmea = new List @@ -184,6 +192,18 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// private GenesisMeter _currentGenesis; + /// + /// Struct to observe replacements + /// + private struct ReplaceVakoByCsd + { + public String RegisterName; + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG + public List VakoValue; + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG + public List CsdValue; + } + /// /// Ctor /// @@ -208,53 +228,140 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore } /// - /// Collect programming parameters from DB. + /// Enable comparison from external set registers for read back with written value /// - /// - /// registers key value pair from data base - /// recovery registers - /// + /// + /// - Initial + /// + public void EnableCompareExternalSetRegisters() + { + _pcbIdFinalRegisterRead = _currentGenesis.PcbId; + _pcbIdWriteRegisters = _currentGenesis.PcbId; + } + + /// + /// Export list of programming parameters to file being able to use it for test purposes. + /// + /// + /// + /// + /// + /// /// - Initial. /// - /// - /// - Sort the registers from DB but keep the PrepareProgramming and FinalizeProgramming in the required sequence. - /// - /// - /// - Removed preparation and finalization of register recovery to remove sequencing as this will be done in the - /// RegisterRestorer by the FwUpdateSw worker giving the ability to log this in the report. - /// - /// - /// - Data base access imported to have a common interface for programming parameters for EOL (shipping) and CUST. - /// - /// - /// - Removed prohibited parameters. - /// - /// - /// - Added un-reversed parameters based on data type (string, uint128). - /// - /// - /// - Check and validate register values with installed or intended to be installed FW and given configuration.json. - /// - /// - /// - Exported register range check to . - /// - /// - /// - Debug lists for CSD and VAKO parameters. - /// - public static StatusReturn DownloadProgrammingParametersFromDb(String pcbId, List recoveryRegistersDb) + public static Boolean ExportRawProgrammingParametersToFile(String path, String fileName, + List programmingParameters) { try { - var url = $"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetProgrammingParameters?PcbID={pcbId}"; - var ppJson = LocalWebRequest.GetRequest(url, 30000); + var fileNamePath = Path.Combine(path, fileName); + var text = JsonConvert.SerializeObject(programmingParameters); + File.WriteAllText(fileNamePath, text); + } + catch (Exception e) + { + Console.WriteLine(e); + return false; + } - if (string.IsNullOrEmpty(ppJson)) + return true; + } + + /// + /// Import list of programming parameters from file being able to use it for test purposes. + /// The input request the absolut path to the XX_YY_RawParameterExample.json and the filters for: + /// - Region, + /// - MeterSize, + /// - "RawParams" and + /// - ".json" + /// + /// + /// path where all raw parameter examples are stored + /// Region for configuration + /// Meter size for programming parameters + /// + /// + /// + /// - Initial. + /// + public static Boolean ImportRawProgrammingParametersFromFile(String paramsRootPath, String region, + String meterSize, List programmingParameters) + { + if (string.IsNullOrEmpty(paramsRootPath) || + string.IsNullOrEmpty(region) || + string.IsNullOrEmpty(meterSize)) + return false; + + programmingParameters.Clear(); + try + { + var filePathNames = Directory.GetFiles(paramsRootPath); + if (filePathNames.Length == 0) + return false; + + foreach (var filePathName in filePathNames) { - return StatusReturn.Failed; - } + var fileName = Path.GetFileName(filePathName); + if (fileName.Contains(region) && + fileName.Contains(meterSize) && + fileName.Contains("RawParams") && + fileName.Contains(".json")) + { + var rawParamsFilePathMane = Path.Combine(paramsRootPath, fileName); + if (!File.Exists(rawParamsFilePathMane)) + return false; - var programmingParameters = JsonConvert.DeserializeObject>(ppJson); - if (programmingParameters == null || programmingParameters.Count == 0) + var text = File.ReadAllText(filePathName); + var progParams = JsonConvert.DeserializeObject>(text); + programmingParameters.AddRange(progParams); + return true; + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + return false; + } + + return false; + } + + /// + /// Process the raw programming parameters got from the database or meanwhile in raw-format stored to file + /// being able to fill the register restorer from external with values and test the byte-wise reverting + /// of the parameter (optional un-reverted if defined in the list ). + /// The priority of the parameters forced by its source is: + /// - CSD (highest), + /// - VAKO, + /// - Order based or standard config (lowest). + /// + /// unprocessed data, not filtered by the priority and un-reversed + /// output as recovery registers reduced to the real needed ones and + /// processed as reverted or non-reverted values which directly can be written to the meter using the + /// meter specific "IGenesisMeter.WriteRegister" + /// error message for caller + /// + /// + /// - Initial imported from . + /// + /// + /// - Return error message, + /// - Requirement to fulfill the at least one parameter has to be a CSD parameter as initially all programming + /// parameters are going to be preset with the default values (coming from the Web-API). After this they are + /// going to be overwritten with the VAKO (variant configuration) and finally again with the CSD of the + /// customer if required. + /// + /// + /// - Debug for overwriting VAKO with CSD including real values. + /// + public static StatusReturn RawProgrammingParametersFilterAndSort(List rawProgParams, + List recoveryRegisters, out String errorMsg) + { + errorMsg = ""; + try + { + if (rawProgParams == null || rawProgParams.Count == 0) { return StatusReturn.Failed; } @@ -262,7 +369,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore // Create DEBUG lists // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG var vakoRegisterList = new List(); - // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG var csdRegisterList = new List(); // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG var orderRegisterList = new List(); @@ -270,20 +376,25 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore var sortableRegisterList = new List(); // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG var multipleAssignedRegisterList = new List(); + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG + var replacedVakoFromCsdList = new List(); // Temporary storage for sorting before assembling those registers with the preparation and // finalization of programming and therefore building a sequence var sortableProgrammingParameters = new List(); - foreach (var proPar in programmingParameters) + foreach (var proPar in rawProgParams) { // reverse byte order for all parameters except those listed below if (!string.IsNullOrEmpty(proPar.RegisterName)) { - // Fill DEBUG lists START - if (sortableRegisterList.Any( a => proPar.RegisterName.Equals(a))) + // Catch multiple assignments + if (sortableRegisterList.Any(a => proPar.RegisterName.Equals(a))) multipleAssignedRegisterList.Add(proPar.RegisterName); + + // Fill DEBUG lists START with all registers even if they are multiple assigned sortableRegisterList.Add(proPar.RegisterName); + switch (proPar.Source) { case ProgrammingSource.Vako: @@ -309,33 +420,64 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore if (proPar.Source == ProgrammingSource.Csd && sortableProgrammingParameters.Any(a => proPar.RegisterName.Equals(a.RegisterName) && a.Source == ProgrammingSource.Vako)) { - var removeProPar = - sortableProgrammingParameters.Where(a => proPar.RegisterName.Equals(a.RegisterName)); - sortableProgrammingParameters.Remove(removeProPar.LastOrDefault()); - sortableProgrammingParameters.Add(proPar); + var removeProPar = + sortableProgrammingParameters.LastOrDefault(a => proPar.RegisterName.Equals(a.RegisterName)); + + var replace = new ReplaceVakoByCsd + { + RegisterName = proPar.RegisterName, + VakoValue = new List(), + CsdValue = new List() + }; + + if (removeProPar != null) + { + replace.VakoValue.AddRange(removeProPar.RegisterValue); + replace.CsdValue.AddRange(proPar.RegisterValue); + replacedVakoFromCsdList.Add(replace); + + sortableProgrammingParameters.Remove(removeProPar); + sortableProgrammingParameters.Add(proPar); + } } } else { - // ATTENTION: These parameters are coming out of the DB in wrong byte order and needed to be reversed - // for the entire sequence + // ATTENTION: These parameters are coming out of the DB in wrong byte order and needed + // to be reversed for the entire sequence + var reversedValue = proPar.RegisterValue.Reverse().ToArray(); // Add parameter if it is not in the list if (sortableProgrammingParameters.All(a => !proPar.RegisterName.Equals(a.RegisterName))) { sortableProgrammingParameters.Add(new ProgrammingParameters(proPar.RegisterName, - proPar.RegisterValue.Reverse().ToArray(), proPar.Source)); + reversedValue, proPar.Source)); continue; } // if parameter from VAKO is in the list and the new is from CSD, replace this with CSD if (proPar.Source == ProgrammingSource.Csd && sortableProgrammingParameters.Any(a => proPar.RegisterName.Equals(a.RegisterName) && a.Source == ProgrammingSource.Vako)) { - var removeProPar = - sortableProgrammingParameters.Where(a => proPar.RegisterName.Equals(a.RegisterName)); - sortableProgrammingParameters.Remove(removeProPar.LastOrDefault()); - sortableProgrammingParameters.Add(new ProgrammingParameters(proPar.RegisterName, - proPar.RegisterValue.Reverse().ToArray(), proPar.Source)); + var removeProPar = + sortableProgrammingParameters.LastOrDefault(a => proPar.RegisterName.Equals(a.RegisterName)); + + var replace = new ReplaceVakoByCsd + { + RegisterName = proPar.RegisterName, + VakoValue = new List(), + CsdValue = new List() + }; + + if (removeProPar != null) + { + replace.VakoValue.AddRange(removeProPar.RegisterValue); + replace.CsdValue.AddRange(reversedValue); + replacedVakoFromCsdList.Add(replace); + + sortableProgrammingParameters.Remove(removeProPar); + sortableProgrammingParameters.Add(new ProgrammingParameters(proPar.RegisterName, + reversedValue, proPar.Source)); + } } } } // register for this FW is defined @@ -355,6 +497,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore orderRegisterList.Sort(); sortableRegisterList.Sort(); multipleAssignedRegisterList.Sort(); + replacedVakoFromCsdList.Sort((x, y) => string.Compare(x.RegisterName, y.RegisterName, + StringComparison.Ordinal)); // convert to RecoveryRegisterItem if (sortableProgrammingParameters.Count > 0) @@ -362,10 +506,17 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore foreach (var proPar in sortableProgrammingParameters) { var recReg = new RecoveryRegisterItem(proPar.RegisterName, proPar.RegisterValue); - recoveryRegistersDb.Add(recReg); + recoveryRegisters.Add(recReg); } } + // Requirement to fulfill that at least one parameter has to be a CSD parameter + if (csdRegisterList.Count == 0) + { + errorMsg = Resources.StrErrorMsgCsdMissing; + return StatusReturn.Failed; + } + return StatusReturn.Okay; } catch (Exception) @@ -374,6 +525,79 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore } } + /// + /// Collect programming parameters from DB. + /// + /// + /// registers key value pair from database + /// error message from parameter analysis + /// recovery registers + /// + /// - Initial. + /// + /// + /// - Sort the registers from DB but keep the PrepareProgramming and FinalizeProgramming in the required sequence. + /// + /// + /// - Removed preparation and finalization of register recovery to remove sequencing as this will be done in the + /// RegisterRestorer by the FwUpdateSw worker giving the ability to log this in the report. + /// + /// + /// - Data base access imported to have a common interface for programming parameters for EOL (shipping) and CUST. + /// + /// + /// - Removed prohibited parameters. + /// + /// + /// - Added un-reversed parameters based on data type (string, uint128). + /// + /// + /// - Check and validate register values with installed or intended to be installed FW and given + /// configuration.json. + /// + /// + /// - Exported register range check to . + /// + /// + /// - Debug lists for CSD and VAKO parameters. + /// + /// + /// - Sorting, filtering for VAKO, CSD and order, reverting or un-reverting parameter value order exported + /// for the ability to load the raw programming parameters from any source and check the correct processing. + /// This will be especially used for unit-tests + /// + /// + /// - Error message. + /// + public static StatusReturn DownloadProgrammingParametersFromDb(String pcbId, + List recoveryRegistersDb, out String errorMsg) + { + errorMsg = ""; + try + { + var url = $"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetProgrammingParameters?PcbID={pcbId}"; + var ppJson = LocalWebRequest.GetRequest(url, 30000); + + if (string.IsNullOrEmpty(ppJson)) + { + return StatusReturn.Failed; + } + + var programmingParameters = JsonConvert.DeserializeObject>(ppJson); + + if (programmingParameters == null || programmingParameters.Count == 0) + { + return StatusReturn.Failed; + } + + return RawProgrammingParametersFilterAndSort(programmingParameters, recoveryRegistersDb, out errorMsg); + } + catch (Exception) + { + return StatusReturn.Failed; + } + } + /// /// Avoid doubling of register restore on subsequent FW-Update trials. /// @@ -394,7 +618,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// EOL (end of line) programming contains a reset of the accumulators. Else it is identical with recover /// registers. /// - /// list of registers to update from data base without special sequence + /// list of registers to update from database without special sequence /// /// true if setup succeeded /// @@ -412,34 +636,28 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// register key value pair /// register definition by configuration.json /// error message if range check failed + /// check default value and supply warning /// status /// /// - Initial, imported from /// + /// + /// - Leave the message generation to the + /// public static StatusReturn ValidateRegisterRange(RecoveryRegisterItem recReg, - RegisterDefinition regDef, out String errorMessage) + RegisterDefinition regDef, out String errorMessage, Boolean checkDefault = false) { - // error message will return on failed check any information + // Error message will be returned on failed check or on default value errorMessage = null; try { // check the limits and avoid writing if not in range - var check = RegisterCheck.CheckRange(regDef, recReg.WriteValue); - if (!string.IsNullOrEmpty(check)) - { - errorMessage = $"{Resources.StrRegisterValueOutOfRange}: " + - RegisterConverter.GetRegisterContentText(regDef, recReg.WriteValue) + - $" - Minimum ({regDef.Minimum})" + - $" - Maximum ({regDef.Maximum})"; - - return StatusReturn.Warning; - } - - return StatusReturn.Okay; + return RegisterCheck.CheckRange(regDef, recReg.WriteValue, out errorMessage, checkDefault); } - catch (Exception) + catch (Exception ex) { + errorMessage = ex.Message; return StatusReturn.Failed; } } @@ -448,7 +666,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// Recover all registers set from caller. Additional preparation and finalization will be added. /// settings. /// - /// list of registers to update from data base without special sequence + /// list of registers to update from database without special sequence /// /// EOL (end of line) programming with accu reset /// true if restoring succeeded @@ -501,7 +719,10 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// - Seal display and Sensus radio to EMEA finalization. /// - public StatusReturn WriteRegisters(List recoveryRegistersDb, Boolean eolProgramming = false) + /// + /// - Exported write routines to . + /// + private StatusReturn WriteRegisters(List recoveryRegistersDb, Boolean eolProgramming = false) { if (_currentGenesis == null || string.IsNullOrEmpty(_currentGenesis.PcbId) || @@ -509,8 +730,6 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore recoveryRegistersDb.Count == 0) return StatusReturn.Failed; - var retVal = StatusReturn.Okay; - // preset recovery registers if not already set if (RecoveryRegisters == null) { @@ -568,151 +787,34 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryPreparation, actualProcessMessage: Resources.StrRegisterRecoveryPreparation)); - foreach (var prepRecReg in _prepareProgramming) + if (StatusReturn.Failed == WriteRegisterParameterSet(_prepareProgramming, recRegistersCount, meterRegisters)) { - _actualRegisterCtr++; - var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / recRegistersCount; - - try - { - // if this call does not throw an exception, the register is present - var regDef = meterRegisters.GetRegisterDefinitionByName(prepRecReg.RegisterIdent); - - _currentGenesis.WriteRegister(prepRecReg.RegisterIdent, prepRecReg.WriteValue); - - var strRawAndConvertedValue = ""; - try - { - strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, prepRecReg.WriteValue); - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Could not convert register value of " + prepRecReg.RegisterIdent + - "; " + ex.Message); - } - finally - { - var actualProcessMsg = $"{Resources.StrWriteRegister}: {strRawAndConvertedValue} "; - - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrWriteRegister}" + - $@" {_actualRegisterCtr} / {recRegistersCount}", - overallProcessCtrPercent, actualProcessMsg)); - } - - if (StopRegisterAccess) - break; - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Could not write register value of " + prepRecReg.RegisterIdent + - "; " + ex.Message); - } - }// prepare recovery + // the logout will force the radio app to activate the settings + _currentGenesis?.Logout(); + return StatusReturn.Failed; + } // register recovery OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryExec, actualProcessMessage: Resources.StrRegisterRecoveryExec)); - foreach (var recReg in recoveryRegistersDb) + + if (StatusReturn.Failed == WriteRegisterParameterSet(recoveryRegistersDb, recRegistersCount, meterRegisters)) { - _actualRegisterCtr++; - var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / recRegistersCount; - - try - { - // if this call does not throw an exception, the register is present - var regDef = meterRegisters.GetRegisterDefinitionByName(recReg.RegisterIdent); - - // avoid writing of NOT writable registers - if (regDef.RegisterDetail.Privilege.Lvl8 != Access.WO - && regDef.RegisterDetail.Privilege.Lvl8 != Access.RW) - continue; - - // check the limits and avoid writing if not in range - retVal = ValidateRegisterRange(recReg, regDef, out var errorMessage); - if (StatusReturn.Okay != retVal) - { - _currentGenesis.WriteLog(errorMessage); - - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrWriteRegister}" + - $@" {_actualRegisterCtr} / {recRegistersCount}", - overallProcessCtrPercent, errorMessage)); - - continue; - } - - _currentGenesis.WriteRegister(recReg.RegisterIdent, recReg.WriteValue); - var strRawAndConvertedValue = ""; - try - { - strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, recReg.WriteValue); - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Could not convert register value of " + recReg.RegisterIdent + - "; " + ex.Message); - } - finally - { - var actualProcessMsg = $"{Resources.StrWriteRegister}: {strRawAndConvertedValue} "; - - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrWriteRegister}" + - $@" {_actualRegisterCtr} / {recRegistersCount}", - overallProcessCtrPercent, actualProcessMsg)); - } - - if (StopRegisterAccess) - break; - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Could not write register value of " + recReg.RegisterIdent + - "; " + ex.Message); - } - }// recovery registers + // the logout will force the radio app to activate the settings + _currentGenesis?.Logout(); + return StatusReturn.Failed; + } // finalize recovery OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryFinalization, actualProcessMessage: Resources.StrRegisterRecoveryFinalization)); - foreach (var finalRecReg in finalizeProgrammingAll) + + if (StatusReturn.Failed == WriteRegisterParameterSet(finalizeProgrammingAll, recRegistersCount, meterRegisters)) { - _actualRegisterCtr++; - var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / recRegistersCount; - - try - { - _currentGenesis.WriteRegister(finalRecReg.RegisterIdent, finalRecReg.WriteValue); - - // if this call does not throw an exception, the register is present - var regDef = meterRegisters.GetRegisterDefinitionByName(finalRecReg.RegisterIdent); - - var strRawAndConvertedValue = ""; - try - { - strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, finalRecReg.WriteValue); - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Could not convert register value of " + finalRecReg.RegisterIdent + "; " - + ex.Message); - } - finally - { - var actualProcessMsg = $"{Resources.StrWriteRegister}: {strRawAndConvertedValue} "; - - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrWriteRegister}" + - $@" {_actualRegisterCtr} / {recRegistersCount}", - overallProcessCtrPercent, actualProcessMsg)); - } - - if (StopRegisterAccess) - break; - } - catch (Exception ex) - { - _currentGenesis.WriteLog("Could not write register value of " + finalRecReg.RegisterIdent + - "; " + ex.Message); - } - }// finalize recovery + // 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; @@ -723,7 +825,99 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore // Wait for completion as storing may need a certain time Thread.Sleep(1000); - return retVal; + return StatusReturn.Okay; + } + + /// + /// Write a parameter set: + /// - + /// + /// + /// + /// + /// + /// + /// - Initial imported from . + /// + private StatusReturn WriteRegisterParameterSet(List recoveryRegistersDb, Int32 recRegistersCount, + MeterRegisters meterRegisters) + { + foreach (var recReg in recoveryRegistersDb) + { + _actualRegisterCtr++; + var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / recRegistersCount; + + RegisterDefinition regDef; + + try + { + // If this call does not throw an exception, the register is present + regDef = meterRegisters.GetRegisterDefinitionByName(recReg.RegisterIdent); + } + catch (Exception ex) + { + _currentGenesis.WriteLog(ex.Message); + regDef = null; + } + + if (null == regDef) + { + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs( + $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", + overallProcessCtrPercent, Resources.StrErrorMsgRegisterNotFound + " Register: " + + recReg.RegisterIdent)); + return StatusReturn.Failed; + } + + // avoid writing of NOT writable registers + if (regDef.RegisterDetail.Privilege.Lvl8 != Access.WO + && regDef.RegisterDetail.Privilege.Lvl8 != Access.RW) + continue; + + // check the limits and avoid writing if not in range + var retVal = ValidateRegisterRange(recReg, regDef, out var errorMessage); + if (StatusReturn.Failed == retVal) + { + _currentGenesis.WriteLog(errorMessage); + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs( + $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", + overallProcessCtrPercent, Resources.StrRegisterValueOutOfRange + " " + errorMessage)); + return StatusReturn.Failed; + } + + if (!_currentGenesis.WriteRegister(recReg.RegisterIdent, recReg.WriteValue)) + { + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs( + $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", + overallProcessCtrPercent, Resources.StrErrorMsgRegisterWrite + " Register: " + + recReg.RegisterIdent)); + return StatusReturn.Failed; + + } + var strRawAndConvertedValue = ""; + try + { + strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, recReg.WriteValue); + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Could not convert register value of " + recReg.RegisterIdent + + "; " + ex.Message); + } + finally + { + var actualProcessMsg = $"{Resources.StrWriteRegister}: {strRawAndConvertedValue} "; + + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs( + $@"{Resources.StrWriteRegister} {_actualRegisterCtr} / {recRegistersCount}", + overallProcessCtrPercent, actualProcessMsg)); + } + + if (StopRegisterAccess) + break; + } + + return StatusReturn.Okay; } /// @@ -912,7 +1106,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore var strReadBackRegisterValue = RegisterConverter.GetRegisterRawText(regDef, readBackValue, encryptRawData); - strRequiredRegisterValue += $" - {Resources.StrMeterValue}: ({strReadBackRegisterValue})" + + strRequiredRegisterValue += $" - {Resources.StrMeterValue} ({strReadBackRegisterValue})h" + $" - {Resources.StrRegisterCompareFailed}"; _failedComparisonRegisters?.Add(new RecoveryRegisterItem(regName, writtenValue, readBackValue)); @@ -925,7 +1119,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore } finally { - var actualProcessMsg = $"{Resources.StrRegisterCompare}: {strRequiredRegisterValue} "; + var actualProcessMsg = $"{Resources.StrRegisterCompare} {strRequiredRegisterValue} "; // Avoid message if nothing to tell if (!string.IsNullOrEmpty(strRequiredRegisterValue)) @@ -960,7 +1154,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// /// - Clear pre update registers if post indicates a different PCB ID to avoid wrong overwriting of - /// registers to non matching new meter. + /// registers to non-matching new meter. /// /// /// - Return true if already executed in previous run. @@ -977,45 +1171,64 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore /// /// - Backup _finalRegisters to RecoveryRegisters. /// + /// + /// - Check readBack value for null. + /// public Boolean FinalReadRegisters() { if (_currentGenesis == null) return false; - // 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 after update register read string - OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}", 0, - Resources.StrReadRegistersAfterUpdate)); - - // Build string list for debug - _finalRegisterList.Clear(); - _finalRegisterList = _finalRegisters.Select(register => register.RegisterIdent).ToList(); - _finalRegisterList.Sort(); - - // executes login read logout - var retVal = ReadRegistersSet(ref _finalRegisters); - - // backup read data to RecoveryRegisters - if (RecoveryRegisters != null && _finalRegisters != null) + Boolean retVal; + try { - foreach (var recReg in RecoveryRegisters) + + // 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 after update register read string + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}", 0, + Resources.StrReadRegistersAfterUpdate)); + + // Build string list for debug + _finalRegisterList.Clear(); + _finalRegisterList = _finalRegisters.Select(register => register.RegisterIdent).ToList(); + _finalRegisterList.Sort(); + + // executes login read logout + retVal = ReadRegistersSet(ref _finalRegisters); + + // backup read data to RecoveryRegisters + if (RecoveryRegisters != null && _finalRegisters != null) { - foreach (var finalReg in _finalRegisters.Where(finalReg => - recReg.RegisterIdent.Equals(finalReg.RegisterIdent))) + foreach (var recReg in RecoveryRegisters) { - recReg.ReadBackValue = new Byte[finalReg.ReadBackValue.Length]; - for (var c = 0; c < finalReg.ReadBackValue.Length; c++) - recReg.ReadBackValue[c] = finalReg.ReadBackValue[c]; + foreach (var finalReg in _finalRegisters.Where(finalReg => + recReg.RegisterIdent.Equals(finalReg.RegisterIdent))) + { + if (finalReg.ReadBackValue == null) + { + recReg.ReadBackValue = null; + continue; + } + + recReg.ReadBackValue = new Byte[finalReg.ReadBackValue.Length]; + for (var c = 0; c < finalReg.ReadBackValue.Length; c++) + recReg.ReadBackValue[c] = finalReg.ReadBackValue[c]; + } } } + + // remind the PCB ID before update for comparison + _pcbIdFinalRegisterRead = _currentGenesis.PcbId; + + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Copying read back data failed " + ex.Message); + retVal = false; } - - // remind the PCB ID before update for comparison - _pcbIdFinalRegisterRead = _currentGenesis.PcbId; - return retVal; } @@ -1156,6 +1369,27 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore return ReadRegistersSet(ref registers); } + /// + /// Read predefined registers from RecoveryRegisters. + /// + /// true if registers could be read + /// + /// - Initial. + /// + public Boolean ReadPresetRegisters() + { + 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. + // The RecoveryRegisters can be preset with a writeValue being able to use FinalReadRegisters + // and compare the readBackValue from those with the preset writeValue. + _pcbIdWriteRegisters = _currentGenesis.PcbId; + _pcbIdFinalRegisterRead = _currentGenesis.PcbId; + + return ReadRegistersSet(ref RecoveryRegisters); + } + /// /// Register read loop. /// All registers needed to be read from the Genesis meter as they are only prepared as template and NOT filled diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs.bak b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs.bak new file mode 100644 index 00000000..b0e2ea9f --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/RegisterRestorer.cs.bak @@ -0,0 +1,1282 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Newtonsoft.Json; +using Xylem.Common.CommonCore.Configuration; +using Xylem.Common.CommonCore.Consts; +using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Properties; +using Xylem.Common.Hardware.WaterMeter.Genesis.Registers; +using Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes; +using Xylem.Common.Logic.ProductionOrderCore; +using Xylem.Common.Logic.SoftwareAccessHelper; +using Xylem.Common.Utils.ProcessExec; +using Xylem.Common.Utils.ProcessExec.EventArguments; +using Access = Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Access; + +namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore +{ + /// + /// Read, compare and restore if unequal al registers marked with + /// equals + /// ". + /// The reader will use the byte values as they are unmodified and + /// will not be rounded and therefor possibly fail the comparison. + /// For logging the register value will be converted its unit. + /// + public class RegisterRestorer : IProcessState + { + /// + /// PCB ID for pre update read for comparison + /// + private String _pcbIdInitialRegisterRead = Constants.StrUnknown; + + /// + /// PCB ID for pre update write for comparison + /// + private String _pcbIdWriteRegisters = Constants.StrUnknown; + + /// + /// PCB ID for post update for comparison + /// + private String _pcbIdFinalRegisterRead = Constants.StrUnknown; + + /// + /// Collection of recovery registers and values + /// + public List RecoveryRegisters; + + /// + /// Register content on initial connect to keep those during update + /// + private List _initialRegisters = new List(); + + /// + /// Register content after all operation had been performed + /// + private List _finalRegisters = new List(); + + /// + /// Register which shall be restored after change of FW or after register recovery + /// + public Int32 RecoveryRegisterCount => RecoveryRegisters.Count; + + /// + /// Register access event for message dispatcher to caller + /// + public event EventHandler OnProcessUpdate; + + /// + /// List for un-reversed parameters which can be written, all others need to be swapped byte-wise + /// + private static readonly List _unReversedParameters = new List + { + "SENSUSRADIO_EncryptionKey", //UInt128 + "GENESISFLOW_DisplayPow10", //SInt8 + "METROLOGYASST_FlowPoint", //Enum8 + "CUSTOMER_SerialNumber", //String + "SYSTEM_CustomerSerialNumber0", //String + "SYSTEM_CustomerSerialNumber1", //String + "SYSTEM_CustomerSerialNumber2", //String + "SYSTEM_CustomerSerialNumber3", //String + "TESTMANAGER_OutputFile" //String + }; + + /// + /// Registers manually explicit excluded from comparison as those may change even if those have the + /// "StaticType": "static" in the configuration.json but will change for some reason. + /// + private static readonly List _excludedFromCompareParameters = new List + { + //THW 15-Aug-2024 reactivated "SYSTEM_UpgradePermissions", + //// Once set to deviating from 0xFF it will maintain this after reboot, + //// it only can be overwritten temporary in RAM! + + "CUSTOMER_AlarmVisualMask", // Will be cyclically overwritten by SENSUSRADIO + "SENSUSRADIO_UpgFWVersion" // After a FW-Update the FW version has changed + }; + + /// + /// Registers manually explicit excluded from reading as those do not contain useful information. + /// Applies for RW commands not RPC data type. + /// + private static readonly List _excludedFromReadParameters = new List + { + "CUSTOMER_AlarmVisualAutoClearMask",// Does NOT respond + "SYSTEM_CustomerSerialNumber0", // Does NOT respond + "SYSTEM_CustomerSerialNumber1", // Does NOT respond + "SYSTEM_CustomerSerialNumber2", // Does NOT respond + "SYSTEM_CustomerSerialNumber3", // Does NOT respond + "SYSTEM_CRC", // Needs application number written to it + "SYSTEM_ExitReason", // Needs application number written to it + "SYSTEM_DriveCapacity", // Needs drive number written to it + "GENESISFLOW_TriggerActive", // Does NOT respond + "SENSUSRADIO_CurrentLoopMax", // Does NOT respond + "SENSUSRADIO_CurrentLoopSource", // Does NOT respond + "SENSUSRADIO_CustomerText" // Does NOT respond + }; + + /// + /// Pre programming parameters for all devices defined here, will be filled with radio parameters + /// if meter has radio + /// + private static readonly List _prepareProgramming = new List + { + // The display needs to be unsealed for change of unit and resolution + new RecoveryRegisterItem("GENESISFLOW_SealDisplay", new Byte[] { 0x00 }) + }; + + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG + private readonly List _failedComparisonRegisters = new List(); + private List _dbParameterRegisterList = new List(); + private List _initialRegisterList = new List(); + private List _finalRegisterList = new List(); + private readonly List _readableRegisterList = new List(); + + /// + /// Post programming parameters for all devices + /// + private static readonly List _finalizeProgrammingAll = new List + { + new RecoveryRegisterItem("LOGGER_TriggerLogFlush", new Byte[] { 0x01 }), + // set counter to 0 as this is a value how often the radio detected a reset + new RecoveryRegisterItem("PERIODICLOG_ResetCounter", new Byte[] { 0x00 }), + // trigger idle 0 releases the display to normal operation + new RecoveryRegisterItem("GENESISFLOW_TriggerIdle", new Byte[] { 0x00 }) + }; + + /// + /// Post programming parameters for EMEA region (as NA region doesn't have radio and seal display shouldn't + /// be executed. + /// + private static readonly List _finalizeProgrammingEmea = new List + { + // 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! + new RecoveryRegisterItem("SENSUSRADIO_SystemState", new Byte[] { 0xFF }), + // seal the display to lock against changes + new RecoveryRegisterItem("GENESISFLOW_SealDisplay", new Byte[] { 0x01 }), + }; + + /// + /// Post programming parameters for EOL (end of line, prepare for shipping workplace) + /// + private static readonly List _finalizeProgrammingEol = new List + { + new RecoveryRegisterItem("GENESISFLOW_ResetAccumulators", new Byte[] { 0x01 }), + new RecoveryRegisterItem("NFC_EraseRMA", new Byte[] { 0x01 }), + new RecoveryRegisterItem("CUSTOMER_RebootCount", new Byte[] { 0x00 }) + }; + + /// + /// Actual register counter + /// + private Int32 _actualRegisterCtr; + + /// + /// Stop register access + /// + public Boolean StopRegisterAccess; + + /// + /// Genesis meter object + /// + private GenesisMeter _currentGenesis; + + /// + /// Ctor + /// + /// + public RegisterRestorer(GenesisMeter currentGenesis) + { + _currentGenesis = currentGenesis; + RecoveryRegisters = null; + RecoveryRegisters = new List(); + } + + /// + /// Assign new genesis after reboot and keep the RegisterRestorer object. + /// + /// + /// + /// - Initial + /// + public void AssignGenesis(GenesisMeter genesisMeter) + { + _currentGenesis = genesisMeter; + } + + /// + /// Collect programming parameters from DB. + /// + /// + /// registers key value pair from data base + /// recovery registers + /// + /// - Initial. + /// + /// + /// - Sort the registers from DB but keep the PrepareProgramming and FinalizeProgramming in the required sequence. + /// + /// + /// - Removed preparation and finalization of register recovery to remove sequencing as this will be done in the + /// RegisterRestorer by the FwUpdateSw worker giving the ability to log this in the report. + /// + /// + /// - Data base access imported to have a common interface for programming parameters for EOL (shipping) and CUST. + /// + /// + /// - Removed prohibited parameters. + /// + /// + /// - Added un-reversed parameters based on data type (string, uint128). + /// + /// + /// - Check and validate register values with installed or intended to be installed FW and given configuration.json. + /// + /// + /// - Exported register range check to . + /// + /// + /// - Debug lists for CSD and VAKO parameters. + /// + public static StatusReturn DownloadProgrammingParametersFromDb(String pcbId, List recoveryRegistersDb) + { + try + { + var url = $"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetProgrammingParameters?PcbID={pcbId}"; + var ppJson = LocalWebRequest.GetRequest(url, 30000); + + if (string.IsNullOrEmpty(ppJson)) + { + return StatusReturn.Failed; + } + + var programmingParameters = JsonConvert.DeserializeObject>(ppJson); + if (programmingParameters == null || programmingParameters.Count == 0) + { + return StatusReturn.Failed; + } + + // Create DEBUG lists + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG + var vakoRegisterList = new List(); + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG + var csdRegisterList = new List(); + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG + var orderRegisterList = new List(); + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG + var sortableRegisterList = new List(); + // ReSharper disable once CollectionNeverQueried.Local IS FOR DEBUG + var multipleAssignedRegisterList = new List(); + + // Temporary storage for sorting before assembling those registers with the preparation and + // finalization of programming and therefore building a sequence + var sortableProgrammingParameters = new List(); + + foreach (var proPar in programmingParameters) + { + // reverse byte order for all parameters except those listed below + if (!string.IsNullOrEmpty(proPar.RegisterName)) + { + // Fill DEBUG lists START + if (sortableRegisterList.Any( a => proPar.RegisterName.Equals(a))) + multipleAssignedRegisterList.Add(proPar.RegisterName); + sortableRegisterList.Add(proPar.RegisterName); + switch (proPar.Source) + { + case ProgrammingSource.Vako: + vakoRegisterList.Add(proPar.RegisterName); + break; + case ProgrammingSource.Csd: + csdRegisterList.Add(proPar.RegisterName); + break; + case ProgrammingSource.Order: + orderRegisterList.Add(proPar.RegisterName); + break; + } + + if (_unReversedParameters.Contains(proPar.RegisterName)) + { + // Add parameter if it is not in the list + if (sortableProgrammingParameters.All(a => !proPar.RegisterName.Equals(a.RegisterName))) + { + sortableProgrammingParameters.Add(proPar); + continue; + } + // if parameter from VAKO is in the list and the new is from CSD, replace this with CSD + if (proPar.Source == ProgrammingSource.Csd && sortableProgrammingParameters.Any(a => + proPar.RegisterName.Equals(a.RegisterName) && a.Source == ProgrammingSource.Vako)) + { + var removeProPar = + sortableProgrammingParameters.Where(a => proPar.RegisterName.Equals(a.RegisterName)); + sortableProgrammingParameters.Remove(removeProPar.LastOrDefault()); + sortableProgrammingParameters.Add(proPar); + } + } + else + { + // ATTENTION: These parameters are coming out of the DB in wrong byte order and needed to be reversed + // for the entire sequence + + // Add parameter if it is not in the list + if (sortableProgrammingParameters.All(a => !proPar.RegisterName.Equals(a.RegisterName))) + { + sortableProgrammingParameters.Add(new ProgrammingParameters(proPar.RegisterName, + proPar.RegisterValue.Reverse().ToArray(), proPar.Source)); + continue; + } + // if parameter from VAKO is in the list and the new is from CSD, replace this with CSD + if (proPar.Source == ProgrammingSource.Csd && sortableProgrammingParameters.Any(a => + proPar.RegisterName.Equals(a.RegisterName) && a.Source == ProgrammingSource.Vako)) + { + var removeProPar = + sortableProgrammingParameters.Where(a => proPar.RegisterName.Equals(a.RegisterName)); + sortableProgrammingParameters.Remove(removeProPar.LastOrDefault()); + sortableProgrammingParameters.Add(new ProgrammingParameters(proPar.RegisterName, + proPar.RegisterValue.Reverse().ToArray(), proPar.Source)); + } + } + } // register for this FW is defined + else + { + return StatusReturn.Failed; + } + } + + // Sort the programming parameters coming from DB (VAKO/CSD) + sortableProgrammingParameters.Sort((x, y) => string.Compare(x.RegisterName, y.RegisterName, + StringComparison.Ordinal)); + + // Sort DEBUG lists + csdRegisterList.Sort(); + vakoRegisterList.Sort(); + orderRegisterList.Sort(); + sortableRegisterList.Sort(); + multipleAssignedRegisterList.Sort(); + + // convert to RecoveryRegisterItem + if (sortableProgrammingParameters.Count > 0) + { + foreach (var proPar in sortableProgrammingParameters) + { + var recReg = new RecoveryRegisterItem(proPar.RegisterName, proPar.RegisterValue); + recoveryRegistersDb.Add(recReg); + } + } + + return StatusReturn.Okay; + } + catch (Exception) + { + return StatusReturn.Failed; + } + } + + /// + /// Avoid doubling of register restore on subsequent FW-Update trials. + /// + /// true if registers already backed up + /// + /// - Initial. + /// + public Boolean RegisterRestoreExecuted() + { + if (_currentGenesis == null) + return false; + if (_currentGenesis.PcbId != _pcbIdFinalRegisterRead) + return false; + return _finalRegisters.Count > 0; + } + + /// + /// EOL (end of line) programming contains a reset of the accumulators. Else it is identical with recover + /// registers. + /// + /// list of registers to update from data base without special sequence + /// + /// true if setup succeeded + /// + /// - Initial. + /// + public StatusReturn EolProgrammingRegisters(List recoveryRegistersDb) + { + // mark EOL as true to force accu reset + return WriteRegisters(recoveryRegistersDb, true); + } + + /// + /// Validate the range of the register. + /// + /// register key value pair + /// register definition by configuration.json + /// error message if range check failed + /// status + /// + /// - Initial, imported from + /// + public static StatusReturn ValidateRegisterRange(RecoveryRegisterItem recReg, + RegisterDefinition regDef, out String errorMessage) + { + + // error message will return on failed check any information + errorMessage = null; + try + { + // check the limits and avoid writing if not in range + var check = RegisterCheck.CheckRange(regDef, recReg.WriteValue); + if (!string.IsNullOrEmpty(check)) + { + errorMessage = $"{Resources.StrRegisterValueOutOfRange}: " + + RegisterConverter.GetRegisterContentText(regDef, recReg.WriteValue) + + $" - Minimum ({regDef.Minimum})" + + $" - Maximum ({regDef.Maximum})"; + + return StatusReturn.Warning; + } + + return StatusReturn.Okay; + } + catch (Exception) + { + return StatusReturn.Failed; + } + } + + /// + /// Recover all registers set from caller. Additional preparation and finalization will be added. + /// settings. + /// + /// list of registers to update from data base without special sequence + /// + /// EOL (end of line) programming with accu reset + /// true if restoring succeeded + /// + /// - Initial. + /// + /// + /// - Return true if already recovered, + /// - replace _restoreRegisters with new value. + /// + /// + /// - Added preparation and finalization of register recovery giving the ability to log this in the report. + /// + /// + /// - Moved register dictionary value set to inner try catch loop to avoid early exit if one register is + /// unknown. + /// + /// + /// - Logging of some exception messages. + /// + /// + /// - EOL sequence for accumulators reset, + /// - Remind pcbId as already recovered before the true return, + /// - Exclude lock of repeated execution for EOL. + /// + /// + /// - Avoid writing of parameters if not writable. The DB delivers parameters which exclusively have to be + /// compared to the specified value. + /// + /// + /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list, + /// - Preset RecoveryRegisters if not set as those have to be compared later on. + /// + /// + /// - Add only registers to recovery list which are found in the generated register list based on installed + /// applications. + /// + /// + /// - Avoid writing of NOT writable registers. + /// + /// + /// - Check register limits, if those are out of range avoid writing and log warning message. + /// + /// + /// - Exported register range check to . + /// + /// + /// - Removed skip recovery if already done in previous run to enable a retry. + /// + /// + /// - Seal display and Sensus radio to EMEA finalization. + /// + public StatusReturn WriteRegisters(List recoveryRegistersDb, Boolean eolProgramming = false) + { + if (_currentGenesis == null || + string.IsNullOrEmpty(_currentGenesis.PcbId) || + recoveryRegistersDb == null || + recoveryRegistersDb.Count == 0) + return StatusReturn.Failed; + + var retVal = StatusReturn.Okay; + + // preset recovery registers if not already set + if (RecoveryRegisters == null) + { + RecoveryRegisters = new List(); + } + if (RecoveryRegisters.Count == 0) + { + RecoveryRegisters = recoveryRegistersDb; + } + + StopRegisterAccess = false; + _actualRegisterCtr = 0; + + // Build string list for debug + _dbParameterRegisterList.Clear(); + _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(); + + // prepare list for finalization depending on SENSUSRADIO installation + var finalizeProgrammingAll = new List(); + + // add EOL (shipping reset of accumulators, alarms and setup of manufacturing date) + if (eolProgramming) + { + finalizeProgrammingAll.AddRange(_finalizeProgrammingEol.Where(finalReg => + meterRegisters.MeterRegisterDic.Any(x => x.Key.GetIdent().Contains(finalReg.RegisterIdent)))); + } + + // add only registers which are defined as needed to restore and in the found register list + // from installed applications + finalizeProgrammingAll.AddRange(_finalizeProgrammingAll.Where(finalReg => + meterRegisters.MeterRegisterDic.Any(x => x.Key.GetIdent().Contains(finalReg.RegisterIdent)))); + + // add special registers for EMEA version + if (_currentGenesis.Region.Equals("EMEA")) + { + finalizeProgrammingAll.AddRange(_finalizeProgrammingEmea.Where(finalReg => + meterRegisters.MeterRegisterDic.Any(x => x.Key.GetIdent().Contains(finalReg.RegisterIdent)))); + } + + // set the process counter + var recRegistersCount = recoveryRegistersDb.Count > 0 ? recoveryRegistersDb.Count : 1; + recRegistersCount += _prepareProgramming.Count; + recRegistersCount += finalizeProgrammingAll.Count; + + // prepare recovery + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryPreparation, + actualProcessMessage: Resources.StrRegisterRecoveryPreparation)); + + foreach (var prepRecReg in _prepareProgramming) + { + _actualRegisterCtr++; + var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / recRegistersCount; + + try + { + // if this call does not throw an exception, the register is present + var regDef = meterRegisters.GetRegisterDefinitionByName(prepRecReg.RegisterIdent); + + _currentGenesis.WriteRegister(prepRecReg.RegisterIdent, prepRecReg.WriteValue); + + var strRawAndConvertedValue = ""; + try + { + strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, prepRecReg.WriteValue); + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Could not convert register value of " + prepRecReg.RegisterIdent + + "; " + ex.Message); + } + finally + { + var actualProcessMsg = $"{Resources.StrWriteRegister}: {strRawAndConvertedValue} "; + + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrWriteRegister}" + + $@" {_actualRegisterCtr} / {recRegistersCount}", + overallProcessCtrPercent, actualProcessMsg)); + } + + if (StopRegisterAccess) + break; + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Could not write register value of " + prepRecReg.RegisterIdent + + "; " + ex.Message); + } + }// prepare recovery + + // register recovery + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryExec, + actualProcessMessage: Resources.StrRegisterRecoveryExec)); + foreach (var recReg in recoveryRegistersDb) + { + _actualRegisterCtr++; + var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / recRegistersCount; + + try + { + // if this call does not throw an exception, the register is present + var regDef = meterRegisters.GetRegisterDefinitionByName(recReg.RegisterIdent); + + // avoid writing of NOT writable registers + if (regDef.RegisterDetail.Privilege.Lvl8 != Access.WO + && regDef.RegisterDetail.Privilege.Lvl8 != Access.RW) + continue; + + // check the limits and avoid writing if not in range + retVal = ValidateRegisterRange(recReg, regDef, out var errorMessage); + if (StatusReturn.Okay != retVal) + { + _currentGenesis.WriteLog(errorMessage); + + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrWriteRegister}" + + $@" {_actualRegisterCtr} / {recRegistersCount}", + overallProcessCtrPercent, errorMessage)); + + continue; + } + + _currentGenesis.WriteRegister(recReg.RegisterIdent, recReg.WriteValue); + var strRawAndConvertedValue = ""; + try + { + strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, recReg.WriteValue); + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Could not convert register value of " + recReg.RegisterIdent + + "; " + ex.Message); + } + finally + { + var actualProcessMsg = $"{Resources.StrWriteRegister}: {strRawAndConvertedValue} "; + + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrWriteRegister}" + + $@" {_actualRegisterCtr} / {recRegistersCount}", + overallProcessCtrPercent, actualProcessMsg)); + } + + if (StopRegisterAccess) + break; + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Could not write register value of " + recReg.RegisterIdent + + "; " + ex.Message); + } + }// recovery registers + + // finalize recovery + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs(Resources.StrRegisterRecoveryFinalization, + actualProcessMessage: Resources.StrRegisterRecoveryFinalization)); + foreach (var finalRecReg in finalizeProgrammingAll) + { + _actualRegisterCtr++; + var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / recRegistersCount; + + try + { + _currentGenesis.WriteRegister(finalRecReg.RegisterIdent, finalRecReg.WriteValue); + + // if this call does not throw an exception, the register is present + var regDef = meterRegisters.GetRegisterDefinitionByName(finalRecReg.RegisterIdent); + + var strRawAndConvertedValue = ""; + try + { + strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, finalRecReg.WriteValue); + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Could not convert register value of " + finalRecReg.RegisterIdent + "; " + + ex.Message); + } + finally + { + var actualProcessMsg = $"{Resources.StrWriteRegister}: {strRawAndConvertedValue} "; + + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrWriteRegister}" + + $@" {_actualRegisterCtr} / {recRegistersCount}", + overallProcessCtrPercent, actualProcessMsg)); + } + + if (StopRegisterAccess) + break; + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Could not write register value of " + finalRecReg.RegisterIdent + + "; " + ex.Message); + } + }// finalize recovery + + // 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); + + return retVal; + } + + /// + /// 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. + /// + /// true if equal + /// + /// - Initial. + /// + /// + /// - Compare registers reactivated based on new interface (configuration.json) with new + /// "StaticType": “approximate”. + /// + /// + /// - Removed as those will change on e.g. FW update. + /// + /// + /// - Avoid message event if message is empty. + /// + /// + /// - Remind registers which failed the comparison including values. + /// + /// + /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. + /// + /// + /// - Removed all registers from comparison which are neither static nor approximate. + /// + /// + /// - Exception logging extended, + /// - Data size base on write data size as this may be shorter than the read data size which is always filled up + /// to a 4 byte chunk size. + /// + /// + /// - Add only registers to recovery list which are found in the generated register list based on installed applications. + /// + /// + /// - Used RecoveryRegisters WriteValue and ReadBackValue for comparison. + /// + /// + /// - Hash password and encryption key with SHA256. + /// + public Boolean CompareRegisters() + { + if (_pcbIdFinalRegisterRead != _pcbIdWriteRegisters || + RecoveryRegisters == null) + return false; + + StopRegisterAccess = 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(); + // Remove all excluded registers + foreach (var regName in _excludedFromCompareParameters.Where(regName => registerNames.Any(reg => reg == regName))) + { + registerNames.Remove(regName); + } + // sort the list of register names + registerNames.Sort(); + // limit the count to 1 to avoid division by zero + var registersCount = registerNames.Count > 0 ? registerNames.Count : 1; + + // get the pre-defined dictionary + var meterRegisters = _currentGenesis.GetConfigRegistersDefinitions(); + + // access every register + foreach (var regName in registerNames) + { + _actualRegisterCtr++; + var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / registersCount; + + RegisterDefinition regDef = null; + try + { + // take the register properties from configuration.json + regDef = meterRegisters.GetRegisterDefinitionByName(regName); + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Meter register not defined or application not installed " + + regName + "; " + ex.Message); + } + + // skip all registers from comparison which are neither static nor approximate or not detected + // in meter registers based on installed applications + if (regDef == null || !regDef.RestoreCapability.CheckRestoreCapability()) + { + continue; + } + + try + { + // Get the raw byte array of this register + var recReg = RecoveryRegisters.First(reg => reg.RegisterIdent.Equals(regName)); + var writtenValue = recReg.WriteValue; + var readBackValue = recReg.ReadBackValue; + + // If any value is null then there is nothing to compare + if (writtenValue == null || readBackValue == null) + { + _failedComparisonRegisters?.Add(new RecoveryRegisterItem(regName, writtenValue, readBackValue)); + continue; //TODO THW check if error should be signalized + } + + // ATTENTION: Take the size of the read back value as this will be filled up to a chunk of 4 + // bytes and therefore the required write value may have a smaller byte list! + var dataSize = writtenValue.Length; + + var strRequiredRegisterValue = ""; + try + { + var isApproximated = false; + var isIdentical = false; + if (regDef.RegisterDetail.StaticType == StaticType.ReadBackApproximated) + { + Int64 restoreValue = 0; + Int64 finalValue = 0; + if (regDef.DataType.Name.Equals("Int32")) + { + restoreValue = RegisterConverter.ByteArrayToValue(writtenValue); + finalValue = RegisterConverter.ByteArrayToValue(readBackValue); + } + else if (regDef.DataType.Name.Equals("UInt32")) + { + restoreValue = RegisterConverter.ByteArrayToValue(writtenValue); + finalValue = RegisterConverter.ByteArrayToValue(readBackValue); + } + // Just half of number range will work due to cast to Int64 + else if (regDef.DataType.Name.Equals("UInt64")) + { + restoreValue = (Int64)RegisterConverter.ByteArrayToValue(writtenValue); + finalValue = (Int64)RegisterConverter.ByteArrayToValue(readBackValue); + } + else if (regDef.DataType.Name.Equals("Int64")) + { + restoreValue = RegisterConverter.ByteArrayToValue(writtenValue); + finalValue = RegisterConverter.ByteArrayToValue(readBackValue); + } + else if (regDef.DataType.Name.Equals("Byte")) + { + restoreValue = RegisterConverter.ByteArrayToValue(writtenValue); + finalValue = RegisterConverter.ByteArrayToValue(readBackValue); + } + else if (regDef.DataType.Name.Equals("SByte")) + { + restoreValue = RegisterConverter.ByteArrayToValue(writtenValue); + finalValue = RegisterConverter.ByteArrayToValue(readBackValue); + } + // Check limited to +/- 3 + if (restoreValue - 3 <= finalValue && restoreValue + 3 >= finalValue) + { + isApproximated = true; + } + } + else + { + for (var c = 0; c < dataSize; c++) + { + if (writtenValue[c] != readBackValue[c]) + { + isIdentical = false; + break; + } + isIdentical = true; + } + } + // 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 + { + var encryptRawData = regName.Contains("EncryptionKey") || regName.Contains("Password"); + + var strReadBackRegisterValue = RegisterConverter.GetRegisterRawText(regDef, readBackValue, + encryptRawData); + + strRequiredRegisterValue += $" - {Resources.StrMeterValue}: ({strReadBackRegisterValue})" + + $" - {Resources.StrRegisterCompareFailed}"; + _failedComparisonRegisters?.Add(new RecoveryRegisterItem(regName, writtenValue, + readBackValue)); + retVal = false; + } + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Could not compare register value of " + regName + "; " + ex.Message); + } + finally + { + var actualProcessMsg = $"{Resources.StrRegisterCompare}: {strRequiredRegisterValue} "; + + // Avoid message if nothing to tell + if (!string.IsNullOrEmpty(strRequiredRegisterValue)) + { + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrRegisterCompare}" + + $@" {_actualRegisterCtr} / {registersCount}", + overallProcessCtrPercent, actualProcessMsg)); + } + } + + if (StopRegisterAccess) + break; + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Could not access register for comparison " + regName + "; " + ex.Message); + } + } + return retVal; + } + + /// + /// Read the registers after the update for comparision. Build the post update registers here, + /// because an update may have changed the registers (new or removed registers). + /// + /// true if registers could be read + /// + /// - Initial. + /// + /// + /// - Build here the post update registers, they may have changed due to update! + /// + /// + /// - Clear pre update registers if post indicates a different PCB ID to avoid wrong overwriting of + /// registers to non matching new meter. + /// + /// + /// - Return true if already executed in previous run. + /// + /// + /// - Return false if PcbId between initial- and final-read does NOT match return false. + /// + /// + /// - Allow final read out as often as called even if done before. + /// + /// + /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. + /// + /// + /// - Backup _finalRegisters to RecoveryRegisters. + /// + public Boolean FinalReadRegisters() + { + if (_currentGenesis == null) + return false; + + // 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 after update register read string + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}", 0, + Resources.StrReadRegistersAfterUpdate)); + + // Build string list for debug + _finalRegisterList.Clear(); + _finalRegisterList = _finalRegisters.Select(register => register.RegisterIdent).ToList(); + _finalRegisterList.Sort(); + + // executes login read logout + var retVal = ReadRegistersSet(ref _finalRegisters); + + // backup read data to RecoveryRegisters + if (RecoveryRegisters != null && _finalRegisters != null) + { + foreach (var recReg in RecoveryRegisters) + { + foreach (var finalReg in _finalRegisters.Where(finalReg => + recReg.RegisterIdent.Equals(finalReg.RegisterIdent))) + { + recReg.ReadBackValue = new Byte[finalReg.ReadBackValue.Length]; + for (var c = 0; c < finalReg.ReadBackValue.Length; c++) + recReg.ReadBackValue[c] = finalReg.ReadBackValue[c]; + } + } + } + + // remind the PCB ID before update for comparison + _pcbIdFinalRegisterRead = _currentGenesis.PcbId; + + return retVal; + } + + /// + /// Get DEFINED registers from GenesisMeter class and read all registers which are flagged with + /// read write (RW) or read only (RO). Build a list of all registers being able to restore flagged + /// with equals ". + /// The defined registers are based on the "configuration.json" and the installed application with + /// a specific version. + /// + /// true if registers could be read + /// + /// - Initial. + /// + /// + /// - Stored registers before and after update. + /// + /// + /// - Extended register check. + /// + /// + /// - Removed after update registers and moved them to FinalReadRegisters. They may have changed + /// during the update. + /// + /// + /// - Deny register pre update if _pcbIdPreUpdate indicates, that this has been already processed. + /// + /// + /// - Removed login/logout, + /// - if _initialReadRegisters and _restoreRegisters are filled, return true. + /// + /// + /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. + /// + public Boolean InitialReadRegisters() + { + if (_currentGenesis == null) + return false; + + // deny update of registers if already done + if (_pcbIdInitialRegisterRead == _currentGenesis.PcbId && + _initialRegisters.Count > 0) + return true; + + // remind the PCB ID before update for comparison + _pcbIdInitialRegisterRead = _currentGenesis.PcbId; + + // create the dictionaries out of the configuration.json + if (!BuildReadableRegisterDictionary(ref _initialRegisters)) + return false; + + // log to report file the initial register read string + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}", 0, + Resources.StrReadRegistersBeforeUpdate)); + + // Build string list for debug + _initialRegisterList.Clear(); + _initialRegisterList = _initialRegisters.Select(register => register.RegisterIdent).ToList(); + _initialRegisterList.Sort(); + + return ReadRegistersSet(ref _initialRegisters); + } + + /// + /// Get DEFINED registers from GenesisMeter class and build a list all registers which are flagged + /// with read write (RW) or read only (RO). + /// The defined registers are based on the "configuration.json" and the installed application with + /// a specific version. + /// + /// all readable registers dictionary creation + /// true if register dictionary is not empty + /// true if registers could be read + /// + /// - Initial from . + /// + /// + /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. + /// + /// + /// - Excluded registers which do not contain useful information. + /// + public Boolean BuildReadableRegisterDictionary(ref List 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 + // internally the register content for comparison ability. Exclude register which contain no useful info. + foreach (var reg in meterRegisters.MeterRegisterDic.Where(r => r.Key.RegisterDetail.Version.First != null + && r.Key.RegisterDetail.Version.Last != null && r.Key.RestoreCapability.StaticTypeValue != null + && r.Key.DataType != typeof(Rpc) && r.Key.IsAvailable && + (r.Key.RegisterDetail.Privilege.Lvl8 == Access.RW || r.Key.RegisterDetail.Privilege.Lvl8 == Access.RO) + && _excludedFromReadParameters.All(regName => regName != r.Key.GetIdent()))) + { + 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)); + return registers.Count > 0; + } + + /// + /// Get DEFINED registers from GenesisMeter class and read all registers which are flagged with read write + /// (RW) or read only (RO). + /// The defined registers are based on the "configuration.json" and the installed application with a specific + /// version. + /// + /// true if registers could be read + /// + /// - Initial. + /// + /// + /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. + /// + public Boolean ReadRegisters() + { + if (_currentGenesis == null) + return false; + + // temporary list of registers just for read and log without keeping them alive + var registers = new List(); + + if (!BuildReadableRegisterDictionary(ref registers)) + return false; + + // log to report file the initial register read string + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}", 0, + Resources.StrReadRegistersBeforeUpdate)); + + return ReadRegistersSet(ref registers); + } + + /// + /// Register read loop. + /// All registers needed to be read from the Genesis meter as they are only prepared as template and NOT filled + /// with the register data! + /// The uses the overall process text and value for user information process + /// bar and text and the actual process text for logging to the report file! + /// Executes login, read cycle and logout. + /// + /// registers to read + /// true if registers could be read + /// + /// - Initial. + /// + /// + /// - Set value to actual process message. + /// + /// + /// - Added PCB ID to logging. + /// + /// + /// - Removed PCB ID from logging. + /// + /// + /// - Simplified input of set of registers to read. + /// + /// + /// - Set raw values in register dictionaries. + /// + /// + /// - Extended try catch to avoid break on one register failed. + /// + /// + /// - Filtered restore registers to access only if assigned, + /// - Logging of some exception messages. + /// + /// + /// - Register list changed from RegisterDefinition to RecoveryRegisterItem list. + /// + private Boolean ReadRegistersSet(ref List registers) + { + if (_currentGenesis == null) + return false; + StopRegisterAccess = false; + _actualRegisterCtr = 0; + + // read values from Genesis + _currentGenesis.ReLogin(); + if (!_currentGenesis.IsLoggedOn) + return false; + + // build a string list of the registers being able to sort those + var registerNames = registers.Select(register => register.RegisterIdent).ToList(); + // sort the list of register names + registerNames.Sort(); + // limit the count to 1 to avoid division by zero + var registersCount = registerNames.Count > 0 ? registerNames.Count : 1; + + // get the pre-defined dictionary + var meterRegisters = _currentGenesis.GetConfigRegistersDefinitions(); + // access every register + foreach (var regName in registerNames) + { + _actualRegisterCtr++; + + // get register definition to analyze the data type and therefore the expected length + var regDef = meterRegisters.GetRegisterDefinitionByName(regName); + + // get the register out of the given list + var register = registers.FirstOrDefault(reg => reg.RegisterIdent.Equals(regName)); + + var overallProcessCtrPercent = 100.0 * _actualRegisterCtr / registersCount; + + try + { + var rawRegister = _currentGenesis.ReadRegister(regName, RegisterConverter.SizeOf(regDef)); + try + { + if (register != null && rawRegister != null) + { + register.ReadBackValue = new Byte[rawRegister.Length]; + for (var c = 0; c < rawRegister.Length; c++) + register.ReadBackValue[c] = rawRegister[c]; + } + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Register value backup failed " + regName + "; " + ex.Message); + } + + var strRawAndConvertedValue = $"{regName} - ?"; + try + { + if (rawRegister != null) + { + // convert register content to text with raw and converted value depending on data type + strRawAndConvertedValue = RegisterConverter.GetRegisterContentText(regDef, rawRegister); + } + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Register value conversion failed " + regName + "; " + ex.Message); + } + finally + { + var actualProcessMsg = $"{Resources.StrReadRegister}: {strRawAndConvertedValue} "; + + OnProcessUpdate?.Invoke(this, new ProcessExecEventArgs($@"{Resources.StrReadRegister}" + + $@" {_actualRegisterCtr} / {registersCount}", + overallProcessCtrPercent, actualProcessMsg)); + } + + if (StopRegisterAccess) + break; + } + catch (Exception ex) + { + _currentGenesis.WriteLog("Register value read access failed " + regName + "; " + ex.Message); + } + } + _currentGenesis.Logout(); + return true; + } + } +} diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/configuration.json b/Common/Hardware/WaterMeter/Genesis/GenesisCore/configuration.json index d0d026f0..d58f83b8 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/configuration.json +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/configuration.json @@ -1,4 +1,18 @@ { +// "SUMMARY": { +// "schema": "1", +// "version": "348", +// "description": "...", +// "build": { +// "emea": "R1415 2025-02-08", +// "na": "B2011 2024-10-10" +// }, +// "CordonelRegisterResponsibilities.xlsx": { +// "version": "66.0", +// "timestamp": "2025-02-18 13:16" +// }, +// "date_modified": "2025-02-21 10:21" +// }, "CONFIGEXCHANGE": { "id": 4, "version": { @@ -31,7 +45,21 @@ "minimum": 0, "maximum": 8 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Used at the same time as Password so probably wants to have column S indicated.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -55,7 +83,24 @@ "first": 3, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F.", + "R.D." + ], + "remarks": "Used in login.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -79,7 +124,21 @@ "first": 20, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -103,7 +162,21 @@ "first": 20, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -127,7 +200,21 @@ "first": 20, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -151,7 +238,21 @@ "first": 20, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -175,7 +276,21 @@ "first": 20, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -199,7 +314,21 @@ "first": 20, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -223,7 +352,21 @@ "first": 20, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -247,7 +390,21 @@ "first": 20, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -271,7 +428,21 @@ "first": 49, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -295,7 +466,23 @@ "first": 59, "last": 242 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": true, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "Used for identification and login.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -319,7 +506,23 @@ "first": 59, "last": 242 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "I don't expect this to be changed.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -343,7 +546,21 @@ "first": 66, "last": 242 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] } @@ -412,7 +629,7 @@ "id": 9, "version": { "first": 1, - "last": 162 + "last": 163 }, "registers": { "AlarmStatus0": { @@ -433,9 +650,23 @@ "description": "8 bit counts corresponding to alarms 0-3.", "version": { "first": 1, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -457,9 +688,23 @@ "description": "8 bit counts corresponding to alarms 4-7.", "version": { "first": 1, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -500,9 +745,31 @@ "description": "Any set bits manually clear the corresponding alarm.", "version": { "first": 111, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [], + "remarks": "Cancel all alarms at the end of production.", + "region": { + "emea": { + "values": { + "default": 4294967295 + } + }, + "na": { + "values": { + "default": 4294967295 + } + } + } + } } ] }, @@ -524,9 +791,23 @@ "description": "8 bit counts corresponding to alarms 8-11.", "version": { "first": 26, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -548,9 +829,23 @@ "description": "8 bit counts corresponding to alarms 12-15.", "version": { "first": 26, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -572,9 +867,23 @@ "description": "8 bit counts corresponding to alarms 16-19.", "version": { "first": 26, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -596,9 +905,23 @@ "description": "8 bit counts corresponding to alarms 20-23.", "version": { "first": 26, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -620,9 +943,23 @@ "description": "8 bit counts corresponding to alarms 24-27.", "version": { "first": 26, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -644,9 +981,23 @@ "description": "8 bit counts corresponding to alarms 28-31.", "version": { "first": 26, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -699,7 +1050,79 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Bitmaskof the alarms that we are interested in. I can imagine some customers may have different requirements to others. The radio does change this.", + "region": { + "emea": { + "values": { + "default": 32851 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } + }, + { + "type": "uint32_t", + "privilege": { + "lvl1": "RO", + "lvl2": "RO", + "lvl3": "RW", + "lvl4": "RO", + "lvl5": "RW", + "lvl6": "RW", + "lvl7": "RW", + "lvl8": "RW" + }, + "description": "Bit set of those alarms which are being monitored.", + "version": { + "first": 163, + "last": 163 + }, + "values": { + "default": 49235, + "minimum": 2, + "maximum": 654915 + }, + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Bitmaskof the alarms that we are interested in. I can imagine some customers may have different requirements to others. The radio does change this.", + "region": { + "emea": { + "values": { + "default": 49235 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -745,14 +1168,38 @@ "description": "Bit set of those alarms which will generate events.", "version": { "first": 111, - "last": 162 + "last": 163 }, "values": { "default": 4294967295, "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "custom", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "This updates the same value asAlarmEnableMask, best to avoid changing it.", + "region": { + "emea": { + "values": { + "default": 32851 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -805,7 +1252,79 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "custom", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S" + ], + "remarks": "Bitmask of the alarms that will be shown on the display (both the alarm ID and the flag icon). Again, I can imagine different customers wanting different things. The radio seems to set this but it seems to be a hardwired value.", + "region": { + "emea": { + "values": { + "default": 8156 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } + }, + { + "type": "uint32_t", + "privilege": { + "lvl1": "RO", + "lvl2": "RO", + "lvl3": "RW", + "lvl4": "RO", + "lvl5": "RW", + "lvl6": "RW", + "lvl7": "RW", + "lvl8": "RW" + }, + "description": "Bit set of those alarms which are displayed with IDs and the alarm icon.", + "version": { + "first": 163, + "last": 163 + }, + "values": { + "default": 16382, + "minimum": 16382, + "maximum": 16382 + }, + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.S" + ], + "remarks": "Bitmask of the alarms that will be shown on the display (both the alarm ID and the flag icon). Again, I can imagine different customers wanting different things. The radio seems to set this but it seems to be a hardwired value.", + "region": { + "emea": { + "values": { + "default": 16382 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -846,9 +1365,23 @@ "description": "Alarms that have their display automatically cleared", "version": { "first": 111, - "last": 162 + "last": 163 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Not in use, ignore.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -942,14 +1475,51 @@ "description": "Flow rate above which broken pipe alarm is set in 1/256 l/h. Due to rounding the value read back may not be exactly the value written. This is why the statictype is given as 'approximate'", "version": { "first": 133, - "last": 162 + "last": 163 + }, + "si_transform": { + "remarks": "Cubic Meters per Second: conversion of 1/256 l/h flow rate units, the volume (liters = (1 / 256) * 10^-3 m^3 = 3.90625 * 10^-6 m^3) and time (hours = 3600 s) into SI base units. Flow rate = (3.90625 * 10^-6 m^3) / (3600 s) = 1.085069444 * 10^-9 m^3/s.", + "units": "m^3/s", + "scale_float_mult": 1.0, + "scale_power_2": -8, + "scale_power_10": -3, + "scale_float_div": 3600.0, + "offset": 0 }, "values": { "default": 639999, "minimum": 0, "maximum": 4294967295 }, - "statictype": "approximate" + "statictype": "approximate", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "This is just the flow rate above which you'll get a broken pipe alarm (assuming it is above for ExcessFlowTimeThreshold). This, along with all the alarm configuration settings seem like things that different customers might want different settings for. However I believe most can be changed via the radio. A.F.: Register is for the EMEA alarms so we don't need them for any NA meter sizes. NA alarms are configured at uniontown using UI-1236. Should NA columns be cleared?", + "region": { + "emea": { + "values": { + "DN40": 6400000, + "DN50": 12800000, + "DN65": 16000000, + "DN80": 22400000, + "DN100": 32000000, + "DN125": 64000000, + "DN150": 96000000, + "DN200": 128000000, + "DN250": 192000000, + "DN300": 256000000 + } + } + } + } } ] }, @@ -1019,14 +1589,42 @@ "description": "Time threshold for leak alarm in minutes", "version": { "first": 119, - "last": 162 + "last": 163 + }, + "si_transform": { + "remarks": "Seconds: time in minutes ...", + "units": "s", + "scale_float_mult": 60.0, + "scale_power_2": 0, + "scale_power_10": 0, + "scale_float_div": 1.0, + "offset": 0 }, "values": { "default": 360, "minimum": 0, "maximum": 69632 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "custom", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Default for J.S. is 20160. A.F.: Register is for the EMEA alarms so we don't need them for any NA meter sizes. NA alarms are configured at uniontown using UI-1236. Should NA columns be cleared?", + "region": { + "emea": { + "values": { + "default": 20160 + } + } + } + } } ] }, @@ -1096,14 +1694,38 @@ "description": "Number of measurements in reverse flow required to set reverse flow alarm", "version": { "first": 143, - "last": 162 + "last": 163 }, "values": { "default": 15, "minimum": 0, "maximum": 65535 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "custom", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "NEW! 1800 is the new default. Sould be up to 15min! A.F.: in normal usage (2Hz measurement) 15 measurements means 7.5 seconds.", + "region": { + "emea": { + "values": { + "default": 1800 + } + }, + "na": { + "values": { + "default": 60 + } + } + } + } } ] }, @@ -1125,14 +1747,30 @@ "description": "Timezone in which this application is set to run.", "version": { "first": 24, - "last": 162 + "last": 163 }, "values": { "default": 0, "minimum": 0, "maximum": 65535 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": true, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "VaKo?? We need a seperation of Timezone an display view. A.F.: There are a lot of locales, not just one per time zone. Using the correct locale should set the display and the timezone correctly.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -1154,9 +1792,23 @@ "description": "A name for the arrangement of applications on the meter", "version": { "first": 130, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "This is a readonly register that gives the firmware a hint about whether it is set up as an EMEA or NA meter (or neither). You can ignore or use it to check the value is as expected. Might be worth checking it.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -1201,13 +1853,27 @@ "description": "The number of times the meter has rebooted", "version": { "first": 111, - "last": 162 + "last": 163 }, "values": { "minimum": 0, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -1277,14 +1943,38 @@ "description": "Time threshold for broken pipe alarm in minutes", "version": { "first": 119, - "last": 162 + "last": 163 }, "values": { "default": 180, "minimum": 0, "maximum": 69632 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Default for J.S. is 5.", + "region": { + "emea": { + "values": { + "default": 5 + } + }, + "na": { + "values": { + "default": 5 + } + } + } + } } ] }, @@ -1378,14 +2068,42 @@ "description": "Flow rate above which leak alarm can be set in 1/256 l/h. Due to rounding the value read back may not be exactly the value written. This is why the statictype is given as 'approximate'", "version": { "first": 133, - "last": 162 + "last": 163 }, "values": { "default": 6399, "minimum": 0, "maximum": 4294967295 }, - "statictype": "approximate" + "statictype": "approximate", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "This is just the flow rate above which you'll get a leak alarm (assuming it is above for LeakTimeThreshold). A.F.: Register is for the EMEA alarms so we don't need them for any NA meter sizes. NA alarms are configured at uniontown using UI-1236. Should NA columns be cleared?", + "region": { + "emea": { + "values": { + "DN40": 64000, + "DN50": 96000, + "DN65": 160000, + "DN80": 224000, + "DN100": 320000, + "DN125": 640000, + "DN150": 960000, + "DN200": 1280000, + "DN250": 2240000, + "DN300": 2560000 + } + } + } + } } ] }, @@ -1407,12 +2125,35 @@ "description": "Charge in uAs available in manufacturing (read only)", "version": { "first": 84, - "last": 162 + "last": 163 + }, + "si_transform": { + "remarks": "Coulombs: charge in uAs ...", + "units": "C", + "scale_float_mult": 1.0, + "scale_power_2": 0, + "scale_power_10": -6, + "scale_float_div": 1.0, + "offset": 0 }, "values": { "default": 181440000 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [], + "remarks": "Check totalusedcharge against this to ensure battery usage in manufacturing isn't too high", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -1431,7 +2172,7 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "High temperature alarm threshold in 0.1°C", + "description": "High temperature alarm threshold in 0.1C", "version": { "first": 88, "last": 100 @@ -1455,7 +2196,7 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "High temperature alarm threshold in 0.1°C", + "description": "High temperature alarm threshold in 0.1C", "version": { "first": 101, "last": 110 @@ -1479,17 +2220,50 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "High temperature alarm threshold in 0.1°C", + "description": "High temperature alarm threshold in 0.1C", "version": { "first": 111, - "last": 162 + "last": 163 + }, + "si_transform": { + "remarks": "Degrees Celsius: temperature in 0.1 degrees C ...", + "units": "C", + "scale_float_mult": 1.0, + "scale_power_2": 0, + "scale_power_10": -1, + "scale_float_div": 1.0, + "offset": 0 }, "values": { "default": 500, "minimum": 0, "maximum": 800 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Checked from J.S.", + "region": { + "emea": { + "values": { + "default": 500 + } + }, + "na": { + "values": { + "default": 270 + } + } + } + } } ] }, @@ -1535,14 +2309,47 @@ "description": "Time threshold for high temperature alarm in seconds", "version": { "first": 111, - "last": 162 + "last": 163 + }, + "si_transform": { + "remarks": "Seconds: time in seconds ...", + "units": "s", + "scale_float_mult": 60.0, + "scale_power_2": 0, + "scale_power_10": 0, + "scale_float_div": 1.0, + "offset": 0 }, "values": { "default": 600, "minimum": 0, "maximum": 10800 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Checked from J.S.", + "region": { + "emea": { + "values": { + "default": 300 + } + }, + "na": { + "values": { + "default": 60 + } + } + } + } } ] }, @@ -1561,7 +2368,7 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "Low temperature alarm threshold in 0.1°C", + "description": "Low temperature alarm threshold in 0.1C", "version": { "first": 88, "last": 100 @@ -1585,7 +2392,7 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "Low temperature alarm threshold in 0.1°C", + "description": "Low temperature alarm threshold in 0.1C", "version": { "first": 101, "last": 110 @@ -1609,17 +2416,41 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "Low temperature alarm threshold in 0.1°C", + "description": "Low temperature alarm threshold in 0.1C", "version": { "first": 111, - "last": 162 + "last": 163 }, "values": { "default": 20, "minimum": -2147483648, "maximum": 2147483647 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Checked from J.S.", + "region": { + "emea": { + "values": { + "default": 20 + } + }, + "na": { + "values": { + "default": 20 + } + } + } + } } ] }, @@ -1665,14 +2496,38 @@ "description": "Time threshold for low temperature alarm in seconds", "version": { "first": 111, - "last": 162 + "last": 163 }, "values": { "default": 600, "minimum": 0, "maximum": 10800 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Checked from J.S.", + "region": { + "emea": { + "values": { + "default": 300 + } + }, + "na": { + "values": { + "default": 60 + } + } + } + } } ] }, @@ -1742,14 +2597,38 @@ "description": "High pressure alarm threshold in Pa", "version": { "first": 122, - "last": 162 + "last": 163 }, "values": { "default": 1600000, "minimum": 0, "maximum": 2550000 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": "custom", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Absolute or relative? A.F.: gauge pressure.", + "region": { + "emea": { + "values": { + "default": 1600000 + } + }, + "na": { + "values": { + "default": 1380000 + } + } + } + } } ] }, @@ -1819,14 +2698,47 @@ "description": "Time threshold for high pressure alarm in seconds", "version": { "first": 119, - "last": 162 + "last": 163 + }, + "si_transform": { + "remarks": "Seconds: ...", + "units": "s", + "scale_float_mult": 60.0, + "scale_power_2": 0, + "scale_power_10": 0, + "scale_float_div": 1.0, + "offset": 0 }, "values": { "default": 600, "minimum": 0, "maximum": 10800 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Checked from J.S.", + "region": { + "emea": { + "values": { + "default": 300 + } + }, + "na": { + "values": { + "default": 60 + } + } + } + } } ] }, @@ -1896,14 +2808,38 @@ "description": "Low pressure alarm threshold in Pa", "version": { "first": 122, - "last": 162 + "last": 163 }, "values": { "default": 30000, "minimum": 0, "maximum": 2550000 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Absolute or relative? A.F.: gauge pressure.", + "region": { + "emea": { + "values": { + "default": 30000 + } + }, + "na": { + "values": { + "default": 240000 + } + } + } + } } ] }, @@ -1973,14 +2909,38 @@ "description": "Time threshold for low pressure alarm in seconds", "version": { "first": 119, - "last": 162 + "last": 163 }, "values": { "default": 600, "minimum": 0, "maximum": 10800 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Checked from J.S.", + "region": { + "emea": { + "values": { + "default": 300 + } + }, + "na": { + "values": { + "default": 60 + } + } + } + } } ] }, @@ -2021,9 +2981,23 @@ "description": "Store all configuration items in non-volatile memory.", "version": { "first": 131, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "You do need to use this if you change any parameters in CUSTOMER and want to keep them.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -2045,9 +3019,26 @@ "description": "Customer serial number string", "version": { "first": 139, - "last": 162 + "last": 163 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.S.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -2069,9 +3060,25 @@ "description": "Internal backup of calendar seconds", "version": { "first": 145, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "Internal use in firmware only", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -2090,12 +3097,36 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "Time meter was determined to have been installed. 0 means not installed", + "description": "Datetime in seconds since 1/1/2000 00:00:00. Time meter was determined to have been installed. 0 means not installed.", "version": { "first": 147, - "last": 162 + "last": 163 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "A.F." + ], + "remarks": "Write to zero before leaving manufacturing to ensure not marked as 'installed'.", + "region": { + "emea": { + "values": { + "default": 0 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -2117,9 +3148,25 @@ "description": "Read to view the string used as a decimal point for this locale", "version": { "first": 151, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -2141,9 +3188,25 @@ "description": "Read to view the string used as a thousands separarator for this locale", "version": { "first": 151, - "last": 162 + "last": 163 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -2165,13 +3228,27 @@ "description": "Test whether the internal login works. Start test by writing '1' then log out to enable the test to run. Log back in and read back this register for result (see status codes)", "version": { "first": 157, - "last": 162 + "last": 163 }, "values": { "minimum": 0, "maximum": 65535 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "Helper function to test the configexchange login at the internal level will succeed (that is, that the password is as expected). This should be tested after installation of password file at end of line. Add to production test if register present in firmware.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -2193,14 +3270,30 @@ "description": "time threshold in Minutes for NoFlowAlarm trigger NoFlowAlarm trigger", "version": { "first": 161, - "last": 162 + "last": 163 }, "values": { "default": 43200, "minimum": 1, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + ".J.L." + ], + "remarks": "This has default setting for DEWA customer. Unsupported.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -2222,14 +3315,30 @@ "description": "number of consecutive samples (Minutes) before NoFlow Alarm gets cleared", "version": { "first": 161, - "last": 162 + "last": 163 }, "values": { "default": 5, "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + ".J.L." + ], + "remarks": "This has default setting for DEWA customer. Unsupported.", + "region": { + "emea": null, + "na": null + } + } } ] } @@ -2498,7 +3607,20 @@ "first": 2, "last": 22 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Can be ignored, temporarily for FW upgrade.", + "region": { + "na": null + } + } } ] }, @@ -2522,7 +3644,20 @@ "first": 2, "last": 22 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Can be ignored, temporarily for FW upgrade.", + "region": { + "na": null + } + } } ] } @@ -2979,7 +4114,31 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "B.D." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 2 + } + }, + "na": { + "values": { + "default": 2 + } + } + } + } }, { "type": "uint8_t", @@ -3104,7 +4263,24 @@ "minimum": -128, "maximum": 127 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int8_t", @@ -3229,7 +4405,24 @@ "minimum": -128, "maximum": 127 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int8_t", @@ -3354,7 +4547,24 @@ "minimum": -128, "maximum": 127 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int8_t", @@ -3479,7 +4689,24 @@ "minimum": -128, "maximum": 127 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int8_t", @@ -3604,7 +4831,24 @@ "minimum": -128, "maximum": 127 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int8_t", @@ -3729,7 +4973,24 @@ "minimum": -128, "maximum": 127 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int8_t", @@ -3854,7 +5115,32 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "Default is 6 and it should stay as 6 for all sizes.", + "region": { + "emea": { + "values": { + "default": 6 + } + }, + "na": { + "values": { + "default": 6 + } + } + } + } }, { "type": "uint8_t", @@ -3979,7 +5265,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "B.D." + ], + "remarks": "Not expecting to change this unless field trials say we should.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -4104,7 +5406,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "B.D." + ], + "remarks": "Not expecting to change this unless field trials say we should.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -4229,7 +5547,24 @@ "minimum": -128, "maximum": 127 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": true, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.S.", + "R.D." + ], + "remarks": "(<=125 = 3n ) 150=> 2n in m -> what about other Units. See Display Unit Customer Specification.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int8_t", @@ -4354,7 +5689,23 @@ "minimum": 0, "maximum": 6 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": true, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Same units for each calculator. Vako.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "enum8", @@ -4503,7 +5854,47 @@ "minimum": 0, "maximum": 17 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": true, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Base No. (4th digit G=50, ...) or B01 Nominal diameter (DN) (DN50, ...).", + "region": { + "emea": { + "values": { + "DN40": 0, + "DN50": 1, + "DN65": 2, + "DN80": 3, + "DN100": 4, + "DN125": 5, + "DN150": 6, + "DN200": 7, + "DN250": 8, + "DN300": 9 + } + }, + "na": { + "values": { + "US1_5": 10, + "US2": 11, + "US3": 12, + "US4": 13, + "US6": 14, + "US8": 15, + "US10": 16, + "US12": 17 + } + } + } + } }, { "type": "enum8", @@ -4652,7 +6043,24 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint16_t", @@ -4801,7 +6209,24 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint16_t", @@ -4950,7 +6375,24 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint16_t", @@ -5094,12 +6536,38 @@ "first": 268, "last": 322 }, + "si_transform": { + "remarks": "Seconds: convert time in 2^-38 seconds...", + "units": "s", + "scale_float_mult": 1.0, + "scale_power_2": -38, + "scale_power_10": 0, + "scale_float_div": 1.0, + "offset": 0 + }, "values": { "default": 0, "minimum": -2147483648, "maximum": 2147483647 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int32_t", @@ -5243,12 +6711,38 @@ "first": 268, "last": 322 }, + "si_transform": { + "remarks": "Seconds: convert time in 2^-38 seconds...", + "units": "s", + "scale_float_mult": 1.0, + "scale_power_2": -38, + "scale_power_10": 0, + "scale_float_div": 1.0, + "offset": 0 + }, "values": { "default": 0, "minimum": -2147483648, "maximum": 2147483647 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int32_t", @@ -5392,12 +6886,38 @@ "first": 268, "last": 322 }, + "si_transform": { + "remarks": "Seconds: convert time in 2^-38 seconds...", + "units": "s", + "scale_float_mult": 1.0, + "scale_power_2": -38, + "scale_power_10": 0, + "scale_float_div": 1.0, + "offset": 0 + }, "values": { "default": 0, "minimum": -2147483648, "maximum": 2147483647 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int32_t", @@ -5493,7 +7013,21 @@ "first": 47, "last": 322 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int64_t", @@ -5593,7 +7127,23 @@ "first": 268, "last": 322 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "R.D." + ], + "remarks": "You will need this if you wish to reset the volume to zero at the end of calibration.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "bool_t", @@ -5703,7 +7253,31 @@ "minimum": 0, "maximum": 2 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 0 + } + }, + "na": { + "values": { + "default": 1 + } + } + } + } }, { "type": "enum8", @@ -5852,7 +7426,31 @@ "minimum": 0, "maximum": 6 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "R.D." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 0 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } }, { "type": "enum8", @@ -5948,7 +7546,23 @@ "first": 54, "last": 322 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "R.D." + ], + "remarks": "You will need to use this during calibration.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint32_t", @@ -6029,7 +7643,21 @@ "first": 54, "last": 322 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint64_t", @@ -6110,7 +7738,21 @@ "first": 54, "last": 322 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint64_t", @@ -6215,12 +7857,62 @@ "first": 268, "last": 322 }, + "si_transform": { + "remarks": "Cubic Meters: conversion of the volume volume in ml ...", + "units": "m^3", + "scale_float_mult": 1.0, + "scale_power_2": 0, + "scale_power_10": -6, + "scale_float_div": 1.0, + "offset": 0 + }, "values": { "default": 200, "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "custom", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S.", + "B.D." + ], + "remarks": "Default for other DN (200 -> DN50).", + "region": { + "emea": { + "values": { + "DN40": 200, + "DN50": 200, + "DN65": 333, + "DN80": 550, + "DN100": 900, + "DN125": "TBD", + "DN150": 2000, + "DN200": 800, + "DN250": "TBD", + "DN300": "TBD" + } + }, + "na": { + "values": { + "US1_5": 200, + "US2": 200, + "US3": 550, + "US4": 900, + "US6": 1833, + "US8": "TBD", + "US10": "TBD", + "US12": "TBD" + } + } + } + } }, { "type": "uint32_t", @@ -6340,12 +8032,46 @@ "first": 268, "last": 322 }, + "si_transform": { + "remarks": "Seconds: time in 2^-16 seconds ...", + "units": "s", + "scale_float_mult": 1.0, + "scale_power_2": -16, + "scale_power_10": 0, + "scale_float_div": 1.0, + "offset": 0 + }, "values": { "default": 3932160, "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S.", + "B.D." + ], + "remarks": "Default for other DN (3932160 -> DN50).", + "region": { + "emea": { + "values": { + "default": 3932160 + } + }, + "na": { + "values": { + "default": 3932160 + } + } + } + } }, { "type": "uint32_t", @@ -6470,7 +8196,21 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "I doubt this will be used. It is to allow less frequent LCD updates if so desired but we're fine.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint32_t", @@ -6595,7 +8335,29 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Default for other DN (J.S.: 2000000-> DN50)", + "region": { + "emea": { + "values": { + "default": 2000000, + "DN125": "TBD", + "DN250": "TBD", + "DN300": "TBD" + } + } + } + } }, { "type": "uint32_t", @@ -6720,7 +8482,21 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Not expecting to change this unless field trials say we should.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -6845,7 +8621,21 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Not expecting to change this unless field trials say we should.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -6970,7 +8760,21 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Not expecting to change this unless field trials say we should.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -7104,7 +8908,23 @@ "first": 307, "last": 322 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "R.D." + ], + "remarks": "You will need this if you use TriggerIdle or TriggerTest", + "region": { + "emea": null, + "na": null + } + } }, { "type": "bool_t", @@ -7190,7 +9010,23 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "R.D." + ], + "remarks": "This was asked for so the battery usage could be minimised in manufacture so I expect it'll be used there.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint16_t", @@ -7310,12 +9146,61 @@ "first": 268, "last": 322 }, + "si_transform": { + "remarks": "Seconds: time in 2^-38 seconds ...", + "units": "s", + "scale_float_mult": 1.0, + "scale_power_2": -38, + "scale_power_10": 0, + "scale_float_div": 1.0, + "offset": 0 + }, "values": { "default": 309237, "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "B.D." + ], + "remarks": "247390 <-DN50 - default for other DN?", + "region": { + "emea": { + "values": { + "DN40": 247390, + "DN50": 247390, + "DN65": 402008, + "DN80": 494779, + "DN100": 618474, + "DN125": "TBD", + "DN150": 439804, + "DN200": 1236948, + "DN250": "TBD", + "DN300": "TBD" + } + }, + "na": { + "values": { + "US1_5": 1855422, + "US2": 1855422, + "US3": 494779, + "US4": 618474, + "US6": 439804, + "US8": "TBD", + "US10": "TBD", + "US12": "TBD" + } + } + } + } }, { "type": "uint32_t", @@ -7440,7 +9325,47 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "B.D" + ], + "remarks": "<-DN50 - default for other DN?", + "region": { + "emea": { + "values": { + "DN40": 24739011, + "DN50": 24739011, + "DN65": 32160714, + "DN80": 39582418, + "DN100": 49478022, + "DN125": "TBD", + "DN150": 46729244, + "DN200": 98956044, + "DN250": "TBD", + "DN300": "TBD" + } + }, + "na": { + "values": { + "US1_5": 24739011, + "US2": 24739011, + "US3": 39582418, + "US4": 49478022, + "US6": 46729244, + "US8": "TBD", + "US10": "TBD", + "US12": "TBD" + } + } + } + } }, { "type": "uint32_t", @@ -7565,7 +9490,47 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "B.D." + ], + "remarks": "<-DN50 - default for other DN?", + "region": { + "emea": { + "values": { + "DN40": 13743895, + "DN50": 13743895, + "DN65": 13743895, + "DN80": 21990232, + "DN100": 27487790, + "DN125": "TBD", + "DN150": 30236569, + "DN200": 54975580, + "DN250": "TBD", + "DN300": "TBD" + } + }, + "na": { + "values": { + "US1_5": 13743895, + "US2": 13743895, + "US3": 21990232, + "US4": 27487790, + "US6": 30236569, + "US8": "TBD", + "US10": "TBD", + "US12": "TBD" + } + } + } + } }, { "type": "uint32_t", @@ -7690,7 +9655,24 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -7815,7 +9797,24 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -7940,7 +9939,24 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -8065,7 +10081,24 @@ "minimum": 3, "maximum": 8 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "B.D.", + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -8190,7 +10223,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "B.D." + ], + "remarks": "A limit for how small the first hit level can be set We don't expect this to change unless firled trials say it should.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -8315,7 +10364,23 @@ "minimum": 1, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "B.D." + ], + "remarks": "This allows us to avoid being stuck with a bad first hit level if conditions change. Not expecting to change it unless field trials show we should.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint32_t", @@ -8440,7 +10505,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "B.D." + ], + "remarks": "Not expecting to change this unless field trials say we should.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -8565,7 +10646,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "B.D." + ], + "remarks": "The amount of time after empty pipe that we stay in zero flow mode. Same as iPerl, not expected to be changed but could be if field trials say we should.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint8_t", @@ -8690,7 +10787,24 @@ "minimum": -2147483648, "maximum": 2147483647 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F.", + "B.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int32_t", @@ -8815,7 +10929,24 @@ "minimum": -2147483648, "maximum": 2147483647 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F.", + "B.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int32_t", @@ -8940,7 +11071,24 @@ "minimum": -2147483648, "maximum": 2147483647 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F.", + "B.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int32_t", @@ -9063,7 +11211,23 @@ "minimum": 0, "maximum": 286720 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "R.D." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "int32_t", @@ -9175,7 +11339,21 @@ "first": 268, "last": 322 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "You do need to use this if you change any parameters in GENESISFLOW and want to keep them.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint32_t", @@ -9285,7 +11463,31 @@ "minimum": 0, "maximum": 1 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "R.D." + ], + "remarks": "Display should be sealed at end of manufacture (EMEA only).", + "region": { + "emea": { + "values": { + "default": 1 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } }, { "type": "bool_t", @@ -9410,7 +11612,21 @@ "minimum": 0, "maximum": 1 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } }, { "type": "bool_t", @@ -9530,12 +11746,45 @@ "first": 268, "last": 322 }, + "si_transform": { + "remarks": "Volts: voltage in 2^-22 millivolts ...", + "units": "v", + "scale_float_mult": 1.0, + "scale_power_2": -22, + "scale_power_10": -3, + "scale_float_div": 1.0, + "offset": 0 + }, "values": { "default": 2936012800, "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "B.D." + ], + "remarks": "629145600 <-DN50 - default for other DN?", + "region": { + "emea": { + "values": { + "default": 2936012800 + } + }, + "na": { + "values": { + "default": 2936012800 + } + } + } + } }, { "type": "uint32_t", @@ -9660,7 +11909,31 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "B.D." + ], + "remarks": "<-DN50 - default for other DN?", + "region": { + "emea": { + "values": { + "default": 629145600 + } + }, + "na": { + "values": { + "default": 629145600 + } + } + } + } }, { "type": "uint32_t", @@ -9785,7 +12058,23 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "A.F." + ], + "remarks": "The number of hard errors before deciding a fatal error has occurred. This will probably only change in response to testing in the field.", + "region": { + "emea": null, + "na": null + } + } }, { "type": "uint16_t", @@ -9886,7 +12175,43 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "custom", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "B.D." + ], + "remarks": "<-DN50 - default for other DN?", + "region": { + "emea": { + "values": { + "default": 1, + "DN100": [ + 1, + 2 + ], + "DN125": "TBD", + "DN200": 2, + "DN250": "TBD", + "DN300": 2 + } + }, + "na": { + "values": { + "default": 1, + "US4": "TBD", + "US8": "TBD", + "US10": "TBD", + "US12": "TBD" + } + } + } + } }, { "type": "uint8_t", @@ -9987,7 +12312,39 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S.", + "B.D." + ], + "remarks": "0.4us for all meter sizes up to DN100, above that TBD. 0.4us is 109951 (0x1AD7F).", + "region": { + "emea": { + "values": { + "default": 109951, + "DN125": "TBD", + "DN200": "TBD", + "DN250": "TBD", + "DN300": "TBD" + } + }, + "na": { + "values": { + "default": 109951, + "US8": "TBD", + "US10": "TBD", + "US12": "TBD" + } + } + } + } }, { "type": "uint32_t", @@ -10088,7 +12445,32 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S.", + "B.D." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 8192 + } + }, + "na": { + "values": { + "default": 8192 + } + } + } + } }, { "type": "uint32_t", @@ -10189,7 +12571,32 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S.", + "B.D." + ], + "remarks": "0.5us for all meter sizes. 0.5us is 137438 (0x218DE).", + "region": { + "emea": { + "values": { + "default": 137438 + } + }, + "na": { + "values": { + "default": 137438 + } + } + } + } }, { "type": "uint32_t", @@ -10285,7 +12692,47 @@ "first": 295, "last": 322 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": "custom", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "M.C." + ], + "remarks": "Will change with different releases - should be tracked elsewhere. meter_lut_202406170836_v0.17_crc_list.", + "region": { + "emea": { + "values": { + "DN40": 16549, + "DN50": 51664, + "DN65": 52673, + "DN80": 18061, + "DN100": 48372, + "DN125": 8134, + "DN150": 1637, + "DN200": 60969, + "DN250": 45341, + "DN300": 49157 + } + }, + "na": { + "values": { + "US1_5": 50785, + "US2": 58892, + "US3": 52036, + "US4": 50586, + "US6": 8010, + "US8": 17423, + "US10": 24406, + "US12": 11854 + } + } + } + } } ] }, @@ -10314,7 +12761,24 @@ "minimum": 0, "maximum": 1 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "This controls the temperature, pressure, flow rate readings on the smaller second row of digits. Previous code would display 012.3 C whereas with DisplayLeadingZeros set to 0 youll get _12.3 C (where the _ is actually just an empty space).", + "region": { + "emea": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -10343,7 +12807,32 @@ "minimum": 0, "maximum": 1 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "Installation detection / bend correction registers. Currently unreleased.", + "region": { + "emea": { + "values": { + "DN250": "TBD", + "DN300": "TBD" + } + }, + "na": { + "values": { + "US8": "TBD", + "US10": "TBD", + "US12": "TBD" + } + } + } + } } ] }, @@ -10372,7 +12861,32 @@ "minimum": 0, "maximum": 10000000 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "Installation detection / bend correction registers. Currently unreleased.", + "region": { + "emea": { + "values": { + "DN250": "TBD", + "DN300": "TBD" + } + }, + "na": { + "values": { + "US8": "TBD", + "US10": "TBD", + "US12": "TBD" + } + } + } + } } ] }, @@ -10400,7 +12914,32 @@ "minimum": 0, "maximum": 163840 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "Installation detection / bend correction registers. Currently unreleased.", + "region": { + "emea": { + "values": { + "DN250": "TBD", + "DN300": "TBD" + } + }, + "na": { + "values": { + "US8": "TBD", + "US10": "TBD", + "US12": "TBD" + } + } + } + } } ] }, @@ -10428,7 +12967,32 @@ "minimum": 0, "maximum": 100 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "Installation detection / bend correction registers. Currently unreleased.", + "region": { + "emea": { + "values": { + "DN250": "TBD", + "DN300": "TBD" + } + }, + "na": { + "values": { + "US8": "TBD", + "US10": "TBD", + "US12": "TBD" + } + } + } + } } ] }, @@ -10457,7 +13021,30 @@ "minimum": 0, "maximum": 1 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "Probably customer specific in EMEA should always be false in NA.", + "region": { + "emea": { + "values": { + "DN250": "TBD", + "DN300": "TBD" + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -10481,7 +13068,21 @@ "first": 313, "last": 322 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Internal use only, ignore.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -10509,7 +13110,21 @@ "minimum": 0, "maximum": 28800 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "Enhancement for ensuring LED is off after metrology testing, useful to add to test software for GenesisFlow versions 3.16 and newer (not released yet June 2024).", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -10538,7 +13153,21 @@ "minimum": 0, "maximum": 1 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "TBD", + "region": { + "emea": null, + "na": null + } + } } ] } @@ -10841,7 +13470,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "1 sec.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -10942,7 +13587,31 @@ "minimum": 1, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 3 + } + }, + "na": { + "values": { + "default": 3 + } + } + } + } } ] }, @@ -11039,7 +13708,21 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11101,7 +13784,21 @@ "first": 161, "last": 213 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "You do need to use this if you change any parameters in IRDA and want to keep them.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11202,7 +13899,23 @@ "minimum": 0, "maximum": 9 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "Cordonel NA can use a subset of the display digits for AMR readings. This is the number of digits to use.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11279,7 +13992,23 @@ "minimum": -9, "maximum": 0 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "Cordonel NA can use a subset of the display digits for AMR readings. This is the offset (from the right).", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11356,7 +14085,23 @@ "minimum": 0, "maximum": 268 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "These are the fields used in NA AMR reading strings.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11388,7 +14133,7 @@ "statictype": "static" }, { - "type": "uint32_t", + "type": "time_t", "privilege": { "lvl1": "RO", "lvl2": "RO", @@ -11409,7 +14154,23 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "A.F." + ], + "remarks": "Simple timestamp, should be filled in at the end of manufacture. Time now.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11486,7 +14247,23 @@ "minimum": 0, "maximum": 1 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "In NA the AMR digits should be displayed on the LCD periodically, in EMEA they shouldn't.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11510,7 +14287,23 @@ "first": 193, "last": 213 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11534,7 +14327,23 @@ "first": 193, "last": 213 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11543,16 +14352,16 @@ "details": [ { "type": "bool_t", - "privilege": { - "lvl1": "RO", - "lvl2": "RO", - "lvl3": "RO", - "lvl4": "RO", - "lvl5": "RW", - "lvl6": "RW", - "lvl7": "RW", - "lvl8": "RW" - }, + "privilege": { + "lvl1": "RO", + "lvl2": "RO", + "lvl3": "RO", + "lvl4": "RO", + "lvl5": "RW", + "lvl6": "RW", + "lvl7": "RW", + "lvl8": "RW" + }, "description": "Boolean controlled by UI-1236 to control resolution of cubic feet unit in some meter size", "version": { "first": 210, @@ -11563,7 +14372,21 @@ "minimum": 0, "maximum": 1 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Internal use in firmware only.", + "region": { + "emea": null, + "na": null + } + } } ] } @@ -11621,7 +14444,23 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11650,7 +14489,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11674,7 +14529,23 @@ "first": 7, "last": 19 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11698,7 +14569,21 @@ "first": 16, "last": 19 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "You do need to use this if you change any parameters in LOGGER and want to keep them.", + "region": { + "emea": null, + "na": null + } + } } ] } @@ -11767,7 +14652,21 @@ "first": 82, "last": 118 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Ignore, no current loop.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11810,7 +14709,21 @@ "first": 82, "last": 118 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "You do need to use this if you change any parameters in METROLOGYASST and want to keep them.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11887,7 +14800,23 @@ "minimum": 1, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": true, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "G01 Pulse value (100 l/Imp., ...). Customer specific.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -11964,7 +14893,23 @@ "minimum": 0, "maximum": 7 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": true, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "G02 Pulse type (Netted Imp./Tamp. (-), ). Customer specific.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12041,7 +14986,23 @@ "minimum": 0, "maximum": 10 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": true, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "G03 Pulse length (500ms, ). Customer specific.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12094,7 +15055,23 @@ "minimum": 0, "maximum": 8 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": true, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "C05 unit (m, kl, US-Gall./Imp.-Gall, Barrel, ...)", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12147,7 +15124,23 @@ "minimum": 0, "maximum": 4 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": true, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Counter size and unit. See FlowPoint.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12190,7 +15183,21 @@ "first": 82, "last": 118 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Ignore, no current loop.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12209,7 +15216,7 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "Units for displaying temperature on the LCD. 0 – Celcius, 1 – Fahrenheit.", + "description": "Units for displaying temperature on the LCD. 0 is Celcius, 1 is Fahrenheit.", "version": { "first": 13, "last": 81 @@ -12233,7 +15240,7 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "Units for displaying temperature on the LCD. 0 – Celcius, 1 – Fahrenheit.", + "description": "Units for displaying temperature on the LCD. 0 is Celcius, 1 is Fahrenheit.", "version": { "first": 82, "last": 118 @@ -12243,7 +15250,31 @@ "minimum": 0, "maximum": 1 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "C - EMEA/China / F - USA.", + "region": { + "emea": { + "values": { + "default": 0 + } + }, + "na": { + "values": { + "default": 1 + } + } + } + } } ] }, @@ -12262,7 +15293,7 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "Units for displaying pressure on the LCD. 0 – Mpa, 1 – PSI.", + "description": "Units for displaying pressure on the LCD. 0 is Mpa, 1 is PSI.", "version": { "first": 13, "last": 81 @@ -12286,7 +15317,7 @@ "lvl7": "RW", "lvl8": "RW" }, - "description": "Units for displaying pressure on the LCD. 0 – Mpa, 1 – PSI.", + "description": "Units for displaying pressure on the LCD. 0 is Mpa, 1 is PSI.", "version": { "first": 82, "last": 118 @@ -12296,7 +15327,34 @@ "minimum": 0, "maximum": 1 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": true, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "Mpa - EMEA/China / PSI - USA / Bar - USA.", + "region": { + "emea": { + "values": { + "default": 0 + } + }, + "na": { + "values": { + "custom": [ + 1, + 2 + ] + } + } + } + } } ] }, @@ -12373,7 +15431,31 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 60000 + } + }, + "na": { + "values": { + "default": 60000 + } + } + } + } } ] }, @@ -12474,7 +15556,31 @@ "minimum": -2000000, "maximum": 2000000 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "-> 0", + "region": { + "emea": { + "values": { + "default": 0 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -12527,7 +15633,23 @@ "minimum": 0, "maximum": 1 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": true, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.S." + ], + "remarks": "B09 Housing option (D,Y). Variant specific.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12551,7 +15673,21 @@ "first": 65, "last": 118 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12575,7 +15711,21 @@ "first": 92, "last": 118 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12603,7 +15753,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "For use in testing.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12631,7 +15797,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "For use in testing.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12660,7 +15842,32 @@ "minimum": 0, "maximum": 1 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 1, + "DN300": 0 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -12688,7 +15895,23 @@ "minimum": 0, "maximum": 7 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "Read only.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12741,7 +15964,31 @@ "minimum": -4000000, "maximum": 4000000 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 0 + } + }, + "na": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -12770,7 +16017,21 @@ "minimum": 0, "maximum": 7 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "Customer specific, controls display of items on row 2. NOTE: In 1.4 stream this can be used to work around bug where pressure is displayed with no pressure sensor (CORDHW-3065).", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12798,7 +16059,21 @@ "minimum": -2147483648, "maximum": 2147483647 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "TBD", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -12826,7 +16101,21 @@ "minimum": -2147483648, "maximum": 2147483647 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "TBD", + "region": { + "emea": null, + "na": null + } + } } ] } @@ -12870,7 +16159,22 @@ "first": 41, "last": 102 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "You do need to use this if you change any parameters in NA2WALARMS and want to keep them.", + "region": { + "na": null + } + } } ] }, @@ -12899,7 +16203,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "NA has a series of alarms called 'predefined' these are the ones that should be enabled.", + "region": { + "na": null + } + } } ] } @@ -13003,7 +16322,22 @@ "first": 147, "last": 199 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "na": null + } + } } ] }, @@ -13027,7 +16361,22 @@ "first": 147, "last": 199 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "na": null + } + } } ] } @@ -13146,7 +16495,23 @@ "first": 7, "last": 65 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "A.F." + ], + "remarks": "You may wish to do this at the end of manufacture to clear all the old data out.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -13170,7 +16535,21 @@ "first": 49, "last": 65 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] } @@ -13443,7 +16822,26 @@ "minimum": 3, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 201335811 + } + } + } + } } ] }, @@ -13472,7 +16870,27 @@ "minimum": 1, "maximum": 1440 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S.", + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 60 + } + } + } + } } ] }, @@ -13501,7 +16919,26 @@ "minimum": 1, "maximum": 60 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 5 + } + } + } + } } ] }, @@ -13530,7 +16967,26 @@ "minimum": 3, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 201335811 + } + } + } + } } ] }, @@ -13559,7 +17015,27 @@ "minimum": 1, "maximum": 28 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.S.", + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 1 + } + } + } + } } ] }, @@ -13588,7 +17064,24 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -13617,7 +17110,24 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 0 + } + } + } + } } ] } @@ -13672,7 +17182,21 @@ "first": 17, "last": 72 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -13699,7 +17223,23 @@ "values": { "default": "Tadiran" }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -13728,7 +17268,31 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": true, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "U.B." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 6 + } + }, + "na": { + "values": { + "default": 6 + } + } + } + } } ] }, @@ -13779,7 +17343,31 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "U.B." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 2 + } + }, + "na": { + "values": { + "default": 2 + } + } + } + } } ] }, @@ -13808,7 +17396,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": true, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "U.B." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -13837,7 +17441,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": true, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "U.B." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -13866,7 +17486,23 @@ "minimum": 0, "maximum": 1 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": true, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "U.B." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -13890,7 +17526,21 @@ "first": 24, "last": 72 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -13914,7 +17564,21 @@ "first": 39, "last": 72 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -13943,7 +17607,32 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "A.F.", + "R.D" + ], + "remarks": "This should be set to the expected life of the meter. In the early days the expected lifetime will be this.", + "region": { + "emea": { + "values": { + "default": 630720000 + } + }, + "na": { + "values": { + "default": 630720000 + } + } + } + } } ] }, @@ -13972,7 +17661,23 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": true, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "U.B." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -13996,7 +17701,21 @@ "first": 61, "last": 72 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "You do need to use this if you change any parameters in POWERMON and want to keep them.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -14025,7 +17744,23 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] } @@ -14092,7 +17827,26 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 15 + } + } + } + } } ] }, @@ -14121,7 +17875,26 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 900 + } + } + } + } } ] }, @@ -14150,7 +17923,26 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 3 + } + } + } + } } ] }, @@ -14179,7 +17971,26 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 3 + } + } + } + } } ] }, @@ -14208,7 +18019,26 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": true, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 7 + } + } + } + } } ] }, @@ -14237,7 +18067,22 @@ "minimum": 433, "maximum": 868 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Constant, do not change.", + "region": { + "emea": null + } + } } ] }, @@ -14266,7 +18111,22 @@ "minimum": -32768, "maximum": 32767 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": true, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "Unchanged.", + "region": { + "emea": null + } + } } ] }, @@ -14295,7 +18155,22 @@ "minimum": 0, "maximum": 127 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "Read calibration value from data base, dependant on used variant.", + "region": { + "emea": null + } + } } ] }, @@ -14317,14 +18192,68 @@ "description": "The internal System State of the Radio", "version": { "first": 100, - "last": 545 + "last": 544 }, "values": { "default": 1, "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Set to 0xFF at the end of parameterization to trigger shipping mode.", + "region": { + "emea": null + } + } + }, + { + "type": "uint8_t", + "privilege": { + "lvl1": "RW", + "lvl2": "RW", + "lvl3": "RW", + "lvl4": "RW", + "lvl5": "RW", + "lvl6": "RW", + "lvl7": "RW", + "lvl8": "RW" + }, + "description": "The internal System State of the Radio", + "version": { + "first": 545, + "last": 545 + }, + "values": { + "default": 1, + "minimum": 1, + "maximum": 255 + }, + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Set to 0xFF at the end of parameterization to trigger shipping mode.", + "region": { + "emea": null + } + } } ] }, @@ -14353,7 +18282,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "Set final radio address.", + "region": { + "emea": null + } + } } ] }, @@ -14382,7 +18326,22 @@ "minimum": -2147483648, "maximum": 2147483647 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Unchanged.", + "region": { + "emea": null + } + } } ] }, @@ -14411,7 +18370,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Unchanged.", + "region": { + "emea": null + } + } } ] }, @@ -14440,7 +18414,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Unchanged.", + "region": { + "emea": null + } + } } ] }, @@ -14469,7 +18458,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Unchanged.", + "region": { + "emea": null + } + } } ] }, @@ -14498,7 +18502,22 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Unchanged.", + "region": { + "emea": null + } + } } ] }, @@ -14527,7 +18546,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14556,7 +18590,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14585,7 +18634,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14614,7 +18678,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14643,7 +18722,22 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14672,7 +18766,22 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14701,7 +18810,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14730,7 +18854,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14759,7 +18898,22 @@ "minimum": 60, "maximum": 60 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14788,7 +18942,22 @@ "minimum": 0, "maximum": 3 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14817,7 +18986,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14846,7 +19030,22 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14875,7 +19074,22 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14904,7 +19118,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14933,7 +19162,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14962,7 +19206,22 @@ "minimum": 60, "maximum": 60 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -14991,7 +19250,22 @@ "minimum": 0, "maximum": 2 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -15020,7 +19294,22 @@ "minimum": 0, "maximum": 15 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -15049,7 +19338,22 @@ "minimum": 0, "maximum": 1000 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -15078,7 +19382,22 @@ "minimum": 0, "maximum": 3 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -15102,7 +19421,22 @@ "first": 100, "last": 545 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Not used anymore.", + "region": { + "emea": null + } + } } ] }, @@ -15126,7 +19460,22 @@ "first": 100, "last": 545 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Not used anymore.", + "region": { + "emea": null + } + } } ] }, @@ -15148,14 +19497,68 @@ "description": "A byte value representing a mask of currently active (1) main alarms. These are the flow and genreral alarms", "version": { "first": 100, - "last": 545 + "last": 544 }, "values": { "default": 207, "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at CUSTOMER APP.", + "region": { + "emea": null + } + } + }, + { + "type": "uint8_t", + "privilege": { + "lvl1": "RW", + "lvl2": "RW", + "lvl3": "RW", + "lvl4": "RW", + "lvl5": "RW", + "lvl6": "RW", + "lvl7": "RW", + "lvl8": "RW" + }, + "description": "A byte value representing a mask of currently active (1) main alarms. These are the flow and genreral alarms", + "version": { + "first": 545, + "last": 545 + }, + "values": { + "default": 207, + "minimum": 128, + "maximum": 255 + }, + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at CUSTOMER APP.", + "region": { + "emea": null + } + } } ] }, @@ -15184,7 +19587,22 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at CUSTOMER APP.", + "region": { + "emea": null + } + } } ] }, @@ -15213,7 +19631,26 @@ "minimum": 0, "maximum": 250 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": { + "values": { + "default": 29 + } + } + } + } } ] }, @@ -15242,7 +19679,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Runtime value.", + "region": { + "emea": null + } + } } ] }, @@ -15266,7 +19718,22 @@ "first": 100, "last": 545 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": true, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "D05 radio key (Sensus (standard), )", + "region": { + "emea": null + } + } } ] }, @@ -15290,7 +19757,22 @@ "first": 100, "last": 545 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "Unchanged.", + "region": { + "emea": null + } + } } ] }, @@ -15319,7 +19801,22 @@ "minimum": 0, "maximum": 65535 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Unchanged.", + "region": { + "emea": null + } + } } ] }, @@ -15343,7 +19840,22 @@ "first": 100, "last": 545 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Customer specific.", + "region": { + "emea": null + } + } } ] }, @@ -15372,7 +19884,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": null + } + } } ] }, @@ -15401,7 +19928,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -15430,7 +19972,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": null + } + } } ] }, @@ -15459,7 +20016,22 @@ "minimum": 0, "maximum": 255 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Dependant on territory setting acc SAP order.", + "region": { + "emea": null + } + } } ] }, @@ -15488,7 +20060,22 @@ "minimum": 0, "maximum": 17 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": "custom", + "vako": true, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Customer specific. Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -15517,7 +20104,26 @@ "minimum": 0, "maximum": 255 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "1: if OTA update is allowed.", + "region": { + "emea": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -15541,7 +20147,22 @@ "first": 100, "last": 545 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -15565,7 +20186,22 @@ "first": 100, "last": 545 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -15594,7 +20230,22 @@ "minimum": 3, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at PERIODIC_LOGGER APP.", + "region": { + "emea": null + } + } } ] }, @@ -15623,7 +20274,22 @@ "minimum": 1, "maximum": 1440 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at PERIODIC_LOGGER APP.", + "region": { + "emea": null + } + } } ] }, @@ -15652,7 +20318,22 @@ "minimum": 1, "maximum": 60 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at PERIODIC_LOGGER APP.", + "region": { + "emea": null + } + } } ] }, @@ -15681,7 +20362,22 @@ "minimum": 3, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at PERIODIC_LOGGER APP.", + "region": { + "emea": null + } + } } ] }, @@ -15710,7 +20406,22 @@ "minimum": 1, "maximum": 28 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at PERIODIC_LOGGER APP.", + "region": { + "emea": null + } + } } ] }, @@ -15739,7 +20450,26 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": { + "values": { + "default": 0 + } + } + } + } } ] }, @@ -15768,7 +20498,22 @@ "minimum": 0, "maximum": 127 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "Read calibration value from data base, dependant on used variant.", + "region": { + "emea": null + } + } } ] }, @@ -15797,7 +20542,22 @@ "minimum": 0, "maximum": 32767 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "Read calibration value from data base, dependant on used variant.", + "region": { + "emea": null + } + } } ] }, @@ -15826,7 +20586,22 @@ "minimum": 0, "maximum": 32767 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "Read calibration value from data base, dependant on used variant.", + "region": { + "emea": null + } + } } ] }, @@ -15855,7 +20630,22 @@ "minimum": 0, "maximum": 1 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignor because is set up at CUSTOMER APP?", + "region": { + "emea": null + } + } } ] }, @@ -15879,7 +20669,22 @@ "first": 100, "last": 545 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": null + } + } } ] }, @@ -15908,7 +20713,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -15937,7 +20757,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -15966,7 +20801,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -15995,7 +20845,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -16024,7 +20889,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -16053,7 +20933,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -16082,7 +20977,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -16111,7 +21021,22 @@ "minimum": -127, "maximum": 127 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because is set up at METROLOGYASST APP.", + "region": { + "emea": null + } + } } ] }, @@ -16135,7 +21060,22 @@ "first": 494, "last": 545 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -16159,7 +21099,22 @@ "first": 494, "last": 545 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -16188,7 +21143,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "J.L." + ], + "remarks": "Can be ignored because these are temporary values just for information.", + "region": { + "emea": null + } + } } ] }, @@ -16217,7 +21187,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": null + } + } } ] }, @@ -16246,7 +21231,22 @@ "minimum": 0, "maximum": 4294967295 }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": false, + "responsible": [ + "J.L." + ], + "remarks": "", + "region": { + "emea": null + } + } } ] } @@ -16306,7 +21306,21 @@ "first": 141, "last": 540 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Firmware upgrade may well use these.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16330,7 +21344,21 @@ "first": 150, "last": 540 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Useful for checking the firmware that is loaded.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16357,7 +21385,23 @@ "values": { "default": "" }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16384,7 +21428,23 @@ "values": { "default": "" }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16411,7 +21471,23 @@ "values": { "default": "" }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16438,7 +21514,23 @@ "values": { "default": "" }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16465,7 +21557,23 @@ "values": { "default": "" }, - "statictype": "infrequentlyupdated" + "statictype": "infrequentlyupdated", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16489,7 +21597,21 @@ "first": 176, "last": 540 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16513,7 +21635,24 @@ "first": 176, "last": 540 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": true, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "A.F.", + "R.D." + ], + "remarks": "Time now. Write the current time during manufacture.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16537,7 +21676,23 @@ "first": 196, "last": 540 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [ + "A.F." + ], + "remarks": "This is effectively another application version number but for the Breeze Core and is worth looking at.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16561,7 +21716,21 @@ "first": 233, "last": 540 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16585,7 +21754,21 @@ "first": 258, "last": 540 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16609,7 +21792,21 @@ "first": 265, "last": 540 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16633,7 +21830,21 @@ "first": 279, "last": 540 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Useful for checking the firmware that is loaded.", + "region": { + "emea": null, + "na": null + } + } } ] }, @@ -16657,7 +21868,32 @@ "first": 470, "last": 540 }, - "statictype": "static" + "statictype": "static", + "production": { + "required": false, + "kitron": false, + "csd": "default", + "vako": false, + "operation_calibration": true, + "runtime_ignore": false, + "responsible": [ + "A.F.", + "R.D." + ], + "remarks": "Set fix as final step at production.", + "region": { + "emea": { + "values": { + "default": 254 + } + }, + "na": { + "values": { + "default": 255 + } + } + } + } } ] }, @@ -16681,7 +21917,21 @@ "first": 529, "last": 540 }, - "statictype": "dynamic" + "statictype": "dynamic", + "production": { + "required": false, + "kitron": false, + "csd": null, + "vako": false, + "operation_calibration": false, + "runtime_ignore": true, + "responsible": [], + "remarks": "Useful for checking the firmware that is loaded.", + "region": { + "emea": null, + "na": null + } + } } ] } diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/DataTypes/UInt48.cs b/Common/Hardware/WaterMeter/Genesis/Registers/DataTypes/UInt48.cs new file mode 100644 index 00000000..821c7505 --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/Registers/DataTypes/UInt48.cs @@ -0,0 +1,8 @@ +using System; + +namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes +{ + public struct UInt48 + { + } +} diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/DataTypes/UInt72.cs b/Common/Hardware/WaterMeter/Genesis/Registers/DataTypes/UInt72.cs new file mode 100644 index 00000000..acd378b2 --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/Registers/DataTypes/UInt72.cs @@ -0,0 +1,8 @@ +using System; + +namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes +{ + public struct UInt72 + { + } +} diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/DataTypes/UInt88.cs b/Common/Hardware/WaterMeter/Genesis/Registers/DataTypes/UInt88.cs new file mode 100644 index 00000000..20733cd7 --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/Registers/DataTypes/UInt88.cs @@ -0,0 +1,8 @@ +using System; + +namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes +{ + public struct UInt88 + { + } +} diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/MeterRegisters.cs b/Common/Hardware/WaterMeter/Genesis/Registers/MeterRegisters.cs index 767d329c..643be59d 100644 --- a/Common/Hardware/WaterMeter/Genesis/Registers/MeterRegisters.cs +++ b/Common/Hardware/WaterMeter/Genesis/Registers/MeterRegisters.cs @@ -122,6 +122,11 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers } } + /// + /// Unimplemented + /// + /// + /// public IEnumerator GetEnumerator() { throw new NotImplementedException(); diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.Designer.cs b/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.Designer.cs new file mode 100644 index 00000000..16618f9e --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.Designer.cs @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to ERROR: Register data type unknown. + /// + internal static string StrRegisterDataTypeUnknown { + get { + return ResourceManager.GetString("StrRegisterDataTypeUnknown", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ERROR: Register value is out of range. + /// + internal static string StrRegisterValueOutOfRange { + get { + return ResourceManager.GetString("StrRegisterValueOutOfRange", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WARNING: Register value is set to default. + /// + internal static string StrSetRegisterToDefault { + get { + return ResourceManager.GetString("StrSetRegisterToDefault", resourceCulture); + } + } + } +} diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.de.Designer.cs b/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.de.Designer.cs new file mode 100644 index 00000000..e69de29b diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.de.resx b/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.de.resx new file mode 100644 index 00000000..36a2b24e --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.de.resx @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + WARNUNG: Registerwert auf Standardwert gesetzt + + + FEHLER: Registerwert außerhalb des zulässigen Bereiches + + + FEHLER: Registerdatentyp ist unbekannt! + + \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.resx b/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.resx new file mode 100644 index 00000000..0e66da42 --- /dev/null +++ b/Common/Hardware/WaterMeter/Genesis/Registers/Properties/Resources.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + WARNING: Register value is set to default + + + ERROR: Register value is out of range + + + ERROR: Register data type unknown + + \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/RegisterCheck.cs b/Common/Hardware/WaterMeter/Genesis/Registers/RegisterCheck.cs index cf8ac8f1..db8dc96d 100644 --- a/Common/Hardware/WaterMeter/Genesis/Registers/RegisterCheck.cs +++ b/Common/Hardware/WaterMeter/Genesis/Registers/RegisterCheck.cs @@ -1,142 +1,264 @@ using System; using Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes; +using Xylem.Common.CommonCore.Consts; +using Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Properties; namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers { + /// + /// Check the register value for Out Of Boundaries (min, max) and optional if set to Default . + /// public static class RegisterCheck { - private static String OutOfRangeMsg(Boolean isMin, String value, String range, String name) + private enum RangeCheck { - return isMin ? $" Register {name} value ({value}) is to small - minimum is ({range})" : - $" Register {name} value ({value}) is to large - maximum is ({range})"; + MinimumExceeded, + MaximumExceeded, + DefaultValue, + NotConvertible + }; + private static String OutOfRangeMsg(RangeCheck rangeCheck, String value, String range, String name) + { + var msg = ""; + switch (rangeCheck) + { + case RangeCheck.DefaultValue: + msg = $"{Resources.StrSetRegisterToDefault} {name}: ({value})"; + break; + case RangeCheck.MaximumExceeded: + msg = $"{Resources.StrRegisterValueOutOfRange} {name}: ({value}) - Maximum ({range})"; + break; + case RangeCheck.MinimumExceeded: + msg = $"{Resources.StrRegisterValueOutOfRange} {name}: ({value}) - Minimum ({range})"; + break; + case RangeCheck.NotConvertible: + msg = $"{Resources.StrRegisterDataTypeUnknown} {name}"; + break; + } + return msg; + } /// /// Check the registers for ot of range (below minimum or above maximum) and return empty string /// if impossible to check (unset limits) or in range. /// - /// + /// /// - /// empty string for in range or unset limits or out of range message + /// feedback message + /// forces a warning if value is set to default + /// + /// if default and check for this is required + /// if the value is in range or has no range defined + /// if value exceeds the limits + /// /// /// - Init. /// /// /// - Modified with try catch block. /// - public static String CheckRange(RegisterDefinition reg, Byte[] value) + /// + /// - Returns warning on default, else error or okay. + /// + /// + /// - Ignore TimeT. + /// + public static StatusReturn CheckRange(RegisterDefinition regDef, Byte[] value, out String msg, + Boolean checkIfValueIsDefault = false) { - // for all registers without min and max a - if (!reg.Minimum.HasValue && !reg.Maximum.HasValue) + msg = ""; + // for all registers without min and max or if type is of TimeT + if ((!regDef.Minimum.HasValue && !regDef.Maximum.HasValue) || regDef.DataType == typeof(TimeT)) { - return string.Empty; + return StatusReturn.Okay; } try { - var type = reg.DataType; + var type = regDef.DataType; if (type == typeof(UInt16)) { var checkValue = RegisterConverter.ByteArrayToValue(value); - if (reg.Minimum.HasValue && checkValue < reg.Minimum.Value) + if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value) { - return OutOfRangeMsg(true, checkValue.ToString(), reg.Minimum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(), + regDef.Minimum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; } - if (reg.Maximum.HasValue && checkValue > reg.Maximum.Value) + if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value) { - return OutOfRangeMsg(false, checkValue.ToString(), reg.Maximum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(), + regDef.Maximum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; + } + if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value) + { + msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(), + regDef.Default.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Warning; } } else if (type == typeof(UInt32)) { var checkValue = RegisterConverter.ByteArrayToValue(value); - if (reg.Minimum.HasValue && checkValue < reg.Minimum.Value) + if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value) { - return OutOfRangeMsg(true, checkValue.ToString(), reg.Minimum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(), + regDef.Minimum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; } - if (reg.Maximum.HasValue && checkValue > reg.Maximum.Value) + if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value) { - return OutOfRangeMsg(false, checkValue.ToString(), reg.Maximum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(), + regDef.Maximum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; + } + if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value) + { + msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(), + regDef.Default.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Warning; } } else if (type == typeof(UInt64)) { var checkValue = RegisterConverter.ByteArrayToValue(value); - if (reg.Minimum.HasValue && checkValue < (UInt64)reg.Minimum.Value) + if (regDef.Minimum.HasValue && checkValue < (UInt64)regDef.Minimum.Value) { - return OutOfRangeMsg(true, checkValue.ToString(), reg.Minimum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(), + regDef.Minimum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; } - if (reg.Maximum.HasValue && checkValue > (UInt64)reg.Maximum.Value) + if (regDef.Maximum.HasValue && checkValue > (UInt64)regDef.Maximum.Value) { - return OutOfRangeMsg(false, checkValue.ToString(), reg.Maximum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(), + regDef.Maximum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; + } + if (checkIfValueIsDefault && regDef.Default.HasValue && 0 == checkValue.CompareTo(regDef.Default.Value)) + { + msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(), + regDef.Default.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Warning; } } else if (type == typeof(Int16)) { var checkValue = RegisterConverter.ByteArrayToValue(value); - if (reg.Minimum.HasValue && checkValue < reg.Minimum.Value) + if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value) { - return OutOfRangeMsg(true, checkValue.ToString(), reg.Minimum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(), + regDef.Minimum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; } - if (reg.Maximum.HasValue && checkValue > reg.Maximum.Value) + if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value) { - return OutOfRangeMsg(false, checkValue.ToString(), reg.Maximum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(), + regDef.Maximum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; + } + if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value) + { + msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(), + regDef.Default.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Warning; } } else if (type == typeof(Int32)) { var checkValue = RegisterConverter.ByteArrayToValue(value); - if (reg.Minimum.HasValue && checkValue < reg.Minimum.Value) + if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value) { - return OutOfRangeMsg(true, checkValue.ToString(), reg.Minimum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(), + regDef.Minimum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; } - if (reg.Maximum.HasValue && checkValue > reg.Maximum.Value) + if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value) { - return OutOfRangeMsg(false, checkValue.ToString(), reg.Maximum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(), + regDef.Maximum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; + } + if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value) + { + msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(), + regDef.Default.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Warning; } } else if (type == typeof(Int64)) { var checkValue = RegisterConverter.ByteArrayToValue(value); - if (reg.Minimum.HasValue && checkValue < reg.Minimum.Value) + if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value) { - return OutOfRangeMsg(true, checkValue.ToString(), reg.Minimum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(), + regDef.Minimum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; } - if (reg.Maximum.HasValue && checkValue > reg.Maximum.Value) + if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value) { - return OutOfRangeMsg(false, checkValue.ToString(), reg.Maximum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(), + regDef.Maximum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; + } + if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value) + { + msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(), + regDef.Default.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Warning; } } else if (type == typeof(Byte) || type == typeof(Enum8)) { var checkValue = RegisterConverter.ByteArrayToValue(value); - if (reg.Minimum.HasValue && checkValue < reg.Minimum.Value) + if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value) { - return OutOfRangeMsg(true, checkValue.ToString(), reg.Minimum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(), + regDef.Minimum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; } - if (reg.Maximum.HasValue && checkValue > reg.Maximum.Value) + if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value) { - return OutOfRangeMsg(false, checkValue.ToString(), reg.Maximum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(), + regDef.Maximum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; + } + if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value) + { + msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(), + regDef.Default.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Warning; } } else if (type == typeof(SByte)) { var checkValue = RegisterConverter.ByteArrayToValue(value); - if (reg.Minimum.HasValue && checkValue < reg.Minimum.Value) + if (regDef.Minimum.HasValue && checkValue < regDef.Minimum.Value) { - return OutOfRangeMsg(true, checkValue.ToString(), reg.Minimum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MinimumExceeded, checkValue.ToString(), + regDef.Minimum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; } - if (reg.Maximum.HasValue && checkValue > reg.Maximum.Value) + if (regDef.Maximum.HasValue && checkValue > regDef.Maximum.Value) { - return OutOfRangeMsg(false, checkValue.ToString(), reg.Maximum.Value.ToString(), reg.GetIdent()); + msg = OutOfRangeMsg(RangeCheck.MaximumExceeded, checkValue.ToString(), + regDef.Maximum.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Failed; + } + if (checkIfValueIsDefault && regDef.Default.HasValue && checkValue == regDef.Default.Value) + { + msg = OutOfRangeMsg(RangeCheck.DefaultValue, checkValue.ToString(), + regDef.Default.Value.ToString(), regDef.GetIdent()); + return StatusReturn.Warning; } } else if (type == typeof(Boolean)) @@ -146,17 +268,18 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers } else { - return ($"Register {reg.RegisterName} has min or max value but the data type {reg.DataType} " + - "doesn't support auto conversion"); + msg = OutOfRangeMsg(RangeCheck.NotConvertible, "", "", regDef.GetIdent()); + return StatusReturn.Failed; } } catch (Exception e) { - return e.Message; + msg = e.Message; + return StatusReturn.Failed; } - // the value is in range - return string.Empty; + // the value is in range and not on default + return StatusReturn.Okay; } } } diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/RegisterConverter.cs b/Common/Hardware/WaterMeter/Genesis/Registers/RegisterConverter.cs index 92268c9a..76e866ef 100644 --- a/Common/Hardware/WaterMeter/Genesis/Registers/RegisterConverter.cs +++ b/Common/Hardware/WaterMeter/Genesis/Registers/RegisterConverter.cs @@ -16,7 +16,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers /// Convert single register from Genesis and return a message of the result. The value input is a byte array /// with the LSB at the index 0 and the MSB at the highest index. A string is sorted with the first character /// at index 0, this does not need to be reversed as it is readable by default. - /// The raw value is swapped byte-wise to get a human readable value with MSB at leftmost and LSB at rightmost. + /// The raw value is swapped byte-wise to get a human-readable value with MSB at leftmost and LSB at rightmost. /// The message contains the register name, the swapped raw value and on the converted value. /// /// @@ -38,32 +38,31 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers public static String GetRegisterContentText(RegisterDefinition registerDefinition, Byte[] regRawByteArray) { String msg; - var strValueResult = "?"; - var strRawResult = "?"; - var registerName = "?"; + String registerName = "?"; try { registerName = registerDefinition.GetIdent(); // getting a result value as text of the data type e.g. UInt32 var strValue = ConvertToText(regRawByteArray, registerDefinition.DataType); - // remove non printable char of the converted result - strValueResult = Regex.Replace(strValue, @"\p{C}+", string.Empty); + // remove non-printable char of the converted result + var strValueResult = Regex.Replace(strValue, @"\p{C}+", string.Empty); // use hashed output being able to compare written and read back values + String strRawResult; if (registerName.Contains("EncryptionKey") || registerName.Contains("Password")) { - strRawResult = GetRegisterRawText(registerDefinition, regRawByteArray, true); - msg = $"{registerName} ({strRawResult})"; + strRawResult = GetRegisterRawText(registerDefinition, regRawByteArray, encryptData:true); + msg = $"{registerName}: ({strRawResult})h"; } else { strRawResult = GetRegisterRawText(registerDefinition, regRawByteArray); - msg = $"{registerName} ({strRawResult}) ({strValueResult})"; + msg = $"{registerName}: ({strRawResult})h ({strValueResult})"; } } catch (Exception) { - msg = $"{registerName} ({strRawResult}) ({strValueResult})"; + throw new ApplicationException($"Cannot convert register {registerName}"); } return msg; @@ -73,7 +72,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers /// Convert single register from Genesis and return a message of the result. The value input is a byte array /// with the LSB at the index 0 and the MSB at the highest index. A string is sorted with the first character /// at index 0, this does not need to be reversed as it is readable by default. - /// The raw value is swapped byte-wise to get a human readable value with MSB at leftmost and LSB at rightmost. + /// The raw value is swapped byte-wise to get a human-readable value with MSB at leftmost and LSB at rightmost. /// The message contains the swapped raw value. /// /// @@ -97,9 +96,12 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers // inverse the raw value to get a readable byte order MSB left and LSB last right position var tmpList = regRawByteArray.ToList(); - // reverse the list if it is not a string or the UInt96 or UInt128 which will be used as - // placeholder for a string + // reverse the list if it is not a string or the UInt48, UInt72, UInt88,UInt96 or UInt128 which + // will be used as placeholder for a string if (registerDefinition.DataType != typeof(String) && + registerDefinition.DataType != typeof(UInt48) && + registerDefinition.DataType != typeof(UInt72) && + registerDefinition.DataType != typeof(UInt88) && registerDefinition.DataType != typeof(UInt96) && registerDefinition.DataType != typeof(UInt128)) { @@ -288,18 +290,39 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers size = sizeof(Int64); } + else if (registerDefinition.DataType == typeof(UInt48)) + { + // 48 Bits / 8 Bits/Byte + size = 6; + } + + else if (registerDefinition.DataType == typeof(UInt72)) + { + // 72 Bits / 8 Bits/Byte + size = 9; + } + + else if (registerDefinition.DataType == typeof(UInt88)) + { + // 88 Bits / 8 Bits/Byte + size = 11; + } + else if (registerDefinition.DataType == typeof(UInt96)) { + // 96 Bits / 8 Bits/Byte size = 3 * 4; } else if (registerDefinition.DataType == typeof(UInt128)) { + // 128 Bits / 8 Bits/Byte size = 4 * 4; } else if (registerDefinition.DataType == typeof(String)) { + // just some value size = 6 * 4; } @@ -361,6 +384,18 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers { return ByteArrayToValue(rawByteArray).ToString(); } + if (type == typeof(UInt48)) + { + return ""; + } + if (type == typeof(UInt72)) + { + return ""; + } + if (type == typeof(UInt88)) + { + return ""; + } if (type == typeof(UInt96)) { return ""; @@ -421,6 +456,18 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers { convertedObj = BitConverter.ToUInt64(rawByteArray, 0); } + else if (type == typeof(UInt48)) + { + return default(T); + } + else if (type == typeof(UInt72)) + { + return default(T); + } + else if (type == typeof(UInt88)) + { + return default(T); + } else if (type == typeof(UInt96)) { return default(T); diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/Registers.csproj b/Common/Hardware/WaterMeter/Genesis/Registers/Registers.csproj index 05051431..03e786d8 100644 --- a/Common/Hardware/WaterMeter/Genesis/Registers/Registers.csproj +++ b/Common/Hardware/WaterMeter/Genesis/Registers/Registers.csproj @@ -113,7 +113,10 @@ + + + @@ -121,6 +124,16 @@ + + Resources.de.resx + True + True + + + True + True + Resources.resx + @@ -136,6 +149,10 @@ + + {1B02C79E-0B19-43E2-8F6B-71EF0C786C97} + CommonCore + {2FD60CF1-45CD-4060-B8E5-4F39FBA7F1CB} ProcessExec @@ -156,6 +173,18 @@ + + + ResXFileCodeGenerator + Resources.de.Designer.cs + Designer + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + +