用 Jupyter Notebook 可视化 GDD 数据:IoT-For-Beginners 农场项目实践指南
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
本指南以IoT-For-Beginners仓库2-farm/lessons/1-predict-plant-growth课程的课后作业为蓝本,讲解如何利用 Jupyter Notebook 对 IoT 温度传感器采集的多日温度数据进行可视化,并计算作物生长所需的 Growing Degree Days(GDD,生长度日)。读完本文你将掌握:搭建 Python 虚拟环境与 Jupyter 运行环境、解析 MQTT 服务器落盘的temperature.csv数据、按日聚合求最高/最低温,以及使用标准 GDD 简化公式完成逐日累计计算——从而为"预测作物成熟时间"这一数字农业场景提供可落地的分析工具。
一、任务背景:从温度遥测到 GDD 计算
在 1-predict-plant-growth 课程中,IoT 设备(Wio Terminal、Raspberry Pi 或 CounterFit 虚拟设备)通过 DHT11 温湿度传感器测量环境温度,并将温度遥测数据经 MQTT 发布到test.mosquitto.org公共 broker。服务器端程序订阅遥测主题,把每条消息追加写入temperature.csv文件,数据流如下:
服务器端核心实现位于 code-server/temperature-sensor-server/app.py,其关键逻辑包括:
- 以 CSV 列头初始化文件:
fieldnames = ['date', 'temperature']; - 订阅
id + '/telemetry'主题,收到消息后以追加模式写入一行记录; - 时间戳使用 ISO 8601 格式(含时区、不含微秒):
datetime.now().astimezone().replace(microsecond=0).isoformat()。
运行一段时间后生成的temperature.csv形如:
date,temperature 2021-04-19T17:21:36-07:00,25 2021-04-19T17:31:36-07:00,24 2021-04-19T17:41:36-07:00,25而要得到可靠的 GDD 数据,必须跨越多日持续采集——这正是本作业的第一项硬性要求:确保服务器代码在 IoT 设备运行的整个周期内始终在线。
二、GDD 核心公式回顾
GDD(Growing Degree Days,又称生长度单位)基于温度衡量植物生长量。只要水分、养分和 CO₂ 充足,温度就决定生长速率。标准简化公式为:
GDD = (Tmax + Tmin) / 2 - Tbase- GDD:当日生长度日数;
- Tmax:当日最高气温(°C);
- Tmin:当日最低气温(°C);
- Tbase:该作物的基础温度(°C),即植物开始生长的最低日均温。
课程 README 给出了玉米的例子:基础温度 10°C,某日最高 16°C、最低 12°C,则当日 GDD = (16+12)/2 − 10 =4。若该玉米品种成熟需 800 GDD,则还差 796。不同作物基础温度与成熟所需 GDD 差异很大(如草莓基础温度 10°C,约需 250 GDD 结果)。本作业要求你在 notebook 中把base_temperature改为你所选作物的值。
三、完整实操步骤
1. 连续采集多日温度数据
作业要求先积累数日数据(详见评分标准)。关键前提是服务器代码全程在线:
- 调整电脑电源管理设置,禁止休眠;
- 或运行一个"保持系统活跃"的 Python 脚本(如 keep-system-active 之类的小工具)。
数据采集期间注意:若使用 CounterFit 虚拟设备,应在温度传感器设置中勾选Random复选框并设定 Min/Max 范围(参考 virtual-device-temp.md),避免每次读到的温度完全相同、导致 GDD 计算失去意义。参考截图如下:
2. 创建项目文件夹并准备数据
- 新建文件夹
gdd-calculation; - 将仓库中的 code-notebook/gdd.ipynb 下载/复制到该文件夹;
- 把 MQTT 服务器生成的
temperature.csv也复制到该文件夹(notebook 通过pd.read_csv('temperature.csv')读取,必须同目录)。
3. 创建 Python 虚拟环境并安装依赖
在gdd-calculation文件夹内创建并激活虚拟环境后,依次安装依赖:
pip install --upgrade pip pip install pandas pip install matplotlib pip install jupyter四个包的职责:
pandas:读取 CSV、按日期分组聚合、计算 GDD;matplotlib:绘制温度随时间变化的折线图;jupyter:提供 notebook 运行环境与浏览器交互界面;pip升级确保后续安装顺利。
4. 启动并运行 notebook
jupyter notebook gdd.ipynbJupyter 会在浏览器中打开该 notebook。notebook 将说明与代码组织成一个个cell(单元格),可逐格阅读、运行,也可直接编辑代码——例如把基础温度改成自己作物的值。
四、notebook 逐格拆解:数据如何变成 GDD
仓库中的 code-notebook/gdd.ipynb 共包含如下关键单元格,下面按执行顺序详解。
第 1 步:设定作物基础温度
base_temperature = 10这是唯一需要按作物修改的常量。示例中的 10°C 对应玉米/草莓等常见作物的基础温度;请根据实际作物替换。
第 2 步:加载 CSV 数据
import pandas as pd import matplotlib.pyplot as plt # Read the temperature CSV file df = pd.read_csv('temperature.csv')pd.read_csv把temperature.csv读入 DataFramedf,其中包含date与temperature两列。如果文件不在同目录,此处会抛 FileNotFoundError——这是最常见的运行错误。
第 3 步:绘制温度曲线
plt.figure(figsize=(20, 10)) plt.plot(df['date'], df['temperature']) plt.xticks(rotation='vertical');以日期为横轴、温度为纵轴绘制折线图,rotation='vertical'让密集的日期刻度竖排避免重叠。该图可直观检查数据是否连续、有无异常突变。
第 4 步:按日期分组并提取每日最高/最低温
# Convert datetimes to pure dates so we can group by the date df['date'] = pd.to_datetime(df['date']).dt.date # Group the data by date so it can be analyzed by date data_by_date = df.groupby('date') # Get the minimum and maximum temperatures for each date min_by_date = data_by_date.min() max_by_date = data_by_date.max() # Join the min and max temperatures into one dataframe and flatten it min_max_by_date = min_by_date.join(max_by_date, on='date', lsuffix='_min', rsuffix='_max') min_max_by_date = min_max_by_date.reset_index()这段代码是 GDD 计算的数据基础:
pd.to_datetime(...).dt.date把带时间的 ISO 8601 字符串截断为纯日期,使同一天的多条记录能聚合;groupby('date')按天分组;.min()与.max()分别得到每天的最低温和最高温;join将两组极值按日期合并,lsuffix='_min'/rsuffix='_max'消歧,得到同时含temperature_min与temperature_max两列的数据表。
第 5 步:逐日计算 GDD
def calculate_gdd(row): return ((row['temperature_max'] + row['temperature_min']) / 2) - base_temperature # Calculate the GDD for each row min_max_by_date['gdd'] = min_max_by_date.apply (lambda row: calculate_gdd(row), axis=1) # Print the results print(min_max_by_date[['date', 'gdd']].to_string(index=False))calculate_gdd逐行实现 GDD 简化公式(Tmax + Tmin) / 2 - Tbase,与课程 README 中给出的公式完全一致;apply(..., axis=1)按行应用,结果写入新列gdd,最后打印每天对应的 GDD。
说明:简化公式未处理 Tmax 高于 30°C 或 Tmin 低于基础温度等边界情形(完整公式更复杂),对初学者已足够逼近真实值。
运行完成后,把每天的 GDD 累加,即可与该作物的成熟阈值(如玉米 800–2700、草莓约 250)对比,判断作物距成熟还差多少生长度日——这正是"按需巡查、接近成熟再人工确认"的数字农业工作流的分析基础。
五、与仓库源码的联动:理解数据从哪来
要让 notebook 真正产出有意义的 GDD,temperature.csv必须由运行中的设备+服务器产生。仓库提供了三种设备端发布实现:
- CounterFit 虚拟设备(code-publish-temperature/virtual-device/temperature-sensor/app.py):通过
DHT("11", 5)读取虚拟传感器,mqtt_client.publish(client_telemetry_topic, telemetry)每 10 分钟发布一条{'temperature': temp}消息; - Raspberry Pi 物理设备(code-publish-temperature/pi/temperature-sensor/app.py):逻辑与虚拟设备完全一致,仅将
counterfit_shims_seeed_python_dht替换为真实的seeed_dht库; - Wio Terminal(code-publish-temperature/wio-terminal/temperature-sensor/src/main.cpp):C++ 实现,WiFi 配置与 MQTT 主题在 config.h 中定义,发布周期同样为 10 分钟。
设备端与服务器端必须共享相同的<ID>前缀(如client_telemetry_topic = id + '/telemetry'),否则服务器订阅不到消息、temperature.csv不会增长。可以推断:采集天数越多、采样间隔越密,GDD 结果越接近作物真实生长状况,因此作业要求至少连续运行多日,而非只测几分钟。
六、评分标准(Rubric)
| 标准 | 优秀 | 合格 | 待改进 |
|---|---|---|---|
| 数据采集 | 采集至少2 个完整自然日的数据 | 采集至少1 个完整自然日的数据 | 只采集到部分数据 |
| GDD 计算 | 成功运行 notebook并计算出 GDD | 成功运行 notebook | 无法运行 notebook |
对照此表自检即可:先保证temperature.csv覆盖完整自然日(含夜间温度,因为公式依赖每日最低温),再保证 notebook 从加载、绘图到gdd列输出全流程无报错。
七、常见问题与排错提示
temperature.csv找不到:确认已把该文件复制进gdd-calculation文件夹(notebook 的pd.read_csv使用相对路径);- 日期无法解析:服务器写入的是 ISO 8601 带时区格式,
pd.to_datetime可正常解析;若自行手工编辑过 CSV,需保证日期格式一致; - GDD 为负数:说明当日平均温低于基础温度(如夜间过冷),此时按简化公式会得到负值,可结合课程 README 了解更完整的边界处理;
- 虚拟设备温度恒定:在 CounterFit 中勾选 Random 并设置范围(见前文截图),否则每日最高温=最低温,GDD 恒等于采样值减基础温度;
- 采集中断:检查电脑电源设置,或运行 keep-system-active 之类的脚本防止休眠,确保覆盖完整自然日。
完成上述流程后,你就拥有了一个可复用的"温度遥测 → CSV 落盘 → Notebook 分析"闭环:只需替换base_temperature与成熟所需 GDD 阈值,即可将其推广到任意作物的生长监测场景。
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考