From 584602cd7faf34fab648dc8e0048ff74d1246aae Mon Sep 17 00:00:00 2001
From: smartwyy <645583145@qq.com>
Date: Fri, 19 Apr 2024 10:59:42 +0800
Subject: [PATCH] modbus
---
ConsoleStarter/ConsoleStarter.csproj | 19 ++
ConsoleStarter/log4net.xml | 32 ++++
HybirdFrameworkCore/Utils/BitUtls.cs | 179 ++++++++++++++----
HybirdFrameworkCore/Utils/ModelConvert.cs | 134 ++-----------
.../ModbusTcpMaster/IModbusProperty.cs | 6 +
.../ModbusTcpMaster/ModbusDecoder.cs | 74 ++++++++
.../ModbusTcpMaster/ModbusProperty.cs | 55 ++++++
.../ModbusTcpMaster/ModbusTcpMaster.cs | 153 ++++++++++++++-
.../ModbusTcpMaster/WaterCoolData.cs | 34 ++++
WebStarter/Program.cs | 2 +
10 files changed, 533 insertions(+), 155 deletions(-)
create mode 100644 ConsoleStarter/log4net.xml
create mode 100644 HybirdFrameworkDriver/ModbusTcpMaster/IModbusProperty.cs
create mode 100644 HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs
create mode 100644 HybirdFrameworkDriver/ModbusTcpMaster/ModbusProperty.cs
create mode 100644 HybirdFrameworkDriver/ModbusTcpMaster/WaterCoolData.cs
diff --git a/ConsoleStarter/ConsoleStarter.csproj b/ConsoleStarter/ConsoleStarter.csproj
index c645c7c..f422989 100644
--- a/ConsoleStarter/ConsoleStarter.csproj
+++ b/ConsoleStarter/ConsoleStarter.csproj
@@ -9,7 +9,26 @@
+
+
+
+
+
+
+
+ true
+ PreserveNewest
+ PreserveNewest
+
+
+
+
+
+ Always
+
+
+
diff --git a/ConsoleStarter/log4net.xml b/ConsoleStarter/log4net.xml
new file mode 100644
index 0000000..faac71d
--- /dev/null
+++ b/ConsoleStarter/log4net.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HybirdFrameworkCore/Utils/BitUtls.cs b/HybirdFrameworkCore/Utils/BitUtls.cs
index be579f6..b95d795 100644
--- a/HybirdFrameworkCore/Utils/BitUtls.cs
+++ b/HybirdFrameworkCore/Utils/BitUtls.cs
@@ -4,6 +4,25 @@ namespace HybirdFrameworkCore.Utils;
public static class BitUtls
{
+ #region Type Def
+
+ private static readonly Type BOOLEAN = typeof(bool);
+ private static readonly Type BYTE = typeof(byte);
+ private static readonly Type SBYTE = typeof(sbyte);
+ private static readonly Type SHORT = typeof(short);
+ private static readonly Type USHORT = typeof(ushort);
+ private static readonly Type INT = typeof(int);
+ private static readonly Type UINT = typeof(uint);
+ private static readonly Type LONG = typeof(long);
+ private static readonly Type ULONG = typeof(ulong);
+ private static readonly Type FLOAT = typeof(float);
+ private static readonly Type DOUBLE = typeof(double);
+ private static readonly Type STRING = typeof(string);
+
+ #endregion
+
+ #region Func
+
public static string Bytes2BinaryString(byte[] bytes)
{
return string.Join(" ", bytes.Select(b => Convert.ToString(b, 2).PadLeft(8, '0')));
@@ -39,6 +58,10 @@ public static class BitUtls
return returnBytes;
}
+ #endregion
+
+ #region Base Func
+
public static byte Byte2Bit(byte[] bytes, int startBit, int length)
{
if (length > 8)
@@ -46,40 +69,6 @@ public static class BitUtls
throw new ArgumentException("length can not be greater then 8!");
}
- /*
- byte result = 0;
- int index = startBit / 8;
- byte b = bytes[index];
-
- int suffix = startBit % 8;
- if (suffix == 0)
- {
- byte mask = (byte)(255 >> (8 - length));
- result = (byte)(b & mask);
- }
- else
- {
- if ((8 - suffix) >= length)
- {
- byte mask = (byte)(255 >> (8 - length));
- result = (byte)(b & mask);
- }
- else
- {
- byte pre = (byte)(b >> suffix);
-
- int remain = length - (8 - suffix);
- byte nextByte = bytes[index + 1];
-
- nextByte = (byte)(nextByte << (8 - remain));
- nextByte = (byte)(nextByte >> (8 - remain));
- nextByte = (byte)(nextByte << (8 - suffix));
-
- result = (byte)(pre | nextByte);
- }
- }
-
- return result;*/
byte[] sub = Sub(bytes, startBit, length);
return sub[0];
}
@@ -203,4 +192,126 @@ public static class BitUtls
return BitConverter.ToInt32(sub, 0);
}
+
+ #endregion
+
+ #region Decode Value
+
+ public static object Bytes2Value(byte[] bytes, Type propertyType, int start, int length, double scale, int round,
+ double offset)
+ {
+ if (propertyType == BOOLEAN)
+ {
+ return Convert.ChangeType(Byte2Bit(bytes, start, length) == 1, propertyType);
+ }
+ else if (propertyType == BYTE || propertyType == SBYTE)
+ {
+ return
+ Convert.ChangeType(Byte2Bit(bytes, start, length) * scale - offset, propertyType);
+ }
+ else if (propertyType == USHORT)
+ {
+ return
+ Convert.ChangeType(Byte2UInt16(bytes, start, length) * scale - offset, propertyType);
+ }
+ else if (propertyType == SHORT)
+ {
+ return
+ Convert.ChangeType(Byte2Int16(bytes, start, length) * scale - offset, propertyType);
+ }
+ else if (propertyType == INT)
+ {
+ return
+ Convert.ChangeType(Byte2Int32(bytes, start, length) * scale - offset, propertyType);
+ }
+ else if (propertyType == UINT)
+ {
+ return
+ Convert.ChangeType(Byte2UInt32(bytes, start, length) * scale - offset, propertyType);
+ }
+ else if (propertyType == FLOAT)
+ {
+ return
+ Convert.ChangeType(Math.Round(Byte2Float(bytes, start, length, scale) - offset, round), propertyType);
+ }
+ else if (propertyType == DOUBLE)
+ {
+ return
+ Convert.ChangeType(Math.Round(Byte2Double(bytes, start, length, scale) - offset, round),
+ propertyType);
+ }
+ else if (propertyType == STRING)
+ {
+ return Convert.ChangeType(BytesToHexStr(bytes, start, length), propertyType);
+ }
+
+ throw new ArgumentException($"参数类型{propertyType}不支持encode!");
+ }
+
+ #endregion
+
+ #region encode value
+
+ public static byte[] Value2Bytes(T value, double scale, double offset)
+ {
+ if (value == null)
+ {
+ return Array.Empty();
+ }
+
+ Type propertyType = value.GetType();
+
+ if (propertyType == BOOLEAN)
+ {
+ return BitConverter.GetBytes(Convert.ToBoolean(value));
+ }
+
+ if (propertyType == BYTE || propertyType == SBYTE)
+ {
+ return new[] { (byte)((Convert.ToByte(value) + offset) / scale) };
+ }
+
+ if (propertyType == USHORT)
+ {
+ return BitConverter.GetBytes((ushort)((Convert.ToUInt16(value) + offset) / scale));
+ }
+
+ if (propertyType == SHORT)
+ {
+ return BitConverter.GetBytes((short)((Convert.ToInt16(value) + offset) / scale));
+ }
+
+ if (propertyType == INT)
+ {
+ return BitConverter.GetBytes((int)((Convert.ToInt32(value) + offset) / scale));
+ }
+
+ if (propertyType == UINT)
+ {
+ return BitConverter.GetBytes((uint)((Convert.ToUInt32(value) + offset) / scale));
+ }
+
+ if (propertyType == FLOAT)
+ {
+ return BitConverter.GetBytes((uint)((Convert.ToSingle(value) + offset) / scale));
+ }
+
+ if (propertyType == DOUBLE)
+ {
+ return BitConverter.GetBytes((UInt64)((Convert.ToDouble(value) + offset) / scale));
+ }
+
+ if (propertyType == STRING)
+ {
+ string? s = Convert.ToString(value);
+ if (s != null)
+ {
+ return Encoding.ASCII.GetBytes(s);
+ }
+ }
+
+ throw new ArgumentException($"参数类型{propertyType}不支持encode!");
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/HybirdFrameworkCore/Utils/ModelConvert.cs b/HybirdFrameworkCore/Utils/ModelConvert.cs
index 0004a15..cb8684c 100644
--- a/HybirdFrameworkCore/Utils/ModelConvert.cs
+++ b/HybirdFrameworkCore/Utils/ModelConvert.cs
@@ -1,24 +1,23 @@
using System.Collections;
using System.Reflection;
-using System.Text;
using HybirdFrameworkCore.Autofac.Attribute;
namespace HybirdFrameworkCore.Utils;
public static class ModelConvert
{
- private static readonly Type BOOLEAN = typeof(bool);
- private static readonly Type BYTE = typeof(byte);
- private static readonly Type SBYTE = typeof(sbyte);
- private static readonly Type SHORT = typeof(short);
- private static readonly Type USHORT = typeof(ushort);
- private static readonly Type INT = typeof(int);
- private static readonly Type UINT = typeof(uint);
- private static readonly Type LONG = typeof(long);
- private static readonly Type ULONG = typeof(ulong);
- private static readonly Type FLOAT = typeof(float);
- private static readonly Type DOUBLE = typeof(double);
- private static readonly Type STRING = typeof(string);
+ public static readonly Type BOOLEAN = typeof(bool);
+ public static readonly Type BYTE = typeof(byte);
+ public static readonly Type SBYTE = typeof(sbyte);
+ public static readonly Type SHORT = typeof(short);
+ public static readonly Type USHORT = typeof(ushort);
+ public static readonly Type INT = typeof(int);
+ public static readonly Type UINT = typeof(uint);
+ public static readonly Type LONG = typeof(long);
+ public static readonly Type ULONG = typeof(ulong);
+ public static readonly Type FLOAT = typeof(float);
+ public static readonly Type DOUBLE = typeof(double);
+ public static readonly Type STRING = typeof(string);
public static T Declode(byte[] bytes) where T : class, new()
{
@@ -39,62 +38,16 @@ public static class ModelConvert
PropertyAttribute? attribute = field.GetCustomAttribute();
if (attribute != null)
{
- double scale = attribute.Scale;
- int length = PropertyReadConstant.Byte == attribute.Type ? attribute.Length * 8 : attribute.Length;
int start = attribute.Start;
+ int length = PropertyReadConstant.Byte == attribute.Type ? attribute.Length * 8 : attribute.Length;
+ double scale = attribute.Scale;
+ int round = attribute.Round;
double offset = attribute.Offset;
Type propertyType = field.PropertyType;
- if (propertyType == BOOLEAN)
- {
- field.SetValue(t,
- Convert.ChangeType(BitUtls.Byte2Bit(bytes, start, length) == 1, propertyType), null);
- }
-
- else if (propertyType == BYTE || propertyType == SBYTE)
- {
- field.SetValue(t,
- Convert.ChangeType(BitUtls.Byte2Bit(bytes, start, length) * scale - offset, propertyType), null);
- }
- else if (propertyType == USHORT)
- {
- field.SetValue(t,
- Convert.ChangeType(BitUtls.Byte2UInt16(bytes, start, length) * scale - offset, propertyType), null);
- }
- else if (propertyType == SHORT)
- {
- field.SetValue(t,
- Convert.ChangeType(BitUtls.Byte2Int16(bytes, start, length) * scale - offset, propertyType), null);
- }
- else if (propertyType == INT)
- {
- field.SetValue(t,
- Convert.ChangeType(BitUtls.Byte2Int32(bytes, start, length) * scale - offset, propertyType), null);
- }
- else if (propertyType == UINT)
- {
- field.SetValue(t,
- Convert.ChangeType(BitUtls.Byte2UInt32(bytes, start, length) * scale - offset, propertyType), null);
- }
- else if (propertyType == FLOAT)
- {
- field.SetValue(t,
- Convert.ChangeType(
- Math.Round(BitUtls.Byte2Float(bytes, start, length, scale) - offset, attribute.Round),
- propertyType), null);
- }
- else if (propertyType == DOUBLE)
- {
- field.SetValue(t,
- Convert.ChangeType(
- Math.Round(BitUtls.Byte2Double(bytes, start, length, scale) - offset, attribute.Round),
- propertyType), null);
- }
- else if (propertyType == STRING)
- {
- field.SetValue(t, Convert.ChangeType(BitUtls.BytesToHexStr(bytes, start, length), propertyType), null);
- }
+ object value = BitUtls.Bytes2Value(bytes, propertyType, start, length, scale, round, offset);
+ field.SetValue(t, value, null);
}
}
@@ -150,57 +103,8 @@ public static class ModelConvert
double offset = attribute.Offset;
double scale = attribute.Scale;
Type propertyType = field.PropertyType;
- object? value = field.GetValue(t);
- if (value == null)
- {
- return Array.Empty();
- }
-
- if (propertyType == BOOLEAN)
- {
- return BitConverter.GetBytes((bool)value);
- }
-
- if (propertyType == BYTE || propertyType == SBYTE)
- {
- return new[] { (byte)(((byte)value + offset) / scale) };
- }
-
- if (propertyType == USHORT)
- {
- return BitConverter.GetBytes((ushort)(((ushort)value + offset) / scale));
- }
-
- if (propertyType == SHORT)
- {
- return BitConverter.GetBytes((short)(((short)value + offset) / scale));
- }
-
- if (propertyType == INT)
- {
- return BitConverter.GetBytes((int)(((int)value + offset) / scale));
- }
- if (propertyType == UINT)
- {
- return BitConverter.GetBytes((uint)(((uint)value + offset) / scale));
- }
-
- if (propertyType == FLOAT)
- {
- return BitConverter.GetBytes((uint)(((float)value + offset) / scale));
- }
-
- if (propertyType == DOUBLE)
- {
- return BitConverter.GetBytes((UInt64)(((double)value + offset) / scale));
- }
-
- if (propertyType == STRING)
- {
- return Encoding.ASCII.GetBytes((string)value);
- }
-
- throw new ArgumentException($"参数类型{propertyType}不支持encode!");
+ object? value = field.GetValue(t);
+ return BitUtls.Value2Bytes(value, scale, offset);
}
}
\ No newline at end of file
diff --git a/HybirdFrameworkDriver/ModbusTcpMaster/IModbusProperty.cs b/HybirdFrameworkDriver/ModbusTcpMaster/IModbusProperty.cs
new file mode 100644
index 0000000..3ad6bb7
--- /dev/null
+++ b/HybirdFrameworkDriver/ModbusTcpMaster/IModbusProperty.cs
@@ -0,0 +1,6 @@
+namespace HybirdFrameworkDriver.ModbusTcpMaster;
+
+public interface IModbusProperty
+{
+ int GetRegisterNo();
+}
\ No newline at end of file
diff --git a/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs b/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs
new file mode 100644
index 0000000..ac87888
--- /dev/null
+++ b/HybirdFrameworkDriver/ModbusTcpMaster/ModbusDecoder.cs
@@ -0,0 +1,74 @@
+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();
+ List