树莓派上传温湿度模拟数据到腾讯云物联网平台

一、主要内容

  1. 树莓派上python代码模拟传感器(温湿度 ),用 MQTT over TLS 上报到腾讯云 IoT Explorer。
  2. 腾讯云 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. 公共实例说明

进入公共实例:

腾讯云物联网平台提供免费额度的公共实例,但需要注意以下几点:

  1. 免费额度:新用户注册后,物联网平台会提供一定的免费额度,包括:

    • 设备连接数:通常有免费设备连接数限制
    • 消息数量:每月有一定数量的免费消息额度
    • 存储空间:有限的免费数据存储
  2. 超出收费 :当您的使用量超过免费额度时,会按照官方定价收费。

  3. 免费期限:部分免费资源可能有时间限制(如首年免费),建议查看最新的官方文档。

  4. 建议

    • 开发测试阶段可以使用公共实例的免费额度
    • 生产环境请根据业务量评估是否需要升级到企业版或购买额外资源
    • 定期在控制台查看资源使用情况,避免意外费用
    • 对于本教程的树莓派传感器数据模拟项目,公共实例的免费额度完全足够学习和测试使用。如果后续需要大规模部署,请参考腾讯云官方的最新计费政策。
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文件中。

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

三、实验结果

树莓派上传温湿度模拟数据到腾讯云物联网平台-python源代码

相关推荐
2501_913981782 小时前
畜牧养殖物联网行业报告与方案解析:智能设备与大数据重塑养殖管理模式
物联网·智慧农业·畜牧业
Benszen2 小时前
云计算基础-4:Linux 进程管理
linux·运维·云计算
Mixtral12 小时前
职场录音转写工具投入产出比实测:随身鹿、通义听悟、阿里云与Trint该怎么选?
阿里云·云计算
CJH(本人账号)16 小时前
【AI安全】大模型安全威胁:Prompt注入与模型防御策略
人工智能·安全·机器学习·语言模型·云计算·prompt
老梁agent17 小时前
LangChain4j AiServices 深度解析:声明式 Agent 编程的魔法背后
物联网·ai编程
Linlingu17 小时前
OpenClaw接入阿里云百炼模型配置教程(完整可落地)
人工智能·阿里云·云计算·办公自动化·数字员工·小龙虾
AKAMAI17 小时前
当OpenClaw遇见Linode:一键部署7×24h云端AI助理
云计算·agent
AOwhisky1 天前
学习自测与解析:MySQL 系列第三期与第四期
linux·运维·数据库·学习·mysql·云计算
yyuuuzz1 天前
AI模型部署中的常见稳定性问题
运维·服务器·网络·数据库·人工智能·云计算·github