模板
模板(也称为 lambda)允许您在 ESPHome 中做几乎 任何事情。例如,如果您只想在某个复杂公式评估为 true 时执行某个自动化,您可以使用模板来实现。让我们先看一个例子:
binary_sensor: - platform: gpio name: "盖板终端止动器" id: top_end_stopcover: - platform: template name: 客厅盖板 lambda: !lambda |- if (id(top_end_stop).state) { return COVER_OPEN; } else { return COVER_CLOSED; }这里发生了什么?首先,我们定义了一个二进制传感器(值得注意的是它有 id: top_end_stop),然后定义了一个模板盖板。(如果您是 Home Assistant 新手,“盖板”指的是百叶窗、卷帘或车库门之类的东西。)模板盖板的 状态 由模板或”lambda”控制。在 lambda 中,您只是编写 C++ 代码,因此使用 lambda 这个名称而不是 Home Assistant 的”模板”术语以避免混淆。不过,不要因为看到”C++“就害怕——编写 lambda 并不那么难!这里有一个简单的入门介绍:
首先,您可能已经想知道 lambda: !lambda |- 这部分是什么意思。!lambda 告诉 ESPHome 接下来的块应该被解释为 lambda 或 C++ 代码。请注意,在这里,lambda: 键实际上会隐式地使其后的块成为 lambda,所以在此上下文中,您也可以写成 lambda: |-。
接下来,还有奇怪的 |- 字符组合。这告诉 YAML 解析器将以下 缩进的 块视为纯文本。没有它,YAML 解析器会尝试读取以下块,就像它是由 YAML 键组成的,例如 cover:。(您可能也见过它的变体,如 >- 或只是 | 或 >。这些不同样式在处理空白方面有细微差别,但就我们的目的而言,我们可以忽略这一点。)
使用 if (...) { ... } else { ... } 我们创建了一个 条件。这实际上意味着如果第一个括号内的内容评估为 true,则执行第一个块(在本例中为 return COVER_OPEN;,否则评估第二个块。return ...; 使代码块向模板返回一个值。在这种情况下,我们要么 返回 COVER_OPEN 要么返回 COVER_CLOSED 来指示盖板是关闭还是打开的。
最后,id(...) 是一个辅助函数,它使 ESPHome 获取具有提供的 ID 的对象(您在其他地方定义的,如 top_end_stop),并让您直接调用 ESPHome 的众多 API 中的任何一个。例如,在这里我们使用 .state 检索终端止动器的当前状态,并使用它来构建我们的盖板状态。
NOTE
ESPHome 不会检查您输入的 lambda 表达式的有效性,而是将它们盲目地复制到生成的 C++ 代码中。如果编译失败或 lambda 出现其他问题,最好查看 <NODE_NAME>/src/main.cpp 下生成的 C++ 源文件。
TIP
要在 lambda 中存储在执行之间保留值的局部变量,您可以创建 static 变量,如下例所示。在这里,每次执行 lambda 时变量 num_executions 都会增加一,并记录当前值。
lambda: |- static int num_executions = 0; ESP_LOGD("main", "I am at execution number %d", num_executions); num_executions += 1;ESPHome 允许您对自动化中使用的大多数操作参数进行模板化。例如,如果您有一个灯,并希望在按下按钮时将其设置为预定义的颜色,您可以这样做:
on_press: then: - light.turn_on: id: some_light_id transition_length: 0.5s red: 0.8 green: 1.0 blue: !lambda |- // 传感器输出 0 到 100 的值。 // 灯颜色的蓝色部分将由传感器值决定。 return id(some_sensor).state / 100.0;当您在给定操作的文档中看到”可模板化”标签时,它可以像此示例一样使用如上所述/显示的 lambda 语法进行模板化。