替换
ESPHome 有一种强大的方式来减少配置文件中的重复:替换。 使用替换,您可以为所有同类节点提供单个通用源文件,并根据需要替换表达式。
substitutions: bme280_temperature_offset: "-1.0"
sensor: - platform: bme280_i2c temperature: name: BME280 温度 filters: - offset: ${bme280_temperature_offset}在顶级 substitutions 部分,您可以根据需要放置任意数量的键值对。在验证您的配置之前,ESPHome 将自动用其值替换所有出现的替换。替换的语法基于 bash 并区分大小写:$substitution_key 或 ${substitution_key}(相同)。
替换变量可以是任何有效的 YAML 类型,例如:
substitutions: device: name: 厨房空调 port: 12 enabled: true color: "黄色" unused_pins: [12, 23, 27]执行两次替换传递,允许复合替换:
substitutions: foo: yellow bar_yellow_value: !secret yellow_secret bar_green_value: !secret green_secret
something: test: ${bar_${foo}_value}以上是为了向后兼容而支持的。建议您今后使用键值字典:
substitutions: foo: yellow bar: yellow: !secret yellow_secret green: !secret green_secret
something: test: ${bar[foo]}Jinja 表达式
Section titled “Jinja 表达式”简单的 Jinja 表达式和过滤器可以在 ${ ... } 语法中使用。
所有替换变量都可以在 Jinja 表达式中通过其名称访问。
如果替换变量是键值字典,您可以使用点表示法访问成员:${ device.name },或索引 ${ device["name"] }
列表可以索引:${ unused_pins[2] }
substitutions: native_width: 480 native_height: 320 high_dpi: true scale: 1.5 sensor_pin: number: 3 inverted: true debug_label: width: 200 height: 20 enabled: true
display: - platform: ili9xxx dimensions: width: ${native_width * 2 if high_dpi else native_width} height: ${native_height * 2 if high_dpi else native_height}
lvgl: widgets: - label: id: debug_info hidden: ${not debug_label.enabled} width: ${ (debug_label.width * scale) | round | int } height: ${ (debug_label.height * scale) | round | int } text: | 高 DPI ${high_dpi and "已启用" or "已禁用"}。
binary_sensor: - platform: gpio name: 引脚 ${sensor_pin.number} 上的二值传感器 pin: ${sensor_pin}请注意,在其他项目中,Jinja 使用 {{ ... }} 语法作为表达式分隔符。
在 ESPHome 中,我们将 Jinja 配置为使用 ${...} 代替,因此它与现有的替换语法相同,并避免与 Home Assistant 自己使用 Jinja 冲突。
要了解可以使用哪些类型的表达式和过滤器,请参阅 Jinja 表达式 文档。
除了 Jinja 的原生运算符如 +、-、*、/、… Python 的 math 库作为模块暴露:
substitutions: x: 20 y: 50lvgl: widgets: - label: x: $x y: $y text: 距离是 ${math.sqrt(x*x+y*y)}。要查看有哪些数学函数可用,请参阅 Python math 库 文档。
除了 Jinja 表达式,ESPHome 还支持许多可在替换中使用的内置函数。
ord返回给定字符的 Unicode 码点。示例:ord("A") == 65chr返回给定 Unicode 码点的字符。示例:chr(65) == "A"len返回字符串的长度。示例:len("Hello") == 5
禁用 Jinja 和替换
Section titled “禁用 Jinja 和替换”您可以通过在任何值之前使用 !literal 标签来防止 ESPHome 替换变量或处理 Jinja:
substitutions: value: "测试值"lvgl: widgets: - label: text: !literal "这是一个 ${value}"在上面的示例中,text 属性的值将是,字面上的,这是一个 ${value}。
替换 !include 变量
Section titled “替换 !include 变量”ESPHome 的 !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: 2on-multi-click.yaml:
- timing: !include click-single.yaml then: - mqtt.publish: topic: ${device_name}/button${id}/status payload: single- timing: !include click-double.yaml then: - mqtt.publish: topic: ${device_name}/button${id}/status payload: double您可以通过添加带有参数 KEY 和 VALUE 的 -s 开关从命令行定义或覆盖替换。这将覆盖替换 KEY 并为其分配值 VALUE。此开关可以多次包含。考虑以下 example.yaml 文件:
substitutions: name: my_default_name
esphome: name: $name…以及以下命令:
esphome -s name my_device01 config example.yaml您将获得类似以下的输出:
substitutions: name: my_device01
esphome: name: my_device01 # ...命令行替换优先于配置文件中的替换。这可用于创建通用的”模板”配置文件(如上面的 example.yaml),可由多个设备使用,利用命令行提供的替换。
额外:YAML 插入运算符
Section titled “额外:YAML 插入运算符”此外,您可以使用 YAML 插入运算符 << 语法创建一个多个节点继承的 YAML 文件:
# 在 common.yaml 中esphome: name: $devicename # ...
sensor:- platform: dht # ... temperature: name: 温度 humidity: name: 湿度# 在 nodemcu1.yaml 中substitutions: devicename: nodemcu1
<<: !include common.yamlTIP
要从仪表板隐藏这些基础文件,您可以
- 将它们放在子目录中(仪表板仅显示顶级目录中的文件)
- 在文件名前加上点,如
.base.yaml