跳转到内容

时间组件

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

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

  • id (可选,ID):指定时间的 ID,供在 lambdas 中使用。

  • timezone (可选,字符串):手动告诉 ESPHome 使用什么时区,格式为 this format (注意:格式相当复杂,参见示例) 或更简单的 TZ 数据库名称 形式, 即 <Region>/<City>。ESPHome 会尝试根据运行 ESPHome 的计算机的时区自动推断时区字符串,但这并不总是准确。在 nRF52 平台上不可用。 空的时区(空字符串 "")意味着不会编译时区处理,因此设备将 严格基于 UTC 运行。

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

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

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

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

# 配置示例
on_...:
if:
condition:
time.has_time:
then:
- logger.log: Time has been set and is valid!
# 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 (可选,字符串):指定自动化将在分钟内的哪些秒触发。 默认为 *(所有秒)。范围从 0 到 59。

  • minutes (可选,字符串):指定自动化将在小时内的哪些分钟触发。 默认为 *(所有分钟)。范围从 0 到 59。

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

  • days_of_month (可选,字符串):指定自动化将在一个月中的哪些日期触发。 默认为 *(所有日期)。范围从 1 到 31。

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

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

  • cron (可选,字符串):或者,你可以指定整个 cron 表达式,如 * /5 * * * *。请注意,年份和一些特殊字符如 L、# 目前不受支持。另外, 周几字段按 days_of_week 变量的方式解释(范围从 1(周日)到 7(周六)), 而不是像其他 cron 实现那样(范围从 0(周日)到 7(周日))。

  • 请参见 Automation。

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

  • seconds: 0

    像 0 或 30 这样的整数将使自动化仅在当前 秒恰好为 0 或 30 时触发。

  • seconds: 0,30,45

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

  • 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: "Synchronized system clock"

NOTE

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

要在 lambdas 中获取应用了时区的当前本地时间,只需像这样调用 .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
%%字面 % 字符%