|
|
|
|
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<T>(byte[] bytes) where T : class, new()
|
|
|
|
|
{
|
|
|
|
|
T t = new T();
|
|
|
|
|
List<object?> fields = t.GetType().GetProperties()
|
|
|
|
|
.Where(it => it.PropertyType.GetGenericTypeDefinition() == typeof(ModbusProperty<>))
|
|
|
|
|
.Select(p => p.GetValue(t)).ToList();
|
|
|
|
|
|
|
|
|
|
int startRegisterNo = Int32.MaxValue;
|
|
|
|
|
foreach (object field in fields)
|
|
|
|
|
{
|
|
|
|
|
if (field != null)
|
|
|
|
|
{
|
|
|
|
|
IModbusProperty p = (IModbusProperty)field;
|
|
|
|
|
if (startRegisterNo > p.GetRegisterNo())
|
|
|
|
|
{
|
|
|
|
|
startRegisterNo = p.GetRegisterNo();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (object field in fields)
|
|
|
|
|
{
|
|
|
|
|
switch (field)
|
|
|
|
|
{
|
|
|
|
|
case ModbusProperty<byte> property:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, property, bytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ModbusProperty<float> floatProperty:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, floatProperty, bytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void SetPropertyValue<T>(int startRegisterNo, ModbusProperty<T> 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;
|
|
|
|
|
|
|
|
|
|
length = type switch
|
|
|
|
|
{
|
|
|
|
|
ModbusDataType.Byte => length * 8,
|
|
|
|
|
ModbusDataType.Register => length * 16,
|
|
|
|
|
_ => length
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Type valueType = typeof(T);
|
|
|
|
|
|
|
|
|
|
object value = BitUtls.Bytes2Value(bytes, valueType, start, length, scale, round, offset);
|
|
|
|
|
field.Value = (T)value;
|
|
|
|
|
}
|
|
|
|
|
}
|