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