cap_scheduler — 定时调度
源码:cap_scheduler.c · 头文件:cap_scheduler.h
cap_scheduler 是 ESP-Claw 的时间触发中心。它负责在指定的时间点生成事件并推送到 claw_event_router。调度器本身不执行具体的业务逻辑(如发消息或调工具),而是通过发布事件来触发后续的自动化规则。
这种「调度与执行分离」的设计,使得定时任务可以复用 Event Router 的所有动作能力(run_agent、call_cap、run_script 等)。
调度项(Schedule Item)
Section titled “调度项(Schedule Item)”每个调度项定义了「什么时候」发布「什么样的事件」。主要字段包括:
id: 唯一标识。kind: 调度类型,支持once(一次性)、interval(间隔)、cron(标准 5 段式 Cron 表达式)。enabled: 是否启用。event_type: 发布事件的类型(对应路由规则的match.event_type)。event_key: 事件键(对应路由规则的match.event_key)。payload_json: 附带的 JSON 数据。
调度数据持久化
Section titled “调度数据持久化”调度器管理两份数据:
- 定义文件 (
schedules.json):存储所有的调度项配置。 - 状态文件(由
schedules_path + ".state"自动推导,例如schedules.json.state):存储运行时的动态信息,如last_fire_ms(上次触发时间)、run_count(运行次数)等。这保证了设备重启后能正确找回进度,不会丢失或重复触发任务。
每次 scheduler_reload(以及启动时加载)后,调度器会将条目按默认值规则补齐 schedules.json 中的缺失字段。
暴露给 LLM 的工具
Section titled “暴露给 LLM 的工具”| 工具 ID | 功能 | 输入参数 |
|---|---|---|
scheduler_list | 列出所有调度项及其运行状态 | (无) |
scheduler_get | 查询单个调度项详情 | id |
scheduler_add | 新增一个调度项 | schedule_json (字符串) |
scheduler_update | 更新一个已存在的调度项 | schedule_json (字符串) |
scheduler_remove | 删除一个调度项 | id |
scheduler_enable | 启用指定调度项 | id |
scheduler_disable | 禁用指定调度项 | id |
scheduler_pause | 暂停指定调度项 | id |
scheduler_resume | 恢复指定调度项 | id |
scheduler_trigger_now | 立即触发一次调度(不影响后续计划) | id |
scheduler_reload | 从磁盘重新加载配置 | (无) |
其中:
schedule_json(字符串) 指{"schedule_json":"<JSON 字符串>"},其中schedule_json是字符串(需转义),不是嵌套的对象。id指{"id":"..."}。
1. 配置调度项
Section titled “1. 配置调度项”典型的 schedules.json 条目:
2. 配置路由规则
Section titled “2. 配置路由规则”在 router_rules.json 中添加对应规则,将该调度事件发送到 IM:
时间同步说明
Section titled “时间同步说明”cap_scheduler 依赖系统时间的准确性。
- 对于
cron和once任务,必须在 SNTP 同步成功后才会触发。 - 对于
interval任务,若没有配置start_at或end_at,则不依赖外部时间,上电即开始计时。 cron的匹配基于设备当前本地时间(localtime_r)。
首次时间同步后的时间校准
Section titled “首次时间同步后的时间校准”basic_demo 在首次 SNTP 同步成功(had_valid_time == false)后,会调用 cap_scheduler_handle_time_sync() 对调度器进行时间校准(rebase):设备上电后可能基于不准确的时钟提前开始计时,首次获得有效系统时间后,调度器会修正各任务的参考时间点,避免重复触发或遗漏触发。
配置与初始化
Section titled “配置与初始化”在应用层初始化: