ESPHome 中的 YAML 配置
ESPHome 配置文件使用 YAML,这是一种人类友好的数据序列化标准。本页面解释了标准 YAML 特性和 ESPHome 特定的扩展。
YAML 的设计目标是易于阅读和编辑,但也可能令人沮丧,特别是在缩进方面。YAML 是 JSON 的超集,JSON 语法可以在 YAML 文件中使用。
ESPHome YAML 文件中配置块的顺序通常不重要,因为在任何验证或处理之前会读取全部内容。
标准 YAML 特性
Section titled “标准 YAML 特性”- 注释:
#后的任何文本都是注释。 - 标量: 字符串、数字、布尔值。
- 序列: 项目列表,使用
-或[ ... ]。 - 映射: 键值对,使用
key: value或{ ... }。 - 锚点和别名: 使用
&anchor和*alias重用 YAML 块。 - 多行字符串: 使用
|或>处理多行文本。
YAML 注释是 # 符号后的任何文本,延伸到行尾。如果需要在字符串中包含 # 字符,必须将其放在引号内。
示例:
# 这是一个注释foo: bar: 3 # 这是另一个注释 text: "# 可以包含在字符串中"YAML 标量是任何不包含冒号 (:) 的值。它可以是字符串、数字、布尔值或 null。
字符串用双引号 (") 或单引号 (') 括起。标准转义序列(如换行符 \n 和 Unicode 码点)仅在双引号内被转换。字符串也可以是不带引号的字符序列,且不是有效的数字或布尔值,例如 23times 即使不加引号也会被视为字符串。字符串也可以是多行的,使用 | 或 >。
布尔值是 true 或 false,不区分大小写。ESPHome 还将其他字符串映射为布尔值:
yes、on和enable映射为true。no、off和disable映射为false。
数值是整数或浮点数。在 ESPHome 中,大多数需要数字的情况下,也可以写成包含整数或浮点数的字符串,将自动转换。
示例:
esp8266: board: esp8285 # esp8285 是一个字符串 restore_from_flash: true # 布尔值
web_server: port: 80 # 整数值YAML 序列是使用 - 或 [ ... ] 的项目列表(或数组)。项目可以是标量、序列或映射。- 标记每行用于一个序列项,而使用 [ ... ] 的 JSON 风格可以在单行上,也可以跨多行。
示例:
# JSON 风格data_pins: [48, 47, 39, 40]
# YAML 风格data_pins: - 48 - 47 - 39 - 40
sensors:# 传感器列表,每个都是一个映射 - platform: gpio name: "Temperature 1" pin: GPIO32
- platform: gpio name: "Temperature 2" pin: GPIO33YAML 格式的序列有时会令人困惑 - 请考虑以下示例:
- platform: gpio name: "Temperature 1"
- label: text: "Temperature 1"第一种情况没有额外缩进,而第二种情况有,这可能看起来很奇怪。区别在于第一种情况的序列项本身是一个映射,键为 platform 和 name,而第二种情况的序列项是键 label,其值为包含键 text 和值 "Temperature 1" 的映射。用 JSON 格式重写这些会更清晰:
- { "platform": "gpio", "name": "Temperature 1" }- { "label": { "text": "Temperature 1" } }一个有用的经验法则是,当序列项以冒号结尾时,其值必须是映射而不是标量,因此后续行需要进一步缩进。以下示例是错误的,会抛出两个错误:
- label: # 会抛出错误 "expected a dictionary" text: "Temperature 1" # 错误!应该缩进。会抛出错误 "text is an invalid option for ..."YAML 映射是使用 key: value 或 { ... } 的键值对列表。键可以是任何有效的 YAML 标量(虽然通常限于预定义集合中的字符串),而值可以是任何有效的 YAML 标量、列表或映射。映射也可以称为字典、关联数组或哈希表。单个映射中使用的键必须唯一。
示例:
sensor: platform: gpio pin: GPIO32 name: "Temperature 1" device_class: temperature unit_of_measurement: "°C" accuracy_decimals: 1 state_class: measurement在上面的示例中,“sensor” 是映射中的一个键,其值是另一个映射。第二个映射有键 platform、pin、name、device_class、unit_of_measurement、accuracy_decimals 和 state_class。
当映射值是序列时,应该在键后缩进,但这是 YAML 对错误缩进宽容的少数情况之一,例如:
widgets:- label: text: Temperature 1- label: text: Temperature 2注意序列标记 - 没有缩进到映射键 widgets 之下。这在技术上是错误的,但会被 YAML 解析器正确解释。建议您坚持正确的格式,但如果您在 YAML 文件中看到这种用法,请理解它是可以工作的 - 并且对于限制复杂配置的缩进深度很有用。
锚点、别名和覆盖值
Section titled “锚点、别名和覆盖值”YAML 锚点 (&anchor) 和别名 (*alias) 允许您定义一次配置块并在其他地方重用。这对于重复的元数据字段特别有用。
您还可以在使用 <<: *anchor 合并时覆盖特定值:
sensor: - &common_adc pin: GPIO32 platform: adc name: "Temperature 1" device_class: temperature unit_of_measurement: "°C" accuracy_decimals: 1 state_class: measurement
- <<: *common_adc pin: GPIO33 name: "Temperature 2"在此示例中,两个传感器共享来自 common_adc 的元数据,但第二个传感器覆盖了 pin 和 name 值。
YAML 以几种不同的方式支持多行字符串。
引号多行字符串
Section titled “引号多行字符串”用双引号 (") 或单引号 (') 括起的字符串可以跨行。注意事项:
- 后续行上的前导空格被忽略;
- 可以通过留空行来插入换行符;
- 像
\n这样的转义序列仅在双引号内被转换;
一般而言,下面描述的块字符串比引号多行字符串更可取。
示例:
sensor: # 此传感器的名称将是 "Sensor Name" - platform: template name: "Sensor Name"块字符串是由特殊字符序列引入的多行字符串,所有缩进大于引入字符串的键的后续行都被视为字符串的一部分。块字符串标记有三个部分:
- 块样式指示符(
|或>)(必需) - 截断指示符(
-或+)(可选) - 缩进值(数字,可选)
块样式控制如何处理嵌入的换行符 - 当使用 |(字面)样式时,嵌入的换行符被保留,而当使用 >(折叠)样式时,嵌入的换行符被折叠成单个空格。
截断指示符控制字符串末尾的处理方式:
- 无截断指示符:以单个换行符结束字符串
-:删除所有尾随换行符;+:保留所有尾随换行符。
缩进值指定在每行开头插入多少空格。它是可选的,默认缩进将从第一行文本推断,因此通常不需要使用它。
在 ESPHome 中,您最常使用 |- 样式,它将保留内部换行符并删除尾随换行符。
示例:
multiline_string: |- 这是一个跨多行的 字符串。内部换行符 将被保留,尾随换行符将被删除。some_other_key: # 这不是字符串的一部分ESPHome YAML 扩展
Section titled “ESPHome YAML 扩展”ESPHome 在标准 YAML 之上添加了几个非标准但有用的特性:
机密和 secrets.yaml 文件
Section titled “机密和 secrets.yaml 文件”!secret 标签允许您引用存储在单独的 secrets.yaml 文件中的敏感值(如密码或 API 密钥)。当您希望分发配置文件而不泄露机密时,这特别有用。
IMPORTANT
为了保护您的机密,secrets.yaml 文件不应被提交到 git 或任何其他版本控制系统。
示例:
wifi: ssid: "MyWiFi" password: !secret wifi_password在您的 secrets.yaml 中:
wifi_password: my_super_secret_password机密文件必须仅包含键到标量值的平面映射。
substitutions: 特性允许您定义可在整个配置中引用的可重用值。有关完整详情,请参阅替换
!include
Section titled “!include”- 在此位置插入另一个 YAML 文件的内容。
- 可在配置的任何级别使用,并将替换到该级别。
- 除非与
packages:结合使用(见下文),否则插入是字面完成的。 - 替换可以在包含的文件中使用,以引用传递给
!include的值。此类值将覆盖任何全局替换,因此全局替换可用于提供默认值。
示例:
binary_sensor: - platform: gpio id: button1 pin: GPIOXX on_multi_click: !include { file: on-multi-click.yaml, vars: { id: 1 } } # 内联语法 - platform: gpio id: button2 pin: GPIOXX on_multi_click: !include # 多行语法 file: on-multi-click.yaml vars: id: 2packages: 特性允许您定义可重用且可能是部分的配置,这些配置可以包含在您的主配置中。数据与主配置合并,主配置中的值优先于包数据中的值。
有关更多详情,请参阅包。
任何以点 (.) 开头的顶级配置键将被忽略,不会包含在最终配置中。这主要用于定义不属于配置的锚点。
.number: &AnchorNumber # 定义锚点,但排除它 optimistic: true min_value: 0 max_value: 600 step: 1 initial_value: 0
number: - platform: template <<: *AnchorNumber # 包含之前定义的锚点 id: "SwitchMainDelay" name: "Main Switch Delay"隐藏键名并不重要,实际上可以只是一个点,但建议使用更具描述性的名称。
Lambda
Section titled “Lambda”在 ESPHome 配置文件中,可以嵌入 lambda,即在运行时评估的 C++ 代码块,用于提供动态值和实现 YAML 中无法实现的逻辑。使用 !lambda 标签定义 lambda。有关更多信息,请参阅模板。