|
|
|
|
using HybirdFrameworkCore.Const;
|
|
|
|
|
using HybirdFrameworkCore.Utils;
|
|
|
|
|
using HybirdFrameworkDriver.Common;
|
|
|
|
|
using log4net;
|
|
|
|
|
|
|
|
|
|
namespace HybirdFrameworkDriver.ModbusTcpMaster;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
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();
|
|
|
|
|
return Decode<T>(bytes, t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static T Decode<T>(byte[] bytes, T t, EndingConst.ByteSeq byteSeq = EndingConst.ByteSeq.AB, EndingConst.WordSeq wordSeq = EndingConst.WordSeq.CD) 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];
|
|
|
|
|
|
|
|
|
|
if (byteSeq == EndingConst.ByteSeq.AB)
|
|
|
|
|
{
|
|
|
|
|
decodeUseBytes = BitUtls.ReverseByteSeq(bytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wordSeq == EndingConst.WordSeq.CD)
|
|
|
|
|
{
|
|
|
|
|
decodeUseBytes = BitUtls.ReverseWordSeq(bytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var field in fields)
|
|
|
|
|
switch (field)
|
|
|
|
|
{
|
|
|
|
|
case ModbusProperty<bool> boolProperty:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, boolProperty, decodeUseBytes);
|
|
|
|
|
//SetPropertyValue(boolProperty.RegisterNo, boolProperty, decodeUseBytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ModbusProperty<byte> byteProperty:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, byteProperty, decodeUseBytes);
|
|
|
|
|
//SetPropertyValue(byteProperty.RegisterNo, byteProperty, decodeUseBytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ModbusProperty<sbyte> sbyteProperty:
|
|
|
|
|
{
|
|
|
|
|
//SetPropertyValue(sbyteProperty.RegisterNo, sbyteProperty, decodeUseBytes);
|
|
|
|
|
SetPropertyValue(startRegisterNo, sbyteProperty, decodeUseBytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ModbusProperty<short> shortProperty:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, shortProperty, decodeUseBytes);
|
|
|
|
|
//SetPropertyValue(shortProperty.RegisterNo, shortProperty, decodeUseBytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ModbusProperty<ushort> ushortProperty:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, ushortProperty, decodeUseBytes);
|
|
|
|
|
// SetPropertyValue(ushortProperty.RegisterNo, ushortProperty, decodeUseBytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ModbusProperty<int> intProperty:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, intProperty, decodeUseBytes);
|
|
|
|
|
// SetPropertyValue(intProperty.RegisterNo, intProperty, decodeUseBytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ModbusProperty<uint> uintProperty:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, uintProperty, decodeUseBytes);
|
|
|
|
|
// SetPropertyValue(uintProperty.RegisterNo, uintProperty, decodeUseBytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ModbusProperty<float> floatProperty:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, floatProperty, decodeUseBytes, true);
|
|
|
|
|
// SetPropertyValue(floatProperty.RegisterNo, floatProperty, decodeUseBytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ModbusProperty<double> doubleProperty:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, doubleProperty, decodeUseBytes);
|
|
|
|
|
// SetPropertyValue(doubleProperty.RegisterNo, doubleProperty, decodeUseBytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ModbusProperty<string> stringProperty:
|
|
|
|
|
{
|
|
|
|
|
SetPropertyValue(startRegisterNo, stringProperty, decodeUseBytes);
|
|
|
|
|
// SetPropertyValue(stringProperty.RegisterNo, stringProperty, decodeUseBytes);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void SetPropertyValue<T>(int startRegisterNo, ModbusProperty<T> field, byte[] bytes,
|
|
|
|
|
bool unSign = true)
|
|
|
|
|
{
|
|
|
|
|
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, unSign);
|
|
|
|
|
field.Value = (T)value;
|
|
|
|
|
}
|
|
|
|
|
}
|