using HslCommunication.Core; using HybirdFrameworkCore.Utils; using log4net; namespace HybirdFrameworkDriver.ModbusTcpMaster; public static class ModbusDecoder { private static readonly ILog Log = LogManager.GetLogger(typeof(ModbusDecoder)); public static T Decode(byte[] bytes) where T : class, new() { T t = new T(); return Decode(bytes, t); } public static T Decode(byte[] bytes, T t) where T : class, new() { var fields = t.GetType().GetProperties() .Where(it => it.PropertyType.GetGenericTypeDefinition() == typeof(ModbusProperty<>)) .Select(p => p.GetValue(t)).ToList(); //startRegisterNo 获得整个对象的起始寄存器数值 var startRegisterNo = int.MaxValue; foreach (var field in fields) if (field != null) { var p = (IModbusProperty)field; if (startRegisterNo > p.GetRegisterNo()) startRegisterNo = p.GetRegisterNo(); } var decodeUseBytes = new byte[bytes.Length]; switch (ModbusTcpMaster.DataFormat) { case DataFormat.ABCD: for (var i = 0; i < bytes.Length; i++) if (i % 2 == 0) decodeUseBytes[i + 1] = bytes[i]; else decodeUseBytes[i - 1] = bytes[i]; break; case DataFormat.BADC: decodeUseBytes = bytes; break; } foreach (var field in fields) switch (field) { case ModbusProperty boolProperty: { SetPropertyValue(startRegisterNo, boolProperty, decodeUseBytes); //SetPropertyValue(boolProperty.RegisterNo, boolProperty, decodeUseBytes); break; } case ModbusProperty byteProperty: { SetPropertyValue(startRegisterNo, byteProperty, decodeUseBytes); //SetPropertyValue(byteProperty.RegisterNo, byteProperty, decodeUseBytes); break; } case ModbusProperty sbyteProperty: { //SetPropertyValue(sbyteProperty.RegisterNo, sbyteProperty, decodeUseBytes); SetPropertyValue(startRegisterNo, sbyteProperty, decodeUseBytes); break; } case ModbusProperty shortProperty: { SetPropertyValue(startRegisterNo, shortProperty, decodeUseBytes); //SetPropertyValue(shortProperty.RegisterNo, shortProperty, decodeUseBytes); break; } case ModbusProperty ushortProperty: { SetPropertyValue(startRegisterNo, ushortProperty, decodeUseBytes); // SetPropertyValue(ushortProperty.RegisterNo, ushortProperty, decodeUseBytes); break; } case ModbusProperty intProperty: { SetPropertyValue(startRegisterNo, intProperty, decodeUseBytes); // SetPropertyValue(intProperty.RegisterNo, intProperty, decodeUseBytes); break; } case ModbusProperty uintProperty: { SetPropertyValue(startRegisterNo, uintProperty, decodeUseBytes); // SetPropertyValue(uintProperty.RegisterNo, uintProperty, decodeUseBytes); break; } case ModbusProperty floatProperty: { SetPropertyValue(startRegisterNo, floatProperty, decodeUseBytes); // SetPropertyValue(floatProperty.RegisterNo, floatProperty, decodeUseBytes); break; } case ModbusProperty doubleProperty: { SetPropertyValue(startRegisterNo, doubleProperty, decodeUseBytes); // SetPropertyValue(doubleProperty.RegisterNo, doubleProperty, decodeUseBytes); break; } case ModbusProperty stringProperty: { SetPropertyValue(startRegisterNo, stringProperty, decodeUseBytes); // SetPropertyValue(stringProperty.RegisterNo, stringProperty, decodeUseBytes); break; } } return t; } private static void SetPropertyValue(int startRegisterNo, ModbusProperty field, byte[] bytes) { var registerNo = field.RegisterNo; var start = field.Start; var length = field.Length; var type = field.Type; var scale = field.Scale; var round = field.Round; var offset = field.Offset; start = (registerNo - startRegisterNo) * 16 + start; var valueType = typeof(T); if (typeof(T) == typeof(byte)) length = length * 8; else length = type switch { ModbusDataType.Register => length * 16, _ => length }; var value = BitUtls.Bytes2Value(bytes, valueType, start, length, scale, round, offset); field.Value = (T)value; } }