Node-RED 调度逻辑
Node-RED 调度逻辑
本节介绍如何通过 Node-RED 实现广播系统的调度逻辑。学习完成后,您将能够:
- 在 Node-RED 中创建定时触发流程
- 配置工作日/节假日不同调度策略
- 实现广播系统状态的可视化仪表板
- 通过仪表板控制广播定时计划
在开始本节之前,请确保:
- 已完成 Node-RED 基础学习
- 了解 Node-RED 的 inject 节点和 function 节点
- Mosquitto 或 EMQX Broker 已运行
- 已完成 ESP32 端的定时调度配置
Node-RED Timer Flow
Section titled “Node-RED Timer Flow”Basic Timer with Inject Node
Section titled “Basic Timer with Inject Node”使用 Node-RED 的 inject 节点实现定时触发:
{ "id": "inject_timer", "type": "inject", "repeat": "custom", // 自定义间隔 "crontab": "0 6 * * 1-5", // cron 表达式:工作日 6:00 "payload": "play", "payload_type": "str", "topic": "factory/broadcast/schedule"}cron 表达式示例:
| cron 表达式 | 含义 |
|---|---|
0 6 * * 1-5 | 工作日 6:00 |
30 7 * * * | 每天 7:30 |
0 8 * * 6,0 | 周末 8:00 |
0 12 * * 1-5 | 工作日 12:00 |
0 17 * * 1-5 | 工作日 17:00 |
0 21 * * * | 每天 21:00 |
Node-RED Schedule Flow
Section titled “Node-RED Schedule Flow” ┌─────────────────────┐ Inject ──────→│ Schedule Check ├──────→ MQTT Out (Timer) │ (Function Node) │ └─────────────────────┘ │ ▼ ┌─────────────────────┐ │ Log to File/Debug │ └─────────────────────┘Schedule Check Function 节点:
// 检查当前时间并执行调度const now = new Date();const hour = now.getHours();const minute = now.getMinutes();const day = now.getDay(); // 0=周日, 1=周一, ...
// 工作日检查(周一至周五)const isWeekday = day >= 1 && day <= 5;
// 解析 cron 触发时间const triggerHour = parseInt(msg.topic.split(' ')[0]);const triggerMinute = parseInt(msg.topic.split(' ')[1]);
if (hour === triggerHour && minute === triggerMinute) { msg.payload = { hour: hour, minute: minute, weekday: isWeekday, action: "schedule_trigger" }; return msg;}return null;Advanced Schedule Configuration
Section titled “Advanced Schedule Configuration”Complete Schedule Flow
Section titled “Complete Schedule Flow”创建完整的调度管理流程:
{ "flows": [ { "id": "schedule_manager", "nodes": [ // 1. 定时触发节点 { "id": "timer_0600_weekdays", "type": "inject", "crontab": "0 6 * * 1-5", "payload": "{\"action\":\"play\",\"station\":0,\"volume\":40}", "topic": "factory/broadcast/control" }, { "id": "timer_0730_weekdays", "type": "inject", "crontab": "30 7 * * 1-5", "payload": "{\"action\":\"play\",\"station\":1,\"volume\":60}", "topic": "factory/broadcast/control" }, { "id": "timer_1200_weekdays", "type": "inject", "crontab": "0 12 * * 1-5", "payload": "{\"action\":\"play\",\"station\":2,\"volume\":50}", "topic": "factory/broadcast/control" }, { "id": "timer_1700_weekdays", "type": "inject", "crontab": "0 17 * * 1-5", "payload": "{\"action\":\"stop\"}", "topic": "factory/broadcast/control" }, // 周末配置 { "id": "timer_0900_weekends", "type": "inject", "crontab": "0 9 * * 6,0", "payload": "{\"action\":\"play\",\"station\":1,\"volume\":30}", "topic": "factory/broadcast/control" }, { "id": "timer_2100_all", "type": "inject", "crontab": "0 21 * * *", "payload": "{\"action\":\"stop\"}", "topic": "factory/broadcast/control" }, // MQTT 输出 { "id": "mqtt_out", "type": "mqtt out", "server": "localhost", "topic": "factory/broadcast/control", "qos": 1 }, // 调试输出 { "id": "debug_out", "type": "debug" } ], "connections": [ {"from": "timer_0600_weekdays", "to": "mqtt_out"}, {"from": "timer_0730_weekdays", "to": "mqtt_out"}, {"from": "timer_1200_weekdays", "to": "mqtt_out"}, {"from": "timer_1700_weekdays", "to": "mqtt_out"}, {"from": "timer_0900_weekends", "to": "mqtt_out"}, {"from": "timer_2100_all", "to": "mqtt_out"} ] } ]}Dashboard Control Panel
Section titled “Dashboard Control Panel”Schedule Control Dashboard
Section titled “Schedule Control Dashboard”创建 Node-RED 仪表板来管理广播调度:
// ui_group: "广播系统"// ui_tab: "工业广播"
// 1. 手动控制区域{ "id": "btn_play", "type": "ui_button", "group": "broadcast_control", "label": "播放", "payload": "play", "topic": "factory/broadcast/play"}
// 2. 电台选择{ "id": "dropdown_station", "type": "ui_dropdown", "group": "broadcast_control", "label": "选择音源", "options": [ {"label": "晨间新闻", "value": "0"}, {"label": "背景音乐", "value": "1"}, {"label": "轻音乐", "value": "2"}, {"label": "古典音乐", "value": "3"} ], "topic": "factory/broadcast/station"}
// 3. 音量滑块{ "id": "slider_volume", "type": "ui_slider", "group": "broadcast_control", "label": "音量", "min": 0, "max": 250, "step": 5, "topic": "factory/broadcast/volume"}
// 4. 状态显示{ "id": "text_status", "type": "ui_text", "group": "broadcast_status", "label": "当前状态"}
// 5. 调度时间表显示{ "id": "table_schedule", "type": "ui_table", "group": "broadcast_schedule", "label": "定时计划"}Dashboard Layout
Section titled “Dashboard Layout”┌─────────────────────────────────────┐│ 工业广播控制面板 │├─────────────────────────────────────┤│ ││ [▶ 播放] [⏸ 暂停] [⏹ 停止] ││ ││ 音源: [下拉选择] ││ ││ 音量: [────────●────────] 65 ││ ││ 当前状态: 播放中 ││ 当前音源: 背景音乐 ││ 当前音量: 65 ││ 当前曲目: Morning Melody ││ │├─────────────────────────────────────┤│ 定时计划 ││ 06:00 工作日 ▶ 晨间新闻 音量:40 ││ 07:30 工作日 ▶ 背景音乐 音量:60 ││ 12:00 工作日 ▶ 轻音乐 音量:50 ││ 17:00 工作日 ⏹ 关闭 ││ 21:00 每天 ⏹ 关闭 │└─────────────────────────────────────┘Status Monitoring Flow
Section titled “Status Monitoring Flow”Real-time Status Display
Section titled “Real-time Status Display”{ "id": "status_listener", "type": "mqtt in", "topic": "factory/broadcast/status", "server": "localhost", "qos": 1}Status Processing Function:
// MQTT 状态消息处理const status = msg.payload;
// 更新仪表板显示const statusMsg = { payload: `播放: ${status.playing ? '🟢 播放中' : '🔴 已停止'}音源: ${status.station_name}音量: ${status.volume}信号: ${status.wifi_rssi} dBm`};
return statusMsg;Logging and History
Section titled “Logging and History”Schedule Event Logging
Section titled “Schedule Event Logging”// 记录调度事件到文件和控制台const eventLog = { timestamp: new Date().toISOString(), event: msg.payload.action || msg.topic, details: msg.payload};
// 写入日志文件context.global.log.push(eventLog);if (context.global.log.length > 1000) { context.global.log.shift();}
node.warn(`调度事件: ${JSON.stringify(eventLog)}`);return msg;问题 1: Node-RED 定时任务不触发
Section titled “问题 1: Node-RED 定时任务不触发”症状: inject 节点到达预设时间但未输出消息
原因:
- Node-RED 服务器时区设置不正确
- 流程未部署
- cron 表达式错误
解决方案:
- 检查 Node-RED 系统时区:
settings.js中的env设置 - 确认流程已部署(右上角 Deploy 按钮)
- 使用
*/1 * * * *测试 cron 表达式是否正常工作
问题 2: 仪表板不显示数据
Section titled “问题 2: 仪表板不显示数据”症状: Dashboard UI 显示空白
原因:
- dashboard 节点未正确配置 group 和 tab
- MQTT 消息未到达
- 上下文变量未初始化
解决方案:
- 检查 ui_group 和 ui_tab 配置
- 使用 debug 节点确认 MQTT 消息到达
- 初始化全局上下文变量
Summary
Section titled “Summary”本节介绍了 Node-RED 端的调度逻辑实现:
- 定时触发:使用 inject 节点的 cron 表达式实现精确时间触发
- Dashboard 控制:创建仪表板界面,支持手动控制和状态监控
- 调度管理:完整的定时播放/停止流程
- 状态监听:实时显示广播系统的工作状态
- 事件记录:记录调度执行日志