diff --git a/.vs/IoTGateway/DesignTimeBuild/.dtbcache.v2 b/.vs/IoTGateway/DesignTimeBuild/.dtbcache.v2
index c93a172..b27cc55 100644
Binary files a/.vs/IoTGateway/DesignTimeBuild/.dtbcache.v2 and b/.vs/IoTGateway/DesignTimeBuild/.dtbcache.v2 differ
diff --git a/.vs/IoTGateway/FileContentIndex/0c07d9e6-cadd-4bfc-b30d-70e3bb4a3b42.vsidx b/.vs/IoTGateway/FileContentIndex/0c07d9e6-cadd-4bfc-b30d-70e3bb4a3b42.vsidx
new file mode 100644
index 0000000..c127c75
Binary files /dev/null and b/.vs/IoTGateway/FileContentIndex/0c07d9e6-cadd-4bfc-b30d-70e3bb4a3b42.vsidx differ
diff --git a/.vs/IoTGateway/FileContentIndex/49c1a143-e289-4b5e-94bd-d8f6eeec765c.vsidx b/.vs/IoTGateway/FileContentIndex/49c1a143-e289-4b5e-94bd-d8f6eeec765c.vsidx
new file mode 100644
index 0000000..26f7868
Binary files /dev/null and b/.vs/IoTGateway/FileContentIndex/49c1a143-e289-4b5e-94bd-d8f6eeec765c.vsidx differ
diff --git a/.vs/IoTGateway/FileContentIndex/fdd8818f-7df8-4b70-9b1b-7813ef583fe3.vsidx b/.vs/IoTGateway/FileContentIndex/541da243-50ad-45a8-9f68-40e68ae1c141.vsidx
similarity index 99%
rename from .vs/IoTGateway/FileContentIndex/fdd8818f-7df8-4b70-9b1b-7813ef583fe3.vsidx
rename to .vs/IoTGateway/FileContentIndex/541da243-50ad-45a8-9f68-40e68ae1c141.vsidx
index c42e72d..afe0540 100644
Binary files a/.vs/IoTGateway/FileContentIndex/fdd8818f-7df8-4b70-9b1b-7813ef583fe3.vsidx and b/.vs/IoTGateway/FileContentIndex/541da243-50ad-45a8-9f68-40e68ae1c141.vsidx differ
diff --git a/.vs/IoTGateway/FileContentIndex/67034209-72e2-48a7-8d44-a57dc4ca3289.vsidx b/.vs/IoTGateway/FileContentIndex/67034209-72e2-48a7-8d44-a57dc4ca3289.vsidx
deleted file mode 100644
index fc3b20b..0000000
Binary files a/.vs/IoTGateway/FileContentIndex/67034209-72e2-48a7-8d44-a57dc4ca3289.vsidx and /dev/null differ
diff --git a/.vs/IoTGateway/FileContentIndex/7390658a-3ccb-47c8-8b9e-0545a71148ea.vsidx b/.vs/IoTGateway/FileContentIndex/7390658a-3ccb-47c8-8b9e-0545a71148ea.vsidx
deleted file mode 100644
index 4874670..0000000
Binary files a/.vs/IoTGateway/FileContentIndex/7390658a-3ccb-47c8-8b9e-0545a71148ea.vsidx and /dev/null differ
diff --git a/.vs/IoTGateway/FileContentIndex/ffc12142-a2fd-4689-a65a-ee57200eab5d.vsidx b/.vs/IoTGateway/FileContentIndex/ffc12142-a2fd-4689-a65a-ee57200eab5d.vsidx
new file mode 100644
index 0000000..f0a7ab5
Binary files /dev/null and b/.vs/IoTGateway/FileContentIndex/ffc12142-a2fd-4689-a65a-ee57200eab5d.vsidx differ
diff --git a/.vs/IoTGateway/v17/.suo b/.vs/IoTGateway/v17/.suo
index b74ca65..e4f7376 100644
Binary files a/.vs/IoTGateway/v17/.suo and b/.vs/IoTGateway/v17/.suo differ
diff --git a/.vs/ProjectEvaluation/iotgateway.metadata.v2 b/.vs/ProjectEvaluation/iotgateway.metadata.v2
index ce11152..ad78594 100644
Binary files a/.vs/ProjectEvaluation/iotgateway.metadata.v2 and b/.vs/ProjectEvaluation/iotgateway.metadata.v2 differ
diff --git a/.vs/ProjectEvaluation/iotgateway.projects.v2 b/.vs/ProjectEvaluation/iotgateway.projects.v2
index 90e040f..b06c94f 100644
Binary files a/.vs/ProjectEvaluation/iotgateway.projects.v2 and b/.vs/ProjectEvaluation/iotgateway.projects.v2 differ
diff --git a/IoTGateway.sln b/IoTGateway.sln
index 5f17919..876b396 100644
--- a/IoTGateway.sln
+++ b/IoTGateway.sln
@@ -43,6 +43,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DriverOmronFins", "Plugins\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DriverFanuc", "Plugins\Drivers\DriverFanuc\DriverFanuc.csproj", "{EA652A3B-5F4A-47FE-A5DA-98A0EFC4F842}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DriverSimTcpClient", "Plugins\Drivers\DriverSimTcpClient\DriverSimTcpClient.csproj", "{F8EC5EDE-9A2C-443B-B125-E39C748EBB2F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -117,6 +119,10 @@ Global
{EA652A3B-5F4A-47FE-A5DA-98A0EFC4F842}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EA652A3B-5F4A-47FE-A5DA-98A0EFC4F842}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EA652A3B-5F4A-47FE-A5DA-98A0EFC4F842}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8EC5EDE-9A2C-443B-B125-E39C748EBB2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8EC5EDE-9A2C-443B-B125-E39C748EBB2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8EC5EDE-9A2C-443B-B125-E39C748EBB2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8EC5EDE-9A2C-443B-B125-E39C748EBB2F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -136,6 +142,7 @@ Global
{28FEF3AF-4CAA-4B5C-B16F-E74BAD70BCE2} = {D05CFF72-D58C-418A-8F52-B06848DAC4F1}
{FE2BFDBD-E021-45EA-B327-C56F6114D7A1} = {D05CFF72-D58C-418A-8F52-B06848DAC4F1}
{EA652A3B-5F4A-47FE-A5DA-98A0EFC4F842} = {D05CFF72-D58C-418A-8F52-B06848DAC4F1}
+ {F8EC5EDE-9A2C-443B-B125-E39C748EBB2F} = {D05CFF72-D58C-418A-8F52-B06848DAC4F1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1F219808-E6E8-4C1D-B846-41F2F7CF20FA}
diff --git a/Plugins/Drivers/DriverSimTcpClient/DriverSimTcpClient.csproj b/Plugins/Drivers/DriverSimTcpClient/DriverSimTcpClient.csproj
new file mode 100644
index 0000000..c517682
--- /dev/null
+++ b/Plugins/Drivers/DriverSimTcpClient/DriverSimTcpClient.csproj
@@ -0,0 +1,15 @@
+
+
+ net6.0
+ ../../../IoTGateway/bin/Debug/net6.0/drivers
+ true
+ enable
+ enable
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plugins/Drivers/DriverSimTcpClient/SimTcpClient.cs b/Plugins/Drivers/DriverSimTcpClient/SimTcpClient.cs
new file mode 100644
index 0000000..ffb32f9
--- /dev/null
+++ b/Plugins/Drivers/DriverSimTcpClient/SimTcpClient.cs
@@ -0,0 +1,218 @@
+using PluginInterface;
+using SimpleTCP;
+using System;
+using System.Text;
+
+namespace DriverSimTcpClient
+{
+ [DriverSupported("SimTcpServerDevice")]
+ [DriverInfoAttribute("SimTcpClient", "V1.0.0", "Copyright iotgateway© 2022-06-04")]
+ public class SimTcpClient : IDriver
+ {
+ ///
+ /// tcp客户端
+ ///
+ private SimpleTcpClient? client;
+ ///
+ /// 缓存最新的服务器返回的原始数据
+ ///
+ private byte[] latestRcvData;
+ #region 配置参数
+
+ [ConfigParameter("设备Id")]
+ public Guid DeviceId { get; set; }
+
+ [ConfigParameter("IP地址")]
+ public string IpAddress { get; set; } = "127.0.0.1";
+
+ [ConfigParameter("端口号")]
+ public int Port { get; set; } = 6666;
+
+ ///
+ /// 为了演示枚举类型在web端的录入,这里没用到 但是你可以拿到
+ ///
+ [ConfigParameter("连接类型")]
+ public ConnectionType ConnectionType { get; set; } = ConnectionType.Long;
+
+ [ConfigParameter("超时时间ms")]
+ public int Timeout { get; set; } = 300;
+
+ [ConfigParameter("最小通讯周期ms")]
+ public uint MinPeriod { get; set; } = 3000;
+
+ #endregion
+
+ public SimTcpClient(Guid deviceId)
+ {
+ DeviceId = deviceId;
+ }
+
+
+ ///
+ /// 判断连接状态
+ ///
+ public bool IsConnected
+ {
+ get
+ {
+ //客户端对象不为空并且客户端已连接则返回true
+ return client != null && client.TcpClient.Connected;
+ }
+ }
+
+ ///
+ /// 进行连接
+ ///
+ /// 连接是否成功
+ public bool Connect()
+ {
+ try
+ {
+ //进行连接
+ client = new SimpleTcpClient().Connect(IpAddress, Port);
+ client.DataReceived += Client_DataReceived;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ return IsConnected;
+ }
+ ///
+ /// 收到服务端数据
+ ///
+ ///
+ ///
+ private void Client_DataReceived(object? sender, Message e)
+ {
+ //如果收到的数据校验正确,则放在内存中
+ if (e.Data.Length == 8 && e.Data[0] == 0x08)
+ latestRcvData = e.Data;
+ }
+
+ ///
+ /// 断开连接
+ ///
+ /// 断开是否成功
+ public bool Close()
+ {
+ try
+ {
+ client.DataReceived -= Client_DataReceived;
+ //断开连接
+ client?.Disconnect();
+ return !IsConnected;
+ }
+ catch (Exception)
+ {
+
+ return false;
+ }
+ }
+
+ ///
+ /// 释放
+ ///
+ public void Dispose()
+ {
+ try
+ {
+ //释放资源
+ client?.Dispose();
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+
+ ///
+ /// 发送数据
+ ///
+ private byte[] sendCmd = new byte[4] { 0x01, 0x02, 0x03, 0x04 };
+
+ ///
+ /// 解析并返回
+ ///
+ /// ioarg.Address为起始变量字节编号;ioarg.ValueType为类型
+ ///
+ [Method("读模拟设备数据", description: "读模拟设备数据,开始字节和长度")]
+ public DriverReturnValueModel Read(DriverAddressIoArgModel ioarg)
+ {
+ var ret = new DriverReturnValueModel { StatusType = VaribaleStatusTypeEnum.Good };
+ ushort startIndex;
+ //判断地址是否为整数
+ if (!ushort.TryParse(ioarg.Address, out startIndex))
+ {
+ ret.StatusType = VaribaleStatusTypeEnum.Bad;
+ ret.Message = "起始字节编号错误";
+ return ret;
+ }
+ //连接正常则进行读取
+ if (IsConnected)
+ {
+ try
+ {
+ //发送请求
+ client?.Write(sendCmd);
+ //等待恢复,这里可以优化
+ Thread.Sleep(Timeout);
+ if (latestRcvData == null)
+ {
+ ret.StatusType = VaribaleStatusTypeEnum.Bad;
+ ret.Message = "没有收到数据";
+ }
+ else
+ {
+ //解析数据,并返回
+ switch (ioarg.ValueType)
+ {
+ case DataTypeEnum.UByte:
+ case DataTypeEnum.Byte:
+ ret.Value = latestRcvData[startIndex];
+ break;
+ case DataTypeEnum.Int16:
+ var buffer16 = latestRcvData.Skip(startIndex).Take(2).ToArray();
+ ret.Value = BitConverter.ToInt16(new byte[] { buffer16[0], buffer16[1] }, 0);
+ break;
+ case DataTypeEnum.Float:
+ //拿到有用的数据
+ var buffer32 = latestRcvData.Skip(startIndex).Take(4).ToArray();
+ //大小端转换一下
+ ret.Value = BitConverter.ToSingle(new byte[] { buffer32[3], buffer32[2], buffer32[1], buffer32[0] }, 0);
+ break;
+ default:
+ break;
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+
+ ret.StatusType = VaribaleStatusTypeEnum.Bad;
+ ret.Message = $"读取失败,{ex.Message}";
+ }
+ }
+ else
+ {
+ ret.StatusType = VaribaleStatusTypeEnum.Bad;
+ ret.Message = "连接失败";
+ }
+ return ret;
+ }
+
+
+ public async Task WriteAsync(string RequestId, string Method, DriverAddressIoArgModel Ioarg)
+ {
+ RpcResponse rpcResponse = new() { IsSuccess = false, Description = "设备驱动内未实现写入功能" };
+ return rpcResponse;
+ }
+ }
+
+ public enum ConnectionType
+ {
+ Long,
+ Short
+ }
+}
\ No newline at end of file