一、主要内容
- 树莓派上python代码模拟传感器(温湿度 ),用 MQTT over TLS 上报到腾讯云 IoT Explorer。
- 腾讯云 IoT Explorer:注册产品、设备接入、物模型管理、消息测试。
二、实现步骤
(一)树莓派端:传感器数据模拟 + MQTT 上云
1.树莓派环境
bash
(venv) zgp@zgp-openclaw:~/.openclaw/workspace/tencent_iot $ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 13 (trixie)
Release: 13
Codename: trixie
Debian 13 (Trixie) ------ 这是树莓派最新版系统,规则非常严格:绝对不能用 sudo pip 安装任何包,必须用虚拟环境,否则一定会报错!
bash
sudo apt update
sudo apt install python3-venv -y
mkdir -p ~/.openclaw/workspace/tencent_iot
cd ~/.openclaw/workspace/tencent_iot
python3 -m venv --system-site-packages venv
# 执行完会在 ~/.openclaw/workspace/tencent_iot 生成一整套独立 Python 环境。
# 加 --system-site-packages 是为了能调用树莓派硬件库(GPIO、传感器)
source venv/bin/activate # 激活环境(关键!)
# 激活成功后,命令行最前面会出现 (venv)
(venv) zgp@zgp-openclaw:~/.openclaw/workspace/tencent_iot $
pip install paho-mqtt
pip install qcloud-iot-explorer-sdk-python
以后每次使用(记住这3 行)
bash
cd /home/zgp/.openclaw/workspace/tencent_iot
source venv/bin/activate
python iot_sender.py
# 退出环境命令:deactivate
2.tencent_iot项目下所有文件

3.config.json文件
javascript
{
// ============================================
// 腾讯物联网平台 (IoT Hub) 设备连接配置
// ============================================
// ---------- MQTT 服务器配置 ----------
// MQTT Broker 地址(由腾讯云分配,格式:产品ID.iotcloud.tencentdevices.com)
"broker": "MRU4GFPVTF.iotcloud.tencentdevices.com",
// MQTT Broker 端口号(1883 = 明文MQTT,8883 = TLS加密MQTT)
"port": 1883,
// ---------- 设备身份认证配置 ----------
// 客户端 ID(由 产品ID + 设备名称 拼接而成)
"client_id": "MRU********st1",
// 用户名(格式:产品ID+设备名称;SDK版本号;连接ID;时间戳)
"username": "MRU4********est********6;718e********00",
// 密码(预计算的 HMAC-SHA256 签名;认证方式标识)
"password": "37c****************************************ha256",
// ---------- 数据上报配置 ----------
// 产品 ID(在腾讯云 IoT 控制台创建产品后获得)
"product_id": "MR********F",
// 设备名称(在腾讯云 IoT 控制台创建设备时指定)
"device_name": "te********1",
// 数据上报间隔(单位:秒)
"report_interval": 10,
// 模拟温度范围(单位:摄氏度 ℃)
"temp_min": 20.0,
"temp_max": 35.0,
// 模拟湿度范围(单位:相对湿度 %RH)
"humi_min": 40.0,
"humi_max": 80.0
}
4.导入依赖库
python
import json # 用于解析配置文件和构造上报消息
import random # 用于生成模拟的温度、湿度随机数
import time # 用于控制上报间隔(sleep)
import signal # 用于捕获 Ctrl+C 信号,实现优雅退出
import sys # 用于 sys.exit() 退出程序
import os # 用于获取脚本所在目录的路径
# 导入 paho-mqtt 库(MQTT 客户端)
import paho.mqtt.client as mqtt
# ==================== 全局变量 ====================
# MQTT 客户端实例(在 main 函数中创建)
client = None
# 运行标志位,用于控制主循环(Ctrl+C 时设为 False)
running = True
5.配置读取函数
python
def load_config(config_path: str) -> dict:
"""
读取 JSONC 格式的配置文件(支持 // 注释)
参数:
config_path: 配置文件的路径
返回:
解析后的配置字典
说明:
JSON 标准不支持注释,这里通过逐行过滤 // 开头的注释行,
然后再用 json.loads() 解析,实现 JSONC 兼容。
"""
# 读取配置文件的所有行
with open(config_path, "r", encoding="utf-8") as f:
lines = f.readlines()
# 过滤掉注释行和空行
# - strip() 去除行首尾空白
# - 跳过以 // 开头的注释行
# - 跳过空行
filtered_lines = []
for line in lines:
stripped = line.strip()
if stripped.startswith("//") or stripped == "":
continue # 跳过注释行和空行
filtered_lines.append(line)
# 将过滤后的行拼接成字符串,再用 json 解析
json_str = "".join(filtered_lines)
config = json.loads(json_str)
return config
6.模拟数据生成函数
python
def generate_sensor_data(temp_min: float, temp_max: float,
humi_min: float, humi_max: float) -> dict:
"""
生成模拟的温度和湿度数据
参数:
temp_min: 温度最小值(℃)
temp_max: 温度最大值(℃)
humi_min: 湿度最小值(%RH)
humi_max: 湿度最大值(%RH)
返回:
包含温度和湿度的字典,例如:
{"temperature": 25.63, "humidity": 62.18}
说明:
使用 random.uniform() 生成指定范围内的随机浮点数,
模拟真实传感器的读数。round() 保留两位小数。
"""
# 生成随机温度值,保留 2 位小数
temperature = round(random.uniform(temp_min, temp_max), 2)
# 生成随机湿度值,保留 2 位小数
humidity = round(random.uniform(humi_min, humi_max), 2)
return {
"temperature": temperature,
"humidity": humidity
}
7.MQTT 连接成功的回调函数
python
def on_connect(client, userdata, flags, reason_code, properties):
"""
MQTT 连接成功的回调函数
参数:
client: MQTT 客户端实例
userdata: 用户自定义数据(这里未使用)
flags: 连接标志
reason_code: 连接结果码(0 = 成功)
properties: MQTT 5.0 属性
说明:
paho-mqtt v2.x 使用 CallbackAPIVersion.VERSION2,
回调签名包含 reason_code 和 properties 参数。
reason_code 为 0 表示连接成功。
"""
if reason_code == 0:
# reason_code == 0 表示连接成功
print(f"✅ [连接成功] 已成功连接到腾讯物联网平台!")
print(f" 连接返回码: {reason_code}")
else:
# 非 0 表示连接失败,打印错误码供排查
print(f"❌ [连接失败] 返回码: {reason_code}")
print(f" 请检查 config.json 中的凭证是否正确")
8.MQTT 断开连接的回调函数
python
def on_disconnect(client, userdata, flags, reason_code, properties):
"""
MQTT 断开连接的回调函数
参数:
client: MQTT 客户端实例
userdata: 用户自定义数据(这里未使用)
flags: 断开标志
reason_code: 断开原因码
properties: MQTT 5.0 属性
说明:
reason_code 为 0 表示正常断开(主动调用 disconnect),
非 0 表示异常断开(网络中断、服务器拒绝等)。
"""
if reason_code == 0:
print(f"👋 [正常断开] 已主动断开与物联网平台的连接")
else:
print(f"⚠️ [异常断开] 返回码: {reason_code},连接意外中断")
9.消息发布成功的回调函数
python
def on_publish(client, userdata, mid, reason_code, properties):
"""
消息发布成功的回调函数
参数:
client: MQTT 客户端实例
userdata: 用户自定义数据(这里未使用)
mid: 消息 ID(MQTT 协议中每条消息的唯一编号)
reason_code: 发布结果码(0 = 成功)
properties: MQTT 5.0 属性
说明:
当 MQTT 消息被服务器确认(QoS >= 1 时)后触发此回调。
这里仅做简单的日志记录。
"""
# 消息确认成功时打印消息 ID
if reason_code == 0:
print(f" 📬 [服务器已确认] 消息ID: {mid}")
10.将传感器数据上报到腾讯物联网平台
python
def report_data(client, product_id: str, device_name: str,
sensor_data: dict) -> int:
"""
将传感器数据上报到腾讯物联网平台
参数:
client: MQTT 客户端实例
product_id: 产品 ID
device_name: 设备名称
sensor_data: 传感器数据字典 {"temperature": x, "humidity": y}
返回:
消息 ID(mid)
说明:
上报 Topic 格式(腾讯云 IoT Explorer 属性上报):
$thing/up/property/{product_id}/{device_name}
消息体格式(腾讯云物联网数据模板标准格式):
{
"method": "report",
"params": {
"temperature": 25.63,
"humidity": 62.18
}
}
"""
# ---- 构造上报 Topic ----
# 腾讯云 IoT Explorer 属性上报的 Topic 格式
topic = f"$thing/up/property/{product_id}/{device_name}"
# ---- 构造消息体 ----
# 按照腾讯云物联网数据模板协议格式构造 JSON
payload = {
"method": "report", # 上报方法标识
"params": sensor_data # 传感器数据(温度、湿度)
}
# 将字典转为 JSON 字符串
payload_str = json.dumps(payload, ensure_ascii=False)
# ---- 发布 MQTT 消息 ----
# qos=1 表示至少送达一次(服务器会返回 ACK 确认)
# retain=False 表示不保留消息(每次都是最新数据)
result = client.publish(topic, payload_str, qos=1, retain=False)
# 打印发送日志
print(f" 📤 [已发送] Topic: {topic}")
print(f" 📦 [数据内容] {payload_str}")
# 返回消息 ID
return result.mid
11.捕获 Ctrl+C 信号的处理函数
python
def signal_handler(sig, frame):
"""
捕获 Ctrl+C 信号的处理函数
参数:
sig: 信号编号(SIGINT = 2)
frame: 当前栈帧(这里未使用)
说明:
当用户按下 Ctrl+C 时,不会立即退出程序,
而是将 running 标志设为 False,让主循环自然结束,
然后执行清理工作(断开 MQTT 连接)。
"""
global running
print(f"\n🛑 [退出信号] 检测到 Ctrl+C,正在优雅退出...")
running = False
11.程序主入口
python
def main():
"""
程序主入口
执行流程:
1. 加载配置文件
2. 创建 MQTT 客户端并设置回调
3. 连接腾讯物联网平台
4. 进入主循环:定时生成模拟数据并上报
5. 退出时断开连接、清理资源
"""
# 声明使用全局变量
global client, running
# ==================== 1. 加载配置 ====================
# 获取脚本所在目录的绝对路径(确保从任何位置运行都能找到配置文件)
script_dir = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.join(script_dir, "config.json")
print(f"📂 [配置文件] {config_path}")
# 检查配置文件是否存在
if not os.path.exists(config_path):
print(f"❌ [错误] 配置文件不存在: {config_path}")
print(f" 请先创建 config.json 文件")
sys.exit(1)
# 读取配置
config = load_config(config_path)
# 从配置字典中提取各项参数
broker = config["broker"] # MQTT 服务器地址
port = config["port"] # MQTT 端口号
client_id = config["client_id"] # 客户端 ID
username = config["username"] # 用户名
password = config["password"] # 密码(预计算的 HMAC-SHA256)
product_id = config["product_id"] # 产品 ID
device_name = config["device_name"] # 设备名称
report_interval = config["report_interval"] # 上报间隔(秒)
temp_min = config["temp_min"] # 温度最小值
temp_max = config["temp_max"] # 温度最大值
humi_min = config["humi_min"] # 湿度最小值
humi_max = config["humi_max"] # 湿度最大值
# 打印启动信息
print(f"{'='*55}")
print(f" 腾讯物联网平台 --- 温湿度数据模拟上报")
print(f"{'='*55}")
print(f" 服务器: {broker}:{port}")
print(f" 客户端: {client_id}")
print(f" 产品ID: {product_id}")
print(f" 设备名: {device_name}")
print(f" 上报间隔: {report_interval} 秒")
print(f" 温度范围: {temp_min}℃ ~ {temp_max}℃")
print(f" 湿度范围: {humi_min}% ~ {humi_max}%")
print(f"{'='*55}")
# ==================== 2. 创建 MQTT 客户端 ====================
# 使用 CallbackAPIVersion.VERSION2(paho-mqtt v2.x 推荐)
# VERSION2 的回调函数签名包含 reason_code 和 properties 参数
client = mqtt.Client(
callback_api_version=mqtt.CallbackAPIVersion.VERSION2,
client_id=client_id # 客户端 ID(腾讯云要求为 产品ID+设备名称)
)
# 设置用户名和密码(腾讯云 HMAC-SHA256 认证方式)
client.username_pw_set(
username=username, # 格式:产品ID+设备名称;SDK版本;连接ID;时间戳
password=password # 格式:HMAC签名;hmacsha256
)
# 注册回调函数
client.on_connect = on_connect # 连接成功时触发
client.on_disconnect = on_disconnect # 断开连接时触发
client.on_publish = on_publish # 消息发布确认时触发
# ==================== 3. 连接 MQTT 服务器 ====================
print(f"\n🔗 [连接中] 正在连接 {broker}:{port} ...")
try:
# 发起 TCP 连接到 MQTT Broker
# keepalive=60 表示每 60 秒发送一次心跳 PING 包
client.connect(broker, port, keepalive=60)
except Exception as e:
print(f"❌ [连接错误] {e}")
print(f" 请检查网络连接和配置参数")
sys.exit(1)
# 启动 MQTT 网络循环(在后台线程中运行)
# 这样主线程可以自由执行数据上报逻辑
client.loop_start()
# ==================== 4. 注册信号处理 ====================
# 注册 SIGINT 信号处理器(捕获 Ctrl+C)
signal.signal(signal.SIGINT, signal_handler)
# ==================== 5. 主循环:定时上报数据 ====================
print(f"\n📡 [运行中] 开始定时上报模拟数据(每 {report_interval} 秒一次)")
print(f" 按 Ctrl+C 退出\n")
# 上报计数器(记录总共上报了多少次)
report_count = 0
# 等待连接建立(最多等待 5 秒)
time.sleep(2)
while running:
# ---- 生成模拟传感器数据 ----
sensor_data = generate_sensor_data(
temp_min, temp_max,
humi_min, humi_max
)
# ---- 上报数据 ----
report_count += 1
print(f"--- 第 {report_count} 次上报 ---")
report_data(client, product_id, device_name, sensor_data)
# ---- 等待指定时间间隔 ----
# 使用循环小步 sleep(每次 0.5 秒),这样可以及时响应 Ctrl+C
waited = 0
while running and waited < report_interval:
time.sleep(0.5)
waited += 0.5
# ==================== 6. 清理退出 ====================
print(f"\n🧹 [清理] 正在断开连接...")
print(f" 本次运行共上报 {report_count} 次数据")
# 停止 MQTT 网络循环
client.loop_stop()
# 断开与 MQTT 服务器的连接
client.disconnect()
print(f"✨ [完成] 程序已安全退出,再见!\n")
12.程序入口
python
if __name__ == "__main__":
# Python 标准入口:只有直接运行此脚本时才执行
# 如果被其他模块 import,则不会自动执行
main()
(二)腾讯云物联网平台配置
1. 登录与进入
登录腾讯云:https://console.cloud.tencent.com/
进入物联网开发平台

2. 公共实例说明
进入公共实例:

腾讯云物联网平台提供免费额度的公共实例,但需要注意以下几点:
-
免费额度:新用户注册后,物联网平台会提供一定的免费额度,包括:
- 设备连接数:通常有免费设备连接数限制
- 消息数量:每月有一定数量的免费消息额度
- 存储空间:有限的免费数据存储
-
超出收费 :当您的使用量超过免费额度时,会按照官方定价收费。
-
免费期限:部分免费资源可能有时间限制(如首年免费),建议查看最新的官方文档。
-
建议:
- 开发测试阶段可以使用公共实例的免费额度
- 生产环境请根据业务量评估是否需要升级到企业版或购买额外资源
- 定期在控制台查看资源使用情况,避免意外费用
- 对于本教程的树莓派传感器数据模拟项目,公共实例的免费额度完全足够学习和测试使用。如果后续需要大规模部署,请参考腾讯云官方的最新计费政策。
3. 创建产品

输入基本信息:

| 项目 | 含义 | 推荐填写 | 说明 |
|---|---|---|---|
| 产品名称 | 给你的设备集合起一个名字,用来在控制台里区分不同项目 | 示例里的 raspberry_sensor 就很好,也可以改成更具体的,比如 pi_dht11_sensor |
支持中英文、数字、下划线,最多 40 个字符,只要不重复、好记就行 |
| 设备类型 | 区分普通设备和带音视频能力的设备 | 选基础设备 | 你的树莓派只是传传感器数据,不需要音视频能力,选基础设备即可 |
| 节点类型 | 设备接入平台的方式 | 选直连设备 | 树莓派直接连 WiFi 上云,不需要通过网关中转,所以选直连设备;如果后面要接多个传感器,再考虑网关 |
| 有效期 | 产品和设备在平台上的生命周期 | 选5 年(默认)就够用了 | 最长可以选 10 年,选 5 年完全能满足你的个人项目需求 |
| 描述 | 可选备注 | 可以留空,也可以写 树莓派温湿度传感器 |
用来自己识别项目用途,别人看不到,不影响功能 |
| 项目 | 含义 | 推荐填写 | 说明 |
|---|---|---|---|
| 通信方式 | 设备和平台的网络连接方式 | 选Wi-Fi | 树莓派用 WiFi 联网,选 Wi-Fi 最匹配;如果后面改成 4G 模块,再改成蜂窝 |
| 认证方式 | 设备接入平台时的身份验证方式 | 选密钥认证 | 开发最简单,Python SDK 直接用三元组就能连,不用处理证书文件,非常适合树莓派开发 |
| 数据协议 | 设备和平台之间数据交互的格式标准 | 选物模型 | 腾讯云推荐的标准方式,能自动生成上报 / 下发 Topic,后面的 Python 代码和小程序直接按规范用,不用自己定义复杂协议 |
✅ 最终推荐配置(直接照着填就能用)
-
产品名称:
raspberry_sensor(或自定义) -
设备类型:基础设备
-
节点类型:直连设备
-
有效期:5 年
-
描述:可留空
-
通信方式:Wi-Fi
-
认证方式:密钥认证
-
数据协议:物模型
直接点「创建」,就能进入下一步的功能定义和设备添加了。
4.新增功能
点击创建的产品,在功能定义下面点击"新增功能",设置传感器参数。

5.新建设备
在设备下点击"新建设备",选择所属产品,输入设备名称即可。
点击查看,可以看到设备连接参数,填入前面的config.json文件中。

在云日志下面可以看到通信内容,在线调试下面可以查看实时信息,有温湿度信息则表示通信成功。

三、实验结果
