定时服务
物联网 (IoT) 主要涉及将设备联网并通过网络交换数据(如遥测数据和命令)。然而,有很多应用需要自动化功能,即设备需要独立运行,例如,下午 6 点定时开灯,晚上 11 点定时关灯。对此,ESP RainMaker 新增了定时服务功能。
注意:为保证定时服务正确运行,需要 设置适当的时区。如果指定的地区使用夏令时 (DST) ,节点也会做相应处理。查看 管理夏令时 (DST) 获取更多信息。
与 ESP RainMaker 的其余功能类似,定时服务全部在节点端以“服务”的形式实现。云后端只充当节点和客户端(如手机应用)之间的通道。
定时服务功能所有复杂的实现细节都封装在一个简单的 C 语言 API 中,并由手机应用抽象出来。即便如此,我们也需要先了解定时服务的说明。
参数说明
定时服务由单个参数组成,参数为对象数组。启用该功能会在节点配置中添加以下 服务:
{
"name": "Schedule",
"params": [{
"bounds": {
"max": 5
},
"data_type": "array",
"name": "Schedules",
"properties": [
"read",
"write"
],
"type": "esp.param.schedules"
}],
"type": "esp.service.schedule"
}
定时服务参数默认为空数组。"max" 阈值表示节点可以拥有的最大定时服务数量。
添加新的定时服务
可以通过在 setparams
中传递类似下方的值来添加新的定时服务。
{
"Schedule": {
"Schedules": [{
"name": "Evening",
"id": "8D36",
"operation": "add",
"triggers": [{
"d": 31,
"m": 1110
}],
"action": {
"Light": {
"power": true
}
}
}]
}
}
- name:定时服务的名称,建议使用用户友好的名称。
- id:定时服务的唯一 ID,只需对某一用户唯一,无需全局唯一。在添加定时服务时,ID 应由客户端生成,然后再用于后续操作,建议使用简短的 ID。
- operation:执行的操作,可能的值是 add、remove、edit、enable 和 disable。
- triggers:触发定时服务的日期和时间。
- d:星期的位图,最低有效位是星期一。[ N/A | 星期日 | 星期六 | 星期五 | 星期二 | 星期三 | 星期二 | 星期一 ]。例如,0b00011111 (31) 表示所有工作日。0 表示只触发一次。
- m:自凌晨以来的分钟数。例如,下午 6:30 = 18 * 60 + 30 = 1110。
- action:在指定时间执行的具体行动。该对象的值与您在设置参数时传递的值相同。例如,开灯对应的是
"Light": {"power": true}
。 - info (可选):根据客户端要求提供的额外信息或描述。
- flags (可选):根据客户端要求使用的通用标志。
一旦成功添加定时服务,对于参数的 get 请求将获取类似下方的值:
{
"Schedule": {
"Schedules": [{
"name": "Evening",
"id": "8D36",
"enabled": true,
"triggers": [{
"d": 31,
"m": 1110
}],
"action": {
"Light": {
"power": true
}
}
}]
}
}
您可以看到,上方的响应包含 "enabled" 键,表示定时服务已启用。
注意:在添加或更新定时服务时,可以发送定时服务数组中的单个条目。但在查询时,节点会返回数组中所有定时服务的信息。
其他操作
编辑
用于编辑定时服务的值与用于添加定时服务的值类似。ID 应与现有的定时服务匹配,"operation" 的值应该是 "edit"。您可以发送整个对象,也可以只发送更改的元素(名称、触发时间或行动)。但是,这些键中的对象必须保持完整。例如,如果当前的行动是 "action":{"Light": {"power": true, "brightness":90}}
,需要将亮度更改为 100,那么应该传递 "action":{"Light": {"power": true, "brightness":100}}
,而不是 "action":{"Light": {"brightness":100}}
。
删除
要删除现有的定时服务,您只需传递服务 ID 和操作,示例如下所示。
{
"Schedule": {
"Schedules": [{
"id": "8D36",
"operation": "remove"
}]
}
}
启用/禁用
禁用操作的有效载荷与删除操作的非常相似。当需要暂时关闭而不是删除定时服务时,可以禁用定时服务。
{
"Schedule": {
"Schedules": [{
"id": "8D36",
"operation": "disable"
}]
}
}
将操作再设置为 "enable" 会重新启用定时服务。
注意:一次性定时服务在执行后自动禁用。
用法说明
固件
ESP RainMaker 提供了单个 API 来启用定时服务。
esp_err_t esp_rmaker_schedule_enable(void);
该 API 应在
esp_rmaker_node_init()
之后esp_rmaker_start()
之前调用。
可以使用 CONFIG_ESP_RMAKER_SCHEDULING_MAX_SCHEDULES
配置选项配置支持的最大定时服务数量 (idf.py menuconfig -> ESP RainMaker Config -> ESP RainMaker Scheduling -> Maximum Schedules
) 。然而,您可能还需要增加 CONFIG_ESP_RMAKER_MAX_PARAM_DATA_SIZE
来支持更多的定时服务,因为定时服务有效载荷也会增加。
在使用定时服务功能之前,如前所述,建议首先设置时区。请查看 这里 获取有关时区的信息。最简单的方法就是设置 CONFIG_ESP_RMAKER_DEF_TIMEZONE
配置选项,如 CONFIG_ESP_RMAKER_DEF_TIMEZONE="Asia/Shanghai"
。
您可以在 idf.py menuconfig -> ESP RainMaker Config -> Default Timezone
找到上述配置项。
现在 switch、led_light、fan 和 multi_device 示例中默认启用定时服务。
手机应用
手机应用为各种定时服务操作提供了非常简单的用户界面。请更新您的手机应用,启用固件中的定时服务,并开始使用。
跨节点的定时服务
如上文所述,定时服务信息由节点维护,而不是由云后端维护。然而,多个节点共享单个定时服务的需求也比较常见。对于这样的定时服务,客户端可以在多个节点上使用相同的定时服务 ID。即使在查询时,也会在所有节点中查找并显示共享的定时服务 ID。
管理夏令时 (DST)
通常当夏令时开始时,时间向前调整 1 小时,夏令时结束时,时间向后调整 1 小时。以美国洛杉矶时区为例,以下为摘自 维基百科 的说明:
在美国,夏令时从三月的第二个星期日开始,到十一月的第一个星期日结束,并在当地时间凌晨 2 点更改时间。有一个关于季节的记忆方法,时钟 "spring forward, fall back" ——也就是说,在春天,时钟从凌晨 2 点调整到凌晨 3 点,在秋天,时钟从凌晨 2 点调整到凌晨 1 点。
除了 DST 调整当天,定时服务都会在预定时间触发,因为节点会自动根据指定时区的 DST 信息调整时钟。但 DST 调整当天会发生什么呢?这是我们需要考虑的。现在让我们一起看看 DST 调整当天定时服务的情况:
设定的时间 | DST 开始(从 2:00 向前调到 3:00 | DST 结束(从 2:00 向后调到 1:00) |
---|---|---|
凌晨 12:59 及之前 | 无变化 | 无变化 |
凌晨 1:00 到凌晨 1:59 | 无变化 | 在 DST 调整之前只触发一次,在 DST 调整之后不再第二次触发 |
凌晨 2:00 到凌晨 2:59 | 延迟 1 小时。在 DST 调整的当天从 3:00 到 3:59 之间触发 | 无变化 |
凌晨 3:00 及之后 | 无变化 | 无变化 |