著名网站建设公司,wordpress检测手机端,制作七星网站,莱芜网吧场景模拟假设你有一批非标设备需要对接#xff0c;你需要根据设备方提供的协议#xff0c;为IoTGateway开发驱动#xff0c;进行数据交互。文章比较长也可以到官网会有更好的体验#xff0c;地址:http://iotgateway.net/docs/iotgateway/driver/tcpclient请先浏览上一篇驱动… 场景模拟假设你有一批非标设备需要对接你需要根据设备方提供的协议为IoTGateway开发驱动进行数据交互。文章比较长也可以到官网会有更好的体验地址:http://iotgateway.net/docs/iotgateway/driver/tcpclient请先浏览上一篇驱动简介http://iotgateway.net/docs/iotgateway/driver/drvier协议概述对方提供了如下协议文档设备作为TCPServer端口6666 字节序:Little-Endian即低地址存放低位请求回复需要你主动发起读取请求:0x01 02 03 04 设备回复:0x08 01 41 D6 3D 71 1A 20参数说明总字节数(byte[0])即0x08:用于简单的校验运行状态(byte[1])即0x01:1为运行;其他为停止设备温度(byte[2]-byte[5])即0x41 D6 3D 71单精度浮点数值26.78电机转速(byte[6]-byte[7])即0x1A 20对应16进制无符号整型倍率0.01值66.88驱动开发创建驱动项目在解决方案-Drivers文件夹右键添加-新建项目-C#类库 项目名DriverSimTcpClient放在iotgateway\Plugins\Drivers路径下 修改Class1为SimTcpClient双击项目修改配置 iotgateway\Plugins\Drivers\DriverSimTcpClient\DriverSimTcpClient.csprojProject SdkMicrosoft.NET.SdkPropertyGroupTargetFrameworknet6.0/TargetFrameworkOutputPath../../../IoTGateway/bin/Debug/net6.0/drivers/OutputPathCopyLocalLockFileAssembliestrue/CopyLocalLockFileAssembliesImplicitUsingsenable/ImplicitUsingsNullableenable/Nullable/PropertyGroupItemGroupPackageReference IncludeSimpleTCP.Core Version1.0.4 //ItemGroupItemGroupProjectReference Include..\..\PluginInterface\PluginInterface.csproj //ItemGroup
/Project说明OutputPath节点指定了生成项目的文件夹SimpleTCP.Core是一个TCP客户端库(你也可以自己写)ProjectReference节点引用了PluginInterface项目CopyLocalLockFileAssemblies节点可以确保你引用的nuget拷贝到driver文件夹下 :::编写项目代码iotgateway\Plugins\Drivers\DriverSimTcpClient\SimTcpClient.csusing 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{/// summary/// tcp客户端/// /summaryprivate SimpleTcpClient? client;/// summary/// 缓存最新的服务器返回的原始数据/// /summaryprivate 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;/// summary/// 为了演示枚举类型在web端的录入这里没用到 但是你可以拿到/// /summary[ConfigParameter(连接类型)]public ConnectionType ConnectionType { get; set; } ConnectionType.Long;[ConfigParameter(超时时间ms)]public int Timeout { get; set; } 300;[ConfigParameter(最小通讯周期ms)]public uint MinPeriod { get; set; } 3000;#endregionpublic SimTcpClient(Guid deviceId){DeviceId deviceId;}/// summary/// 判断连接状态/// /summarypublic bool IsConnected{get{//客户端对象不为空并且客户端已连接则返回truereturn client ! null client.TcpClient.Connected;}}/// summary/// 进行连接/// /summary/// returns连接是否成功/returnspublic bool Connect(){try{//进行连接client new SimpleTcpClient().Connect(IpAddress, Port);client.DataReceived Client_DataReceived;}catch (Exception){return false;}return IsConnected;}/// summary/// 收到服务端数据/// /summary/// param namesender/param/// param namee/paramprivate void Client_DataReceived(object? sender, Message e){//如果收到的数据校验正确则放在内存中if (e.Data.Length 8 e.Data[0] 0x08)latestRcvData e.Data;}/// summary/// 断开连接/// /summary/// returns断开是否成功/returnspublic bool Close(){try{client.DataReceived - Client_DataReceived;//断开连接client?.Disconnect();return !IsConnected;}catch (Exception){return false;}}/// summary/// 释放/// /summarypublic void Dispose(){try{//释放资源client?.Dispose();}catch (Exception){}}/// summary/// 发送数据/// /summaryprivate byte[] sendCmd new byte[4] { 0x01, 0x02, 0x03, 0x04 };/// summary/// 解析并返回/// /summary/// param nameioargioarg.Address为起始变量字节编号;ioarg.ValueType为类型/param/// returns/returns[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 TaskRpcResponse WriteAsync(string RequestId, string Method, DriverAddressIoArgModel Ioarg){RpcResponse rpcResponse new() { IsSuccess false, Description 设备驱动内未实现写入功能 };return rpcResponse;}}public enum ConnectionType{Long,Short}
}注册驱动生成DriverSimTcpClient 项目iotgateway\IoTGateway\bin\Debug\net6.0\drivers\net6.0路径下可以看到生成了DriverSimTcpClient.dll运行IoTGateway访问本地518端口添加驱动网关配置-驱动管理-添加注意:添加驱动后需要重启一下项目后面会优化创建设备采集配置-设备维护-添加设备 添加变量采集配置-设备维护-添加设备手动添加或者通过excel批量导入下面变量变量名方法地址类型表达式设备名运行状态Read1uint8模拟设备设备温度Read2float模拟设备电机转速Read6int16raw*0.01模拟设备开始采集采集配置-设备维护-编辑设备 启动TcpServer运行你熟悉的TCPServer测试工具启动端口6666网关客户端连接后发送响应报文查看数据