扩展!为 Zabbix 增加动环能力 —— 以 Modbus 采集温湿度为例
Zabbix Agent 主机变身 FSU,可以通过 RS485 以 Modbus 协议读取温湿度,充分扩展 Zabbix 的动环监控能力。
工作原理
串口读 Modbus 协议数据,将其写入 Redis 中,Zabbix Server 请求 Zabbix Agent 读 Redis 中数据。引入 Redis 主要为了解耦,避免多个进程同时读串口造成冲突。
这里 Zabbix Agent 作为 Modbus RTU 主站,每个传感器作为一个单独的 Modbus RTU 从站,在一条 485 总线上,站号唯一,所以主站可以通过轮询的方式向从站读取数据。
材料准备
硬件准备
- 树莓派或其他开发板,甚至是 x86 工控机,只要有多路串口就行(我以树莓派 3B+为例)
- RS485 温湿度模组(我以 2 个模组为例)
- TTL 转 485 转接板(树莓派默认是 TTL 电平,需要转换成 485 电平)
- USB 转 485 调试器(主要方便调试)
- 线缆若干,485 通信线建议为双绞线
软件准备
- 树莓派系统选择 RPIOS,即为 Debian11
- 安装 Zabbix Agent 6.0 LTS
- 安装 Redis
传感器配置
使用 USB 转 485 模块直连传感器,方便刷写 485 站号和做简单的功能验证。
对单个传感器刷写站号,根据我买到的传感器文档中定义,传感器的 485 站号是存在地址为 10 的保持寄存器中的。需要特殊标记每个传感器的站号,需要根据站号采集温湿度值。
根据 Modbus 协议,写保持寄存器的功能码是 0x06,我们可以使用 Modbus 调试工具使用该功能码写保持寄存器来刷写站号。
继续读文档,根据文档定义,传感器的温湿度数据保存在只读的输入寄存器中,寄存器起始地址为 0 长度为 2,且实际值=寄存器值*0.1。
根据 Modbus 协议,读输入寄存器的功能码是 0x04,这个功能码和寄存器我们后面写串口通讯程序时要用到,所以应该提前关注一下。
下面可以连线了,如图连接即可。
树莓派的 4 引脚为 5V+ 接 TTL 转 485 的 VCC 脚,5 引脚为 GND 接 TTL 转 485 的 GND 脚。8 为串口 TXD 接 TTL 转 485 的 RXD 脚,10 为串口 RXD 接 TTL 转 485 的 TXD 脚。
TTL 转 485 的 AB 和 GND 接法,GND 接传感器 GND,A+接传感器 A+,B+接传感器 B+,传感器的 VCC 从 TTL 转 485 的 VCC 引脚取电。
额外提一下:若 485 总线过长,需要在总线起点、终点应加终端电阻(120Ω)。485 长度可以达到 2km,但测点线要小于 1m(布线不规范,会造成通讯不稳定)。下图红色线为总线,绿色线为测点线。当系统中测点大于 30 个点时,考虑到总线驱动能力,建议每 20 点增加一个中继器,进行信号增强。
树莓派配置
禁用 wifi 和蓝牙串口
vim /boot/config.txt,增加以下配置项目。重启后生效。
1 | dtoverlay=pi3-disable-wifi |
这样的操作主要是为了避免蓝牙和 Wifi 影响板载串口。
安装 redis
可参考 redis 官方手册进行安装。
1 | curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg |
使用 redis-cli 登录,发送 ping,系统回复 pong,则 redis 服务正常。
安装 python 依赖
1 | pip install serial redis modbus_tk |
脚本编写
编写一个程序,轮询读取 Modbus 数据并存储到 redis 中,正常应该能打印出两个温湿度模块的温湿度值,并且可以通过 redis-cli 中的 get 方法提取到传感器值。
文中注释和提示请根据实际情况进行修改。
1 | import serial |
编写 dht-read 脚本,从 redis 中读温湿度值,将其另存在树莓派中,文件名为 /etc/zabbix/scripts/dht-read.py。
1 | import sys |
Zabbix 配置
启动采集进程。若需要开启启动可加入 /etc/rc.local 中。
1 | nohup /usr/bin/python /home/pi/dht-modbus/main.py |
配置自定义监控项,修改 zabbix_agentd.conf,增加以下配置项目。
1 | UnsafeUserParameters=1 |
重启 zabbix_agent。
正常情况,我们可以通过 zabbix_get 命令远程读取传感器的值。
1 | zabbix_get -s RPI-FSUIP -p 10050 -k 'dht.read[type,site]' |
这里 RPI-FSUIP 是树莓派的 IP,type 可选 temperature,humidity,site 为 485 站号。
在 ZabbixWeb 中,将树莓派增加为主机,接口为客户端。
添加自定义监控项。类型为客户端,信息类型为浮点数,键值类似于 dht.read[type,site]。type 可选 temperature,humidity,site 为 485 站号。
效果展示
添加完毕效果:
历史数据视图效果:
Next
下一步会继续集成烟感、漏水等传感器。