HTTPS API数据获取(Node-RED)
HTTPS API数据获取(Node-RED)
本节介绍使用 Node-RED 从 REST API 获取天气数据。电子纸显示屏显示天气数据,该数据先从 API 获取,在 Node-RED 中处理,然后通过 MQTT 发送到 ESP32。完成本节后,你将能够:
- 在 Node-RED 中配置 HTTP Request 节点
- 从公共 REST API(OpenWeatherMap)获取数据
- 处理 API 响应和错误情况
- 为通过 MQTT 传输到 ESP32 准备数据
开始本节前,请确保:
- Node-RED 已安装并运行(参见第 9 章)
- MQTT Broker(Mosquitto)正在运行
- 基本理解 REST API
- OpenWeatherMap API 密钥(在 openweathermap.org 免费注册)
[天气 API] ──HTTPS──→ [Node-RED] ──MQTT──→ [ESP32] ──SPI──→ [电子墨水屏] │ ↓ [调试/日志]Node-RED 作为中间件:
- 定期从 API 获取天气数据
- 解析 JSON 响应
- 提取相关值(温度、湿度、预报)
- 通过 MQTT 将处理后的数据发布到 ESP32
为什么用 Node-RED 而非 ESP32 直接获取?
Section titled “为什么用 Node-RED 而非 ESP32 直接获取?”| 考量 | ESP32 直接获取 | Node-RED 中间件 |
|---|---|---|
| API 密钥安全 | 暴露在固件中 | 存储在服务器上 |
| 数据处理 | 内存有限 | 完整的 JavaScript |
| 多个显示屏 | 各自独立获取 | 一次获取,多端订阅 |
| 错误处理 | 复杂且含延迟 | 使用 catch 节点轻松处理 |
| API 速率限制 | 难以管理 | 集中控制 |
| 固件更新 | API 更改需要更新固件 | 无需更改固件 |
步骤 1:注册 OpenWeatherMap API
Section titled “步骤 1:注册 OpenWeatherMap API”- 访问 openweathermap.org
- 点击 Sign In → Create an Account
- 注册后,转到 API Keys 标签页
- 复制默认 API 密钥(或创建一个新密钥)
重要提示:新 API 密钥可能需要 1-2 小时才能激活。在 Node-RED 中使用前,先在浏览器中测试密钥。
步骤 2:获取位置坐标
Section titled “步骤 2:获取位置坐标”查找你所在位置的纬度和经度:
# 选项 1:使用 latlong.nethttps://www.latlong.net/
# 选项 2:使用 OpenWeatherMap 的地理编码 API# https://api.openweathermap.org/geo/1.0/direct?q={city}&limit=1&appid={API_KEY}示例:中国北京 → lat: 39.9042, lon: 116.4074
步骤 3:构建 Node-RED 流程
Section titled “步骤 3:构建 Node-RED 流程”在 Node-RED 中创建一个包含以下节点的新流程:
流程图:
[Inject(时间戳)] ─→ [HTTP Request] ─→ [JSON Parse] ─→ [Function] ─→ [MQTT Out] │ ↓ [Debug]节点 1:Inject(触发器)
Section titled “节点 1:Inject(触发器)”创建一个 Inject 节点来触发流程:
- 名称:
每 30 分钟触发 - 载荷:
timestamp - 重复:
interval,每30分钟
节点 2:HTTP Request
Section titled “节点 2:HTTP Request”添加 HTTP Request 节点来获取天气数据:
- 方法:
GET - URL:
https://api.openweathermap.org/data/2.5/weather?lat=39.9042&lon=116.4074&units=metric&appid=YOUR_API_KEY- 名称:
获取天气数据 - 返回:
A parsed JSON object
参数说明:
lat:纬度lon:经度units=metric:以摄氏度返回温度appid:你的 API 密钥
节点 3:JSON Parse
Section titled “节点 3:JSON Parse”添加 JSON 节点来解析响应:
- 名称:
解析 JSON - 动作:
Always convert to JSON object
节点 4:Function(数据转换)
Section titled “节点 4:Function(数据转换)”添加 Function 节点来提取和格式化数据:
// 从 OpenWeatherMap 响应中提取相关数据const weatherData = { temperature: msg.payload.main.temp.toFixed(1), feels_like: msg.payload.main.feels_like.toFixed(1), humidity: msg.payload.main.humidity, pressure: msg.payload.main.pressure, description: msg.payload.weather[0].description, icon: msg.payload.weather[0].icon, city: msg.payload.name, timestamp: new Date().toISOString()};
// 设置输出为 JSON 字符串,用于 MQTTmsg.payload = JSON.stringify(weatherData);
return msg;名称:格式化天气数据
节点 5:MQTT Out
Section titled “节点 5:MQTT Out”添加 MQTT Out 节点来发布格式化后的数据:
- 服务器:选择你的 Mosquitto Broker
- 主题:
factory/weather/data - QoS:
1 - 名称:
发布天气数据
步骤 4:完整流程 JSON(可直接导入)
Section titled “步骤 4:完整流程 JSON(可直接导入)”将此 JSON 复制并导入到 Node-RED:
[ { "id": "trigger", "type": "inject", "name": "每 30 分钟触发", "repeat": "1800", "crontab": "", "once": true, "payload": "", "payloadType": "date", "wires": [["http_req"]] }, { "id": "http_req", "type": "http request", "name": "获取天气数据", "method": "GET", "url": "https://api.openweathermap.org/data/2.5/weather?lat=39.9042&lon=116.4074&units=metric&appid=YOUR_API_KEY", "ret": "obj", "tls": "", "wires": [["json_parse"]] }, { "id": "json_parse", "type": "json", "name": "解析 JSON", "action": "", "property": "payload", "wires": [["format_data"]] }, { "id": "format_data", "type": "function", "name": "格式化天气数据", "func": "const weatherData = {\n temperature: msg.payload.main.temp.toFixed(1),\n feels_like: msg.payload.main.feels_like.toFixed(1),\n humidity: msg.payload.main.humidity,\n pressure: msg.payload.main.pressure,\n description: msg.payload.weather[0].description,\n icon: msg.payload.weather[0].icon,\n city: msg.payload.name,\n timestamp: new Date().toISOString()\n};\n\nmsg.payload = JSON.stringify(weatherData);\nreturn msg;", "wires": [["mqtt_out"]] }, { "id": "mqtt_out", "type": "mqtt out", "name": "发布天气数据", "topic": "factory/weather/data", "qos": "1", "retain": "false", "broker": "your_broker_id", "wires": [] }]步骤 5:测试流程
Section titled “步骤 5:测试流程”- 在 Node-RED 中点击 部署
- 点击 Inject 节点上的按钮手动触发
- 检查 Debug 面板的输出:
预期调试输出:
{ "temperature": "25.5", "feels_like": "24.0", "humidity": 60, "pressure": 1013, "description": "scattered clouds", "icon": "03d", "city": "London", "timestamp": "2026-05-17T10:30:00.000Z"}步骤 6:验证 MQTT 传输
Section titled “步骤 6:验证 MQTT 传输”使用 MQTT Explorer 或命令行进行验证:
# 订阅天气主题mosquitto_sub -h localhost -t "factory/weather/data"
# 预期输出(触发后):# {"temperature":"25.5","humidity":60,"description":"scattered clouds",...}处理 API 错误
Section titled “处理 API 错误”添加错误处理以防止损坏的数据到达 ESP32:
带错误处理的 Function 节点:
// 检查 API 是否返回有效数据if (!msg.payload || !msg.payload.main) { // 出错时返回缓存/默认数据 const fallbackData = { temperature: "--.-", humidity: "--", description: "无数据", error: true, timestamp: new Date().toISOString() }; msg.payload = JSON.stringify(fallbackData); return msg;}
// 正常处理const weatherData = { temperature: msg.payload.main.temp.toFixed(1), humidity: msg.payload.main.humidity, description: msg.payload.weather[0].description, error: false, timestamp: new Date().toISOString()};
msg.payload = JSON.stringify(weatherData);return msg;使用静态测试数据
Section titled “使用静态测试数据”在开发期间,使用静态 JSON 以避免达到 API 速率限制:
带静态 JSON 的 Inject 节点:
创建一个带有静态天气数据的第二个 Inject 节点:
{ "temperature": "25.5", "feels_like": "24.0", "humidity": 60, "pressure": 1013, "description": "scattered clouds", "icon": "03d", "city": "London", "timestamp": "2026-05-17T10:30:00.000Z"}将其直接连接到 MQTT Out 节点用于离线测试。
- Node-RED 流程部署无错误
- API 返回有效的 JSON 数据
- 数据正确格式化并发布到 MQTT
- MQTT Explorer 显示已发布的消息
- ESP32 接收 MQTT 数据(如果已连接)
问题 1:HTTP 请求返回错误
Section titled “问题 1:HTTP 请求返回错误”症状:
Error: ETIMEDOUTError: "Not found"解决方案:
- 检查 API 密钥是否正确
- 确认 API 密钥已激活(超过 1 小时)
- 检查互联网连接
- 验证 URL 参数(lat、lon、units、appid)
问题 2:收到无效 JSON
Section titled “问题 2:收到无效 JSON”症状:
Error: Unexpected token解决方案:
- 在 HTTP Request 节点后直接添加调试节点,查看原始响应
- 检查 API 是否返回了错误消息而非数据
- 使用 Catch 节点添加 JSON 解析错误处理
问题 3:MQTT 未收到数据
Section titled “问题 3:MQTT 未收到数据”症状:
- MQTT Out 节点显示无错误
- ESP32 未收到数据
解决方案:
- 验证 MQTT 代理是否正在运行:
docker ps | grep mosquitto - 检查发布者和订阅者之间的主题名称是否匹配
- 验证 QoS 设置是否一致
- ✅ 开发期间使用静态测试数据——避免达到 API 速率限制
- ✅ 在 Function 节点中添加错误处理——防止损坏的数据传播
- ✅ 设置 inject 的 “once: true”——部署后立即获取初始数据
- ❌ 不要超过每 10 分钟一次获取频率——遵守 API 速率限制
- ❌ 不要在共享流程中硬编码 API 密钥——使用环境变量
- Node-RED 通过 HTTP Request 节点从公共 API 获取天气数据
- JSON 数据在 Function 节点中解析和转换
- 处理后的数据通过 MQTT 发布到 ESP32
- Node-RED 处理错误情况并提供回退数据
- 30 分钟更新间隔在数据新鲜度和 API 速率限制之间取得平衡