Internal Automations
Prepare some internal automations!
What are Internal Automations?
Internal automations are a powerful way to create simple, core automations that run directly on your boneIO ESP controller. This means they will work even if your main smart home hub (like Home Assistant) is offline. They are perfect for critical functions, like turning on a light with a wall switch.
Basic Automation: Toggling a Light
Let's start with a default configuration that links a button press to a light.
binary_sensor:
- platform: gpio
name: 'IN_01'
id: in_01
pin:
pcf8574: pcf_inputs
number: 0
mode:
input: true
inverted: true
on_press: # This is our automation trigger
then:
- light.toggle: chl_01 # This is the action to perform
light:
- platform: monochromatic
output: chl01
name: 'CHL 01'
id: chl_01
default_transition_length: 2s
gamma_correct: 0In the on_press: section, we define what happens when the button is pressed.
The action - light.toggle: chl_01 will toggle the state of the light with the ID chl_01.
Advanced Automation: Multi-Click
ESPHome allows you to define multiple actions for a single button based on how it's pressed (single, double, or long press). This is done using the on_multi_click component.
Let's configure one button (in_01) to control three different lights.
1. The Goal
- Single Click: Toggle
chl_01. - Double Click: Toggle
chl_02. - Long Press: Toggle
chl_03.
2. The Configuration
First, ensure you have your lights defined. Then, in your binary_sensor configuration, replace on_press with on_multi_click.
# Ensure these lights are defined elsewhere in your config
light:
- platform: monochromatic
output: chl01
name: 'CHL 01'
id: chl_01
default_transition_length: 2s
gamma_correct: 0
- platform: monochromatic
output: chl02
name: 'CHL 02'
id: chl_02
default_transition_length: 2s
gamma_correct: 0
- platform: monochromatic
output: chl03
name: 'CHL 03'
id: chl_03
default_transition_length: 2s
gamma_correct: 0
# Now, configure the multi-click automation
binary_sensor:
- platform: gpio
name: 'IN_01'
id: in_01
pin:
pcf8574: pcf_inputs
number: 0
mode:
input: true
inverted: true
on_multi_click:
# Note: The order matters! ESPHome checks from top to bottom.
# It's best to define the most complex patterns (longest clicks) first.
# 1. Long Click Action
- timing:
- ON for at least 1.4s
then:
- logger.log: 'Long Click Detected, toggling Light 1'
- light.toggle: chl_01
# 2. Double Click Action
- timing:
- ON for at most 1s
- OFF for at most 0.5s
- ON for at most 1s
- OFF for at least 0.2s
then:
- logger.log: 'Double Click Detected, toggling Light 2'
- light.toggle: chl_02
# 3. Single Click Action
- timing:
- ON for at most 1s
- OFF for at least 0.5s
then:
- logger.log: 'Single Click Detected, toggling Light 3'
- light.toggle: chl_033. How It Works
The on_multi_click automation checks a sequence of timing blocks from top to bottom. The first one that matches the user's button press pattern is executed.
-
timing: This defines the pattern of ON (pressed) and OFF (released) states. You can adjust the time values (e.g.,at most 1s,at least 0.5s) to fine-tune the responsiveness, but the defaults are usually a good starting point. -
then: This block contains the actions to be performed when thetimingpattern is matched. We've included alogger.logaction, which is very helpful for debugging your automations in the device logs.
By arranging the clicks from most complex (long press) to least complex (single press), you ensure that a long press doesn't also trigger the single press action.
Brightening lights with a button hold
binary_sensor:
- platform: gpio
name: 'IN_01'
id: in_01
pin:
pcf8574: pcf_inputs
number: 1
mode:
input: true
inverted: true
on_press:
then:
- while:
condition:
binary_sensor.is_on: in_01
then:
- if:
condition:
lambda: 'return id(chl_01).current_values.get_brightness() >= 0.90f;'
then:
- light.control:
id: chl_01
brightness: 0%
- light.turn_off:
id: chl_01
else:
- light.dim_relative:
id: chl_01
relative_brightness: 5%
transition_length: 0.2s
- delay: 200msHow it works
on_presstrigger: Starts the automation when the button is pressed and immediately enters awhileloop.whilewith condition:binary_sensor.is_on: in_01keeps looping for as long as the button remains physically pressed.- Brightness threshold:
lambda: 'return id(chl_01).current_values.get_brightness() >= 0.90f;'reads the current brightness ofchl_01(0.0–1.0). Once it reaches ≥ 90%, it executes a shutdown sequence:light.control: brightness: 0%sets brightness to 0 without a transition,light.turn_offensures the light is OFF.
- Step brightening: If the threshold is not reached,
light.dim_relative: relative_brightness: 5%increases brightness by 5% with a short0.2stransition. - Update cadence:
delay: 200mssets the step frequency (every 200 ms) until the button is released or the threshold is reached.
Tips
- Ensure a light with
id: chl_01exists in yourlight:configuration (see examples above). - Want to dim instead of brighten? Use a negative value, e.g.
relative_brightness: -5%. - Adjust
5%,0.2s, and200msto change step size, smoothness, and responsiveness.
Multi-Click: Single click — toggle, short hold — dimming
Warning
This code hasn't been tested in real life — it may not work without additional fixes.
binary_sensor:
- platform: gpio
name: 'IN_01_MultiClick_Dim'
id: in_01
pin:
pcf8574: pcf_inputs
number: 1
mode:
input: true
inverted: true
on_multi_click:
# 1. Short hold: dim while holding
- timing:
- ON for at least 0.6s
then:
- while:
condition:
binary_sensor.is_on: in_01
then:
- light.dim_relative:
id: chl_01
relative_brightness: -5%
transition_length: 0.2s
- delay: 200ms
# 2. Single click: toggle the light
- timing:
- ON for at most 0.5s
- OFF for at least 0.2s
then:
- light.toggle: chl_01How it works
- Pattern order: The shorter single-click pattern is placed last so it doesn't intercept the hold gesture.
- Dim while holding: After
ON for at least 0.6s, a loop reduces brightness by5%every200msuntil release. - Tuning thresholds: Adjust
0.6s,0.5s, and0.2sto fine-tune gesture detection based on your button hardware and responsiveness needs.
Change RGBW color on click
Warning
This code hasn't been tested in real life — it may not work without additional fixes.
This example cycles through a predictable color palette on each click, so it's easy to reach common presets and return to white.
# Color palette exposed as a select (visible in Home Assistant)
select:
- platform: template
name: "RGBW Color Preset"
id: rgbw_palette
optimistic: true
options:
- White
- Red
- Green
- Blue
- Cyan
- Magenta
- Yellow
- Amber
- Purple
set_action:
# White (uses W channel)
- if:
condition:
lambda: 'return id(rgbw_palette).state == "White";'
then:
- light.turn_on:
id: rgbw_l
brightness: 80%
white: 100%
red: 0%
green: 0%
blue: 0%
# Red
- if:
condition:
lambda: 'return id(rgbw_palette).state == "Red";'
then:
- light.turn_on:
id: rgbw_l
brightness: 80%
red: 100%
green: 0%
blue: 0%
white: 0%
# Green
- if:
condition:
lambda: 'return id(rgbw_palette).state == "Green";'
then:
- light.turn_on:
id: rgbw_l
brightness: 80%
red: 0%
green: 100%
blue: 0%
white: 0%
# Blue
- if:
condition:
lambda: 'return id(rgbw_palette).state == "Blue";'
then:
- light.turn_on:
id: rgbw_l
brightness: 80%
red: 0%
green: 0%
blue: 100%
white: 0%
# Cyan
- if:
condition:
lambda: 'return id(rgbw_palette).state == "Cyan";'
then:
- light.turn_on:
id: rgbw_l
brightness: 80%
red: 0%
green: 100%
blue: 100%
white: 0%
# Magenta
- if:
condition:
lambda: 'return id(rgbw_palette).state == "Magenta";'
then:
- light.turn_on:
id: rgbw_l
brightness: 80%
red: 100%
green: 0%
blue: 100%
white: 0%
# Yellow
- if:
condition:
lambda: 'return id(rgbw_palette).state == "Yellow";'
then:
- light.turn_on:
id: rgbw_l
brightness: 80%
red: 100%
green: 100%
blue: 0%
white: 0%
# Amber
- if:
condition:
lambda: 'return id(rgbw_palette).state == "Amber";'
then:
- light.turn_on:
id: rgbw_l
brightness: 80%
red: 100%
green: 60%
blue: 0%
white: 0%
# Purple
- if:
condition:
lambda: 'return id(rgbw_palette).state == "Purple";'
then:
- light.turn_on:
id: rgbw_l
brightness: 80%
red: 60%
green: 0%
blue: 100%
white: 0%
# Click = next color in the palette
binary_sensor:
- platform: gpio
id: in_01
name: "IN_01_Color_Next"
pin:
pcf8574: pcf_inputs
number: 1
mode:
input: true
inverted: true
on_press:
then:
- select.next: rgbw_paletteHow it works
- Palette as
select: Lets you view and choose the current color from Home Assistant as well. select.nexton click: Each press advances to the next preset and applies it torgbw_l.- Predictable set: A fixed list (White, Red, Green, …) makes operation simple and returning to White easy.
Tips
- Make sure a
rgbw_lRGBW light is defined in yourlight:configuration. - Optionally add double-click to jump to White, or a hold to dim/brighten.