diff --git a/Common/Docu/SoftwareDesign/CordonelParametrizationV03.pptx b/Common/Docu/SoftwareDesign/CordonelParametrizationV03.pptx index cbaca353..fc43c6cd 100644 Binary files a/Common/Docu/SoftwareDesign/CordonelParametrizationV03.pptx and b/Common/Docu/SoftwareDesign/CordonelParametrizationV03.pptx differ diff --git a/Common/Hardware/WaterMeter/Genesis/Registers/RegisterConverter.cs b/Common/Hardware/WaterMeter/Genesis/Registers/RegisterConverter.cs index 195a529d..e84d623f 100644 --- a/Common/Hardware/WaterMeter/Genesis/Registers/RegisterConverter.cs +++ b/Common/Hardware/WaterMeter/Genesis/Registers/RegisterConverter.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; @@ -51,7 +52,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers String strRawResult; if (registerName.Contains("EncryptionKey") || registerName.Contains("Password")) { - strRawResult = GetRegisterRawText(registerDefinition, regRawByteArray, encryptData:true); + strRawResult = GetRegisterRawText(registerDefinition, regRawByteArray, encryptData: true); msg = $"{registerName}: ({strRawResult})h"; } else @@ -64,7 +65,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers { throw new ApplicationException($"Cannot convert register {registerName}"); } - + return msg; } @@ -86,7 +87,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers /// /// - Hash password and encryption key with SHA256. /// - public static String GetRegisterRawText(RegisterDefinition registerDefinition, Byte[] regRawByteArray, + public static String GetRegisterRawText(RegisterDefinition registerDefinition, Byte[] regRawByteArray, Boolean encryptData = false) { String msg; @@ -146,8 +147,8 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers regRawByteArray = ValueToByteArray(registerDefinition.Default); return true; } - - regRawByteArray = new Byte[] {0}; + + regRawByteArray = new Byte[] { 0 }; return false; } @@ -291,7 +292,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers } else if (registerDefinition.DataType == typeof(UInt48)) - { + { // 48 Bits / 8 Bits/Byte size = 6; } @@ -436,6 +437,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers /// /// - Return default (T) on input == null; /// + /// + /// - Padding bytes if input doesn't fit the required size; + /// public static T ByteArrayToValue(Byte[] rawByteArray) { if (rawByteArray == null) @@ -443,61 +447,39 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers try { - Object convertedObj; + Object convertedObj = null; var type = typeof(T); - if (type == typeof(Boolean)) - { - convertedObj = BitConverter.ToBoolean(rawByteArray, 0); - } - else if (type == typeof(UInt16)) - { - convertedObj = BitConverter.ToUInt16(rawByteArray, 0); - } - else if (type == typeof(UInt32)) - { - convertedObj = BitConverter.ToUInt32(rawByteArray, 0); - } - else if (type == typeof(UInt64)) - { - convertedObj = BitConverter.ToUInt64(rawByteArray, 0); - } - else if (type == typeof(UInt48)) + // For non-numerical or single byte values use the standard implementation + if (type == typeof(UInt48)) { return default(T); } - else if (type == typeof(UInt72)) + if (type == typeof(UInt72)) { return default(T); } - else if (type == typeof(UInt88)) + if (type == typeof(UInt88)) { return default(T); } - else if (type == typeof(UInt96)) + if (type == typeof(UInt96)) { return default(T); } - else if (type == typeof(UInt128)) + if (type == typeof(UInt128)) { return default(T); } - else if (type == typeof(Int16)) - { - convertedObj = BitConverter.ToInt16(rawByteArray, 0); - } - else if (type == typeof(Int32)) - { - convertedObj = BitConverter.ToInt32(rawByteArray, 0); - } - else if (type == typeof(Int64)) - { - convertedObj = BitConverter.ToInt64(rawByteArray, 0); - } - else if (type == typeof(Byte) || type == typeof(Enum8)) + + if (type == typeof(Byte) || type == typeof(Enum8)) { convertedObj = rawByteArray[0]; } + else if (type == typeof(Boolean)) + { + convertedObj = BitConverter.ToBoolean(rawByteArray, 0); + } else if (type == typeof(SByte)) { // set all others to 0 as only the LSB is of interest @@ -545,6 +527,54 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers // the value contains always the seconds since 01.Jan 2000 convertedObj = new TimeT { SecondsSince2000 = ByteArrayToValue(rawByteArray) }; } + + if (convertedObj != null) + { + return (T)Convert.ChangeType(convertedObj, type); + } + + // Padding byte array to required byte size will be used for numerical values + var requiredSize = Marshal.SizeOf(typeof(T)); + var paddedRawByteArray = new Byte[requiredSize]; + var inputArraySize = rawByteArray.Length; + for (var ctr = 0; ctr < requiredSize; ctr++) + { + if (inputArraySize > 0) + { + paddedRawByteArray[ctr] = rawByteArray[ctr]; + inputArraySize--; + } + else + { + paddedRawByteArray[ctr] = 0x00; + } + } + + // For all numerical values the padded raw byte array will be used + if (type == typeof(UInt16)) + { + convertedObj = BitConverter.ToUInt16(paddedRawByteArray, 0); + } + else if (type == typeof(UInt32)) + { + convertedObj = BitConverter.ToUInt32(paddedRawByteArray, 0); + } + else if (type == typeof(UInt64)) + { + convertedObj = BitConverter.ToUInt64(paddedRawByteArray, 0); + } + else if (type == typeof(Int16)) + { + convertedObj = BitConverter.ToInt16(paddedRawByteArray, 0); + } + else if (type == typeof(Int32)) + { + convertedObj = BitConverter.ToInt32(paddedRawByteArray, 0); + } + else if (type == typeof(Int64)) + { + convertedObj = BitConverter.ToInt64(paddedRawByteArray, 0); + } else { throw new ApplicationException($"Data type {type} not implemented"); @@ -552,9 +582,10 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers return (T)Convert.ChangeType(convertedObj, type); } - catch (Exception) + catch (Exception ex) { - return default(T); + throw new ApplicationException($"Data type {typeof(T)} not implemented. Message: {ex.Message}"); + //return default(T); } } }