How to make LED flash green and then return to previous setting

I have a device (m5stack-atom) set up to allow me to press the button, expose this to Home Assistant, run some tasks via automations. This all works wonderfully.

The difficulty I am having is that I’ve added the LED now so I can have the automations change the LED to represent that things are running or alert for different states.

The issue I am having with this is that I’ve set the LED to flash green when the button is pressed and then turn off. But this then overrides the current status of the LED. Is there a way to store the state of the LED, perform an action and then restore the state of the LED? This way I can set the LED however I want, press the button, have it flash/pulse green twice to show the button press was successful and then return to it’s previous state.

I’d like to do this in the ESP yaml coding so that the functionality is built into each button and I don’t have to externally code around it using Home Assistant.

Sorry if this has been asked and solved before but I’ve spent a little while looking for a simple solution and I can’t find one.

It’s always better to do the automation in esphome. Post your yaml and tell what you want to do according to it and the led.

Yes…

Have a look at the automation docs, use a global variable to store and then restore the state of your led.

Here’s the code I’m using with a few parameters removed.
Basically it’s mostly configuration for the push button to allow me to single, double, triple and long press. It hard coded flashes the LED green when a command triggered.

But I’ve also exposed the LED as well which means I can flash the LED when things happen in home assistant like the contact sensor on the post box could cause it to pulse red. Or the doorbell, whatever.

I’d like to have it so that before it sets the LED to green it saves the current state of the LED and instead of turning the LED off after 1 second, just restore the state, if the state was off, then off. I am thinking this can be a global variable and a script or two but it’s so far a little beyond me.

substitutions:
  name: host-name-goes-here
  friendly_name: Nice Name Goes Here

esphome:
  name: ${name}
  name_add_mac_suffix: false
  friendly_name: ${friendly_name}
  min_version: 2024.12.4

esp32:
  board: m5stack-atom
  framework:
    type: esp-idf

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  domain: .local.domain.here

api:
  encryption:
    key: "KEYGOESHERE"

logger:

ota:
  - platform: esphome
    id: ota_esphome

esp32_ble_tracker:
  scan_parameters:
    active: true

bluetooth_proxy:
  active: true

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO39
      inverted: true
    id: echo_button
    on_multi_click:
      # Single press
      - timing:
          - ON for at most 1s
          - OFF for at least 0.25s
        then:
          - light.turn_on:
              id: led
              blue: 0%
              red: 0%
              green: 100%
              effect: none
          - event.trigger:
              id: button_press_event
              event_type: "single_press"
          - delay: 1s
          - light.turn_off: led
      # Double press
      - timing:
          - ON for at most 1s
          - OFF for at most 0.25s
          - ON for at most 1s
          - OFF for at least 0.25s
        then:
          - light.turn_on:
              id: led
              blue: 0%
              red: 0%
              green: 100%
              effect: none
          - event.trigger:
              id: button_press_event
              event_type: "double_press"
          - delay: 1s
          - light.turn_off: led
      # Triple Press
      - timing:
          - ON for at most 1s
          - OFF for at most 0.25s
          - ON for at most 1s
          - OFF for at most 0.25s
          - ON for at most 1s
          - OFF for at least 0.25s
        then:
          - light.turn_on:
              id: led
              blue: 0%
              red: 0%
              green: 100%
              effect: none
          - event.trigger:
              id: button_press_event
              event_type: "triple_press"
          - delay: 1s
          - light.turn_off: led
      # Long Press
      - timing:
          - ON for at least 1s
        then:
          - light.turn_on:
              id: led
              blue: 0%
              red: 0%
              green: 100%
              effect: none
          - event.trigger:
              id: button_press_event
              event_type: "long_press"
          - delay: 1s
          - light.turn_off: led

event:
  - platform: template
    id: button_press_event
    name: "Button press"
    icon: mdi:button-pointer
    device_class: button
    event_types:
      - single_press
      - double_press
      - triple_press
      - long_press

light:
  - platform: esp32_rmt_led_strip
    id: led
    name: LED
    icon: "mdi:led-outline"
    entity_category: config
    pin: GPIO27
    default_transition_length: 0s
    restore_mode: RESTORE_DEFAULT_OFF
    chipset: SK6812
    num_leds: 1
    rgb_order: grb
    rmt_channel: 0
    effects:
      - pulse:
          name: "Slow Pulse"
          transition_length: 250ms
          update_interval: 250ms
          min_brightness: 50%
          max_brightness: 100%
      - pulse:
          name: "Fast Pulse"
          transition_length: 100ms
          update_interval: 100ms
          min_brightness: 50%
          max_brightness: 100%

button:
  - platform: factory_reset
    id: factory_reset_button
    name: "Factory Reset"
    entity_category: diagnostic
    internal: true
  - platform: restart
    id: restart_button
    name: "Restart"
    entity_category: config
    disabled_by_default: true
    icon: "mdi:restart"

I’m not sure what the final result you are trying achieve is, but I can give you more pointers on saving and restoring a light state. The yaml/code snippet below will save and restore a RGB LED state. The parameters saved are just the state, brightness and colour, but there are a bunch of other traits which can be read as well if you have other types of lights.

So - the LED is the same as yours:

light:
  - platform: esp32_rmt_led_strip
    id: led
    name: LED
    icon: "mdi:led-outline"
    entity_category: config
    pin: GPIO27
    default_transition_length: 0s
    restore_mode: RESTORE_DEFAULT_OFF
    chipset: SK6812
    num_leds: 1
    rgb_order: grb
    rmt_channel: 0

Define some global variables to store the state values:

globals:
  - id: saved_state
    type: bool
  - id: saved_R
    type: float
  - id: saved_G
    type: float
  - id: saved_B
    type: float
  - id: saved_brightness
    type: float

Then we have two scripts, one to save the state and one to restore. You would call the save one before flashing your LED or whatever you want to do with it, then the restore one once you finish.

script:
  - id: save_light_state
    then:
      - lambda: |-
          id(saved_state) = id(led).current_values.is_on();
          id(saved_brightness) = id(led).current_values.get_brightness();
          id(saved_R) = id(led).current_values.get_red();
          id(saved_G) = id(led).current_values.get_green();
          id(saved_B) = id(led).current_values.get_blue();
          ESP_LOGD("custom", "Current LED state is: %i", id(saved_state));
          ESP_LOGD("custom", "Current LED brightness is: %f", id(saved_brightness));
          ESP_LOGD("custom", "Current LED red level is: %f", id(saved_R));
          ESP_LOGD("custom", "Current LED green level is: %f", id(saved_G));
          ESP_LOGD("custom", "Current LED blue level is: %f", id(saved_B));

  - id: restore_light_state
    then:
      - lambda: |-
          if (id(saved_state)) {
            ESP_LOGD("custom", "Saved LED state is ON"); 
            auto call = id(led).turn_on();
            call.set_brightness(id(saved_brightness)); 
            call.set_rgb(id(saved_R), id(saved_G), id(saved_B)); 
            call.perform(); }
          else {
            ESP_LOGD("custom", "Saved LED state is OFF"); 
            auto call = id(led).turn_off(); 
            call.set_brightness(id(saved_brightness)); 
            call.set_rgb(id(saved_R), id(saved_G), id(saved_B)); 
            call.perform();
          }
          ESP_LOGD("custom", "LED state is restored"); 
1 Like