首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >基于腾讯云 IoT Explorer 的 POE 网口温湿度传感器接入:物模型与属性上报实践

基于腾讯云 IoT Explorer 的 POE 网口温湿度传感器接入:物模型与属性上报实践

原创
作者头像
BJ盛世宏博小程
发布于 2026-09-22 13:19:56
发布于 2026-09-22 13:19:56
1710
举报

基于腾讯云 IoT Explorer 的 POE 网口温湿度传感器接入:物模型与属性上报实践

一、场景与架构

现场:跨城多机房/库房,每个机房部署 PoE 网口温湿度变送器(RJ45,Modbus TCP),机房内已有内网和 PoE 交换机。目标:统一接入腾讯云 IoT Explorer,集中监控、告警、可视化。

关键决策:传感器不直接暴露公网,边缘网关收敛协议后上云。

代码语言:javascript
复制
PoE交换机 ── Modbus TCP ──> 边缘网关(机房内)
                              │
                  MQTT over TLS (8883)
                              ▼
                  腾讯云 IoT Explorer
                      │ 规则引擎
                      ▼
             云函数/CKafka → CTSDB/InfluxDB → 云图/Grafana

为什么不直接让设备连云:

  • 工业以太网温湿度传感器原生跑 Modbus TCP/SNMP,无 MQTT/TLS 栈
  • 跨城内网出口 NAT,无公网 IP,被动监听 Trap 不友好
  • 边缘侧做缓存、补传、本地联动,断网不影响现场告警

二、设备侧准备

1. 传感器配置

  • IP:机房内网 VLAN,静态分配,如 192.168.10.10/24
  • 端口:502 Modbus TCP
  • PoE:802.3af/at,交换机 PoE 池留余量(单台峰值 3–4W,按 15W 端口预算更稳)
  • 寄存器表(以常见产品为例,务必向厂家索取确认):
    • 40001 温度 INT16,实际值/10
    • 40002 湿度 INT16,实际值/10
    • 40003 状态字:bit0 传感器故障,bit1 越上限,bit2 越下限,bit3 本地告警输出
    • 40101 高温阈值 INT16 /10,40102 高湿阈值 INT16 /10(可选写回)

2. 边缘网关

  • 硬件:无风扇工业 ARM/x86 小机,双网口或单网口+管理网段
  • 软件:Python 3.10+,pymodbus、paho-mqtt、systemd 托管
  • 出网:仅需 TLS 长连接至 IoT Explorer,安全组/防火墙放行出站 8883

三、IoT Explorer 侧配置

1. 创建产品

  • 控制台 → 物联网开发平台 → 新建项目/产品
  • 节点类型:网关子设备​ 否;此处边缘网关作为直连设备,传感器作为"逻辑子设备"由网关代发,或把每个机房抽象为一个设备
  • 更实用做法:每个边缘网关 = 一个直连设备(DeviceName=gw-room-xxx),payload 内带 room_id/sensor_id;也可为每个传感器创建虚拟子设备,复杂度更高。本文采用前者。

产品信息:

  • 认证方式:密钥认证(设备级 PSK)或证书。批量部署推荐密钥+动态注册,或预创建设备名+PSK 下发
  • 数据协议:数据模板(物模型)JSON,通过 MQTT 主题 $thing/up/property

2. 物模型定义

腾讯云数据模板(TSL)描述在控制台 GUI 填写,导出后如下(精简):

代码语言:javascript
复制
{
  "version": "1.0",
  "properties": [
    { "id": "temperature", "name": "温度", "define": { "type": "float", "min": "-40", "max": "85", "step": "0.1", "unit": "°C" } },
    { "id": "humidity", "name": "湿度", "define": { "type": "float", "min": "0", "max": "100", "step": "0.1", "unit": "%RH" } },
    { "id": "sensor_status", "name": "传感器状态", "define": { "type": "enum", "mapping": { "0": "正常", "1": "故障", "2": "离线", "3": "越限" } } },
    { "id": "power_voltage", "name": "供电电压", "define": { "type": "float", "min": "9", "max": "36", "step": "0.1", "unit": "V" } },
    { "id": "room_id", "name": "机房编号", "define": { "type": "string", "len": 64 } },
    { "id": "last_collect_ts", "name": "采集时间戳", "define": { "type": "int64", "unit": "ms" } }
  ],
  "events": [
    { "id": "temp_high_alarm", "name": "温度高告警", "type": "alert", "params": [
        { "id": "value", "define": { "type": "float" } },
        { "id": "threshold", "define": { "type": "float" } }
    ]},
    { "id": "humidity_high_alarm", "name": "湿度高告警", "type": "alert", "params": [
        { "id": "value", "define": { "type": "float" } }
    ]},
    { "id": "sensor_offline", "name": "传感器离线", "type": "alert", "params": [
        { "id": "sensor_id", "define": { "type": "string" } }
    ]}
  ],
  "actions": []
}

注意点:

  • Explorer 数据模板枚举 mapping 键为字符串;上报时传数值或字符串以 SDK/协议为准,建议统一上报数值,控制台映射显示
  • 多传感器机房:属性上报聚合值(平均/主备),或扩展属性 sensors 用自定义透传。数据模板不支持嵌套数组时,两种办法:
    • 扁平化:temp_s1,humi_s1,temp_s2,humi_s2
    • 走事件/自定义Topic上报原始JSON,规则引擎解析后写存储
  • 本文走标准属性通道 + 扩展 Topic 补充明细。

3. 设备接入参数

  • Broker:${ProductID}.iotcloud.tencentdevices.com,端口 8883
  • ClientID:${ProductID}${DeviceName}
  • Username:${ProductID}${DeviceName};${SignMethod}
  • Password:HMAC-SHA256(connId, expiry, SK) 签名,或用 SDK 封装。Python 侧推荐 tencent-iot-explorer-sdk 或直接 paho + 手动签名。

手动签名要点:

  • connId 任意,expiry 0 表示长期
  • signContent = deviceName=${DeviceName}&productId=${ProductID}&expiry=${expiry}&nonce=${nonce}
  • sign = HMAC-SHA256(deviceSecret, signContent),base64
  • password 串格式见官方文档,别拼错分隔符

省事做法:用官方 Python SDK qcloud_iot_explorer(或 C-SDK 封装),避免手误。

四、边缘网关代码实践

1. 采集 + 上报主循环

代码语言:javascript
复制
import time, json, logging
from pymodbus.client import ModbusTcpClient
import paho.mqtt.client as mqtt
from hashlib import sha256
import hmac, base64, os

PRODUCT_ID = os.environ["PRODUCT_ID"]
DEVICE_NAME = os.environ["DEVICE_NAME"]
DEVICE_SECRET = os.environ["DEVICE_SECRET"]
BROKER = f"{PRODUCT_ID}.iotcloud.tencentdevices.com"
PORT = 8883
CA_FILE = "root.ca.pem"   # 腾讯云根证书或Amazon CA1可用,按文档
SENSORS = [{"id": "s1", "ip": "192.168.10.10", "port": 502, "unit": 1}]
ROOM_ID = os.environ.get("ROOM_ID", "room-default")
REPORT_INT = 15.0

def sign_password():
    # 简化:使用腾讯云推荐的密钥认证方式,paho_tls_set + username/password
    # 实际部署建议用SDK;此处给手动构造示例
    conn_id = "edgegw"
    expiry = 0
    nonce = str(int(time.time()))
    sign_content = f"deviceName={DEVICE_NAME}&productId={PRODUCT_ID}&expiry={expiry}&nonce={nonce}"
    raw = hmac.new(DEVICE_SECRET.encode(), sign_content.encode(), sha256).digest()
    sig = base64.b64encode(raw).decode()
    username = f"{DEVICE_NAME};hmacsha256"
    password = f"{sig}"
    return username, password

client = mqtt.Client(client_id=f"{PRODUCT_ID}{DEVICE_NAME}", transport="tcp")
client.tls_set(ca_certs=CA_FILE, cert_reqs=2)
uname, pwd = sign_password()
client.username_pw_set(uname, pwd)
client.connect_async(BROKER, PORT, keepalive=60)

# Explorer 属性上报主题
UP_TOPIC = f"$thing/up/property/{PRODUCT_ID}/{DEVICE_NAME}"
DOWN_TOPIC = f"$thing/down/property/{PRODUCT_ID}/{DEVICE_NAME}"

def on_connect(c, u, f, rc):
    logging.info("connected %s", rc)
    c.subscribe(DOWN_TOPIC)
    # 上线后上报一次
    report()

def read_sensor(s):
    c = ModbusTcpClient(host=s["ip"], port=s["port"], timeout=1.0)
    try:
        if not c.connect():
            return None
        r = c.read_holding_registers(0, 3, unit=s["unit"])
        if r.is_error():
            return None
        temp = r.registers[0]/10.0
        humi = r.registers[1]/10.0
        status_word = r.registers[2]
        return temp, humi, status_word
    finally:
        c.close()

def build_payload():
    temps, humis, st = [], [], 0
    sensor_status = 0
    last_ts = int(time.time()*1000)
    detail = []
    for s in SENSORS:
        d = read_sensor(s)
        if d is None:
            sensor_status = 2  # 离线
            detail.append({"sensor_id": s["id"], "status": "offline"})
            continue
        t, h, sw = d
        temps.append(t); humis.append(h)
        if sw & 0x1: sensor_status = 1
        detail.append({"sensor_id": s["id"], "temperature": t, "humidity": h, "sw": sw})
    payload = {
        "method": "report",
        "clientToken": f"{DEVICE_NAME}-{int(time.time())}",
        "params": {
            "temperature": round(sum(temps)/len(temps), 1) if temps else 0.0,
            "humidity": round(sum(humis)/len(humis), 1) if humis else 0.0,
            "sensor_status": sensor_status,
            "room_id": ROOM_ID,
            "last_collect_ts": last_ts
        }
    }
    # 扩展明细走自定义topic或事件,此处附在property下行调试用event上报
    return payload, detail

def report():
    payload, detail = build_payload()
    client.publish(UP_TOPIC, json.dumps(payload), qos=1)
    # 可选:上报事件
    evt = {"method": "event_post", "clientToken": payload["clientToken"],
           "params": {"sensors_detail": detail}}
    client.publish(f"$thing/up/event/{PRODUCT_ID}/{DEVICE_NAME}", json.dumps(evt), qos=1)

def loop():
    while True:
        try:
            if client.is_connected():
                report()
        except Exception as e:
            logging.warning("report err %s", e)
        client.loop_start()
        time.sleep(REPORT_INT)

if __name__ == "__main__":
    client.on_connect = on_connect
    client.loop_start()
    while True:
        time.sleep(1)

注意:

  • paho v2 API 有变更,CallbackAPIVersion 需适配;上面为示意,生产用 SDK 或更健壮封装
  • read_holding_registers(0,3) 对应协议地址 40001 起;pymodbus 默认地址=寄存器号-1,即 0 开始。以厂家点表核对
  • 多传感器时做采集超时隔离,别因一台阻塞拖垮整轮
  • 本地缓存:上报失败时在本地 SQLite/RocksDB 缓冲,重连后续传;Explorer 侧用规则引擎落地,断网期间平台侧显示最后影子值

2. 下行控制(可选)

控制台/云API改阈值、远程复位继电器:

  • 订阅 $thing/down/property 收到期望属性,网关解析后写 Modbus 保持寄存器(40101/40102)或触发 DO
  • 回复 $thing/up/property 带 reported,完成闭环

五、数据流转与存储

1. 规则引擎转发

Explorer 控制台 → 规则引擎 → 创建规则:

  • 数据源:设备上报属性消息
  • 转发目标:云函数 SCF / CKafka / 第三方 HTTP
  • 推荐:转发至 CKafka,消费侧写入时序库;或直接 SCF 桥接 InfluxDB/CTSDB

示例 SCF(Python)伪代码:

代码语言:javascript
复制
def main(event, context):
    for msg in parse_kafka_or_direct(event):
        dev = msg["deviceName"]
        props = msg["payload"]["params"]
        point = {
          "measurement": "env",
          "tags": {"room": props.get("room_id"), "dev": dev},
          "fields": {
             "temp": props["temperature"],
             "humi": props["humidity"],
             "status": props["sensor_status"]
          },
          "time": props.get("last_collect_ts", int(time.time()*1000))
        }
        write_influx(point)   # influxdb-client v2
    return "ok"

2. 时序库选型

  • 腾讯云 CTSDB(Prometheus 兼容/OpenTSDB 协议)或自建 InfluxDB v2
  • 保留策略:高频机房 15s 粒度留 30d,降采样后留 1y
  • 边缘侧已聚合,云侧别再高频写;按机房维度批量

六、告警与可视化

  • Explorer 控制台配置告警规则(属性阈值),推企业微信/短信/电话
  • 更灵活:Flux 任务或外部规则引擎消费 Kafka,去抖 debounce 后通知
  • 云图 DataV / Grafana 面板:机房地图下钻,实时值+历史曲线+离线状态
  • 边缘联动:网关本地判断阈值,触发继电器开除湿机/空调,断网时仍动作;云侧告警为二次通知

七、部署与运维

  • systemd unit 托管网关进程,Watchdog 重启
  • NTP 校时,避免时序库时间错乱
  • 配置管理:Ansible/CloudInit 批量下发 DeviceName+PSK,避免逐台手敲
  • OTA:网关容器化,镜像仓库拉取更新;传感器固件由厂家工具本地升,不进云通道
  • 诊断:tcpdump on edge, Wireshark 回传 pcap;Explorer 日志服务查设备在线/消息轨迹

八、常见坑

  • Topic 拼错:Explorer 用 $thing/up/property/{ProductID}/{DeviceName},注意 ProductID 是大写字母+数字,别带产品名
  • TLS CA:腾讯云 IoT 用根证书校验,paho tls_set 需传 CA bundle,否则 ssl handshake fail
  • 密码签名:手动构造易错,建议用 SDK 或预签名脚本离线生成后注入 secrets manager
  • Modbus 单位号:很多设备 unit=1,但有的默认 255,先 modpoll 验证
  • 多机房同 DeviceName:必须唯一,否则影子互相覆盖;建议 gw-<city>-<room>
  • QoS 与离线消息:Explorer 不支持保留消息,断网期间上报需在边缘缓存,上线后补发
  • PoE 掉电恢复:交换机 PoE 重启后设备获 IP 慢,网关重连逻辑要等 DHCP+DNS,加退避
  • 属性频率限流:Explorer 有限流,上报间隔别低于 1s,15–60s 工程够用

九、小结

接入本质是把工业以太网传感器经边缘网关转成 IoT Explorer 数据模板属性流。物模型别过度设计,聚合上报 + 事件补明细;边缘侧保活、缓存、本地联动,云侧做汇聚、存储、告警、可视化。批量部署时,配置注入和运维通道比单点联通更重要。


物联网 #Modbus #TCP/IP #UDP #POE供电 #腾讯云 #Wireshark #Python #InfluxDB #以太网温湿度传感器 #网口温湿度变送器 #机房监控

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

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

目录
  • 基于腾讯云 IoT Explorer 的 POE 网口温湿度传感器接入:物模型与属性上报实践
    • 一、场景与架构
    • 二、设备侧准备
      • 1. 传感器配置
      • 2. 边缘网关
    • 三、IoT Explorer 侧配置
      • 1. 创建产品
      • 2. 物模型定义
      • 3. 设备接入参数
    • 四、边缘网关代码实践
      • 1. 采集 + 上报主循环
      • 2. 下行控制(可选)
    • 五、数据流转与存储
      • 1. 规则引擎转发
      • 2. 时序库选型
    • 六、告警与可视化
    • 七、部署与运维
    • 八、常见坑
    • 九、小结
      • 物联网 #Modbus #TCP/IP #UDP #POE供电 #腾讯云 #Wireshark #Python #InfluxDB #以太网温湿度传感器 #网口温湿度变送器 #机房监控
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档