Stepped LED Brightness in ESPHome

I use ESPHome for a number of projects including LED task lighting, and my devices often use an inexpensive TTP223 capacitive touch sensor as a button. I like to be able to tap the sensor multiple times to cycle through brightness levels, so here’s the script I use to do that. It feels like there should be an easier way to do this, but I haven’t found it, so this is what I ended up with.

A couple of notes:

  • The lowest light level is what I call a nightlight level (barely on), and the highest is at 100% brightness.
  • Floating point math introduces the potential for floating point rounding error, so the epsilon tries to account for that.
  • The brightness levels aren’t evenly spaced out because when they were, it was just just an extra tap that I never really stopped on.
  • Note the comment in the code regarding isOn.
script:
  - id: cycle_brightness
    then:
      lambda: |-
        auto light = id(my_light).turn_on();
        float level = id(my_light).current_values.get_brightness();
        bool isOn = id(my_light).current_values.is_on();
        const float epsilon = 0.0001;  // accommodate floating point rounding error

        // If the brightness is set to zero, then the light is actually turned off 
        // as opposed to on with a zero brightess. The brightness, though, still reads
        // at 100%, so testing for isOn here allows us to capture and handle that. 
        if ( ( level < 0.03 - epsilon ) | !isOn )  level = 0.03; //nightlight level
        else if ( level < 0.3 - epsilon )          level = 0.3; 
        else if ( level < 0.6 - epsilon )          level = 0.6; 
        else if ( level < 0.8 - epsilon )          level = 0.8; 
        else if ( level < 1.0 - epsilon )          level = 1.0; 
        else                                       level = 0.0; 
 
        light.set_brightness(level);
        light.perform();

Leave a Reply

Your email address will not be published. Required fields are marked *