Hello.
It’s possible that I’m missing something really simple here…
but I thought that changing light effect for some addressable LEDs would have been simple… in reality, I can change effect only if I turn them off and then ON again; but I want to avoid that since I defined “on_turn_on” and “on_turn_off” to switch their power with a relay.
This is my whole config file:
esphome:
name: garage-automation
on_boot:
priority: -100
then:
- script.execute: deactivate_outputs
- wait_until:
condition:
wifi.connected:
- script.execute: blink_onboard_led
esp32:
# ESP-WROOM32 (micro-USB)
board: esp32doit-devkit-v1
framework:
type: arduino
# Enable logging
logger:
ota:
- platform: esphome
password: ""
wifi:
ssid: "------------------"
password: "------------------"
# Optional manual IP
manual_ip:
static_ip: 192.168.1.123
gateway: 192.168.1.1
subnet: 255.255.255.0
dns1: 192.168.1.2
dns2: 192.168.1.1
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "------------------"
password: "------------------"
globals:
- id: current_state
type: int
restore_value: no
initial_value: '0' # Default state (both outputs OFF)
- id: relay_timeout
type: int
initial_value: '5000' # temp: final will be 60000 - Maximum relay timeout in milliseconds
output:
- platform: gpio
pin: GPIO2
id: onboard_led
# Global functions
script:
- id: blink_onboard_led
then:
- output.turn_on: onboard_led
- delay: 150ms
- output.turn_off: onboard_led
- delay: 100ms
- output.turn_on: onboard_led
- delay: 150ms
- output.turn_off: onboard_led
- delay: 100ms
- output.turn_on: onboard_led
- delay: 150ms
- output.turn_off: onboard_led
- id: deactivate_outputs
then:
- switch.turn_off: output_open
- switch.turn_off: output_close
- globals.set:
id: current_state
value: '0' # OFF: Both outputs OFF
- lambda: |-
id(actuators_state).publish_state("OFF");
- select.set:
id: actuators_output_ctrl
option: "OFF"
- id: deactivation_on_timeout
then:
- delay: !lambda 'return id(relay_timeout);' # Timeout
- logger.log: "Timeout reached. Deactivating outputs.."
- script.execute: deactivate_outputs
- logger.log: "... and starting LED strip control."
- script.execute: led_strip_control
- id: activate_output_open
then:
- switch.turn_off: output_close
- delay: 250ms
- script.execute: led_strip_blue_red
- switch.turn_on: output_open
- globals.set:
id: current_state
value: '1' # OPEN: Output 1 ON, Output 2 OFF
- lambda: |-
id(actuators_state).publish_state("OPEN");
- select.set:
id: actuators_output_ctrl
option: "OPEN"
- script.execute: deactivation_on_timeout
- id: activate_output_close
then:
- switch.turn_off: output_open
- delay: 250ms
- script.execute: led_strip_blue_red
- switch.turn_on: output_close
- globals.set:
id: current_state
value: '2' # CLOSE: Output 2 ON, Output 1 OFF
- lambda: |-
id(actuators_state).publish_state("CLOSE");
- select.set:
id: actuators_output_ctrl
option: "CLOSE"
- script.execute: deactivation_on_timeout
- id: led_strip_static_green
then:
- light.turn_on:
id: led_strip
brightness: 100%
red: 0%
green: 100%
blue: 0%
- id: led_strip_blue_red
then:
- light.turn_on:
id: led_strip
effect: "Alternanza Blu e Rosso"
- id: led_strip_control
then:
- if:
condition:
binary_sensor.is_on: button_door
then:
- logger.log: "Door opened, turning on (green) LED strip."
#TODO
# FIXME
- script.execute: led_strip_static_green
# FIXME
else:
- logger.log: "Door closed, turning off LED strip."
- light.turn_off: led_strip
# Service for controlling outputs via Home Assistant
api:
services:
- service: set_state
variables:
state: int
then:
- logger.log: "Received state change request via service..."
- if:
condition:
lambda: 'return state == 0;'
then:
- script.execute: deactivate_outputs
- if:
condition:
lambda: 'return state == 1;'
then:
- logger.log: "...for value 1"
- script.execute: activate_output_open
- if:
condition:
lambda: 'return state == 2;'
then:
- logger.log: "...for value 2"
- script.execute: activate_output_close
- service: set_relay_timeout
variables:
timeout: int
then:
- globals.set:
id: relay_timeout
value: !lambda 'return timeout;'
- logger.log:
format: "Relay timeout updated to %d ms"
args: ["timeout"]
# HA Selection menu for controlling outputs
select:
- platform: template
name: "Controllo Attuatori"
id: actuators_output_ctrl
options:
- "OFF"
- "OPEN"
- "CLOSE"
icon: mdi:toggle-switch
initial_option: "OFF"
optimistic: true
set_action:
- logger.log:
format: "Chosen option: %s"
args: ["x.c_str()"]
- if:
condition:
lambda: 'return x == "OFF";'
then:
- script.execute: deactivate_outputs
- if:
condition:
lambda: 'return x == "OPEN";'
then:
- script.execute: activate_output_open
- if:
condition:
lambda: 'return x == "CLOSE";'
then:
- script.execute: activate_output_close
# HA Switches
switch:
- platform: gpio
pin: GPIO25
id: output_open
#name: "Output Open" # (hidden)
restore_mode: ALWAYS_OFF
- platform: gpio
pin: GPIO26
id: output_close
#name: "Output Close" # (hidden)
restore_mode: ALWAYS_OFF
- platform: gpio
pin: GPIO27
id: output_led_bars
name: "Barre LED (interno)"
restore_mode: ALWAYS_OFF
- platform: gpio
pin: GPIO14
id: output_led_strip
#name: "Striscia LED ON/OFF" # (hidden)
restore_mode: ALWAYS_OFF
# HA Buttons and sensors
binary_sensor:
- platform: gpio
pin:
number: GPIO32
mode: INPUT_PULLUP
inverted: true
id: button_open
name: "Tasto OPEN"
icon: "mdi:arrow-up-bold-box"
on_press:
- script.execute: activate_output_open
on_release:
- script.execute: deactivate_outputs
- platform: gpio
pin:
number: GPIO33
mode: INPUT_PULLUP
inverted: true
id: button_close
name: "Tasto CLOSE"
icon: "mdi:arrow-down-bold-box"
on_press:
- script.execute: activate_output_close
on_release:
- script.execute: deactivate_outputs
- platform: gpio
pin:
number: GPIO13
mode: INPUT_PULLUP
id: button_door
name: "Serranda"
icon: "mdi:window-shutter"
filters:
- delayed_on_off: 5s
on_press:
- logger.log: "Door sensor opened"
on_release:
- logger.log: "Door sensor closed"
# HA Text Sensor for showing actuators state
text_sensor:
- platform: template
name: "Stato Attuatori"
id: actuators_state
lambda: |-
if (id(current_state) == 1) {
return std::string("OPEN");
} else if (id(current_state) == 2) {
return std::string("CLOSE");
} else {
return std::string("OFF");
}
icon: "mdi:boom-gate-up"
update_interval: never # Disable automatic updates for performance
light:
- platform: fastled_clockless
id: led_strip
chipset: WS2812B
pin: GPIO04
num_leds: 23
rgb_order: GRB
name: "Striscia LED (esterno)"
on_turn_on:
- switch.turn_on: output_led_strip
on_turn_off:
- switch.turn_off: output_led_strip
effects:
- addressable_lambda:
name: "Alternanza Blu e Rosso"
update_interval: 500ms
lambda: |-
static bool toggle = false;
int half = it.size() / 2;
for (int i = 0; i < it.size(); i++) {
if ((toggle && i < half) || (!toggle && i >= half)) {
it[i] = ESPColor(0, 0, 255); // Blu
} else {
it[i] = ESPColor(255, 0, 0); // Rosso
}
}
toggle = !toggle;
Maybe it’s quite long, but there’s a “# FIXME” comment for the line that gets ignored…
Basically, this should be the logic:
There’s a garage door opened by two linear actuators and there’s a door switch.
While the door is moving (opening or closing) the led strip will show the “red_blue” effect.
At the end of the opening motion, [door sensor OPEN] the red_blue effect should turn to green (THIS is what’s not working), while at the end of the closing motion [door sensor CLOSED], the strip turns off.
Thanks for any help.