using HslCommunication.Core; using HslCommunication.Secs.Types; 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, T t) where T : class, new() { List fields = t.GetType().GetProperties() .Where(it => it.PropertyType.GetGenericTypeDefinition() == typeof(ModbusProperty<>)) .Select(p => p.GetValue(t)).ToList(); //startRegisterNo 获得整个对象的起始寄存器数值 int startRegisterNo = Int32.MaxValue; foreach (object? field in fields) { if (field != null) { IModbusProperty p = (IModbusProperty)field; if (startRegisterNo > p.GetRegisterNo()) { startRegisterNo = p.GetRegisterNo(); } } } byte[] decodeUseBytes = new byte[bytes.Length]; switch (ModbusTcpMaster.DataFormat) { case DataFormat.ABCD: for (int 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 (object? 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) { int registerNo = field.RegisterNo; int start = field.Start; int length = field.Length; ModbusDataType type = field.Type; double scale = field.Scale; int round = field.Round; double offset = field.Offset; start = (registerNo - startRegisterNo) * 16 + start; Type valueType = typeof(T); if (typeof(T) == typeof(byte)) length = length * 8; else { length = type switch { ModbusDataType.Register => length * 16, _ => length }; } object value = BitUtls.Bytes2Value(bytes, valueType, start, length, scale, round, offset); field.Value = (T)value; } }