
IoT-For-Beginners 实战用 MQTT 协议将树莓派夜灯接入互联网【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本篇文章聚焦于 Microsoft「IoT-For-Beginners」课程第 4 课Connect your Device to the Internet中的单板计算机分支——教你在树莓派Raspberry Pi或虚拟 IoT 设备virtual IoT device上使用 Python 编写代码通过paho-mqtt客户端库连接公共 MQTT 代理test.mosquitto.org为互联网夜灯项目打好通信地基。学完本节你将掌握 MQTT 客户端对象的创建、代理连接、后台消息循环loop_start的用法以及如何在公共代理上安全地使用唯一客户端名与主题命名空间为后续发送遥测telemetry、接收命令commands的完整链路做好准备。一、任务背景从本地控制到互联网控制本课程的夜灯项目此前已经实现了传感器读光、LED 亮灭的本地闭环逻辑。这一部分要做的是把设备接入互联网让 IoT 设备通过 MQTT 与test.mosquitto.org通信发送携带光照读数的遥测值并接收控制 LED 的指令。整个课程的核心架构基于 MQTT 的发布/订阅publish/subscribe模型一个 broker代理/中间人多个 client客户端。所有客户端都连接到 broker由 broker 将消息路由给相关客户端消息通过命名主题topic路由而不是直接发给某个客户端。客户端可以向某个主题**发布publish**消息订阅subscribe了该主题的客户端都会收到这条消息本课中IoT 设备向 broker 发布光照遥测服务器代码订阅遥测主题并分析数据后再向命令主题发布led_on指令设备订阅命令主题并驱动 LED。 这一设计在真实世界中的典型场景是多传感器汇聚决策例如体育场有大量灯光需要综合多个光照传感器的读数再决定是否开灯避免仅仅因为一片云或一只鸟挡住单个传感器就误开灯。本课程的对应流程图见 assignment-1-internet-flow.png。本部分文档对应的源码存放位置虚拟设备版code-mqtt/virtual-device/nightlight/app.py树莓派版code-mqtt/pi/nightlight/app.py二、选择公共测试代理test.mosquitto.org本课不要求自己搭建 MQTT 代理而是使用 Eclipse Mosquitto开源 MQTT broker提供的公共测试服务器test.mosquitto.org。它的优点在于无需注册账号即可使用适合快速验证 MQTT 客户端与服务器代码任何人都可以发布/订阅非常适合教学实验。⚠️ 安全提醒该测试代理是公开且不安全的。任何在网络上的人都有可能监听到你发布的内容因此绝不能用它传输需要保密的数据。由于代理是公共的全球有大量用户包括正在学习同一作业的其他同学同时在向它发布消息。为了避免你的客户端与主题与其他人的代码撞车必须使用唯一的 MQTT 客户端名和唯一的主题名——这就是下面代码中id变量的核心作用。 如果你需要生成唯一 ID可以使用 GUIDGen 之类的 GUID 生成工具。三、安装 MQTT 客户端库paho-mqtt要与 MQTT 代理通信需要在树莓派上或虚拟设备所在的虚拟环境中安装 MQTT 的 pip 库。操作步骤在 VS Code 中打开 nightlight 项目如果使用虚拟 IoT 设备确认终端已激活虚拟环境虚拟环境由python3 -m venv .venv创建可参考 4-connect-internet 的 README 中Configure a Python virtual environment一节如果使用树莓派直接在系统环境中安装无需虚拟环境运行安装命令pip3 install paho-mqttpaho-mqtt是 Eclipse Paho 项目提供的流行 MQTT Python 库。安装后仅在你安装它的那个环境虚拟环境或系统环境中可用。四、编写设备端连接代码设备端代码的改动分三步导入库 → 定义唯一 ID 与客户端名 → 创建客户端并连接代理。步骤 1导入 paho.mqtt.client在app.py顶部添加import paho.mqtt.client as mqttpaho.mqtt.client库让你的应用能够通过 MQTT 协议通信。步骤 2定义唯一 ID 与客户端名在光照传感器light_sensor与 LED 定义之后添加id ID client_name id nightlight_client将ID替换为你的唯一 ID。它会用于该设备客户端的名称client name后续该设备发布与订阅的主题名如ID/telemetry、ID/commands后面编写服务器代码时也需要使用同一个 ID来拼接主题名——两端 ID 不一致服务器就收不到你的遥测。client_name是该 MQTT 客户端在 broker 上的唯一标识名。步骤 3创建客户端对象并连接代理在刚添加的代码下方继续添加mqtt_client mqtt.Client(client_name) mqtt_client.connect(test.mosquitto.org) mqtt_client.loop_start() print(MQTT connected!)这段代码做了三件事mqtt.Client(client_name)创建客户端对象传入唯一客户端名connect(test.mosquitto.org)连接公共 MQTT 代理默认端口 1883loop_start()启动一个在后台线程中运行的处理循环持续监听任何已订阅主题上的消息。 关于 MQTT 连接方式的补充来自本课 READMEMQTT 通信基于 TCP/IP与 HTTP 相同的基础网络协议但使用不同端口也可以基于MQTT over websockets与浏览器中的 Web 应用通信或用于防火墙等阻止标准 MQTT 连接的场景。连接可以是公开开放的也可以通过用户名/密码或证书进行加密和安全保护。步骤 4运行代码验证连接以与上一部分作业相同的方式运行代码。如果使用虚拟 IoT 设备请确保 CounterFit 应用正在运行并且光照传感器与 LED 已创建在正确引脚上(.venv) ➜ nightlight python app.py MQTT connected! Light level: 0 Light level: 0看到MQTT connected!即表示设备已成功连接到 MQTT broker。五、从源码看完整的连接上下文仓库中 code-mqtt/virtual-device/nightlight/app.py 展示了完整的虚拟设备代码树莓派版 code-mqtt/pi/nightlight/app.py 结构一致仅传感器/LED 的 import 来源不同import time from counterfit_connection import CounterFitConnection from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor from counterfit_shims_grove.grove_led import GroveLed import paho.mqtt.client as mqtt CounterFitConnection.init(127.0.0.1, 5000) light_sensor GroveLightSensor(0) led GroveLed(5) id ID client_name id nightlight_client mqtt_client mqtt.Client(client_name) mqtt_client.connect(test.mosquitto.org) mqtt_client.loop_start() print(MQTT connected!) while True: light light_sensor.light print(Light level:, light) if light 300: led.on() else: led.off() time.sleep(1)从这份代码可以观察到几个与本部分主题密切相关的要点虚拟设备通过 CounterFit 模拟硬件CounterFitConnection.init(127.0.0.1, 5000)让 Python 代码连接本机的 CounterFit 模拟器GroveLightSensor(0)与GroveLed(5)分别对应在模拟器上创建的 0 号引脚光照传感器和 5 号引脚 LEDMQTT 连接与业务主循环解耦连接成功后主循环只负责读取光照、打印读数并控制 LEDloop_start()启动的后台线程此时虽尚无订阅主题但已经为下一步发布遥测/接收命令铺好了通道树莓派版本使用from grove.grove_light_sensor_v1_2 import GroveLightSensor与from grove.grove_led import GroveLed其余 MQTT 相关代码完全一致即 MQTT 接入逻辑与具体硬件无关。作为对照同课程的 Arduino Wio Terminal 分支code-mqtt/wio-terminal/nightlight/src/main.cpp使用的是 C 的PubSubClient库通过client.setServer(BROKER.c_str(), 1883)设置 broker 与 1883 端口并在loop()中调用client.loop()维持连接与消息处理——这与 Python 版loop_start()的作用相对应。这说明 MQTT 客户端结构在不同语言/平台上具有一致性创建客户端 → 指定 broker → 启动消息循环。六、MQTT 核心概念速览连接后的下一步储备虽然本部分只完成连接但理解以下概念有助于你衔接后续的遥测与命令任务主题层级与通配符主题可以分层客户端可用通配符订阅不同层级。例如温度遥测发到/telemetry/temperature、湿度发到/telemetry/humidity云应用订阅/telemetry/*即可同时收到两类消息QoS服务质量决定消息送达的保证程度至多一次at most once只发送一次客户端与 broker 不采取额外确认步骤fire and forget至少一次at least once发送方重试直到收到确认acknowledged delivery恰好一次exactly once发送方与接收方通过两级握手确保只收到一份消息assured delivery。无消息队列MQTT 名字里虽有 Queue但实际不提供消息队列。客户端断开再重连不会收到断开期间发送的消息QoS 流程中已开始处理的消息除外。若消息设置了retained保留标志broker 会保存该主题的最后一条消息并在新客户端订阅时发送给它保证客户端总能拿到最新值Keep Alive 保活在消息间隔较长时检查连接是否仍然存活断线处理MQTT 本身不保证断线期间的消息送达。若业务要求不丢数据需要设备端/服务器端自行负责例如要求所有消息在回复主题上得到应答否则手动入队以便稍后重放。本课 README 中还提示在自建 Mosquitto 代理时默认不允许匿名连接、也不允许来自本机之外的连接可通过mosquitto.conf配置listener 1883 0.0.0.0与allow_anonymous true来开放。七、下一步与作业衔接成功打印出MQTT connected!后你已完成本部分目标。后续两个部分将在此基础上继续发送遥测single-board-computer-telemetry.md定义client_telemetry_topic id /telemetry用json.dumps({light: light})编码数据并mqtt_client.publish(client_telemetry_topic, telemetry)每 5 秒发送一次接收命令single-board-computer-commands.md定义server_command_topic id /commands通过mqtt_client.subscribe(server_command_topic)订阅并设置mqtt_client.on_message handle_command回调——回调解析payload[led_on]来决定led.on()还是led.off()。完整的闭环代码可见 code-commands/virtual-device/nightlight/app.py其中client_telemetry_topic、server_command_topic、client_name三者均由同一个id派生再次印证了唯一 ID 决定命名空间、两端必须一致这一贯穿整个作业的关键约束。 本课的最终作业是调研 AMQP 与 HTTP/HTTPS并从功耗、安全性、连接断开时的消息持久化三个维度与 MQTT 对比详见 assignment.md。本文小结通过安装paho-mqtt、定义唯一id与client_name、调用connect()与loop_start()你的树莓派或虚拟 IoT 设备已成功接入公共 MQTT 代理。这一层连接是整个互联网控制夜灯项目的通信基石后续所有遥测发布与命令订阅都建立在这段连接之上。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考