驱动开发实战之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

参数说明

  1. 总字节数

    (byte[0])即0x08:用于简单的校验

  2. 运行状态

    (byte[1])即0x01:1为运行;其他为停止

  3. 设备温度

    (byte[2]-byte[5])即0x41 D6 3D 71:单精度浮点数值26.78

  4. 电机转速

    (byte[6]-byte[7])即0x1A 20:对应16进制无符号整型,倍率0.01值66.88

驱动开发

创建驱动项目

  1. 在解决方案->Drivers文件夹,右键添加->新建项目->C#类库 7c040849bf82883f7fb59fe3bdf69e88.png

  2. 项目名DriverSimTcpClient,放在iotgateway\Plugins\Drivers路径下 d908dbd43e5e2d9c4e4fe2f598e630fe.png

  3. 修改Class1SimTcpClient

  4. 双击项目,修改配置 21f1a4cc8347cf7032a294d40900712a.png

    iotgateway\Plugins\Drivers\DriverSimTcpClient\DriverSimTcpClient.csproj

    <Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net6.0</TargetFramework><OutputPath>../../../IoTGateway/bin/Debug/net6.0/drivers</OutputPath><CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies><ImplicitUsings>enable</ImplicitUsings><Nullable>enable</Nullable></PropertyGroup><ItemGroup><PackageReference Include="SimpleTCP.Core" Version="1.0.4" /></ItemGroup><ItemGroup><ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" /></ItemGroup>
    </Project>

说明:

OutputPath节点指定了生成项目的文件夹

SimpleTCP.Core是一个TCP客户端库(你也可以自己写)

ProjectReference节点引用了PluginInterface项目

CopyLocalLockFileAssemblies节点可以确保你引用的nuget拷贝到driver文件夹下 :::

编写项目代码:

iotgateway\Plugins\Drivers\DriverSimTcpClient\SimTcpClient.cs

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{/// <summary>/// tcp客户端/// </summary>private SimpleTcpClient? client;/// <summary>/// 缓存最新的服务器返回的原始数据/// </summary>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;/// <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>/// 判断连接状态/// </summary>public bool IsConnected{get{//客户端对象不为空并且客户端已连接则返回truereturn client != null && client.TcpClient.Connected;}}/// <summary>/// 进行连接/// </summary>/// <returns>连接是否成功</returns>public bool Connect(){try{//进行连接client = new SimpleTcpClient().Connect(IpAddress, Port);client.DataReceived += Client_DataReceived;}catch (Exception){return false;}return IsConnected;}/// <summary>/// 收到服务端数据/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Client_DataReceived(object? sender, Message e){//如果收到的数据校验正确,则放在内存中if (e.Data.Length == 8 && e.Data[0] == 0x08)latestRcvData = e.Data;}/// <summary>/// 断开连接/// </summary>/// <returns>断开是否成功</returns>public bool Close(){try{client.DataReceived -= Client_DataReceived;//断开连接client?.Disconnect();return !IsConnected;}catch (Exception){return false;}}/// <summary>/// 释放/// </summary>public void Dispose(){try{//释放资源client?.Dispose();}catch (Exception){}}/// <summary>/// 发送数据/// </summary>private byte[] sendCmd = new byte[4] { 0x01, 0x02, 0x03, 0x04 };/// <summary>/// 解析并返回/// </summary>/// <param name="ioarg">ioarg.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 Task<RpcResponse> WriteAsync(string RequestId, string Method, DriverAddressIoArgModel Ioarg){RpcResponse rpcResponse = new() { IsSuccess = false, Description = "设备驱动内未实现写入功能" };return rpcResponse;}}public enum ConnectionType{Long,Short}
}

注册驱动

  1. 生成DriverSimTcpClient 项目

    iotgateway\IoTGateway\bin\Debug\net6.0\drivers\net6.0路径下可以看到生成了DriverSimTcpClient.dll

  2. 运行IoTGateway,访问本地518端口

  3. 添加驱动

网关配置->驱动管理->添加

6e582cba306714982e65949ff3c7544e.png

注意:添加驱动后需要重启一下项目,后面会优化

创建设备

采集配置->设备维护->添加设备

 a19152f349a35b6c859afc64080d8b54.png

添加变量

采集配置->设备维护->添加设备

手动添加或者通过excel批量导入下面变量

变量名方法地址类型表达式设备名
运行状态Read1uint8
模拟设备
设备温度Read2float
模拟设备
电机转速Read6int16raw*0.01模拟设备

开始采集

采集配置->设备维护->编辑设备 cff95584ef6e2e4a7ba33dcabcb0dbb1.png

启动TcpServer

运行你熟悉的TCPServer测试工具,启动端口6666,网关客户端连接后发送响应报文

6806f1df7841dede03934362b512265f.png

查看数据

75938eafdf47e8d4581d61ae85d7d298.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/286442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php读取acc

<?PHP/*创建ADO连接*/$conn new COM("ADODB.Connection") or die ("ADO Connection faild.");$connstr "DRIVER{Microsoft Access Driver (*.mdb)}; DBQ" . realpath("DATUM/cnbt.mdb");$conn->Open($connstr);/*创建记录集查…

【遥感数字图像处理实验】Erdas版详细图文实验教程(8实验全)

文章目录1. 专栏简介2. 专栏地址3. 专栏目录1. 专栏简介 遥感数字图像的处理&#xff0c;是对遥感数字图像的计算机处理。与工业和医学数字图像不同&#xff0c;遥感数字图像类型更为多样&#xff0c;内容更为复杂。因此&#xff0c;遥感数字图像的处理&#xff0c;不仅需要掌握…

WEBAPI 增加身份验证 (OAUTH 2.0方式)

1&#xff0c;在Webapi项目下添加如下引用&#xff1a;Microsoft.AspNet.WebApi.OwinOwinMicrosoft.Owin.Host.SystemWebMicrosoft.Owin.Security.OAuthMicrosoft.Owin.Security.CookiesMicrosoft.AspNet.Identity.OwinMicrosoft.Owin.Cors2&#xff0c; 在项目下新建Startup类…

C语言试题二之计算并输出下列多项式值s=1+1/(1+2)+1/(1+2+3)+..1/(1+2+3…+50)

📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 计算并输出…

无代码iVX编程实现简单 小蜜蜂 经典游戏

首先咱们打开 iVX 的在线编辑器&#xff1a;https://editor.ivx.cn/ 随后选择相对定位&#xff0c;咱们选择2D游戏类型制作一个简单小蜜蜂游戏&#xff1a; 接着咱们创建一个物理世界&#xff0c;并且将页面布局如以下&#xff1a; 以上布局中&#xff0c;矩形为模拟飞机、…

【无人机航空摄影测量精品教程】目录:Pix4d、EPS、CC、PhotoScan、Godwork项目化作业流程及注意事项汇总

文章目录1. 专栏简介2. 专栏地址3. 专栏目录1. 专栏简介 该专栏为目前最为热门的无人机航测内外业项目&#xff0c;主要内容包括&#xff1a;无人机航测外业作业流程&#xff08;像控点布设、航线规划、仿地飞行、航拍&#xff09;和内业数据处理软件&#xff08;Pix4d、CC、EP…

WPF 基础控件之 Slider 样式

其他基础控件1.Window2.Button3.CheckBox4.ComboBox5.DataGrid 6.DatePicker7.Expander8.GroupBox9.ListBox10.ListView11.Menu12.PasswordBox13.TextBox14.RadioButton15.ToggleButtonSlider 实现下面的效果1&#xff09;Slider来实现动画&#xff1b;Grid嵌套 Border并设置S…

SQL 通过syscolumns.xtype动态查找指定数据类型字段所包含的数据

表中太多列&#xff0c;只想查找某些比如&#xff0c;数据类型为varchar的字段的数据。 思路&#xff1a;1、先获取列名&#xff1a; select * from syscolumns where id(select max(id) from sysobjects where xtypeu and nametest_A)2、查找指定数据类型&#xff0c;xtype就…

css案例学习之span边框实现的特殊效果

bottom left bottom right top left top right 配合颜色来使用&#xff0c;实现一些神奇的效果 #menu a span{height:0;width:0;/*border-top:solid 6px #fff;border-left:solid 6px #f90;*//*border-top:solid 6px #fff;border-right:solid 6px #f90;*//*border-bottom:solid …

网页版消消乐快速实现,无代码吗iVX 真那么简单?

最近没事想做个消消乐&#xff0c;然后听说 iVX 免费了&#xff0c;所以又跑去看看 iVX 了&#xff0c;就用一个无代码来看看消消乐怎么玩吧。 首先咱们打开 iVX 的在线编辑器&#xff1a;https://editor.ivx.cn/ 随后咱们不需要游戏类型也可以制作一个消消乐游戏&#xff1a…

虚拟化记录--No.1

近段时间&#xff0c;会花些时间做关于系统虚拟化的工作。所以会做一些这样的记录。相信很多东西不会特别成体系&#xff0c;每个人因为关注的不同而记录和学习的重点也会有比较大的出入。这篇是NO.1(注意不是TOP 1 )真的是由于对于ORACLE很有感觉&#xff0c;所以上手去做的也…

C语言试题三之计算并输出 s=1+(1+2^(0.5))+(1+2^(0.5)+3^(0.5))+…+(1+2^(0.5)+3^(0.5)+…+n^(0.5))

📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1 、题目 请编写函…

C# Java间进行RSA加密解密交互

这里&#xff0c;讲一下RSA算法加解密在C#和Java之间交互的问题&#xff0c;这两天纠结了很久&#xff0c;也看了很多其他人写的文章&#xff0c;颇受裨益&#xff0c;但没能解决我的实际问题&#xff0c;终于&#xff0c;还是被我捣鼓出来了。 首先&#xff0c;介绍一下写这代…

【Microstation】三维建模基础及软件入门到精通实验教程目录

文章目录1. 专栏简介2. 专栏地址3. 专栏目录1. 专栏简介 MicroStation是一款非常不错的二维和三维设计软件&#xff0c;由奔特力&#xff08;Bentley&#xff09;工程软件系统有限公司开发的一款软件。在CAD设计上该软件是和AutoCAD是齐名的软件&#xff0c;其专用的文件格式是…

无代码iVX编程实现简单魂斗罗

首先咱们打开 iVX 的在线编辑器&#xff1a;https://editor.ivx.cn/ 随后咱们选择2D游戏类型制作一个简单魂斗罗游戏&#xff1a; 随后咱们开始创建一个物理世界&#xff0c;不并且在物理世界之下创建一个一个图片添加物体属性&#xff0c;在物体属性中更改对应的属性内容&am…

【ArcGIS遇上Python】ArcGIS Python批处理入门到精通实用教程目录

文章目录1. 专栏简介2. 专栏地址3. 专栏目录1. 专栏简介 Python语言是目前很火热的语言&#xff0c;极大的促进了人工智能发展。你知道在ArcGIS中也会有python的身影吗&#xff1f;事实上&#xff0c;在ArcGIS中使用Python会起到事半功倍的效果&#xff0c;大大提高工作效率&am…

Android之提示javax.net.ssl.SSLHandshakeException: Chain validation failed

1、问题 个别手机用OkDownload下载Bilibili网址视频的时候下载失败,但是大部分手机下载没问题。 在继承的DownloadListener4WithSpeed类的重写taskEnd函数里面。 override fun taskEnd(task: DownloadTask, cause: EndCause, realCause: Exception?, taskSpeed: SpeedCalcu…

c# XML和实体类之间相互转换(序列化和反序列化)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Data; using System.Xml; using System.Xml.Serialization; /// <summary>/// Xml序列化与反序列化/// </summary>public class XmlUtil {…

深入探究MinimalApi是如何在Swagger中展示的

前言之前看到技术群里有同学讨论说对于MinimalApi能接入到Swagger中感到很神奇,加上Swagger的数据本身是支持OpenApi2.0和OpenApi3.0使得swagger.json成为了许多接口文档管理工具的标准数据源。ASP.NET Core能够轻松快速的集成Swagger得益于微软对OpenApi的大力支持&#xff0c…

语句的输入、输出

一、C#基础 1、项目后缀&#xff1a; .config——配置文件&#xff08;存放配置参数文件&#xff09; .csproj——项目文件&#xff08;管理文件项&#xff09; .sln——解决方案文件&#xff08;管理项目&#xff09; .cs——源文件&#xff08;程序代码&#xff09; 2、函数四…