喷灌控制器
sprinkler 控制器组件旨在像喷灌/灌溉阀门控制器一样运行,类似于 Rain Bird 或 Hunter 等公司生产的控制器。它通过自动化控制多个 switch 组件来实现这一点,每个组件通常用于通过继电器或其他切换设备控制单独的电动阀门。它提供了喷灌控制器应具备的许多功能,包括:
-
每个控制器实例可以拥有几乎任意数量的区域(喷灌系统的区段),仅受限于 ESP 上可用的内存和/或 GPIO(包括 I/O 扩展器!)引脚数量。
-
运行能力:
- 系统的一个或多个完整循环(遍历所有区域)
- 只运行单个区域
-
自动循环重复
-
乘数,用于成比例地增加或减少所有区域的运行时长
-
支持位于分配阀门上游的泵/主阀门
-
暂停和恢复区域/循环
-
按正序或逆序遍历区域
-
支持保持型(“脉冲式”)和非保持型阀门(可以任意混用!)
不过,它还更进一步,提供了一些更高级的功能:
-
多个喷灌控制器实例可以在单个(ESP)设备上同时运行
-
多个泵,每个泵可以在控制器实例之间共享
-
每个区域的启用/禁用开关,允许在系统的完整循环中跳过某些区域
-
阀门/区域排队机制,旨在为自动化提供更高级的支持
-
多种阀门管理策略,以适应不同类型的硬件/安装:
- 可调的”阀门开启延迟”,帮助确保下一个阀门开启前上一个阀门完全关闭
- 可调的”阀门重叠”,帮助最大限度地减少因水锤效应导致的管道敲击
- 可调的延迟间隔,用于协调分配阀门开启和关闭时泵的启动和停止
NOTE
尽管本文档全程使用”泵”一词,但控制的设备不一定是 实际的泵。相反,它可能只是位于分配 阀门上游的另一个电动阀门(行业内通常称为”主”或”主控”阀门)。泵或上游阀门 只控制下游其他阀门的水源。

# 示例最小配置条目# (...但请看下面更详细的示例!)sprinkler: - id: sprinkler_ctrlr main_switch: "Sprinklers" auto_advance_switch: "Sprinklers Auto Advance" valves: - valve_switch: "Front Lawn" enable_switch: "Enable Front Lawn" run_duration: 1800s valve_switch_id: lawn_sprinkler_valve_sw0 - valve_switch: "Back Lawn" enable_switch: "Enable Back Lawn" run_duration: 900s valve_switch_id: lawn_sprinkler_valve_sw1请参见下方的 控制器示例 部分,里面提供了大量详细的配置示例,可以直接复制粘贴!
-
main_switch (可选, string): 当有多个阀门时为必需。喷灌控制器的主开关名称,即在前端显示的名称。该开关打开时,调用
sprinkler.resume_or_start_full_cycle动作;关闭时,调用sprinkler.shutdown动作(见下文)。当控制器上有任何阀门处于活动状态时,它将显示为”打开”。如果控制器只配置了一个阀门,此开关不会在前端出现。 -
auto_advance_switch (可选, string): 当有多个阀门时为必需。喷灌控制器”自动前进”开关在前端显示的名称。当此开关在阀门处于活动状态时被打开时,当阀门的
run_duration达到时,喷灌控制器将作为系统”完整循环”的一部分自动前进到下一个启用的阀门。当此开关关闭时,喷灌控制器将在活动阀门的run_duration达到后关闭(除非队列中有阀门——详见下方的 喷灌控制器队列 部分)。如果控制器只配置了一个阀门,此开关不会在前端出现。 -
manual_selection_delay (可选, Time): 在调用
next_valve和previous_valve动作后,控制器应等待多长时间激活阀门。如果控制界面仅由前进/后退按钮组成,此设置非常有用,因为按钮可能被按下多次以进行选择。 -
queue_enable_switch (可选, string): 喷灌控制器队列启用开关在前端显示的名称。当此开关打开或未提供时,控制器将根据队列中的内容选择要运行的下一个阀门/区域;队列优先于将作为系统完整循环一部分运行的阀门(当自动前进开启/启用时)。详见下方的 喷灌控制器队列 部分。
-
reverse_switch (可选, string): 喷灌控制器反向开关在前端显示的名称。当此开关打开时,控制器将以相反顺序遍历阀门(按它们在控制器配置中出现的顺序从最后到第一个)。当此开关关闭或未提供时,控制器将以从第一个到最后一个的顺序遍历阀门。如果控制器只配置了一个阀门,此开关不会在前端出现。
-
standby_switch (可选, string): 喷灌控制器待机开关在前端显示的名称。当此开关打开时,控制器不会启动任何阀门。 如果没有此状态的视觉指示,可能会导致令人困惑/意想不到的行为!
-
valve_open_delay (可选, Time): 在(分配)阀门切换之间应插入的最小延迟秒数——换言之,一个阀门关闭到下一个阀门开启之间必须经过的时间。对于依赖足够水压才能关闭的阀门系统很有用。不能与
valve_overlap一起使用。 -
valve_overlap (可选, Time): 当前阀门和下一个阀门在下一个阀门/区域启动时同时运行的秒数。这有助于防止阀门关闭时管道敲击。不能与
valve_open_delay一起使用。 -
pump_switch_off_during_valve_open_delay (可选, boolean): 如果设为
true,泵将在valve_open_delay间隔期间关闭;否则保持开启。只有配置了valve_open_delay时才能指定(见上文)。默认为false。 -
pump_start_pump_delay (可选, Time): 分配阀门打开到关联泵激活之间的延迟秒数。有助于确保在没有分配阀门打开时运行泵不会导致压力积聚。不能与
pump_start_valve_delay一起使用。 -
pump_start_valve_delay (可选, Time): 泵启动到关联分配阀门打开之间的延迟秒数。对于分配阀门需要足够压力才能完全/快速关闭的系统很有用。不能与
pump_start_pump_delay一起使用。 -
pump_stop_pump_delay (可选, Time): 分配阀门关闭到相应泵停用之间的延迟秒数。对于分配阀门需要足够压力才能完全/快速关闭的系统很有用。不能与
pump_stop_valve_delay一起使用。 -
pump_stop_valve_delay (可选, Time): 泵停用到相应分配阀门关闭之间的延迟秒数。有助于确保在没有分配阀门打开时运行泵不会导致压力积聚,或让通往分配阀门的主管道排出水流。不能与
pump_stop_pump_delay一起使用。 -
multiplier_number (可选, string): 应呈现给前端(Home Assistant)的 number 组件的名称,以便控制喷灌控制器的
multiplier值。详见下方的 使用喷灌控制器的数值。 -
repeat_number (可选, string): 应呈现给前端(Home Assistant)的 number 组件的名称,以便控制喷灌控制器的
repeat值。不能与repeat一起使用。详见下方的 使用喷灌控制器的数值。 -
repeat (可选, int): 完整循环应重复的次数。默认为 0。不能与
repeat_number一起使用。 -
next_prev_ignore_disabled (可选, boolean): 设为
true将使sprinkler.next_valve动作 和sprinkler.previous_valve动作 跳过 未启用的阀门。默认为false。 -
id (可选, ID): 手动指定用于代码生成的 ID。虽然是可选的, 但在调用控制器动作(如
start_full_cycle或shutdown,见下文)时需要它来识别控制器实例(特别是在定义了多个实例的情况下)。 -
valves (必选, list): 控制器应使用的阀门列表。每个阀门包含:
-
enable_switch (可选, string): 用于启用此阀门作为系统完整循环一部分运行的开关组件名称。当此开关关闭时,阀门将被排除在系统的完整循环之外。当此开关打开或未提供时,控制器将把阀门包含在系统的完整循环中。
-
valve_switch (必选, string): 用于控制喷灌系统此部分(通常称为”区域”)阀门的开关组件名称。当此开关打开时,控制器的”自动前进”功能被禁用,它将根据控制器乘数值乘以
run_duration激活关联阀门。当此开关关闭时,调用sprinkler.shutdown动作(见下文)。 -
pump_switch_id (可选, Switch): 这是用于控制阀门泵或上游电动阀门的 switch 组件。通常这是一个连接到继电器或其他切换设备的 GPIO 开关, 进而激活相应的泵/阀门。对于保持型阀门/泵,请使用 H-Bridge 开关。 不建议将此开关暴露给前端;请参见 关于 GPIO 开关和控制的重要说明 了解更多细节。
-
run_duration_number (可选, string): 应呈现给前端(Home Assistant)的 number 组件的名称,以便控制阀门的
run_duration值。 不能与run_duration一起使用。详见下方的 使用喷灌控制器的数值。小技巧: 想要以分钟为单位显示时间?在 number 配置中添加unit_of_measurement: min。详见 使用喷灌控制器的数值。 -
run_duration (可选, Time): 未提供
run_duration_number时为必需。阀门激活后应保持开启/打开的秒数。当某个阀门被激活时, 控制器的乘数值与此值相乘以确定阀门的实际运行时长,从而 允许按需要成比例地增加或减少所有阀门/区域的运行时长。不能与run_duration_number一起使用。 -
valve_switch_id (可选, Switch): 这是用于控制操作给定喷灌系统区段或区域的阀门的 switch 组件。通常这是一个连接到继电器的 GPIO 开关 或其他切换设备,进而激活相应的阀门。对于保持型阀门,请使用 H-Bridge 开关。不建议将此开关暴露给前端;请参见 关于 GPIO 开关和控制的重要说明 了解更多细节。
-
关于 GPIO 开关和控制的重要说明
Section titled “关于 GPIO 开关和控制的重要说明”经验老道和/或资深的 ESPHome 用户会很快意识到,pump_switch_id 和 valve_switch_id(如上所述)实际上只是指向 ESPHome YAML 配置中其他位置的开关的指针。
你可能会觉得理所当然地认为这些开关(通常是 GPIO 开关 或 H-Bridge 开关)可以用来打开和关闭各个喷灌区域, 但事实并非如此。重要的是要注意,喷灌控制器为每个配置的区域提供了一个开关——最终,这个开关将用于打开或关闭任何给定区域,而不是区域配置的底层开关。
请记住,开关直接控制其关联的硬件(GPIO 引脚、H-Bridge 电路等)。虽然在技术上可以”覆盖”此行为,但这并不总是可取的。例如,如果你希望在测试系统/配置期间手动控制开关的状态,这将使这样做变得不可能(或至少比必要的更困难),并带来其他复杂性。最终,灵活性是关键,正如我们在 ESPHome Discord 服务器上的多次对话中学到的那样。
正如介绍中所提到的,喷灌控制器自动化控制你提供给它的开关——它不会”覆盖”对这些开关的控制,也不会改变它们的行为,只是在根据配置的调度需要时简单地打开或关闭它们。
那么为什么不直接使用底层开关来控制各个喷灌区域呢?就喷灌控制器本身而言,主要原因与状态有关——也就是说,我们需要确保开关状态与喷灌控制器的配置保持一致。对于每个区域只有一个阀门的系统来说,这并不那么重要,但对于具有一定复杂性的系统来说,这变得非常重要。考虑一个带有泵和连接到该泵的多个分配阀门的系统示例;此时控制器的配置是在关闭任何给定分配阀门的之前3 秒关闭泵。如果你突然手动关闭连接到这些分配阀门之一的底层开关,泵会发生什么?喷灌控制器应该怎么做?它应该重新打开分配阀门吗?……或者也许只是把泵也关掉?无论哪种情况,根据其配置,泵本应在阀门之前关闭,但你刚刚把阀门关了。泵可能会损坏。还有许多其他类似的情况,最简单的情况只是确保任何给定阀门在某段时间后关闭,而不会永远保持开启/打开。
总之,为确保你的喷灌控制器始终按预期运行:
-
仅使用喷灌控制器组件提供的开关来打开或关闭任何给定喷灌区域。
-
不要在配置中使用底层开关(GPIO、H-Bridge 等)来控制喷灌区域/阀门,除非是对设备配置进行初步测试。
-
为防止意外事故,最好不将每个喷灌区域的底层开关暴露给前端。可以通过两种方式实现:
- 不要为开关提供
name:参数,或者 - 在每个开关配置中添加
internal: true
- 不要为开关提供
这些简单的配置调整将有助于防止各种错误(人为的、自动化的或其他类型的),并可能有助于避免灾难!
sprinkler.start_full_cycle 动作
Section titled “sprinkler.start_full_cycle 动作”启动系统的完整循环。这将启用控制器的”自动前进”功能并禁用队列。控制器将遍历所有启用的阀门/区域。它们各自将按其配置的 run_duration 乘以控制器的乘数值运行。注意,如果在调用此动作时没有启用任何阀门,控制器将自动启用所有阀门。
on_...: then: - sprinkler.start_full_cycle: sprinkler_ctrlrsprinkler.start_from_queue 动作
Section titled “sprinkler.start_from_queue 动作”启动控制器从队列运行阀门。如果队列中没有阀门,此动作不会做任何事;否则,它将禁用控制器的”自动前进”功能,使得只有排队的阀门/区域会运行。排队的阀门将保持开启,时间要么为排队请求中指定的时长,要么为按其配置的 run_duration 乘以控制器的乘数值(如果排队请求的运行时长未指定或为零)。注意,排队的阀门会忽略阀门是否已启用;也就是说,一旦控制器启动,排队的阀门将始终运行,当然,除非队列在轮到它们之前被(手动)清除。另请注意,目前,队列有 100 个条目的硬编码限制以限制内存使用。
详见下方的 喷灌控制器队列 部分。
on_...: then: - sprinkler.start_from_queue: id: sprinkler_ctrlrsprinkler.start_single_valve 动作
Section titled “sprinkler.start_single_valve 动作”启动单个阀门。这将禁用控制器的”自动前进”和队列功能,使得只有此阀门/区域会运行。阀门将保持开启指定时长,或者(如果未指定 run_duration 或为零)按其配置的 run_duration 乘以控制器的乘数值运行。注意,此动作会忽略阀门是否已启用;也就是说,调用时,指定的阀门将始终运行。 阀门按其出现在喷灌控制器配置中的顺序编号,从 0 开始。
on_...: then: - sprinkler.start_single_valve: id: sprinkler_ctrlr valve_number: 0 run_duration: 600s # 可选sprinkler.shutdown 动作
Section titled “sprinkler.shutdown 动作”启动所有阀门/系统的关机过程,同时遵守任何配置的泵或阀门停止延迟。
on_...: then: - sprinkler.shutdown: sprinkler_ctrlrsprinkler.next_valve 动作
Section titled “sprinkler.next_valve 动作”前进到下一个阀门(按数字顺序)。如果配置了 manual_selection_delay,控制器
将等待再激活所选阀门。如果没有阀门处于活动状态,将启动第一个阀门(按它们在
控制器配置中出现的顺序)。将 next_prev_ignore_disabled 设置为 true
将导致此动作跳过未通过其阀门启用开关启用的阀门(见上文)。
on_...: then: - sprinkler.next_valve: sprinkler_ctrlrsprinkler.previous_valve 动作
Section titled “sprinkler.previous_valve 动作”前进到上一个阀门(按数字顺序)。如果配置了 manual_selection_delay,控制器
将等待再激活所选阀门。如果没有阀门处于活动状态,将启动最后一个阀门(按它们在
控制器配置中出现的顺序)。将 next_prev_ignore_disabled 设置为 true
将导致此动作跳过未通过其阀门启用开关启用的阀门(见上文)。
on_...: then: - sprinkler.previous_valve: sprinkler_ctrlrsprinkler.pause 动作
Section titled “sprinkler.pause 动作”立即关闭所有阀门,保存活动阀门和剩余时间,以便 以后可以恢复循环。
on_...: then: - sprinkler.pause: sprinkler_ctrlrsprinkler.resume 动作
Section titled “sprinkler.resume 动作”恢复通过 sprinkler.pause 暂停的循环。如果没有暂停的循环,此动作
不会做任何事。
on_...: then: - sprinkler.resume: sprinkler_ctrlrsprinkler.resume_or_start_full_cycle 动作
Section titled “sprinkler.resume_or_start_full_cycle 动作”恢复通过 sprinkler.pause 暂停的循环,但如果没有任何循环被暂停,则启动完整
循环(相当于 sprinkler.start_full_cycle)。
on_...: then: - sprinkler.resume_or_start_full_cycle: sprinkler_ctrlrsprinkler.queue_valve 动作
Section titled “sprinkler.queue_valve 动作”将指定的阀门添加到控制器的队列中。当队列启用时,队列中的阀门
优先于作为系统完整循环一部分排定的阀门(当自动前进
启用时)。如果未指定 run_duration 或为零,喷灌控制器将使用
阀门的配置运行时长。阀门按其出现在喷灌
控制器配置中的顺序编号,从 0 开始。注意,目前,队列有 100 个条目的硬编码
限制以限制内存使用。 请参见下方的 喷灌控制器队列
部分以获取更多详细信息和示例。
on_...: then: - sprinkler.queue_valve: id: sprinkler_ctrlr valve_number: 2 run_duration: 900ssprinkler.clear_queued_valves 动作
Section titled “sprinkler.clear_queued_valves 动作”从控制器的队列中移除所有排队的阀门。请参见下方的 喷灌控制器队列 部分以获取更多详细信息和示例。
on_...: then: - sprinkler.clear_queued_valves: id: sprinkler_ctrlrsprinkler.set_multiplier 动作
Section titled “sprinkler.set_multiplier 动作”设置用于成比例地增加或减少所有阀门/区域运行时长的乘数值。 对于季节变化,使用乘数调整浇水时间比直接调整 运行时长更容易。将运行时长设置为温和天气(春季/秋季)所需的时间,然后 使用乘数增加(夏季)或减少(冬季)计算出的运行时间。当某个阀门被 激活时,此值与阀门的运行时长相乘以确定阀门的实际 运行时长。注意,允许乘数值为零;如果乘数值为零, 喷灌控制器将不启动任何阀门。 如果没有 此状态的视觉指示,可能会导致令人困惑/意想不到的行为!
on_...: then: - sprinkler.set_multiplier: id: sprinkler_ctrlr multiplier: 1.5sprinkler.set_repeat 动作
Section titled “sprinkler.set_repeat 动作”指定完整循环应重复的次数。注意,控制器运行的循环总数
等于重复值加 1。 例如,当 repeat 值
为 1 时,初始循环将运行,然后重复循环将运行,总共有两个循环。
on_...: then: - sprinkler.set_repeat: id: sprinkler_ctrlr repeat: 2 # 将运行三个循环sprinkler.set_divider 动作
Section titled “sprinkler.set_divider 动作”divider 值按如下方式同时设置 multiplier 和 repeat 值:
- multiplier 值被设为 1 /
divider - repeat 值被设为
divider- 1
例如,给定 divider 值为 4,multiplier 将设为 0.25,repeat 值 将设为 3。
这可以将每个阀门的运行时长分成多个较短的循环,从而 避免因径流而让地面有更多时间吸收水分。
on_...: then: - sprinkler.set_divider: id: sprinkler_ctrlr divider: 2sprinkler.set_valve_run_duration 动作
Section titled “sprinkler.set_valve_run_duration 动作”设置指定阀门的运行时长。当阀门被激活时,此值与 乘数值(见上文)相乘以确定阀门的实际运行时长。
on_...: then: - sprinkler.set_valve_run_duration: id: sprinkler_ctrlr valve_number: 0 run_duration: 600sNOTE
-
start_single_valve动作会忽略阀门是否通过其启用开关被启用。 -
如果配置了
manual_selection_delay或下方 泵和分配阀门协调 部分所述的任何一种延迟机制,next_valve和previous_valve动作可能看起来不会立即响应。 如果你使用了这些配置选项中的任何一个,请务必在认为某事没有正常工作之前 等待延迟间隔过去! -
如果阀门在运行时长或乘数值被更改时处于活动状态,活动 阀门的运行时长将在下次启动之前保持不变。
泵和分配阀门协调
Section titled “泵和分配阀门协调”喷灌控制器提供了与泵和阀门切换相关的广泛灵活性。让我们更仔细地看看如何使用这些功能来调整你的系统。
泵或阀门的延迟启动和/或停止
Section titled “泵或阀门的延迟启动和/或停止”对于有泵的系统,在不打开任何分配阀门的情况下运行泵通常是个坏主意。这会导致压力积聚,甚至在一段时间后损坏泵。对于有(一个或多个)泵的系统,你可能希望添加两个配置选项:
sprinkler: - id: lawn_sprinkler_ctrlr pump_start_pump_delay: 3s pump_stop_valve_delay: 3s ...这将导致任何给定泵在任何关联分配阀门打开之后(在此示例中)三秒才启动。此外,它会在泵停止后等待三秒再关闭最后一个分配阀门。这将允许泵减速、压力下降和管道排空,然后
再关闭(最后一个)关联的分配阀门。(在这些配置中,启用 valve_overlap 也可能
是可取的——详见下文。)
某些类型的电动阀门需要足够的水压才能(完全/快速)关闭。这些类型的 阀门,如果与分配阀门上游的电动阀门(行业内通常称为 “主”或”主控”阀门)配合使用,可能需要在上游阀门在任何给定分配 阀门之前开启,使水压稳定并迫使所有分配阀门关闭,然后才打开任何单个 分配阀门。在这些情况下,上述配置的相反方案可能是可取的:
sprinkler: - id: lawn_sprinkler_ctrlr pump_start_valve_delay: 3s pump_stop_pump_delay: 3s ...在此示例中,上游阀门将在任何给定关联分配
阀门之前三秒打开,使水压迫使任何连接的分配阀门关闭。延迟之后,
所需的分配阀门被打开,循环开始。循环完成后,(最后一个)分配
阀门将在上游阀门之前三秒关闭。(在这些配置中,启用 valve_open_delay 也可能是可取的。)
NOTE
将 pump_stop_valve_delay 或 pump_stop_pump_delay 与 valve_open_delay 和
pump_switch_off_during_valve_open_delay 一起使用可能会增加每个区域操作之间
插入的关闭时间,因为控制器必须等待给定区域(泵和阀门)完全关闭之后
才能再次启动它。
敲击的管道或无法一致关闭的阀门
Section titled “敲击的管道或无法一致关闭的阀门”人们抱怨喷灌系统的常见问题之一是管道敲击。在其他不太常见的情况下, 一些系统会因阀门无法(完全/快速)关闭而出现问题。有控制器选项可 用来解决这两种抱怨/担忧:
valve_overlapvalve_open_delaypump_switch_off_during_valve_open_delay
第一个选项 valve_overlap 使当前阀门和下一个阀门(当控制器遍历
阀门时)在指定时长内同时运行。这里的想法是,这会在下一个区域
启动时导致水压降低,从而在即将关闭的阀门最终关闭时
最小化管道敲击(即”水锤”效应)。
第二和第三个选项可用于确保有足够的压力迫使阀门关闭。 对于水压低时不能快速和/或完全关闭的压力敏感型阀门可能很有用。
对于有泵的系统,在切换到下一个分配
阀门/区域之前关闭泵可能是可取的。在这些情况下,pump_switch_off_during_valve_open_delay 可能与
valve_open_delay 一起发挥作用。
无论哪种情况,下一节中的示例都说明了如何在你的配置中添加这些选项。
单个控制器,单个阀门,无泵
Section titled “单个控制器,单个阀门,无泵”此第一个示例说明了一个完整的无泵/上游阀门的单一阀门系统。它
可用于控制一个独立于任何其他喷灌控制器的阀门。通过添加 pump_switch_id 参数和一个 switch,可以轻松添加泵。
esphome: name: esp-sprinkler-controller
esp32: board: esp32dev
wifi: ssid: "wifi_ssid" password: "wifi_password"
logger:
sprinkler: - id: garden_sprinkler_ctrlr valves: - valve_switch: "Flower Garden" run_duration: 300s valve_switch_id: garden_sprinkler_valve
switch: - platform: gpio id: garden_sprinkler_valve pin: GPIOXX单个控制器,三个阀门,无泵
Section titled “单个控制器,三个阀门,无泵”此示例说明了一个完整的简单三阀门无泵/上游阀门系统:
esphome: name: esp-sprinkler-controller
esp32: board: esp32dev
wifi: ssid: "wifi_ssid" password: "wifi_password"
logger:
sprinkler: - id: lawn_sprinkler_ctrlr main_switch: "Lawn Sprinklers" auto_advance_switch: "Lawn Sprinklers Auto Advance" reverse_switch: "Lawn Sprinklers Reverse" multiplier_number: "Lawn Sprinkler Multiplier" repeat_number: "Lawn Sprinkler Repeat" valve_overlap: 5s valves: - valve_switch: "Front Lawn" enable_switch: "Enable Front Lawn" run_duration_number: "Front Yard Run Duration" valve_switch_id: lawn_sprinkler_valve_sw0 - valve_switch: "Side Lawn" enable_switch: "Enable Side Lawn" run_duration_number: "Front Yard Run Duration" valve_switch_id: lawn_sprinkler_valve_sw1 - valve_switch: "Back Lawn" enable_switch: "Enable Back Lawn" run_duration_number: "Front Yard Run Duration" valve_switch_id: lawn_sprinkler_valve_sw2
switch: - platform: gpio id: lawn_sprinkler_valve_sw0 pin: GPIOXX - platform: gpio id: lawn_sprinkler_valve_sw1 pin: GPIOXX - platform: gpio id: lawn_sprinkler_valve_sw2 pin: GPIOXX单个控制器,三个阀门,单个泵
Section titled “单个控制器,三个阀门,单个泵”此示例说明了一个带有一个泵/上游阀门的完整三阀门系统:
esphome: name: esp-sprinkler-controller
esp32: board: esp32dev
wifi: ssid: "wifi_ssid" password: "wifi_password"
logger:
sprinkler: - id: lawn_sprinkler_ctrlr main_switch: "Lawn Sprinklers" auto_advance_switch: "Lawn Sprinklers Auto Advance" reverse_switch: "Lawn Sprinklers Reverse" valve_open_delay: 5s valves: - valve_switch: "Front Lawn" enable_switch: "Enable Front Lawn" pump_switch_id: sprinkler_pump_sw run_duration: 900s valve_switch_id: lawn_sprinkler_valve_sw0 - valve_switch: "Side Lawn" enable_switch: "Enable Side Lawn" pump_switch_id: sprinkler_pump_sw run_duration: 900s valve_switch_id: lawn_sprinkler_valve_sw1 - valve_switch: "Back Lawn" enable_switch: "Enable Back Lawn" pump_switch_id: sprinkler_pump_sw run_duration: 900s valve_switch_id: lawn_sprinkler_valve_sw2
switch: - platform: gpio id: sprinkler_pump_sw pin: GPIOXX - platform: gpio id: lawn_sprinkler_valve_sw0 pin: GPIOXX - platform: gpio id: lawn_sprinkler_valve_sw1 pin: GPIOXX - platform: gpio id: lawn_sprinkler_valve_sw2 pin: GPIOXX单个控制器,三个保持型阀门,单个保持型泵
Section titled “单个控制器,三个保持型阀门,单个保持型泵”此示例与上一个示例类似,不过它说明了如何使用 H-Bridge 开关 配置”保持型”或”脉冲式”阀门。这种类型的阀门 需要两个 GPIO 引脚才能工作——一个用于打开阀门,另一个用于关闭阀门。
请注意,虽然此示例说明了使用全保持型阀门的配置, 但在任何配置中都可以混用保持型和非保持型阀门,即使它们连接到 同一个泵/上游阀门。
esphome: name: esp-sprinkler-controller
esp32: board: esp32dev
wifi: ssid: "wifi_ssid" password: "wifi_password"
logger:
sprinkler: - id: lawn_sprinkler_ctrlr main_switch: "Lawn Sprinklers" auto_advance_switch: "Lawn Sprinklers Auto Advance" queue_enable_switch: "Lawn Sprinklers Queue Enable" reverse_switch: "Lawn Sprinklers Reverse" valve_open_delay: 5s valves: - valve_switch: "Front Lawn" enable_switch: "Enable Front Lawn" pump_switch_id: sprinkler_pump_sw run_duration: 900s valve_switch_id: lawn_sprinkler_valve_sw0 - valve_switch: "Side Lawn" enable_switch: "Enable Side Lawn" pump_switch_id: sprinkler_pump_sw run_duration: 900s valve_switch_id: lawn_sprinkler_valve_sw1 - valve_switch: "Back Lawn" enable_switch: "Enable Back Lawn" pump_switch_id: sprinkler_pump_sw run_duration: 900s valve_switch_id: lawn_sprinkler_valve_sw2
switch: - platform: hbridge id: sprinkler_pump_sw on_pin: GPIOXX off_pin: GPIOXX pulse_length: 250ms - platform: hbridge id: lawn_sprinkler_valve_sw0 on_pin: GPIOXX off_pin: GPIOXX pulse_length: 250ms - platform: hbridge id: lawn_sprinkler_valve_sw1 on_pin: GPIOXX off_pin: GPIOXX pulse_length: 250ms - platform: hbridge id: lawn_sprinkler_valve_sw2 on_pin: GPIOXX off_pin: GPIOXX pulse_length: 250ms双控制器,五个阀门,两个泵
Section titled “双控制器,五个阀门,两个泵”此示例说明了一个完整的更复杂的双控制器系统,共有五个 阀门(第一个控制器上三个,第二个控制器上两个)和两个泵/上游 阀门,每个都在两个控制器之间共享:
esphome: name: esp-sprinkler-controller
esp32: board: esp32dev
wifi: ssid: "wifi_ssid" password: "wifi_password"
logger:
sprinkler: - id: lawn_sprinkler_ctrlr main_switch: "Lawn Sprinklers" auto_advance_switch: "Lawn Sprinklers Auto Advance" reverse_switch: "Lawn Sprinklers Reverse" valve_overlap: 5s valves: - valve_switch: "Front Lawn" enable_switch: "Enable Front Lawn" pump_switch_id: sprinkler_pump_sw0 run_duration: 900s valve_switch_id: lawn_sprinkler_valve_sw0 - valve_switch: "Side Lawn" enable_switch: "Enable Side Lawn" pump_switch_id: sprinkler_pump_sw0 run_duration: 900s valve_switch_id: lawn_sprinkler_valve_sw1 - valve_switch: "Back Lawn" enable_switch: "Enable Back Lawn" pump_switch_id: sprinkler_pump_sw1 run_duration: 900s valve_switch_id: lawn_sprinkler_valve_sw2 - id: garden_sprinkler_ctrlr main_switch: "Garden Sprinklers" auto_advance_switch: "Garden Sprinklers Auto Advance" reverse_switch: "Garden Sprinklers Reverse" valve_open_delay: 5s valves: - valve_switch: "Front Garden" enable_switch: "Enable Front Garden" pump_switch_id: sprinkler_pump_sw0 run_duration_number: id: garden_sprinkler_ctrlr_front_run_duration name: "Front Garden Run Duration" initial_value: 10 unit_of_measurement: min valve_switch_id: garden_sprinkler_valve_sw0 - valve_switch: "Back Garden" enable_switch: "Enable Back Garden" pump_switch_id: sprinkler_pump_sw1 run_duration_number: id: garden_sprinkler_ctrlr_back_run_duration name: "Back Garden Run Duration" initial_value: 10 unit_of_measurement: min valve_switch_id: garden_sprinkler_valve_sw1
switch: - platform: gpio id: sprinkler_pump_sw0 pin: GPIOXX - platform: gpio id: sprinkler_pump_sw1 pin: GPIOXX - platform: gpio id: lawn_sprinkler_valve_sw0 pin: GPIOXX - platform: gpio id: lawn_sprinkler_valve_sw1 pin: GPIOXX - platform: gpio id: lawn_sprinkler_valve_sw2 pin: GPIOXX - platform: gpio id: garden_sprinkler_valve_sw0 pin: GPIOXX - platform: gpio id: garden_sprinkler_valve_sw1 pin: GPIOXXNOTE
在最后的这个完整配置示例中,泵控制被分配给了两个喷灌 控制器实例。其行为符合预期;控制器的多个实例将 通信以确保任何给定泵仅按需要激活和停用,即使 控制器在同时运行。
使用喷灌控制器的数值
Section titled “使用喷灌控制器的数值”喷灌控制器可以利用 ESPHome/Home Assistant 的 number 组件, 使阀门运行时长能够从前端(Home Assistant)轻松调整。
sprinkler: - id: lawn_sprinkler_ctrlr multiplier_number: "Lawn Sprinkler Multiplier" repeat_number: "Lawn Sprinkler Repeat" ...使用 number 组件的另一个好处是,修改后的阀门运行时长、 乘数和重复值可以在 ESP 设备的重置/重启之间保持。如果这是你期望的行为,应 在你的喷灌控制器配置中配置 number 组件。
喷灌控制器对 number 组件的实现基于 ESPHome 的 Number,支持它的所有 配置变量, 以及 Template Number 组件 的部分配置变量, 包括:
initial_value(阀门默认为 900,乘数默认为 1,重复默认为 0)max_value(阀门默认为 86400,乘数和重复默认为 10)min_value(阀门默认为 1,乘数和重复默认为 0)step(阀门和重复默认为 1,乘数默认为 0.1)restore_value(默认为true;设为false以在启动时始终恢复initial_value)set_actionunit_of_measurement(仅用于运行时长;默认为s表示秒,或指定min表示分钟)
这是一个简短示例:
sprinkler: - id: lawn_sprinkler_ctrlr main_switch: "Lawn Sprinklers" ... multiplier_number: id: controller_multiplier_number name: "Lawn Sprinkler Multiplier" initial_value: 1.5 min_value: 0.1 max_value: 5 set_action: - lambda: "some_function();" ...扩展喷灌控制器的开关
Section titled “扩展喷灌控制器的开关”值得注意的是,喷灌控制器配置中的各种开关都是标准的 ESPHome switch 组件。它们的配置可以像 以下示例一样进行扩展:
# 扩展 'main_switch' 的开关配置sprinkler: - id: sprinkler_ctrlr main_switch: name: "Lawn Sprinklers" id: sprinkler_ctrlr_main_switch_id on_turn_on: light.turn_on: my_light ...喷灌控制器配置块中的任何其他开关都可以这样处理,
例外是 pump_switch_id 和 valve_switch_id(因为它们是配置中其他地方已
定义的 switch 组件的 ID)。此外,指定每个开关 ID 可以在配置的其他位置
引用喷灌控制器的任何开关。这里还有一个简短示例:
# 模板开关作为辅助主开关switch: - platform: template id: my_switch name: "My Special Sprinkler Switch" on_turn_off: - switch.turn_off: sprinkler_ctrlr_main_switch_id - light.turn_off: sprinkler_indicator_light on_turn_on: - switch.turn_on: sprinkler_ctrlr_main_switch_id - light.turn_on: sprinkler_indicator_light ...虽然上面的示例仅说明了创建辅助”主”开关,但这种做法可以扩展
以利用其他设备,例如湿度 sensor——当湿度
过低时(寻找 on_value 或 on_value_range),喷灌控制器(或特定阀门)可以
通过调用控制器的启动动作之一来激活,例如 sprinkler.start_full_cycle、
sprinkler.start_from_queue、sprinkler.start_single_valve 或 sprinkler.resume_or_start_full_cycle。
喷灌控制器队列
Section titled “喷灌控制器队列”排队机制对于喷灌控制器来说是一个不寻常的功能;由于 ESPHome 和 Home Assistant 的 极大灵活性,它变得很有用。鉴于当今可用的丰富生态系统, 喷灌控制器的排队机制提供了一种高级功能,旨在支持更高级的自动化。
总的来说,它归结为灵活性:更传统的”运行完整循环”和”运行单个阀门”功能 是设计供人类使用的(通过前端或物理控制界面),而排队机制旨在 支持自动化。
这是一个实际的示例:
考虑一个院子被分成多个喷灌区域的房子——也许它甚至包含一个或两个 花园(当然是花和蔬菜!)。可以在各个区域和花园中部署一系列土壤湿度传感器,当某个传感器低于某个定义阈值时,该传感器的区域就会被输入喷灌控制器的队列。
然后,每天早上在某个特定时间,Home Assistant(甚至 ESP 设备本身!)调用喷灌
控制器的 sprinkler.start_from_queue 动作,导致控制器只遍历排队的区域。
由于运行时长可以作为排队请求的一部分指定,这可以扩展为根据当天土壤的具体湿度水平计算每个区域的具体运行时长。可能性是无限的,只受你的创造力限制!
重要的是要注意,如果同时打开了自动前进和队列开关,排队的阀门 优先于将作为系统完整循环一部分运行的阀门。 换言之,如果队列 已启用,并且一个阀门在完整循环处于活动状态时被输入队列,那么在下一个阀门切换时, 队列条目将在将作为完整循环一部分运行的下一个阀门之前被选中。目前,此 行为无法更改。还应注意,队列有 100 个条目的硬编码限制,以限制 内存使用。
通过 user-API 暴露喷灌控制器动作
Section titled “通过 user-API 暴露喷灌控制器动作”此配置代码片段说明了如何使用用户定义的 ESPHome API 动作将 各种喷灌控制器动作暴露给前端。这对于更改设置 和/或通过自动化触发喷灌控制器动作可能很有用。
api: actions: - action: set_multiplier variables: multiplier: float then: - sprinkler.set_multiplier: id: lawn_sprinkler_ctrlr multiplier: !lambda 'return multiplier;' - action: start_full_cycle then: - sprinkler.start_full_cycle: lawn_sprinkler_ctrlr - action: start_single_valve variables: valve: int then: - sprinkler.start_single_valve: id: lawn_sprinkler_ctrlr valve_number: !lambda 'return valve;' - action: next_valve then: - sprinkler.next_valve: lawn_sprinkler_ctrlr - action: previous_valve then: - sprinkler.previous_valve: lawn_sprinkler_ctrlr - action: shutdown then: - sprinkler.shutdown: lawn_sprinkler_ctrlr理解喷灌控制器的状态
Section titled “理解喷灌控制器的状态”许多人询问如何确定喷灌控制器的状态。本节旨在概述如何 使用喷灌控制器的 API 参考:API 来确定它在做什么,通常旨在在 某种形式的 display 硬件上指示此状态。请注意,此 讨论主要围绕 C++ 代码(如在 ESPHome lambda 中使用的代码)。
用于确定喷灌控制器状态的许多方法返回一种称为 optional 的值类型。
如果你好奇,optional 类型的一般参考可以
在 cppreference.com 上找到,但目前重要的是:
-
optional类型可能包含值,也可能不包含-
方法
has_value()用于确定值是否存在。例如:id(lawn_sprinkler_ctrlr).active_valve().has_value() -
方法
value()用于确定值,前提是已确定值存在。例如:auto running_valve = id(lawn_sprinkler_ctrlr).active_valve().value()
-
-
optional类型可以包含任何 C++ 类型的值(bool、int、float等)。(在 C++ 术语中,它是一个模板。)
下面的示例说明了在 display lambda 中使用喷灌控制器方法的用法。这些示例旨在说明一种模式,且(为了 简洁起见)并不完整;至少,你需要填写 display 组件的具体配置细节后才能使用它们。
考虑到这些要点,让我们讨论一些指示喷灌控制器状态的方法。 我们将从”如何……”的角度来处理。
-
……确定喷灌控制器是否在运行?
使用方法
optional<size_t> active_valve()检查是否有活动阀门。如果返回的optionalhas_value(),则喷灌控制器正在运行,你可以使用value()方法检查哪个具体 阀门处于活动状态。示例:
display: - platform: ... # ...display configuration... lambda: |- if (id(lawn_sprinkler_ctrlr).active_valve().has_value()) { // 控制器正在运行,获取活动阀门到 running_valve 并打印它 auto running_valve = id(lawn_sprinkler_ctrlr).active_valve().value(); it.printf(0, 0, "Valve %u active", running_valve); } else { // 控制器未运行 it.print(0, 0, "Idle"); }-
……确定喷灌控制器是否已暂停,以及如果是,哪个阀门被暂停?
使用方法
optional<size_t> paused_valve()检查是否有暂停的阀门。如果返回的optionalhas_value(),则喷灌控制器已暂停,你可以使用value()方法检查哪个具体 阀门被暂停。总体而言,这与上面的 active_valve() 示例 遵循相同的模式。 -
……确定喷灌控制器的当前模式?
如果你指的是”是否启用了自动前进/队列/反向/待机?“,你就找对地方了。有专门为 此目的设计的方法:
bool auto_advance()bool queue_enabled()bool reverse()bool standby()
每种方法在相应”模式”启用时都会返回
true。示例:
display: - platform: ... # ...display configuration... lambda: |- if (id(lawn_sprinkler_ctrlr).auto_advance()) { // 自动前进已启用 it.print(0, 0, "Auto-advance enabled"); } else { // 自动前进未启用 it.print(0, 0, "Auto-advance disabled"); } if (id(lawn_sprinkler_ctrlr).queue_enabled()) { // 队列已启用 it.print(0, 10, "Queue enabled"); } else { // 队列未启用 it.print(0, 10, "Queue disabled"); }-
……确定喷灌控制器的乘数/重复值?
此处感兴趣的方法是:
float multiplier()optional<uint32_t> repeat()optional<uint32_t> repeat_count()
请注意,每个
repeat方法都返回一个optional类型;如果返回的optionalhas_value(),则已启用重复,你可以使用optional的value()方法获取重复目标(repeat())或当前重复 次数(repeat_count())。multiplier()方法返回float类型,因此它始终有值。示例:
display: - platform: ... # ...display configuration... lambda: |- it.printf(0, 0, "Multiplier: %f", id(lawn_sprinkler_ctrlr).multiplier());
if (id(lawn_sprinkler_ctrlr).repeat().has_value()) { // 控制器正在重复,打印重复目标值 it.printf(0, 10, "Repeat %u times", id(lawn_sprinkler_ctrlr).repeat().value()); }-
……确定还剩/需要多长时间?
有多种方法可供使用:
uint32_t total_cycle_time_all_valves()uint32_t total_cycle_time_enabled_valves()uint32_t total_cycle_time_enabled_incomplete_valves()uint32_t total_queue_time()optional<uint32_t> time_remaining_active_valve()optional<uint32_t> time_remaining_current_operation()
请注意,与前面几个示例类似,
time_remaining_...方法都返回optional类型。如果返回的optionalhas_value(),则有阀门处于活动/运行状态;如果它has_value()不成立,则没有 阀门处于活动状态,意味着控制器处于空闲状态。示例:
display: - platform: ... # ...display configuration... lambda: |- if (id(lawn_sprinkler_ctrlr).time_remaining_active_valve().has_value()) { // 控制器正在运行,打印剩余秒数 it.printf(0, 0, "Time left: %u sec.", id(lawn_sprinkler_ctrlr).time_remaining_active_valve().value()); } else { // 控制器未运行 it.print(0, 0, "Idle"); }