首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >SNMP协议采集以太网温湿度变送器:数据读取与OID调试实战

SNMP协议采集以太网温湿度变送器:数据读取与OID调试实战

原创
作者头像
盛世宏博科技
发布于 2026-10-12 09:35:08
发布于 2026-10-12 09:35:08
280
举报

SNMP协议采集以太网温湿度变送器:数据读取与OID调试实战

物联网 · 盛世宏博 · 以太网温湿度变送器、SNMP采集、OID调试、数据读取

近期在调试一套工业环境监控系统时,遇到了关于Modbus连接保持的问题。这次接手的是一批已上线两年的以太网温湿度变送器,客户要求从原有Modbus TCP采集切到SNMP,理由是运维团队习惯用Zabbix做全网设备监控,希望温湿度也进同一套体系。设备厂家给了一份MIB文件,但OID注释写得像天书,snmpwalk跑出来一堆十六进制,读不出可读的温度值。这篇从零讲清楚以太网温湿度变送器的SNMP数据读取、OID定位、类型解码和调试过程,适合第一次接触这类设备的人照着做。


一、设备与协议基础

项目

详情

设备

以太网温湿度变送器(网口,支持SNMP v1/v2c)

数量

24台,同网段192.168.90.0/24

SNMP配置

community:只读public,读写private(默认未改)

MIB厂商OID段

.1.3.6.1.4.1.39812

管理工具

snmpwalk / snmpget / Wireshark / Zabbix

目标

读出温度、湿度、露点、设备状态、在线时长

SNMP在温湿度设备里的定位

很多工程师习惯把以太网温湿度变送器当Modbus设备用,其实它内置了精简SNMP Agent:

  • 标准系统组(sysDescr、sysUpTime等)
  • 厂商私有MIB(温度/湿度/露点等)
  • 支持GET/GETNEXT/GETBULK/WALK
  • 走UDP 161端口,无连接、轻量

二、第一步:确认SNMP可达性

先别急着读OID,先把链路打通。

代码语言:javascript
复制
# 1. 看设备是否响应SNMP
snmpget -v 2c -c public 192.168.90.11 sysName.0

# 2. 看设备描述
snmpget -v 2c -c public 192.168.90.11 sysDescr.0

# 3. 看运行时间
snmpget -v 2c -c public 192.168.90.11 sysUpTime.0

预期返回示例:

代码语言:javascript
复制
SNMPv2-MIB::sysName.0 = STRING: TH-RJ45-011
SNMPv2-MIB::sysDescr.0 = STRING: SHHB Ethernet TH Sensor v2.5
SNMPv2-MIB::sysUpTime.0 = Timeticks: (12345678) 1 day, 10:17:36.78

💡 如果这里超时,先查:设备SNMP是否开启、community是否对、防火墙是否放通UDP 161、网段是否同广播域。


三、OID定位:从MIB文件到可用叶子节点

3.1 加载MIB还是直接跑walk?

两种路线都可用,新手建议先walk全树看结构:

代码语言:javascript
复制
snmpwalk -v 2c -c public 192.168.90.11 .1.3.6.1.4.1.39812

返回片段:

代码语言:javascript
复制
...39812.1.1.1.1.0 = INTEGER: 2235
...39812.1.1.1.2.0 = INTEGER: 5120
...39812.1.1.1.3.0 = INTEGER: 5088
...39812.1.1.1.4.0 = INTEGER: 1
...39812.1.1.1.5.0 = Timeticks: (9876543) 1 day, 3:25:45.43

3.2 对照MIB注释还原含义

厂家MIB里是这样写的(整理后):

OID

名称

类型

换算方式

.1.3.6.1.4.1.39812.1.1.1.1.0

thTemp

INTEGER

值×0.01 = ℃

.1.3.6.1.4.1.39812.1.1.1.2.0

thHumidity

INTEGER

值×0.01 = %RH

.1.3.6.1.4.1.39812.1.1.1.3.0

thDewPoint

INTEGER

值×0.01 = ℃

.1.3.6.1.4.1.39812.1.1.1.4.0

thStatus

INTEGER

1=正常,2=温度告警,3=湿度告警

.1.3.6.1.4.1.39812.1.1.1.5.0

thUpTime

TimeTicks

设备运行时间

3.3 读一个温度值的完整命令

代码语言:javascript
复制
snmpget -v 2c -c public 192.168.90.11 .1.3.6.1.4.1.39812.1.1.1.1.0
# 返回:INTEGER: 2235
# 实际温度 = 2235 × 0.01 = 22.35℃

四、数据类型解码实战

这是新手最容易懵的地方,SNMP返回的不是字符串温度,是ASN.1编码后的数值。

4.1 常见类型对照

ASN.1类型

SNMP显示

处理方式

INTEGER

INTEGER: 2235

按缩放系数换算

OCTET STRING

Hex-STRING: 00 1A 2B...

可能是MAC或二进制结构

TimeTicks

Timeticks: (xxx)

百分之一秒,÷100转秒

Gauge32

Gauge32: 5120

无符号,同缩放

OBJECT IDENTIFIER

OID: ...

引用其他对象

4.2 温度解码示例(Python)

代码语言:javascript
复制
def decode_temp(raw_int):
    # 厂商约定 ×0.01
    return round(raw_int * 0.01, 2)

# 2235 -> 22.35
print(decode_temp(2235))

4.3 十六进制字符串处理

部分老固件把序列号放在OCTET STRING里:

代码语言:javascript
复制
snmpget -v 2c -c public 192.168.90.11 .1.3.6.1.4.1.39812.1.1.2.1.0
# Hex-STRING: 53 48 48 42 2D 30 30 31 31
# 转ASCII = "SHHB-0011"

五、OID调试踩坑实录

坑1:MIB里写的是表,实际是标量

现象:MIB文档写thTempTable,按表索引读.1.1.1.1.1返回空。

原因:单探头设备把表退化成标量,叶子挂在.0上,不是行索引1。

解法:直接读.0结尾的OID,不用带行号。用walk确认实际结构再写采集项。


坑2:温度返回负数变成超大正数

现象:冷通道某点实际8℃,snmpget返回INTEGER: 65432。

原因:老固件用UINT16存温度,负数按补码转成了无符号,没做符号还原。

解法:

代码语言:javascript
复制
def decode_signed_temp(v, scale=0.01):
    if v > 32767:
        v -= 65536
    return round(v * scale, 2)
# 65432 -> 65432-65536 = -4 -> -0.04℃(结合场景判定为8℃附近需核对固件手册)

⚠️ 实际项目中遇到此问题后,联系厂家确认该批次固件其实是INT16,只是pysnmp默认按unsigned解析,强制指定类型即可。


坑3:snmpwalk返回OID顺序乱

现象:walk出来顺序不是MIB文档顺序,调试时以为漏了节点。

原因:SNMP按OID字典序返回,不是按MIB书写顺序;子树嵌套深时会穿插。

解法:用sort -V或程序按数值排序,或直接指定具体叶子OID读取,不依赖walk顺序。


坑4:community写错成private导致只读项也超时

现象:用private读温度,部分设备返回NoSuchObject,部分超时。

原因:设备对private配置了写权限限制+ACL,只允许特定源IP,普通采集机不在白名单。

解法:只读数据统一用public,写操作单独走白名单源IP+private。


坑5:Wireshark里看得到请求,设备无响应

现象:抓包显示GET请求发出,无Response。

原因:

  1. 设备SNMP绑定了特定管理IP(只响应网关地址)
  2. 或交换机ACL拦截了非管理网段的UDP 161

解法:

  • Wireshark过滤:snmp || udp.port==161
  • 核对设备“SNMP源地址白名单”
  • 交换机放行采集机到设备段的UDP 161

坑6:GETBULK把整棵私有树拉爆

现象:对.1.3.6.1.4.1.39812做GETBULK设max-repetitions=20,返回几KB数据还包含固件版本字符串、网卡统计等无关项。

解法:GETBULK起始OID精确到.1.3.6.1.4.1.39812.1.1.1,只拉温湿度子树,max-repetitions=5足够。


六、接入Zabbix的落地配置

配置项

值

模板

SNMPv2c设备模板(自定义)

Key示例

sensor.temp[192.168.90.11]

OID

.1.3.6.1.4.1.39812.1.1.1.1.0

预处理

乘0.01

更新间隔

30s

社区

public

触发器

temp>24

Zabbix预处理示例

代码语言:javascript
复制
步骤1:提取INTEGER数值
步骤2:自定义乘数 0.01
步骤3:单位标注 ℃

七、标准读取流程清单(可照抄)

代码语言:javascript
复制
1. ping通设备,确认同网段
2. snmpget读 sysDescr.0 验证Agent存活
3. snmpwalk厂商OID前缀,定位叶子节点
4. 对照MIB文档确认类型与缩放系数
5. 单点snmpget读温度OID,手算验证(如2235→22.35℃)
6. Wireshark抓包核对请求/响应结构
7. 写Zabbix/平台采集项,加预处理换算
8. 跑24小时比对同点位Modbus读数,偏差≤0.2℃即通过

实测交叉验证(同设备双协议对比)

点位

Modbus TCP

SNMP v2c

偏差

机柜前11

22.35℃

22.35℃

0

机柜后11

28.12℃

28.11℃

0.01℃

冷通道顶

19.84℃

19.83℃

0.01℃


八、调试工具组合建议

场景

工具

用法

快速验证

snmpget

单OID读取

摸结构

snmpwalk

遍历子树

批量拉取

snmpbulkget

同子树多叶子

抓包分析

Wireshark(过滤snmp)

看PDU结构、社区名、错误状态

平台接入

Zabbix/NMS

生产级轮询

脚本解码

Python + pysnmp/aiosnmp

工程化采集


九、关键经验

  1. 先通链路再读OID,sysDescr.0是最好用的“Hello World”。
  2. 厂商MIB文档不可全信,以snmpwalk实际返回结构为准,尤其注意标量挂.0还是表索引。
  3. 温度类数值几乎都是INTEGER×0.01,负数要注意有符号/无符号解析差异。
  4. Wireshark是排查“无响应”的终极手段,过滤snmp一眼看请求有没有回包。
  5. 只读用public、写用private且绑IP,别混用社区名。
  6. GETBULK要收着用,起始OID精确到业务子树,不然拉出一堆无关节点还占带宽。
  7. 切SNMP前用Modbus同点对比24小时,是验收时最硬的交叉验证证据。

十、关键词

以太网温湿度变送器、SNMP采集、OID调试、snmpwalk、snmpget、GETBULK、MIB解析、数据解码、Zabbix接入、Wireshark抓包、Modbus交叉验证、工业物联网

物联网 #SNMP #温湿度监测 #以太网变送器 #OID调试 #snmpwalk #Zabbix #Wireshark #MIB #工业物联网 #数据采集 #环境监测

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、设备与协议基础
    • SNMP在温湿度设备里的定位
  • 二、第一步:确认SNMP可达性
  • 三、OID定位:从MIB文件到可用叶子节点
    • 3.1 加载MIB还是直接跑walk?
    • 3.2 对照MIB注释还原含义
    • 3.3 读一个温度值的完整命令
  • 四、数据类型解码实战
    • 4.1 常见类型对照
    • 4.2 温度解码示例(Python)
    • 4.3 十六进制字符串处理
  • 五、OID调试踩坑实录
    • 坑1:MIB里写的是表,实际是标量
    • 坑2:温度返回负数变成超大正数
    • 坑3:snmpwalk返回OID顺序乱
    • 坑4:community写错成private导致只读项也超时
    • 坑5:Wireshark里看得到请求,设备无响应
    • 坑6:GETBULK把整棵私有树拉爆
  • 六、接入Zabbix的落地配置
    • Zabbix预处理示例
  • 七、标准读取流程清单(可照抄)
    • 实测交叉验证(同设备双协议对比)
  • 八、调试工具组合建议
  • 九、关键经验
  • 十、关键词
  • 物联网 #SNMP #温湿度监测 #以太网变送器 #OID调试 #snmpwalk #Zabbix #Wireshark #MIB #工业物联网 #数据采集 #环境监测
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档