
IoT-For-Beginners 智慧农场实战Raspberry Pi 与虚拟设备通过 MQTT 发布温度遥测数据【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本篇指南基于 IoT-For-Beginners 课程第 2 周农场场景预测植物生长中发布温度这一实战环节讲解如何把 Raspberry Pi 或虚拟 IoT 设备CounterFit上 DHT11 传感器采集到的温度值通过 MQTT 发布到公共 Broker供服务端订阅并存储最终用于计算植物的生长度日GDDGrowing Degree Days。学完本篇你将掌握复用第 4 课的 MQTT 连接模式改造遥测应用、按正确字段名与 JSON 结构发布温度数据、为传感器轮询设定合理的休眠周期并在真实 Pi 与虚拟设备两种环境下验证发布结果。背景为什么要把温度发出去在 预测植物生长课程 中温度是计算 GDD 的核心输入。GDD 的简化公式为Tmax—— 当日最高温度摄氏度Tmin—— 当日最低温度摄氏度Tbase—— 该植物的基础温度base temperature如草莓约为 10°C要算出当日的 GDD就必须持续、长期地收集温度数据。因此本课的架构是IoT 设备测量温度后通过 MQTT 把遥测数据telemetry发布到互联网上的 Broker服务端代码订阅这些数据并追加保存到 CSV 文件之后例如夜间任务再基于历史数据计算 GDD、累计作物生长进度并在接近成熟时发出告警。原文档中对这一步的概括是温度被读取后就可以通过 MQTT 发布给某个服务端代码由它读取数值并存储好等待被用于 GDD 计算。本篇对应的正是整个链路中的设备侧发布环节官方指南为 single-board-computer-temp-publish.md适用对象是Raspberry Pi 单板计算机和虚拟 IoT 设备使用 Seeed 的 CounterFit 应用模拟硬件Wio TerminalArduino走的是另一份指南 wio-terminal-temp-publish.md。前提已建好的 temperature-sensor 项目发布温度之前你需要已经完成本课前面测量温度的小节拥有一个名为temperature-sensor的项目其中app.py能够读取 DHT11 传感器并打印温度。Pi 与虚拟设备两条路线的前置条件分别见Raspberry Pi 路线pi-temp.md —— DHT11 Grove 传感器插在 Grove Base Hat 的数字口D5上代码侧通过pip3 install seeed-python-dht安装驱动并创建sensor DHT(11, 5)实例第一个参数指定 DHT11 型号第二个参数指定 D5 引脚用sensor.read()返回(humidity, temperature)元组。虚拟设备路线virtual-device-temp.md —— 安装counterfit-shims-seeed-python-dht垫片包并在 CounterFit 应用中创建两个传感器湿度传感器放在 Pin 5、温度传感器放在 Pin 6shim 会把DHT(11, 5)模拟为这两个组合传感器代码以counterfit_shims_seeed_python_dht替代seeed_dht导入DHT类。任务改造程序以发布温度数据按原文档任务是给设备编程让它发布温度数据。完整步骤如下。第 1 步打开项目复用第 4 课的 MQTT 连接步骤打开temperature-sensor应用项目如尚未打开。然后重复你在 第 4 课连接互联网 中做过的两件事连接 MQTT Broker和发送遥测使用的仍然是同一个公共 Mosquitto Brokertest.mosquitto.org。这两步各自包含的细分为添加 MQTT 的 pip 包pip3 install paho-mqtt添加连接 MQTT Broker 的代码添加发布遥测的代码如果需要回看细节可参考第 4 课的两份指南single-board-computer-mqtt.md连接 MQTT与 single-board-computer-telemetry.md发送遥测。其中与本项目直接相关的要点在app.py顶部导入import paho.mqtt.client as mqtttest.mosquitto.org是公共 Broker很多使用者包括其他学习本课程的同学同时在线因此必须给自己分配一个唯一 ID作为客户端名和主题名的前缀避免与他人的客户端/主题冲突client_name是本 MQTT 客户端在 Broker 上的唯一名称mqtt_client.connect(test.mosquitto.org)建立连接mqtt_client.loop_start()启动后台线程处理订阅消息。第 2 步让 client_name 体现本项目名称把第 4 课小夜灯项目里的客户端名后缀改成本项目的名称client_name id temperature_sensor_client从仓库中 Pi 版完整示例 code-publish-temperature/pi/temperature-sensor/app.py 可以看到与客户端名配套的主题定义是id ID client_telemetry_topic id /telemetry client_name id temperature_sensor_client mqtt_client mqtt.Client(client_name) mqtt_client.connect(test.mosquitto.org) mqtt_client.loop_start() print(MQTT connected!)注意ID需要替换成你自己的唯一标识可以用 GUID 生成器等工具产生这个 ID 之后写服务端订阅代码时还会用到——客户端与服务端必须共用同一个 ID 才能对上同一个/telemetry主题。第 3 步发布温度遥测字段名为 temperature与第 4 课发送光照值{light: ...}不同这里要发送从 DHT 传感器读到的温度值放在 JSON 文档中名为temperature的属性上_, temp sensor.read() telemetry json.dumps({temperature : temp})这里sensor.read()返回(湿度, 温度)元组下划线丢弃湿度temp是摄氏温度。json.dumps把它编码成 JSON 字符串如{temperature: 25}。这个字段名不是随意的服务端代码在解析消息时会直接按payload[temperature]取值见下文服务端剖析字段名不一致会导致KeyError。第 4 步把轮询间隔设为 10 分钟温度值不需要高频读取——短时间内变化很小所以把time.sleep设为 10 分钟time.sleep(10 * 60)time.sleep以秒为单位因此传一个计算式的结果60 秒/分钟 × 10 分钟 600 秒。这个低频策略同时兼顾了数据用途GDD 只关心每日最高/最低温和设备能耗。第 5 步运行并验证像之前运行本项目代码的方式一样运行Pi 上在用户家目录的temperature-sensor文件夹里执行python3 app.py虚拟设备则在激活虚拟环境的终端中执行python app.py并确保CounterFit 应用在运行、湿度与温度传感器已创建在正确引脚湿度 Pin 5、温度 Pin 6。预期输出piraspberrypi:~/temperature-sensor $ python3 app.py MQTT connected! Sending telemetry {temperature: 25} Sending telemetry {temperature: 25}看到MQTT connected!与每 10 分钟一次的Sending telemetry {temperature: ...}日志即表示温度已成功作为遥测从设备发布出去。如果用的是虚拟设备建议在 CounterFit 里勾选Random复选框并设置一个 Min/Max 区间参考课程中的截图 select-the-random-checkbox-and-set-a-range.png这样每次读取会得到不同的温度值便于后续验证服务端是否正确累计了多条记录。 完整可运行代码可在仓库中找到code-publish-temperature/virtual-device虚拟设备版或 code-publish-temperature/piPi 版。源码纵深客户端完整代码剖析把上面 5 步合起来Pi 版 app.py 全文只有 28 行结构非常清晰import time from seeed_dht import DHT import paho.mqtt.client as mqtt import json sensor DHT(11, 5) id ID client_telemetry_topic id /telemetry client_name id temperature_sensor_client mqtt_client mqtt.Client(client_name) mqtt_client.connect(test.mosquitto.org) mqtt_client.loop_start() print(MQTT connected!) while True: _, temp sensor.read() telemetry json.dumps({temperature : temp}) print(Sending telemetry , telemetry) mqtt_client.publish(client_telemetry_topic, telemetry) time.sleep(10 * 60)几个值得注意的实现细节连接是一次性的发布是循环的connect/loop_start在while True之外只执行一次循环体内依次是读传感器 → 编码 JSON → 打印 → publish → 休眠。paho 的loop_start()让网络收发在后台线程进行因此即使主线程sleep600 秒也不会丢失连接处理。虚拟设备版与 Pi 版仅两处差异对比 虚拟设备版 app.py它额外在前两行初始化 CounterFit 连接CounterFitConnection.init(127.0.0.1, 5000)并把传感器库从seeed_dht换成垫片包counterfit_shims_seeed_python_dht其余 MQTT 逻辑完全一致。这说明应用层代码与硬件解耦是本课程的刻意设计同一套发布逻辑可以无缝跑在真机与模拟器上。time.sleep(10 * 60)位于 publish 之后先发送再休眠保证程序启动后立即产生第一条遥测而不是空等 10 分钟。数据流向哪服务端订阅与 CSV 落盘发布的温度并不是终点。同一课程提供了一份配套服务端代码 code-server/temperature-sensor-server/app.py它展示了设备侧发布的数据如何被消费理解它对把握发布端字段约定很有帮助client_telemetry_topic id /telemetry server_command_topic id /commands client_name id temperature_sensor_server mqtt_client mqtt.Client(client_name) mqtt_client.connect(test.mosquitto.org) mqtt_client.loop_start() temperature_file_name temperature.csv fieldnames [date, temperature] if not path.exists(temperature_file_name): with open(temperature_file_name, modew) as csv_file: writer csv.DictWriter(csv_file, fieldnamesfieldnames) writer.writeheader() def handle_telemetry(client, userdata, message): payload json.loads(message.payload.decode()) print(Message received:, payload) with open(temperature_file_name, modea) as temperature_file: temperature_writer csv.DictWriter(temperature_file, fieldnamesfieldnames) temperature_writer.writerow({date : datetime.now().astimezone().replace(microsecond0).isoformat(), temperature : payload[temperature]}) mqtt_client.subscribe(client_telemetry_topic) mqtt_client.on_message handle_telemetry从源码结构看服务端做三件与设备侧呼应的事同名主题订阅subscribe(id /telemetry)即设备端 publish 的那个主题。两边id必须一致这是公共 Broker 上避免串数据的关键约定服务端自己补时间戳很多 IoT 设备缺乏可靠的时钟所以 CSV 中的date列取的是服务端收到消息的时刻带时区、去掉微秒的 ISO 8601 格式而非设备端时间追加写入 CSV文件不存在时先建表头date,temperature之后每条消息append一行。这正是 README 中服务端代码可以增强数据augment the data的体现——设备只发温度位置、时间等上下文由服务端补齐。积累一天的数据后理想情况就可按 课程 README 中的方法找出当日最高/最低温并套用 GDD 公式最终用 Jupyter Notebook 作业 可视化 GDD 数据。常见问题与注意事项ID 不唯一公共 Broker 上若客户端名或主题与他人重复会互相干扰甚至导致断连。务必使用唯一 ID并在设备端与服务端保持一致。虚拟设备传感器引脚DHT(11, 5)在 CounterFit 中隐含要求湿度传感器在 Pin 5、温度传感器在 Pin 6shim 假设温度传感器在下一个引脚。只建了温度传感器会导致读数异常。sleep 单位是秒time.sleep(10 * 60)是 600 秒。调试时可以先改成更短的值如 10 秒快速验证确认无误后再改回 10 分钟。长时间采集如果计划让服务端连续运行一整天采集 GDD 数据需要确保运行服务端代码的电脑不会进入睡眠调整电源设置或运行保持唤醒的脚本。小结本篇完成了预测植物生长课程中设备侧的关键一步temperature-sensor应用从打印温度升级为通过 MQTT 发布{temperature: ...}遥测核心改动只有三处——客户端名id temperature_sensor_client、遥测字段改为temperature、休眠周期拉长到 10 分钟发布链路复用第 4 课的paho-mqtttest.mosquitto.org模式。数据落地端服务端订阅 CSV 落盘的对应代码在 code-server/temperature-sensor-server 中可以直接对照阅读两者拼合起来就是传感器 → MQTT → 存储 → GDD 计算这条数字农业数据链的完整最小实现。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考