跳转到内容

时间组件

time 组件允许您为 ESPHome 设置实时时钟时间源。然后您可以在 lambda 中获取当前时间。

所有时间配置模式继承这些选项。

  • id (可选, ID):指定用于 lambda 的时间 ID。

  • timezone (可选, string):使用 此格式 手动告诉 ESPHome 使用什么时区(警告:格式相当复杂,请参阅 示例)或更简单的 TZ 数据库名称,形式为 <区域>/<城市>。ESPHome 尝试根据运行 ESPHome 的计算机时区自动推断时区字符串,但这可能并不总是准确的。在 nRF52 平台上不可用。

  • on_time (可选, 自动化):使用类似 cron 的语法在特定间隔运行的自动化。请参阅 on_time 触发器

  • on_time_sync (可选, 自动化):当时间源可以(重新)同步时运行的自动化。请参阅 on_time_sync 触发器

  • update_interval (可选, 时间):从源同步设备时间的频率。默认为 15min

条件 检查时间是否已设置且有效。

# 示例配置
on_...:
if:
condition:
time.has_time:
then:
- logger.log: 时间已设置且有效!
# 示例 lambda
lambda: |-
if (id(my_time).now().is_valid()) {
//在此处执行某些操作
}

这个强大的自动化可用于在特定时间的特定间隔运行自动化。语法是 crontab 语法的子集。

有两种指定时间间隔的方法:使用 seconds:minutes: … 键,如下所示,或使用类似 cron 的表达式,如 * /5 * * * *

请注意,普通的 cron 实现不知道秒,而这个 esphome 实现知道,因此您有 6 个字段(秒、分钟、小时、月中的日、月、周中的日)。

基本上,自动化引擎每秒都会查看您配置的时间计划,并评估是否应该运行自动化。

time:
- platform: sntp
# ...
on_time:
# 每 5 分钟
- seconds: 0
minutes: /5
then:
- switch.toggle: my_switch
# 工作日每天早上
- seconds: 0
minutes: 30
hours: 7
days_of_week: MON-FRI
then:
- light.turn_on: my_light
# Cron 语法,每 5 分钟触发
- cron: '00 /5 * * * *'
then:
- switch.toggle: my_switch

配置变量:

  • seconds (可选, string):指定分钟中的哪些秒将触发自动化。默认为 *(所有秒)。范围是 0 到 59。

  • minutes (可选, string):指定小时中的哪些分钟将触发自动化。默认为 *(所有分钟)。范围是 0 到 59。

  • hours (可选, string):指定一天中的哪些小时将触发自动化。默认为 *(所有小时)。范围是 0 到 23。

  • days_of_month (可选, string):指定月中的哪些天将触发自动化。默认为 *(所有天)。范围是 1 到 31。

  • months (可选, string):指定一年中的哪些月份触发。默认为 *(所有月份)。月份名称 JAN 到 DEC 会自动替换。范围是 1(一月)到 12(十二月)。

  • days_of_week (可选, string):指定一周中的哪些天触发。默认为 *(所有天)。名称 SUN 到 SAT 会自动替换。范围是 1(星期日)到 7(星期六)。

  • cron (可选, string):或者,您可以指定整个 cron 表达式,如 * /5 * * * *。请注意,目前不支持年份和某些特殊字符如 L#。此外,周中的日字段解释与 days_of_week 变量相同(范围从 1(星期日)到 7(星期六)),而不是其他 cron 实现的方式(范围从 0(星期日)到 7(星期日))。

  • 请参阅 自动化

seconds:minutes: … 字段中,您可以使用以下运算符:

  • seconds: 0

    030 这样的整数将使自动化仅在当前秒正好是 0 或 30 时触发。

  • seconds: 0,30,45

    您可以使用 , 运算符组合多个表达式。此运算符使得如果用逗号分隔的任一表达式成立,自动化就会触发。例如 0,30,45 将在当前秒是 03045 时触发。

  • days_of_week: 2-6
    # 相同于
    days_of_week: MON-FRI
    # 相同于
    days_of_week: 2,3,4,5,6
    # 相同于
    days_of_week: MON,TUE,WED,THU,FRI

    -(连字符)运算符可用于创建值的范围,是使用 , 运算符列出所有值的简写。

  • # 每 5 分钟
    seconds: 0
    minutes: /5
    # 分钟为 5,15,25,... 的每个时间戳
    seconds: 0
    minutes: 5/10

    / 运算符可用于创建步进值。例如 minutes:/5 使自动化仅在小小时为 0、或 5、10、15、… 时触发。/ 前面的值指定应用步进的偏移量。

  • # 每分钟
    seconds: 0
    minutes: '*'

    最后,* 运算符匹配每个数字。在上面的示例中,* 可以替换为 0-59

WARNING

请注意,以下自动化将在分钟 0、5、10、15 的每一秒触发,而不是每 5 分钟一次,因为没有设置 seconds 变量:

time:
- platform: sntp
# ...
on_time:
- minutes: /5
then:
- switch.toggle: my_switch

NOTE

on_time 不会为由于本地夏令时或其他本地时间调整(如闰秒)而跳过或重复的时间重新安排事件。在有夏令时的地区,这意味着位于 01:00 - 02:00 之间的事件可能每年触发两次,而计划在 02:00 - 03:00 之间的事件可能每年跳过一次。这不同于 cron 的行为,尽管允许使用类似的 crontab 语法。同样,在不存在的月份日期上的触发器(“每月 31 日”)将在这些日期不存在时跳过。

此自动化在时间源成功获取当前时间后触发。请参阅 DS1307 配置示例,了解从 Home Assistant 服务器进行网络时间同步触发写入外部硬件实时时钟芯片的场景。

on_time_sync:
then:
- logger.log: "系统时钟已同步"

NOTE

组件在更新系统时钟时应触发 on_time_sync。但是,并非所有实时组件的行为都完全相同。例如,组件可能仅在观察到显著时间变化时才触发,而其他组件可能在运行其时间同步机制时触发——即使这并未有效更改系统时间。有些(如某些情况下的 SNTP)甚至可能在另一个实时组件负责时间变化时触发。

要在 lambda 中获取应用了时区的当前本地时间,只需像这样调用 .now() 方法:

auto time = id(sntp_time).now();

或者,您可以使用 .utcnow() 获取当前 UTC 时间。

返回的对象可以直接用于获取当前分钟、小时、… 作为数字,也可以基于给定格式创建字符串。如果要获取当前时间属性,可以使用这些字段

名称含义范围(含)示例
.second分钟后的秒数[0-60](通常为 [0-59],额外范围用于适应闰秒)42
.minute小时后的分钟数[0-59]31
.hour午夜后的小时数[0-23]16
.day_of_week一周中的第几天,星期日=1[1-7]7(星期六)
.day_of_month月中的日[1-31]18
.day_of_year年中的日[1-366]231
.month月份,一月=1[1-12]8(八月)
.year公元年份[1970-∞[2018
.is_dst是否为夏令时false, truetrue
.timestampUnix 时间戳(自 UTC 1970 年 1 月 1 日午夜以来的秒数)[-2147483648 - 2147483647](负值表示 2038 年 1 月 19 日之后的时间)1534606002
.is_valid()基本检查时间是否有效(即不是 1970 年 1 月 1 日)false, truetrue

NOTE

在 ESP 连接到互联网并获取当前时间之前,日期将是 1970 年 1 月 1 日。因此,在触发任何操作之前,请确保检查 .is_valid() 是否为 true

使用时间对象的第二种方法是将其直接转换为字符串,如 2018-08-16 16:31。这直接使用 C 的 strftime 函数完成,该函数提供了很大的灵活性。

// 例如,在显示对象中
it.strftime(0, 0, id(font), "%Y-%m-%d %H:%M", id(time).now());

strftime 将解析格式字符串(此处为 "%Y-%m-%d %H:%M"),并匹配任何以百分号 % 和对应于以下格式选项之一的字母开头的内容,并将其替换为该格式选项的当前时间表示。

指令含义示例
%a缩写的星期名称Sat
%A完整的星期名称Saturday
%w星期作为十进制数,其中 0 是星期日,6 是星期六6
%d月中的日作为零填充的十进制数01, 02, …, 31
%b缩写的月份名称Aug
%B完整的月份名称August
%m月份作为零填充的十进制数01, 02, …, 12
%y年份不含世纪作为零填充的十进制数00, 01, …, 99
%Y年份含世纪作为十进制数2018
%H小时(24 小时制)作为零填充的十进制数00, 01, …, 23
%I小时(12 小时制)作为零填充的十进制数00, 01, …, 12
%pAM 或 PM 标识AM, PM
%M分钟作为零填充的十进制数00, 01, …, 59
%S作为零填充的十进制数00, 01, …, 59
%j年中的日作为零填充的十进制数001, 002, …, 366
%U年份的周数(星期日为一周的第一天)作为零填充的十进制数。新年中第一个星期日之前的所有天被视为第 0 周。00, 01, …, 53
%W年份的周数(星期一为一周的第一天)作为零填充的十进制数。新年中第一个星期一之前的所有天被视为第 0 周。00, 01, …, 53
%c日期和时间表示Sat Aug 18 16:31:42 2018
%x日期表示08/18/18
%X时间表示16:31:42
%%字面的 % 字符%