由于项目需求需要将传感器数据实时显示,而该屏只支持 ModBus 协议且板卡不支持设置为主站读取传感器数值显示。刚开始采用 Python 通过 TCP 的方式实现传输,但考虑实际场景并不能保证终端一直实时运行,于是便通过tb后台 + 规则链实现该功能。
执行流程
如若对其中名词含义不了解,请前往tb中文网或官网学习,这里不做展开。
将传感器传上来的遥测数据进行处理,过滤出需要的数值,然后构建RPC(全称叫做远程过程调用,是分布式系统中不同节点通信的一种流行的方式。)消息,再变化发起角色(需构建关联)为LED屏幕通过回调RPC给到LED屏幕接到串口服务器的com口,最终显示到LED屏幕。也可先根据手动进行调试后再进行自动更新配置。
环境需求
- 服务器(已通过docker部署在Ubantu)
- 若干485类型传感器
- 串口服务器(USR-N580)
- LED 屏幕(支持ModBus)
tb 服务器(Ubantu)
需修改后台配置文件(tb_gateway.json
)和添加LED屏幕配置文件(modbus_LED.json
),图中是已提前建立好CO2和O2,若LED屏幕配置正确,tb平台会出现LED sensor(与配置文件中的deviceName相同)需要注意的是串口服务器连接的com口。
修改 tb_gateway.json 文件
在tb_gateway.json
中需要添加LED屏的连接到串口服务器的参数,name 可自定义。
添加到如上图红框位置,注意上面花括号后有一个,
:
{
"name": "Modbus Connector7",
"type": "modbus",
"configuration": "modbus_LED.json"
}
添加 modbus_LED.json 文件
使用 touch 命令创建该文件。
此文件可不添加timeseries
遥测字段,本次LED的数据是通过RPC调用而来。至于其它字段可通过中文网了解。
{
"master": {
"slaves": [
{
"host": "192.168.1.100",
"port": 41,
"type": "tcp",
"method": "rtu",
"timeout": 35,
"byteOrder": "BIG",
"wordOrder": "BIG",
"retries": true,
"retryOnEmpty": true,
"retryOnInvalid": true,
"pollPeriod": 10000,
"unitId": 1,
"deviceName": "LED Sensor",
"sendDataOnlyOnChange": false,
"connectAttemptTimeMs": 5000,
"connectAttemptCount": 5,
"waitAfterFailedAttemptsMs": 300000,
"rpc": [
{
"tag": "sendIntValue",
"type": "16int",
"functionCode": 6,
"objectsCount": 1,
"address": 0
},
{
"tag": "sendPointFront",
"type": "16int",
"functionCode": 6,
"objectsCount": 1,
"address": 1
},
{
"tag": "sendPointBack",
"type": "16int",
"functionCode": 6,
"objectsCount": 1,
"address": 2
}
]
}
]
}
}
该文件具体含义如下:
具体配置过程需要查看相应LED屏幕手册文档,这里给出该屏幕样例:
保存以上两个文件之后,需重启一下后台,在登录平台即可看到LED屏幕已加入到tb设备列表。
docker restart LT-IOT-gateway
所有都需要进入配置文件夹,文件都是可读,如需修改可能需提权sudo
。
cd .tb-gateway/config/
此时登录平台即可看到LED屏幕已添加到设备列表中,名称就是刚刚我们填入到modbus_LED.json
文件中的deviceName字段里的内容。
LED 屏幕(需支持 ModBus)
各个厂家设置的板卡配置不同,如需请翻看对应文档修改为 ModBus 的通信方式。
通过厂家(ZkLED.exe)提供的上位机修改为 ModBus 方式通信即可,这里不做详细演示,只说明需要注意的事项:
-
高级数字时钟中设置自定义格式时%Rxxxx后的xxxx对应的就是我在
modbus_LED.json
文件中的address。%R(0~65535)换成%N(-32768~32767) 可以支持负数。 -
加入多条数据可能会出现第一行数据闪烁的情况,询问厂家解决办法是先添加后面的两行,在添加第一行。
-
显示小数需要使用两个寄存器,举例:
氧气:%R0000.%R0001 %%
tb平台:规则链
这里其实就是一个设备之间的联动性,需要在设备中先加入关联关系,这里以CO2举例,加入一条向外的数据。
类型可以自定义名称,但需要注意这个名称就是对应的触发这个向外的关联关系(转换角色发起者),说通俗点就是假设温度过高需要降温,然后触发风扇降温,那么这个降温就是他们之间的关联关系。关联关系可以同时触发多个。
建立完成后,此时配置规则链库中的规则链(信息的读取与控制),可先查看此时CO2的遥测数据是否上来,因为10s一次触发,可能在规则链中的数值会产生变化。
规则链的编写
脚本统一采用的 Java Script。创建完成后建议勾选调试模式,如下都在该模式下进行。
创建并选择一个规则链开始编写,这里我选择的是原有的iot:
过滤节点(filter)
把需要给到LED屏幕显示的数据过滤出来,这里只是一个简单示例做验证性,代码可根据需求更改:
稍等刷新,点击事件即可看到CO2的数据已经成功上来。
转换节点(transformation)-- 构建 RPC
确认有数据成功后,我们需要将这条信息里的数据重新组建一条rpc,这里就要对应上之前LED屏幕配置文件里RPC的调用方式。
代码如下:
var newMsg = {};
newMsg.method = 'sendIntValue';
newMsg.params = msg.CO2;
return {msg: newMsg, metadata: metadata, msgType: msgType};
转换节点(transformation)-- 变更发起者
点击查看中文文档的详细说明,这里不做过多赘述。
关联就是在之前建立好的关联关系(从CO2到LED屏幕),关系类型可自定义。这一目的是将LED屏幕变成发起者,若没有这一条包括关联关系会将我们上一条组装的RPC下发给所有的接入设备,我们需要指定给LED屏幕。
属性节点(Enrichment)
更新消息的数据信息,点击查看中文文档的详细说明。个人常用于测试判断数据源。
选择关系即可,可以获取消息发起者的字段值。
查看事件中的RPC的发送数据:
发送方式和参数与之前一致,随时间变化数字已改变。
外部节点(External)
成功后,直接向LED屏幕发送RPC显示。
同时LED屏幕数据也被更新,至此自动数据更新便以完成。
手动调试
准备环境
- ModBus Poll
- ThingBoard 仪表盘
- LED屏幕调成ModBus模式
ModBus Poll
LED屏幕的连接串口服务器的IP以及端口号:
ThingBoard 仪表盘
创建一个仪表盘,选择 Control widgets 添加 RPC部件,如黄色箭头所指:
添加完成以后,RPC方法采用modbus_LED.json
文件中所配置的RPC,保存应用后点击,如下图所示:
此时打开 Poll ,可以发现图中寄存器的值已更改。
这是变化后的值,01 ED(H) 转成十进制刚好对应上 493。
数据实时可能存在的问题
- 网络环境,如网卡。此时需要调整配置文件中
pollPeriod
,默认为 10s - 硬件要求,可减少适当设备调试。
- 使用 Poll 读寄存器时也会有一些丢包。
希望能解决您同样的问题与困惑,同时也愿和您共同学习、进步!
怎么回事吴总?这么久还不更新?
感谢关注,会催更,同时也会多多听取您的意见!
支持
已更新🤩
吴总,求更新
点赞
江董实力,还在关注穷酸书生。