mirror of
https://github.com/esphome/esphome-docs.git
synced 2024-11-17 11:05:39 +01:00
cfc56b9c00
* Sprinkler docs v2 update * Correction * Polishing up * Fixing some links * Add 'Understanding the Sprinkler Controller's State' section * Shorten text in examples * Fix example, syntax highlighting * Add divider to action index, other copy tweaks * Document unit_of_measurement use
1290 lines
60 KiB
ReStructuredText
1290 lines
60 KiB
ReStructuredText
Sprinkler Controller
|
|
====================
|
|
|
|
.. seo::
|
|
:description: Instructions for setting up the sprinkler controller component in ESPHome to control sprinkler valves.
|
|
:image: sprinkler-variant.svg
|
|
|
|
.. figure:: images/sprinkler.png
|
|
:align: center
|
|
|
|
The ``sprinkler`` controller component aims to behave like a sprinkler/irrigation valve controller,
|
|
much like those made by companies such as Rain Bird or Hunter. It does so by automating control of a
|
|
number of :ref:`switch <config-switch>` components, each of which would typically be used to control
|
|
an individual electric valve via a relay or other switching device. It provides a number of features
|
|
you'd expect of a sprinkler controller, including:
|
|
|
|
- Virtually any number of zones (sections of the sprinkler system) per controller instance, limited only by
|
|
available memory and/or GPIO (including I/O expanders!) pin availability on the ESP
|
|
- The ability to run:
|
|
|
|
- One or more full cycles (iterations through all zones) of the system
|
|
- Only a single zone
|
|
|
|
- Automatic cycle repeating
|
|
- A multiplier value to proportionally increase or decrease the run duration for all zones
|
|
- Support for pumps/main valves located upstream of distribution valves
|
|
- Pausing and resuming a zone/cycle
|
|
- Iterating through zones in forward or reverse order
|
|
- Support for both latching ("pulsed") and non-latching valves (which can be arbitrarily mixed!)
|
|
|
|
It reaches even further, however, offering several more advanced features, as well:
|
|
|
|
- Multiple sprinkler controller instances can operate simultaneously on a single (ESP) device
|
|
- Multiple pumps, each of which may be shared across controller instances
|
|
- Enable/disable switches for each individual zone, allowing zones to be omitted from full cycles of the system
|
|
- A valve/zone queuing mechanism aimed at providing advanced support for automation
|
|
- Several valve management strategies to accommodate varying types of hardware/installations:
|
|
|
|
- Adjustable "valve open delay" to help ensure valves are fully closed before the next one is opened
|
|
- Adjustable "valve overlap" to help minimize banging of pipes due to water hammer
|
|
- Adjustable delay intervals to coordinate pump starting and stopping relative to distribution valve opening and closing
|
|
|
|
.. note::
|
|
|
|
While the term "pump" is used throughout this document, the device controlled need not be a
|
|
physical pump. Instead, it may simply be another electric valve located upstream of distribution
|
|
valves (often known in the industry as a "main" or "master" valve). The pump or upstream valve
|
|
simply controls the water supply to other downstream valves.
|
|
|
|
.. figure:: images/sprinkler-ui.jpg
|
|
:align: center
|
|
:width: 60.0%
|
|
|
|
Example Sprinkler Controller UI -- Note that this example leverages :doc:`number </components/number/index>`
|
|
components for setting run durations, repeat and multiplier values.
|
|
:ref:`More details below. <sprinkler-controller-sprinkler_controller_numbers>`
|
|
|
|
.. code-block:: yaml
|
|
|
|
# Example minimal configuration entry
|
|
# (...but please see more detailed examples below!)
|
|
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
|
|
|
|
Please see the :ref:`sprinkler-controller-examples` section below for extensive, detailed configuration
|
|
examples that are ready for you to copy and paste!
|
|
|
|
Configuration variables:
|
|
------------------------
|
|
|
|
- **main_switch** (*Optional*, *string*): Required with more than one valve. The name for the sprinkler
|
|
controller's main switch as it will appear in the front end. This switch, when turned on, calls the
|
|
``sprinkler.resume_or_start_full_cycle`` action; when turned off, it calls the ``sprinkler.shutdown``
|
|
action (see below). It will appear to be "on" when any valve on the controller is active. This switch
|
|
will not appear in the front end if the controller is configured with only one valve.
|
|
- **auto_advance_switch** (*Optional*, *string*): Required with more than one valve. The name for the
|
|
sprinkler controller's "auto-advance" switch as it will appear in the front end. When this switch is
|
|
turned on while a valve is active, when the valve's ``run_duration`` is reached, the sprinkler
|
|
controller will automatically advance to the next enabled valve as a part of a "full cycle" of the
|
|
system. When turned off, the sprinkler controller will shut down after the active valve's
|
|
``run_duration`` is reached (unless there are valves in the queue -- see
|
|
:ref:`sprinkler-controller-sprinkler_controller_queue` section below for more detail). This switch will
|
|
not appear in the front end if the controller is configured with only one valve.
|
|
- **manual_selection_delay** (*Optional*, :ref:`config-time`): The amount of time the controller should
|
|
wait to activate a valve after the ``next_valve`` and ``previous_valve`` actions are called. Useful
|
|
if the control interface consists of only forward/reverse buttons as the button(s) may be pressed
|
|
multiple times to make the selection.
|
|
- **queue_enable_switch** (*Optional*, *string*): The name for the sprinkler controller's queue enable
|
|
switch as it will appear in the front end. When this switch is turned on or not provided, the controller
|
|
will select the next valve/zone to run based on the contents of the queue; the queue takes precedence over
|
|
valves that would otherwise run as a part of a full cycle of the system (when auto-advance is on/enabled).
|
|
See :ref:`sprinkler-controller-sprinkler_controller_queue` section below for more detail.
|
|
- **reverse_switch** (*Optional*, *string*): The name for the sprinkler controller's reverse switch
|
|
as it will appear in the front end. When this switch is turned on, the controller will iterate through
|
|
the valves in reverse order (last-to-first as they appear in the controller's configuration). When
|
|
this switch is turned off or not provided, the controller will iterate through the valves first-to-last.
|
|
This switch will not appear in the front end if the controller is configured with only one valve.
|
|
- **standby_switch** (*Optional*, *string*): The name for the sprinkler controller's standby switch
|
|
as it will appear in the front end. When this switch is turned on, the controller *will not start any valves.*
|
|
**This can result in confusing/unexpected behavior if there is no visual indication of this condition!**
|
|
- **valve_open_delay** (*Optional*, :ref:`config-time`): The *minimum* delay in seconds that should be
|
|
inserted between (distribution) valve switching -- in other words, the amount of time that must elapse
|
|
between one valve switching off and the next one switching on. Useful for systems with valves which depend
|
|
on sufficient water pressure to close. May not be used with ``valve_overlap``.
|
|
- **valve_overlap** (*Optional*, :ref:`config-time`): The amount of time in seconds that the current valve
|
|
and the next valve should run simultaneously as the next valve/zone starts up. This may help prevent pipes
|
|
from banging as valves close. May not be used with ``valve_open_delay``.
|
|
- **pump_switch_off_during_valve_open_delay** (*Optional*, boolean): If set to ``true``, the pump will be
|
|
switched off during the ``valve_open_delay`` interval; otherwise, it remains on. This may only be
|
|
specified when ``valve_open_delay`` is configured (see above). Defaults to ``false``.
|
|
- **pump_start_pump_delay** (*Optional*, :ref:`config-time`): The delay in seconds from when a distribution
|
|
valve is opened to when the associated pump is activated. Useful to ensure pressure does not build
|
|
up from running the pump when no distribution valves are open. May not be used with ``pump_start_valve_delay``.
|
|
- **pump_start_valve_delay** (*Optional*, :ref:`config-time`): The delay in seconds from when a pump
|
|
is started to when the associated distribution valve is opened. Useful for systems where distribution
|
|
valves require sufficient pressure to fully/quickly close. May not be used with ``pump_start_pump_delay``.
|
|
- **pump_stop_pump_delay** (*Optional*, :ref:`config-time`): The delay in seconds from when a distribution
|
|
valve is closed to when the respective pump is deactivated. Useful for systems where distribution valves
|
|
require sufficient pressure to fully/quickly close. May not be used with ``pump_stop_valve_delay``.
|
|
- **pump_stop_valve_delay** (*Optional*, :ref:`config-time`): The delay in seconds from when a pump is
|
|
deactivated to when the respective distribution valve is closed. Useful to ensure pressure does not build
|
|
up from running the pump when no distribution valves are open or to allow the main line out to distribution
|
|
valves to drain. May not be used with ``pump_stop_pump_delay``.
|
|
- **pump_pulse_duration** (*Optional*, :ref:`config-time`): The *minimum* length of the pulse generated to
|
|
operate a pump in milliseconds. *Required* when one or more latching pumps is configured. Note that the *exact*
|
|
length of the pulse is determined by the frequency of the main application loop (as are other ``delay`` timers
|
|
used in ESPHome). Typically this is expected to provide a resolution of approximately 16 milliseconds, however
|
|
this may vary somewhat depending on your exact configuration. Regardless, it should provide
|
|
more-than-sufficient precision to operate any such valve.
|
|
- **valve_pulse_duration** (*Optional*, :ref:`config-time`): The *minimum* length of the pulse generated to
|
|
operate a valve in milliseconds. *Required* when one or more latching valves is configured. Note that the *exact*
|
|
length of the pulse is determined by the frequency of the main application loop (as are other ``delay`` timers
|
|
used in ESPHome). Typically this is expected to provide a resolution of approximately 16 milliseconds, however
|
|
this may vary somewhat depending on your exact configuration. Regardless, it should provide more-than-sufficient
|
|
precision to operate any such valve.
|
|
- **multiplier_number** (*Optional*, *string*): The name of the :doc:`number </components/number/index>` component that
|
|
should be presented to the front end (Home Assistant) to enable control of the sprinkler controller's ``multiplier``
|
|
value. See :ref:`sprinkler-controller-sprinkler_controller_numbers` below for more detail.
|
|
- **repeat_number** (*Optional*, *string*): The name of the :doc:`number </components/number/index>` component that
|
|
should be presented to the front end (Home Assistant) to enable control of the sprinkler controller's ``repeat``
|
|
value. May not be used with ``repeat``. See :ref:`sprinkler-controller-sprinkler_controller_numbers` below for more
|
|
detail.
|
|
- **repeat** (*Optional*, int): The number of times a full cycle should be repeated. Defaults to 0. May not be used
|
|
with ``repeat_number``.
|
|
- **next_prev_ignore_disabled** (*Optional*, boolean): Set to ``true`` to cause
|
|
:ref:`sprinkler-controller-action_next_valve` and :ref:`sprinkler-controller-action_previous_valve` to skip
|
|
over valves that are not enabled. Defaults to ``false``.
|
|
- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation. While optional,
|
|
this is necessary to identify the controller instance (particularly in cases where more than one is
|
|
defined) when calling controller actions (see below) such as ``start_full_cycle`` or ``shutdown``.
|
|
- **valves** (**Required**, *list*): A list of valves the controller should use. Each valve consists of:
|
|
|
|
- **enable_switch** (*Optional*, *string*): The name for the switch component to be used to enable
|
|
this valve to be run as a part of a full cycle of the system. When this switch is turned off, the valve
|
|
will be excluded from a full cycle of the system. When this switch is turned on or not provided, the
|
|
controller will include the valve in a full cycle of the system.
|
|
- **valve_switch** (**Required**, *string*): The name for the switch component to be used to control
|
|
the valve for this part of the sprinkler system (often referred to as a "zone"). When this switch is
|
|
turned on, the controller's "auto-advance" feature is disabled and it will activate the associated
|
|
valve for its ``run_duration`` multiplied by the controller's multiplier value. When this switch is
|
|
turned off, the ``sprinkler.shutdown`` action is called (see below).
|
|
- **pump_switch_id** (*Optional*, :ref:`Switch <config-switch>`): This is the :ref:`switch <config-switch>`
|
|
component to be used to control the valve's pump or upstream electric valve. Typically this would be a
|
|
:doc:`GPIO switch <switch/gpio>` wired to control a relay or other switching device which in turn would
|
|
activate the respective pump/valve. *It is not recommended to expose this switch to the front end; please
|
|
see* :ref:`sprinkler-controller-an_important_note_about_gpio_switches_and_control` *below for more detail.*
|
|
May not be specified with *pump_off_switch_id* or *pump_on_switch_id*.
|
|
- **pump_off_switch_id** (*Optional*, :ref:`Switch <config-switch>`): This is the :ref:`switch <config-switch>`
|
|
component to be used to *turn off* the valve's pump or upstream electric *latching* valve. Typically this
|
|
would be a :doc:`GPIO switch <switch/gpio>` wired to control a relay or other switching device which in turn
|
|
would *switch off* the respective pump/valve. *It is not recommended to expose this switch to the front end; please
|
|
see* :ref:`sprinkler-controller-an_important_note_about_gpio_switches_and_control` *below for more detail.*
|
|
May not be specified with *pump_switch_id*.
|
|
- **pump_on_switch_id** (*Optional*, :ref:`Switch <config-switch>`): This is the :ref:`switch <config-switch>`
|
|
component to be used to *turn on* the valve's pump or upstream electric *latching* valve. Typically this
|
|
would be a :doc:`GPIO switch <switch/gpio>` wired to control a relay or other switching device which in turn
|
|
would *switch on* the respective pump/valve. *It is not recommended to expose this switch to the front end; please
|
|
see* :ref:`sprinkler-controller-an_important_note_about_gpio_switches_and_control` *below for more detail.*
|
|
May not be specified with *pump_switch_id*.
|
|
- **run_duration_number** (*Optional*, *string*): The name of the :doc:`number </components/number/index>` component
|
|
that should be presented to the front end (Home Assistant) to enable control of the valve's ``run_duration`` value.
|
|
May not be used with ``run_duration``. See :ref:`sprinkler-controller-sprinkler_controller_numbers` below for more
|
|
detail. **Pro tip:** Want times in minutes? Add ``unit_of_measurement: min`` to the number configuration. See
|
|
:ref:`sprinkler-controller-sprinkler_controller_numbers` for more detail.
|
|
- **run_duration** (*Optional*, :ref:`config-time`): Required when ``run_duration_number`` is not provided. The
|
|
duration in seconds this valve should remain on/open after it is activated. When a given valve is activated, the
|
|
controller's multiplier value is multiplied by this value to determine the actual run duration for the valve, thus
|
|
allowing the run duration for all valves/zones to be proportionally increased or decreased as desired. May not be
|
|
used with ``run_duration_number``.
|
|
- **valve_switch_id** (**Required**, :ref:`Switch <config-switch>`): This is the :ref:`switch <config-switch>`
|
|
component to be used to control the valve that operates the given section or zone of the sprinkler
|
|
system. Typically this would be a :doc:`GPIO switch <switch/gpio>` wired to control a relay
|
|
or other switching device which in turn would activate the respective valve. *It is not recommended
|
|
to expose this switch to the front end; please see* :ref:`sprinkler-controller-an_important_note_about_gpio_switches_and_control`
|
|
*below for more detail.* May not be specified with *valve_off_switch_id* or *valve_on_switch_id*.
|
|
- **valve_off_switch_id** (**Required**, :ref:`Switch <config-switch>`): This is the :ref:`switch <config-switch>`
|
|
component to be used to *turn off* the *latching* valve that operates the given section or zone of the
|
|
sprinkler system. Typically this would be a :doc:`GPIO switch <switch/gpio>` wired to control a relay
|
|
or other switching device which in turn would *switch off* the respective valve. *It is not recommended
|
|
to expose this switch to the front end; please see* :ref:`sprinkler-controller-an_important_note_about_gpio_switches_and_control`
|
|
*below for more detail.* May not be specified with *valve_switch_id*.
|
|
- **valve_on_switch_id** (**Required**, :ref:`Switch <config-switch>`): This is the :ref:`switch <config-switch>`
|
|
component to be used to *turn on* the *latching* valve that operates the given section or zone of the
|
|
sprinkler system. Typically this would be a :doc:`GPIO switch <switch/gpio>` wired to control a relay
|
|
or other switching device which in turn would *switch on* the respective valve. *It is not recommended
|
|
to expose this switch to the front end; please see* :ref:`sprinkler-controller-an_important_note_about_gpio_switches_and_control`
|
|
*below for more detail.* May not be specified with *valve_switch_id*.
|
|
|
|
.. _sprinkler-controller-an_important_note_about_gpio_switches_and_control:
|
|
|
|
An Important Note about GPIO Switches and Control
|
|
-------------------------------------------------
|
|
|
|
The savvy and/or seasoned ESPHome user will quickly realize that ``pump_switch_id``, ``pump_off_switch_id``,
|
|
``pump_on_switch_id``, ``valve_switch_id``, ``valve_off_switch_id`` and ``valve_on_switch_id`` (as described above)
|
|
are really just pointers to other (GPIO) switches elsewhere in the ESPHome yaml configuration.
|
|
|
|
It might seem reasonable to assume that these :doc:`GPIO switches <switch/gpio>` may be used to switch the various
|
|
sprinkler zones on and off, however, this is **not** the case. It's important to note that the sprinkler controller
|
|
provides a switch for each configured zone -- ultimately, this switch is to be used to switch any given zone on or
|
|
off, **not** the :doc:`GPIO switch <switch/gpio>` the zone is configured with.
|
|
|
|
Keep in mind that a :doc:`GPIO switch <switch/gpio>` directly controls the state of the GPIO pin it is associated
|
|
with. While it's technically feasible to "override" this behavior, it might not always be desirable. For example,
|
|
if you *wanted* to control the state of the switch/pin manually during testing of your system/configuration, this
|
|
would make doing so impossible (or at least more difficult than necessary), presenting other complications. Ultimately,
|
|
flexibility is key, as we've learned from any number of conversations on the ESPHome Discord server.
|
|
|
|
As mentioned in the introduction, the sprinkler controller automates control of the :doc:`GPIO switches <switch/gpio>`
|
|
you provide it with -- it does not "override" control of these switches or alter how they behave beyond simply
|
|
switching them on or off as required based on the configured scheduling.
|
|
|
|
So why not just use the :doc:`GPIO switch <switch/gpio>` to control the various sprinkler zones directly? As it relates
|
|
to the sprinkler controller itself, the primary reason relates to *state* -- that is, we need to be able to ensure
|
|
that the :doc:`GPIO switch <switch/gpio>` state(s) are kept consistent with the configuration of the sprinkler
|
|
controller. While it's less important for systems that simply consist of one valve per zone, it becomes very important
|
|
for systems with some additional complexity. Consider the example of a system with a pump and multiple distribution
|
|
valves attached to said pump; the controller in this case is configured to switch the pump off three seconds *before*
|
|
switching off any given distribution valve. If you suddenly manually switch off a :doc:`GPIO switch <switch/gpio>`
|
|
connected to one of these distribution valves, what happens to the pump? What should the sprinkler controller do? Should
|
|
it switch the distribution valve back on?...or maybe just switch the pump off, too? In either case, based on its
|
|
configuration, the pump was supposed be shut down before the valve, but you just went and turned off the valve. The pump
|
|
could be damaged. There are many other similar situations such as this that may occur, the simplest of which is little
|
|
more than ensuring that any given valve is switched off after *some* duration and does not remain on/open perpetually.
|
|
|
|
In summary, to ensure that your sprinkler controller consistently operates as expected:
|
|
|
|
- Only use the switches provided by the sprinkler controller component to switch any given sprinkler zone on or off.
|
|
- Do not use the :doc:`GPIO switches <switch/gpio>` you have in your configuration to control sprinkler zones/valves
|
|
outside of initial testing of your device configuration.
|
|
- To help prevent accidents, it's probably best if the :doc:`GPIO switches <switch/gpio>` for each sprinkler zone are
|
|
**not** exposed to the front end. This can be accomplished in two ways:
|
|
|
|
- Do not provide a ``name:`` parameter to your :doc:`GPIO switches <switch/gpio>`, or
|
|
- Add ``internal: true`` to each of your :doc:`GPIO switch <switch/gpio>` configurations
|
|
|
|
These simple configuration tweaks will help prevent any number of errors (human, automation, or otherwise) and may help
|
|
to avert disaster!
|
|
|
|
.. _sprinkler-controller-actions:
|
|
|
|
Controller Actions
|
|
------------------
|
|
|
|
.. _sprinkler-controller-action_start_full_cycle:
|
|
|
|
``sprinkler.start_full_cycle`` action
|
|
*************************************
|
|
|
|
Starts a full cycle of the system. This enables the controller's "auto-advance" feature and disables
|
|
the queue. The controller will iterate through all enabled valves/zones. They will each run for their
|
|
configured ``run_duration`` multiplied by the controller's multiplier value. *Note that if NO valves
|
|
are enabled when this action is called, the controller will automatically enable all valves.*
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.start_full_cycle: sprinkler_ctrlr
|
|
|
|
.. _sprinkler-controller-action_start_from_queue:
|
|
|
|
``sprinkler.start_from_queue`` action
|
|
*************************************
|
|
|
|
Starts the controller running valves from its queue. If no valves are in the queue, this action does
|
|
nothing; otherwise, this disables the controller's "auto-advance" feature so that only queued
|
|
valves/zones will run. Queued valves will remain on for either the amount of time specified in the
|
|
queue request or for their configured ``run_duration`` multiplied by the controller's multiplier value
|
|
(if the queue request run duration is not specified or is zero). *Note that queued valves ignore whether
|
|
the valve is enabled; that is, queued valves will always run once the controller is started, unless, of
|
|
course, the queue is (manually) cleared prior to the queue reaching them. Also note that, at present,
|
|
the queue has a hard-coded limit of 100 entries to limit memory use.*
|
|
See :ref:`sprinkler-controller-sprinkler_controller_queue` section below for more detail.
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.start_from_queue:
|
|
id: sprinkler_ctrlr
|
|
|
|
.. _sprinkler-controller-action_start_single_valve:
|
|
|
|
``sprinkler.start_single_valve`` action
|
|
***************************************
|
|
|
|
Starts a single valve. This disables the controller's "auto-advance" and queue features so that only this valve/zone
|
|
will run. The valve will remain on for the specified duration or (if ``run_duration`` is not specified or is zero) for
|
|
its configured ``run_duration`` multiplied by the controller's multiplier value. *Note that this action ignores whether
|
|
the valve is enabled; that is, when called, the specified valve will always run.* Valves are numbered in the order they
|
|
appear in the sprinkler controller's configuration starting at zero (0).
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.start_single_valve:
|
|
id: sprinkler_ctrlr
|
|
valve_number: 0
|
|
run_duration: 600s # optional
|
|
|
|
.. _sprinkler-controller-action_shutdown:
|
|
|
|
``sprinkler.shutdown`` action
|
|
*****************************
|
|
|
|
Initiates a shutdown of all valves/the system, respecting any configured pump or valve stop delays.
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.shutdown: sprinkler_ctrlr
|
|
|
|
.. _sprinkler-controller-action_next_valve:
|
|
|
|
``sprinkler.next_valve`` action
|
|
*******************************
|
|
|
|
Advances to the next valve (numerically). If ``manual_selection_delay`` is configured, the controller
|
|
will wait before activating the selected valve. If no valve is active, the first valve (as they appear
|
|
in the controller's configuration) will be started. Setting ``next_prev_ignore_disabled`` to ``true``
|
|
will cause this action to skip valves that are not enabled via their valve enable switch (see above).
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.next_valve: sprinkler_ctrlr
|
|
|
|
.. _sprinkler-controller-action_previous_valve:
|
|
|
|
``sprinkler.previous_valve`` action
|
|
***********************************
|
|
|
|
Advances to the previous valve (numerically). If ``manual_selection_delay`` is configured, the controller
|
|
will wait before activating the selected valve. If no valve is active, the last valve (as they appear in
|
|
the controller's configuration) will be started. Setting ``next_prev_ignore_disabled`` to ``true`` will
|
|
cause this action to skip valves that are not enabled via their valve enable switch (see above).
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.previous_valve: sprinkler_ctrlr
|
|
|
|
.. _sprinkler-controller-action_pause:
|
|
|
|
``sprinkler.pause`` action
|
|
**************************
|
|
|
|
Immediately turns off all valves, saving the active valve and the amount of time remaining so that
|
|
the cycle may be resumed later on.
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.pause: sprinkler_ctrlr
|
|
|
|
.. _sprinkler-controller-action_resume:
|
|
|
|
``sprinkler.resume`` action
|
|
***************************
|
|
|
|
Resumes a cycle placed on hold with ``sprinkler.pause``. If there is no paused cycle, this action
|
|
will do nothing.
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.resume: sprinkler_ctrlr
|
|
|
|
.. _sprinkler-controller-action_resume_or_start_full_cycle:
|
|
|
|
``sprinkler.resume_or_start_full_cycle`` action
|
|
***********************************************
|
|
|
|
Resumes a cycle placed on hold with ``sprinkler.pause``, but if no cycle was paused, starts a full
|
|
cycle (equivalent to ``sprinkler.start_full_cycle``).
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.resume_or_start_full_cycle: sprinkler_ctrlr
|
|
|
|
.. _sprinkler-controller-action_queue_valve:
|
|
|
|
``sprinkler.queue_valve`` action
|
|
********************************
|
|
|
|
Adds the specified valve into the controller's queue. When the queue is enabled, valves in the queue
|
|
take precedence over valves scheduled as a part of a full cycle of the system (when auto-advance is
|
|
enabled). If ``run_duration`` is not specified or is zero, the sprinkler controller will use the
|
|
valve's configured run duration. Valves are numbered in the order they appear in the sprinkler
|
|
controller's configuration starting at zero (0). *Note that, at present, the queue has a hard-coded
|
|
limit of 100 entries to limit memory use.* Please see :ref:`sprinkler-controller-sprinkler_controller_queue`
|
|
section below for more detail and examples.
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.queue_valve:
|
|
id: sprinkler_ctrlr
|
|
valve_number: 2
|
|
run_duration: 900s
|
|
|
|
.. _sprinkler-controller-action_clear_queued_valves:
|
|
|
|
``sprinkler.clear_queued_valves`` action
|
|
****************************************
|
|
|
|
Removes all queued valves from the controller's queue. Please see :ref:`sprinkler-controller-sprinkler_controller_queue`
|
|
section below for more detail and examples.
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.clear_queued_valves:
|
|
id: sprinkler_ctrlr
|
|
|
|
.. _sprinkler-controller-action_set_multiplier:
|
|
|
|
``sprinkler.set_multiplier`` action
|
|
***********************************
|
|
|
|
Sets the multiplier value used to proportionally increase or decrease the run duration for all valves/zones.
|
|
When a given valve is activated, this value is multiplied by the valve's run duration (see below) to determine the
|
|
valve's actual run duration. *Note that a multiplier value of zero is allowed; if the multiplier value is zero, the
|
|
sprinkler controller will not start any valves.* **This can result in confusing/unexpected behavior if a visual
|
|
indication of this condition is not available!**
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.set_multiplier:
|
|
id: sprinkler_ctrlr
|
|
multiplier: 1.5
|
|
|
|
.. _sprinkler-controller-action_set_repeat:
|
|
|
|
``sprinkler.set_repeat`` action
|
|
*******************************
|
|
|
|
Specifies the number of times full cycles should be repeated. **Note that the total number of cycles
|
|
the controller will run is equal to the repeat value plus one.** For example, with a ``repeat`` value
|
|
of 1, the initial cycle will run, then the repeat cycle will run, resulting in a total of two cycles.
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.set_repeat:
|
|
id: sprinkler_ctrlr
|
|
repeat: 2 # would run three cycles
|
|
|
|
.. _sprinkler-controller-action_set_divider:
|
|
|
|
``sprinkler.set_divider`` action
|
|
********************************
|
|
|
|
The divider value sets both the multiplier and repeat values as follows:
|
|
|
|
- The multiplier value is set to the value of 1 / ``divider``
|
|
- The repeat value is set to ``divider`` - 1
|
|
|
|
As an example, given a divider value of 4, the multiplier would be set to 0.25 and the repeat value
|
|
would be set to 3.
|
|
|
|
This can be useful for dividing the run duration for each valve into multiple shorter cycles, therefore
|
|
avoiding run-off by allowing the ground more time to absorb the water.
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.set_divider:
|
|
id: sprinkler_ctrlr
|
|
divider: 2
|
|
|
|
.. _sprinkler-controller-action_set_valve_run_duration:
|
|
|
|
``sprinkler.set_valve_run_duration`` action
|
|
*******************************************
|
|
|
|
Sets the run duration for the specified valve. When the valve is activated, this value is multiplied
|
|
by the multiplier value (see above) to determine the valve's actual run duration.
|
|
|
|
.. code-block:: yaml
|
|
|
|
on_...:
|
|
then:
|
|
- sprinkler.set_valve_run_duration:
|
|
id: sprinkler_ctrlr
|
|
valve_number: 0
|
|
run_duration: 600s
|
|
|
|
.. note::
|
|
|
|
- The ``start_single_valve`` action ignores whether a valve is enabled via its enable switch.
|
|
- The ``next_valve`` and ``previous_valve`` actions may not appear to respond immediately if either
|
|
``manual_selection_delay`` or any of the various delay mechanisms described in the
|
|
:ref:`sprinkler-controller-pump_and_distribution_valve_coordination` section below are configured.
|
|
If you are using any of these configuration options, be sure to allow the delay intervals to elapse
|
|
before assuming something isn't working!
|
|
- If a valve is active when its ``run_duration`` or the multiplier value is changed, the active
|
|
valve's run duration will remain unaffected until the next time it is started.
|
|
|
|
.. _sprinkler-controller-pump_and_distribution_valve_coordination:
|
|
|
|
Pump and Distribution Valve Coordination
|
|
----------------------------------------
|
|
|
|
The sprinkler controller allows extensive flexibility relating to the switching of pumps and valves.
|
|
Let's take a closer look at how to use these features to tune your system.
|
|
|
|
Delayed Starting and/or Stopping of Pumps or Valves
|
|
***************************************************
|
|
|
|
For systems with pumps, it's generally a bad idea to run the pump with no distribution valves open.
|
|
This causes pressure to build up and can even destroy the pump after some time. For systems with (a)
|
|
pump(s), you'll likely want to add two configuration options:
|
|
|
|
.. code-block:: yaml
|
|
|
|
sprinkler:
|
|
- id: lawn_sprinkler_ctrlr
|
|
pump_start_pump_delay: 3s
|
|
pump_stop_valve_delay: 3s
|
|
...
|
|
|
|
This will cause any given pump to start (in this example) three seconds *after* any associated distribution
|
|
valve is opened. In addition, it will wait three seconds to close the *last* distribution valve *after*
|
|
the pump is stopped. This would allow the pump to spin down, pressure to drop and lines to drain prior
|
|
to switching off the (last) associated distribution valve. (In these configurations, it might also be
|
|
desirable to enable ``valve_overlap``, as well -- more on this below.)
|
|
|
|
Some types of electric valves require sufficient water pressure to (fully/quickly) close. These types of
|
|
valves, when coupled with electric valves upstream of distribution valves (often known in the industry as
|
|
"main" or "master" valves), may require that the upstream valve is switched on *before* any given distribution
|
|
valve(s), allowing the water pressure to stabilize and force all distribution valves closed *before* any single
|
|
distribution valve is opened. In these situations, the reverse of the above configuration may be desirable:
|
|
|
|
.. code-block:: yaml
|
|
|
|
sprinkler:
|
|
- id: lawn_sprinkler_ctrlr
|
|
pump_start_valve_delay: 3s
|
|
pump_stop_pump_delay: 3s
|
|
...
|
|
|
|
In this example, the upstream valve would open three seconds prior to any given associated distribution
|
|
valve, allowing the water pressure to force any attached distribution valves closed. After the delay, the
|
|
required distribution valve is opened and the cycle starts. When the cycle is complete, the (last) distribution
|
|
valve would be switched off three seconds prior to the upstream valve. (In these configurations, it might also
|
|
be desirable to enable ``valve_open_delay``, as well.)
|
|
|
|
.. note::
|
|
|
|
Using ``pump_stop_valve_delay`` or ``pump_stop_pump_delay`` with ``valve_open_delay`` and
|
|
``pump_switch_off_during_valve_open_delay`` may increase the off-time inserted between the operation
|
|
of each zone, as the controller must wait for a given zone (pump *and* valve) to fully shut down before
|
|
it can be started again.
|
|
|
|
Banging Pipes or Valves That Don't Consistently Close
|
|
*****************************************************
|
|
|
|
A common complaint people have with sprinkler systems is that of banging pipes. In other, less common situations,
|
|
some systems suffer from valves that do not (fully/quickly) close. There are three controller options available to
|
|
address either of these complaints/concerns:
|
|
|
|
- ``valve_overlap``
|
|
- ``valve_open_delay``
|
|
- ``pump_switch_off_during_valve_open_delay``
|
|
|
|
The first option, ``valve_overlap``, causes the current valve and the next valve (as the controller is iterating
|
|
through valves) to run simultaneously for the duration specified. The idea here is that this causes a reduction
|
|
in water pressure as the next zone starts up, therefore minimizing banging pipes (aka the "water hammer" effect)
|
|
when the valve that is finishing up finally closes.
|
|
|
|
The second and third options may be used to ensure sufficient water pressure is available to force valves closed.
|
|
This may be useful for pressure-sensitive valves that don't quickly and/or fully close when water pressure is low.
|
|
|
|
For systems with pumps, it may be desirable to switch off the pump before switching to the next distribution
|
|
valve/zone. In these situations, ``pump_switch_off_during_valve_open_delay`` may prove useful in conjunction
|
|
with ``valve_open_delay``.
|
|
|
|
In any case, the examples in the next section illustrate how/where to add these options into your configuration.
|
|
|
|
.. _sprinkler-controller-examples:
|
|
|
|
Controller Examples
|
|
-------------------
|
|
|
|
Single Controller, Single Valve, No Pump
|
|
****************************************
|
|
|
|
This first example illustrates a complete, single-valve system with no pump/upstream valve(s). It
|
|
could be useful for controlling a single valve independent of any other sprinkler controllers. A pump
|
|
could easily be added by adding the ``pump_switch_id`` parameter and a :ref:`switch <config-switch>`.
|
|
|
|
.. code-block:: yaml
|
|
|
|
esphome:
|
|
name: esp-sprinkler-controller
|
|
platform: ESP32
|
|
board: featheresp32
|
|
|
|
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: 5
|
|
|
|
Single Controller, Three Valves, No Pump
|
|
****************************************
|
|
|
|
This example illustrates a complete, simple three-valve system with no pump/upstream valve(s):
|
|
|
|
.. code-block:: yaml
|
|
|
|
esphome:
|
|
name: esp-sprinkler-controller
|
|
platform: ESP32
|
|
board: featheresp32
|
|
|
|
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: 0
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw1
|
|
pin: 2
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw2
|
|
pin: 4
|
|
|
|
Single Controller, Three Valves, Single Pump
|
|
********************************************
|
|
|
|
This example illustrates a complete three-valve system with a single pump/upstream valve:
|
|
|
|
.. code-block:: yaml
|
|
|
|
esphome:
|
|
name: esp-sprinkler-controller
|
|
platform: ESP32
|
|
board: featheresp32
|
|
|
|
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: 12
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw0
|
|
pin: 0
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw1
|
|
pin: 2
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw2
|
|
pin: 4
|
|
|
|
Single Controller, Three Latching Valves, Single Latching Pump
|
|
**************************************************************
|
|
|
|
This example is similar to the previous example, however it illustrates how a "latching" or "pulsed"
|
|
valve can be configured. This type of valve requires two :doc:`GPIO switches <switch/gpio>` to
|
|
operate -- one to switch the valve on and one to switch the valve off. To switch on the valve, the
|
|
"on" :doc:`GPIO switch <switch/gpio>` is switched on for the configured duration and then switched
|
|
off. To switch the valve off, the "off" :doc:`GPIO switch <switch/gpio>` is switched on for the
|
|
configured duration and then switched off.
|
|
|
|
Note that, while this example illustrates a configuration that uses exclusively latching valves,
|
|
latching and non-latching valves may be mixed and matched in any configuration, even if attached to
|
|
a common pump/upstream valve.
|
|
|
|
.. code-block:: yaml
|
|
|
|
esphome:
|
|
name: esp-sprinkler-controller
|
|
platform: ESP32
|
|
board: featheresp32
|
|
|
|
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"
|
|
pump_pulse_duration: 250ms
|
|
valve_pulse_duration: 250ms
|
|
valve_open_delay: 5s
|
|
valves:
|
|
- valve_switch: "Front Lawn"
|
|
enable_switch: "Enable Front Lawn"
|
|
pump_off_switch_id: sprinkler_pump_sw_off
|
|
pump_on_switch_id: sprinkler_pump_sw_on
|
|
run_duration: 900s
|
|
valve_off_switch_id: lawn_sprinkler_valve_sw0_off
|
|
valve_on_switch_id: lawn_sprinkler_valve_sw0_on
|
|
- valve_switch: "Side Lawn"
|
|
enable_switch: "Enable Side Lawn"
|
|
pump_off_switch_id: sprinkler_pump_sw_off
|
|
pump_on_switch_id: sprinkler_pump_sw_on
|
|
run_duration: 900s
|
|
valve_off_switch_id: lawn_sprinkler_valve_sw1_off
|
|
valve_on_switch_id: lawn_sprinkler_valve_sw1_on
|
|
- valve_switch: "Back Lawn"
|
|
enable_switch: "Enable Back Lawn"
|
|
pump_off_switch_id: sprinkler_pump_sw_off
|
|
pump_on_switch_id: sprinkler_pump_sw_on
|
|
run_duration: 900s
|
|
valve_off_switch_id: lawn_sprinkler_valve_sw2_off
|
|
valve_on_switch_id: lawn_sprinkler_valve_sw2_on
|
|
|
|
switch:
|
|
- platform: gpio
|
|
id: sprinkler_pump_sw_off
|
|
pin: 14
|
|
- platform: gpio
|
|
id: sprinkler_pump_sw_on
|
|
pin: 15
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw0_off
|
|
pin: 0
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw0_on
|
|
pin: 2
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw1_off
|
|
pin: 4
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw1_on
|
|
pin: 5
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw2_off
|
|
pin: 12
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw2_on
|
|
pin: 13
|
|
|
|
Dual Controller, Five Valves, Two Pumps
|
|
***************************************
|
|
|
|
This example illustrates a complete and more complex dual-controller system with a total of five
|
|
valves (three on the first controller and two on the second controller) and two pumps/upstream
|
|
valves, each of which are shared between the two controllers:
|
|
|
|
.. code-block:: yaml
|
|
|
|
esphome:
|
|
name: esp-sprinkler-controller
|
|
platform: ESP32
|
|
board: featheresp32
|
|
|
|
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: 12
|
|
- platform: gpio
|
|
id: sprinkler_pump_sw1
|
|
pin: 13
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw0
|
|
pin: 0
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw1
|
|
pin: 2
|
|
- platform: gpio
|
|
id: lawn_sprinkler_valve_sw2
|
|
pin: 4
|
|
- platform: gpio
|
|
id: garden_sprinkler_valve_sw0
|
|
pin: 14
|
|
- platform: gpio
|
|
id: garden_sprinkler_valve_sw1
|
|
pin: 15
|
|
|
|
.. note::
|
|
|
|
In this final complete configuration example, pump control is split among the two sprinkler
|
|
controller instances. This will behave as expected; multiple instances of the controller will
|
|
communicate to ensure any given pump is activated and deactivated only as necessary, even when
|
|
the controllers are operating simultaneously.
|
|
|
|
.. _sprinkler-controller-sprinkler_controller_numbers:
|
|
|
|
Using the Sprinkler Controller's Numbers
|
|
****************************************
|
|
|
|
The sprinkler controller can leverage ESPHome's/Home Assistant's :doc:`number </components/number/index>` component to
|
|
make valve run durations easily adjustable from the front end (Home Assistant).
|
|
|
|
.. code-block:: yaml
|
|
|
|
sprinkler:
|
|
- id: lawn_sprinkler_ctrlr
|
|
multiplier_number: "Lawn Sprinkler Multiplier"
|
|
repeat_number: "Lawn Sprinkler Repeat"
|
|
...
|
|
|
|
An added benefit of using :doc:`number </components/number/index>` components is that modified valve run durations,
|
|
multiplier and repeat values can persist across resets/reboots of the ESP device. If this is your desired behavior, you
|
|
should configure the :doc:`number </components/number/index>` components within your sprinkler controller configuration.
|
|
|
|
The sprinkler controller's implementation of the :doc:`number </components/number/index>` component is based on
|
|
ESPHome's :doc:`/components/number/index`, supporting all of its :ref:`configuration variables <config-number>` in
|
|
addition to a subset of the :doc:`Template Number Component's </components/number/template>` configuration variables,
|
|
including:
|
|
|
|
- ``initial_value`` (Defaults to 900 for valves, 1 for multiplier, 0 for repeat)
|
|
- ``max_value`` (Defaults to 86400 for valves, 10 for multiplier and repeat)
|
|
- ``min_value`` (Defaults to 1 for valves, 0 for multiplier and repeat)
|
|
- ``step`` (Defaults to 1 for valves and repeat, 0.1 for multiplier)
|
|
- ``restore_value`` (Defaults to ``true``; set to ``false`` to always restore ``initial_value`` at boot)
|
|
- ``set_action``
|
|
- ``unit_of_measurement`` (For run durations only; defaults to ``s`` for seconds or specify ``min`` for minutes)
|
|
|
|
Here's a brief example:
|
|
|
|
.. code-block:: yaml
|
|
|
|
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();"
|
|
...
|
|
|
|
.. _sprinkler-controller-sprinkler_controller_extending_switches:
|
|
|
|
Extending the Sprinkler Controller's Switches
|
|
*********************************************
|
|
|
|
It is worth noting that each of the various switches in the sprinkler controller's configuration are standard
|
|
ESPHome :ref:`switch <config-switch>` components. Their configuration may be extended in a manner similar to
|
|
the following example:
|
|
|
|
.. code-block:: yaml
|
|
|
|
# Extended switch configuration for '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
|
|
...
|
|
|
|
This arrangement is possible for any other switch within the sprinkler controller's configuration block, with
|
|
the exception of ``pump_off_switch_id``, ``pump_on_switch_id``, ``pump_switch_id``, ``valve_off_switch_id``,
|
|
``valve_on_switch_id`` and ``valve_switch_id`` (because these are the IDs of other switch components already
|
|
defined elsewhere in your configuration). In addition, specifying each switch ID enables the ability to refer
|
|
to any of the sprinkler controller's switches from elsewhere in your configuration. Here's another brief example:
|
|
|
|
.. code-block:: yaml
|
|
|
|
# Template switch as a secondary main switch
|
|
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
|
|
...
|
|
|
|
While the above example simply illustrates creating a secondary "main" switch, this approach could be extended
|
|
to take advantage of other devices such as a moisture :ref:`sensor <config-sensor>` -- when the moisture level
|
|
is too low (look for ``on_value`` or ``on_value_range``), the sprinkler controller (or a specific valve) could
|
|
be activated by calling one of the controller's start-up actions, such as ``sprinkler.start_full_cycle``,
|
|
``sprinkler.start_from_queue``, ``sprinkler.start_single_valve``, or ``sprinkler.resume_or_start_full_cycle``.
|
|
|
|
.. _sprinkler-controller-sprinkler_controller_queue:
|
|
|
|
The Sprinkler Controller Queue
|
|
******************************
|
|
|
|
The queuing mechanism is an unusual feature for a sprinkler controller; it becomes useful as a result of the
|
|
extreme flexibility of both ESPHome and Home Assistant. Given the extensive ecosystem of devices available today,
|
|
the sprinkler controller's queuing mechanism provides an advanced feature aimed at allowing even more advanced automation.
|
|
|
|
In general, it comes down to flexibility: the more traditional "run full cycle" and "run single valve" functionality
|
|
is intended for use by humans (via the front end or physical control interface) while the queuing mechanism is aimed
|
|
at supporting automation.
|
|
|
|
Here's a practical example:
|
|
|
|
Consider a home with a yard divided into a number of sprinkler zones -- perhaps it even includes a garden or two
|
|
(flowers and vegetables, of course!). An array of soil moisture sensors could be deployed throughout the various
|
|
zones and gardens and when a given sensor falls below some defined threshold, that sensor's zone is entered into
|
|
the sprinkler controller's queue.
|
|
|
|
Then, each morning at some specific hour, Home Assistant (or even the ESP device itself!) calls the sprinkler
|
|
controller's ``sprinkler.start_from_queue`` action, causing the controller to iterate only through queued zones.
|
|
Because the run duration may be specified as a part of the queue request, this could be extended to compute a
|
|
specific run duration for each zone depending on the specific moisture level of the soil on any given day. The
|
|
possibilities are endless and are only limited by your creativity!
|
|
|
|
It is important to note that, if *both* the auto-advance and queue switches are turned on/enabled, **queued valves
|
|
take precedence over valves that would run as a part of a full cycle of the system.** In other words, if the queue
|
|
is enabled and a valve is entered into the queue while a full cycle is active, at the next valve transition, the
|
|
queue entry will be picked up *before* the next valve that would run as a part of the full cycle. At present, this
|
|
behavior cannot be changed. It should also be noted that the queue has a hard-coded limit of 100 entries to limit
|
|
memory use.
|
|
|
|
Expose Sprinkler Controller Actions via user-API
|
|
************************************************
|
|
|
|
This configuration snippet illustrates how user-defined ESPHome API services may be used to expose
|
|
various sprinkler controller actions to the front end. This could be useful to change settings
|
|
and/or trigger sprinkler controller actions using automations.
|
|
|
|
.. code-block:: yaml
|
|
|
|
api:
|
|
services:
|
|
- service: set_multiplier
|
|
variables:
|
|
multiplier: float
|
|
then:
|
|
- sprinkler.set_multiplier:
|
|
id: lawn_sprinkler_ctrlr
|
|
multiplier: !lambda 'return multiplier;'
|
|
- service: start_full_cycle
|
|
then:
|
|
- sprinkler.start_full_cycle: lawn_sprinkler_ctrlr
|
|
- service: start_single_valve
|
|
variables:
|
|
valve: int
|
|
then:
|
|
- sprinkler.start_single_valve:
|
|
id: lawn_sprinkler_ctrlr
|
|
valve_number: !lambda 'return valve;'
|
|
- service: next_valve
|
|
then:
|
|
- sprinkler.next_valve: lawn_sprinkler_ctrlr
|
|
- service: previous_valve
|
|
then:
|
|
- sprinkler.previous_valve: lawn_sprinkler_ctrlr
|
|
- service: shutdown
|
|
then:
|
|
- sprinkler.shutdown: lawn_sprinkler_ctrlr
|
|
|
|
.. _sprinkler-controller-sprinkler_controller_understanding_state:
|
|
|
|
Understanding the Sprinkler Controller's State
|
|
----------------------------------------------
|
|
|
|
A number of people have asked about how to determine the sprinkler controller's state. This section aims to outline how
|
|
to use the sprinkler controller's :apiref:`API <sprinkler/sprinkler.h>` to determine what it is doing, generally with
|
|
the goal of indicating this on some form of :doc:`display </components/display/index>` hardware. Note that this
|
|
discussion largely revolves around C++ code (as is used in ESPHome lambdas).
|
|
|
|
Many of the methods used to determine the sprinkler controller's state return a type of value known as an ``optional``.
|
|
If you are curious, a general reference for the ``optional`` type may be found
|
|
`here <https://en.cppreference.com/w/cpp/utility/optional>`__, but what is important for now is:
|
|
|
|
- The ``optional`` type *may* or *may not* contain a value
|
|
|
|
- The method ``has_value()`` is used to determine if a value is present. For example:
|
|
``id(lawn_sprinkler_ctrlr).active_valve().has_value()``
|
|
- The method ``value()`` is used to determine the value, *if* it is determined that a value is present. For example:
|
|
``auto running_valve = id(lawn_sprinkler_ctrlr).active_valve().value()``
|
|
|
|
- The ``optional`` type can contain a value of any C++ type (``bool``, ``int``, ``float``, etc.) (In C++ terms, it is a
|
|
template.)
|
|
|
|
The examples that follow illustrate use of the the sprinkler controller's methods within a
|
|
:doc:`display </components/display/index>` lambda. The examples are intended to illustrate a pattern and (for sake of
|
|
brevity) *are not complete*; at very least you'll need to fill out the :doc:`display </components/display/index>`
|
|
component's specific configuration details before you can use them.
|
|
|
|
With these points in mind, let's discuss some of the methods which indicate the state of the sprinkler controller.
|
|
We'll approach this from the angle of *"how do I..."*
|
|
|
|
.. _sprinkler-controller-sprinkler_controller_understanding_state_how_do_i:
|
|
|
|
How Do I...
|
|
***********
|
|
|
|
- **...determine if the sprinkler controller is running?**
|
|
|
|
Use the method ``optional<size_t> active_valve()`` to check if there is an active valve. If the ``optional`` returned
|
|
``has_value()``, the sprinkler controller is running and you may use the ``value()`` method to check which specific
|
|
valve is active.
|
|
|
|
*Example:*
|
|
|
|
.. code-block:: c++
|
|
|
|
display:
|
|
- platform: ...
|
|
# ...display configuration...
|
|
lambda: |-
|
|
if (id(lawn_sprinkler_ctrlr).active_valve().has_value()) {
|
|
// the controller is running, get the active valve into running_valve and print it
|
|
auto running_valve = id(lawn_sprinkler_ctrlr).active_valve().value();
|
|
it.printf(0, 0, "Valve %u active", running_valve);
|
|
} else {
|
|
// the controller is NOT running
|
|
it.print(0, 0, "Idle");
|
|
}
|
|
|
|
- **...determine if the sprinkler controller is paused and, if so, which valve is paused?**
|
|
|
|
Use the method ``optional<size_t> paused_valve()`` to check if there is a paused valve. If the ``optional`` returned
|
|
``has_value()``, the sprinkler controller is paused and you may use the ``value()`` method to check which specific
|
|
valve is paused. In general, this follows the same pattern as the
|
|
:ref:`active_valve() example above <sprinkler-controller-sprinkler_controller_understanding_state_how_do_i>`.
|
|
|
|
- **...determine the sprinkler controller's current mode?**
|
|
|
|
If by this you mean, "is auto-advance/the queue/reverse/standby enabled?", you are in the right spot. Methods exist
|
|
for just this purpose:
|
|
|
|
- ``bool auto_advance()``
|
|
- ``bool queue_enabled()``
|
|
- ``bool reverse()``
|
|
- ``bool standby()``
|
|
|
|
Each will return ``true`` if the respective "mode" is enabled.
|
|
|
|
*Examples:*
|
|
|
|
.. code-block:: c++
|
|
|
|
display:
|
|
- platform: ...
|
|
# ...display configuration...
|
|
lambda: |-
|
|
if (id(lawn_sprinkler_ctrlr).auto_advance()) {
|
|
// auto-advance is enabled
|
|
it.print(0, 0, "Auto-advance enabled");
|
|
} else {
|
|
// auto-advance is NOT enabled
|
|
it.print(0, 0, "Auto-advance disabled");
|
|
}
|
|
if (id(lawn_sprinkler_ctrlr).queue_enabled()) {
|
|
// queue is enabled
|
|
it.print(0, 10, "Queue enabled");
|
|
} else {
|
|
// queue is NOT enabled
|
|
it.print(0, 10, "Queue disabled");
|
|
}
|
|
|
|
- **...determine the sprinkler controller's multiplier/repeat values?**
|
|
|
|
Methods of interest in this case are:
|
|
|
|
- ``float multiplier()``
|
|
- ``optional<uint32_t> repeat()``
|
|
- ``optional<uint32_t> repeat_count()``
|
|
|
|
Note again that each of the ``repeat`` methods returns an ``optional`` type; if the ``optional`` returned
|
|
``has_value()``, repeating is enabled and you can get the repeat target (``repeat()``) or current repeat
|
|
count (``repeat_count()``) with ``optional``'s ``value()`` method.
|
|
|
|
The ``multiplier()`` method returns a ``float`` type and, as such, it always has a value.
|
|
|
|
*Examples:*
|
|
|
|
.. code-block:: c++
|
|
|
|
display:
|
|
- platform: ...
|
|
# ...display configuration...
|
|
lambda: |-
|
|
it.printf(0, 0, "Multiplier: %f", id(lawn_sprinkler_ctrlr).multiplier());
|
|
|
|
if (id(lawn_sprinkler_ctrlr).repeat().has_value()) {
|
|
// the controller is repeating, print the repeat target value
|
|
it.printf(0, 10, "Repeat %u times", id(lawn_sprinkler_ctrlr).repeat().value());
|
|
}
|
|
|
|
- **...determine how much time is left/required?**
|
|
|
|
Several methods are available for this purpose:
|
|
|
|
- ``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()``
|
|
|
|
Note that, as with several of the earlier examples, the ``time_remaining_...`` methods each return an ``optional``
|
|
type. If the ``optional`` returned ``has_value()``, a valve is active/running; if it does not ``has_value()``, no
|
|
valve is active, meaning the controller is idle.
|
|
|
|
*Example:*
|
|
|
|
.. code-block:: c++
|
|
|
|
display:
|
|
- platform: ...
|
|
# ...display configuration...
|
|
lambda: |-
|
|
if (id(lawn_sprinkler_ctrlr).time_remaining_active_valve().has_value()) {
|
|
// the controller is running, print the number of seconds remaining
|
|
it.printf(0, 0, "Time left: %u sec.", id(lawn_sprinkler_ctrlr).time_remaining_active_valve().value());
|
|
} else {
|
|
// the controller is NOT running
|
|
it.print(0, 0, "Idle");
|
|
}
|
|
|
|
See Also
|
|
--------
|
|
|
|
- :apiref:`sprinkler/sprinkler.h`
|
|
- :apiref:`switch/switch.h`
|
|
- :ghedit:`Edit`
|