Push button dimmer - how?

These are all esp8266 based.

But is depends a bit on the dimmer used…

The trick is to figure out the IO used, meaning the IO pins might differ a bit between different models
So this applies to Moes:

uart:
  tx_pin: GPIO1
  rx_pin: GPIO3

- platform: duty_cycle
    pin: GPIO13
  - platform: esp8266_pwm
    pin: GPIO14
    frequency: 800 Hz

But other brands might use other pins.
I haven’t found a suitable device list for ESPHome, but I did find a good list for Tasmota, and since they both use the same pins it is a good reference :stuck_out_tongue:

1 Like

Yes, I realised I was missing the point of needing an MCU of some sort, was kinda hoping to achieve dimmer effect via basic light component :roll_eyes: Then I remembered I had some experience with Sonoff T4 coding where you can setup slow LED activation like this one:

# Setting up slow LED activation
output:  
  - platform: esp8266_pwm
    id: blue_led
    pin: GPIO13
    inverted: True

light:
  - platform: monochromatic
    name: "Sonoff ${device_name} Blue LED"
    internal: true
    output: blue_led
    id: led

and then it hit me - I WAS using software PWM for that purpose. Now I’m on the right track with coding, going to order some dimmers :smiley:

I still got to the 220v dimmer module. it works and I will continue to connect bulbs for testing

@RGN01 trying to do the same thing here.

The light I want to control is not directly attached to the esp board like most of the examples here seem to be. I do have that on another node and use a little while loop like this:

              - while:
                  condition:
                    binary_sensor.is_on: the_orange_button
                  then:
                  - light.dim_relative:
                      id: led
                      relative_brightness: -1%
                      transition_length: 0.01s
                  - delay: 0.01s

For another button I was setting up today - again, not connected directly to the light I want to control. I use this little while loop blurb:

  - timing:
    - ON for at least 0.75s
    then:
    - while:
        condition:
          binary_sensor.is_on: the_button
        then:
        - logger.log: "Hoooooolds it"
        - homeassistant.service:
            service: light.turn_on
            data:
              brightness_step_pct: "5"
              transition: "1"
              entity_id: light.office_lamp
        - delay: 3s

Still futzing with the values for step_pct, transition and delay but this does seem to work.

Figured I could make this a bit more awesome so I added a sensor to the esp config that gets the current brightness of the light from home assistant. Once I knew that I was able to make it so that if I hold the button and the light is below 50% it will increase the brightness, if it’s above 50% it will decrease it.

Brightness sensor:

sensor:
  - platform: homeassistant
    id: light_bright
    entity_id: light.office_lamp
    attribute: brightness

Then the binary_sensor - aka - the_button

binary_sensor:
- platform: gpio
  pin:
    number: D6
    mode: INPUT_PULLUP
    inverted: True
  name: "$name Button"
  id: the_button
  internal: true
  on_multi_click:
  - timing:
    - ON for at most 1s
    - OFF for at least 0.5s
    then:
    - logger.log: "Single Click"
    - homeassistant.service:
        service: light.toggle
        data:
          entity_id: light.office_lamp
  - timing:
    - ON for at least 0.75s
    then:
    - while:
        condition:
          binary_sensor.is_on: the_button
        then:
        - logger.log: "Hoooooolds it"
        - homeassistant.service:
            service: light.turn_on
            data:
              brightness_step_pct: "5"
              transition: "1"
              entity_id: light.office_lamp
        - delay: 3s
        - if:
            condition:
              - lambda: 'return id(light_bright).state < 127;'
            then:
              - while:
                  condition:
                    binary_sensor.is_on: the_button
                  then:
                    - logger.log: "Hoooooolds it up"
                    - homeassistant.service:
                        service: light.turn_on
                        data:
                          brightness_step_pct: "5"
                          transition: "1"
                          entity_id: light.office_lamp
                    - delay: 3s
            else:
              - while:
                  condition:
                    binary_sensor.is_on: the_button
                  then:
                    - logger.log: "Hoooooolds it down"
                    - homeassistant.service:
                        service: light.turn_on
                        data:
                          brightness_step_pct: "-5"
                          transition: "1"
                          entity_id: light.office_lamp
                    - delay: 3s

It works. I’m sure somebody could make it better but this works.

cheers! :beers:

This is great - thank you!

I have a setup on an ESP node where the button can dim or brighten the attached LEDS and will try to merge that code with yours so the same logic can be used on lights not directly attached to the ESP. I’m a bit short on time right now so it won’t be immediately.

Thanks again for sharing your code!

1 Like

I managed to merge the code as mentioned. This uses a touch switch module on a ESPHOME ESP-01 node to control a remote HASS light.

A click toggles the light while holding the switch brightens or dims it. To reverse operation (e.g. if it is dimming and you need it brighten) then release the hold down and go straight to hold down again.

I hope it is helpful.

esphome:
  name: $devicename
  platform: ESP8266
  board: esp01_1m

substitutions:
  devicename: light-remote-switch        # name of this node  
  upper_devicename: "Light and Switch"   # English Readable name for the node
  short_devicename: "LightSwitch"        # Short form English readable name
  hass_light: "light.study_ceiling"      # HASS entity name of the HASS light to be controlled
  address_ip: X.Y.Z.A
  address_subnet: Y.Y.Y.Y
  address_gateway: X.Y.Z.B

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  domain: !secret wifi_domain
  reboot_timeout: 5min

  manual_ip:
    static_ip: $address_ip
    gateway: $address_gateway
    subnet: $address_subnet

logger:
api:
ota:


globals:
  - id: bool_dim_or_bright #false = dim, true = brighten
    type: bool
    restore_value: no
    initial_value: 'false'

switch:
# This is to restart the ESPHome device remotely
  - platform: restart
    name: ${upper_devicename} - Restart

sensor:
  - platform: wifi_signal
    name: ${upper_devicename} - WiFi
    update_interval: 60s

  - platform: homeassistant #a local sensor to hold the HASS light brightness
    id: light_brightness_from_hass
    entity_id: $hass_light 
    attribute: brightness    

binary_sensor:
  - platform: homeassistant # a local binary sensor to hold the HASS light on / off status
    id: controlled_light_on_hass
    entity_id: $hass_light 

  - platform: gpio
    pin: # Note: This must be true or the ESP-01 will not boot is using a touch switch module (which must be set to be active low)
      number: 0
      inverted: TRUE 
      mode: INPUT_PULLUP
    id: touch_switch
    filters:
      - delayed_on: 50ms  
      - delayed_off: 50ms 
    on_click:
      then:
        - if:
            condition:
              binary_sensor.is_off: controlled_light_on_hass # if light is off, turn it on
            then:
              - homeassistant.service:
                  service: light.turn_on
                  data:
                    entity_id: $hass_light 
            else: # else it is on so turn it off
              - homeassistant.service:
                  service: light.turn_off
                  data:
                    entity_id: $hass_light 
    on_press:
      then:
      - if:
          condition: 
              lambda: |-
                return id(bool_dim_or_bright);
# When above condition evaluates to true - brighter function else dimmer
          then:
          - delay: 0.5s
          - while:
              condition:
                binary_sensor.is_on: touch_switch
              then:
                - homeassistant.service:
                    service: light.turn_on
                    data:
                      brightness_step: "5"
#                      transition: "1" 
                      entity_id: $hass_light 
                - delay: 0.05s
          - lambda: |-
              id(bool_dim_or_bright) = (false);
          else:
          - delay: 0.5s
          - while:
              condition:
                and:
                  - binary_sensor.is_on: touch_switch
# This is to set the minimum value so that touch sensor only allows pre-set minimum
                  - sensor.in_range:
                      id: light_brightness_from_hass
                      above: 10
              then:
                - homeassistant.service:
                    service: light.turn_on
                    data:
                      brightness_step: "-5"
#                      transition: "1"
                      entity_id: $hass_light 
                - delay: 0.05s
          - lambda: |-
              id(bool_dim_or_bright) = (true);
3 Likes

Is this the solution or still work in progress?

I am using it but everything on my HASS installation is permanently a WIP! :joy:

I tested it and it works great for me. I immediately flashed it on a sonoff mini which controls an esp led dimmer in my ceiling lamp. I couldn’t figure out how to do it otherwise, while still using my conventional wall switches. Before I had to adjust the dimming through home assistant and the wall switch was used for powering on/off. However, this was not making the wife happy.
Now, she is happy again. Also because now we can controll all led lighting through the momentary wall switches.

Hi, thanks for the dimming yaml.

globals:
  - id: bool_dim_or_bright #false = dim, true = brighten
    type: bool
    restore_value: no
    initial_value: 'false'

  - id: bool_warm_or_cold #false = warm, true = cold
    type: bool
    restore_value: no
    initial_value: 'false'


binary_sensor:
  - platform: gpio
    pin:
      number: GPIO5
    name: ${device_name} button
    id: ${device_name} button
    # config for multi click actions
    on_multi_click:
      # double click
      - timing:
          - ON for at most 1s
          - OFF for at most 1s
          - ON for at most 1s
          - OFF for at least 0.2s
        then:
          - if:
              condition:
                and:
                  - wifi.connected:
                  - api.connected:
              # double click to toggle between cold and warm light
              then:
              - if:
                  condition: 
                      lambda: |-
                        return id(bool_dim_or_bright);
        # When above condition evaluates to true - cold else warm
                  then:
                  - delay: 0.5s
                  - while:
                      condition:
                        binary_sensor.is_on: ${device_name} button
                      then:
                        - light.turn_on:
                            id: light_1
                            brightness: 40%
                            color_temperature: 2000 K
                  - lambda: |-
                      id(bool_dim_or_bright) = (false);
                  else:
                  - delay: 0.5s
                  - while:
                      condition:
                        and:
                          - binary_sensor.is_on: ${device_name} button
                      then:
                        - light.turn_on:
                            id: light_1
                            brightness: 100%
                            color_temperature: 6530 K
                  - lambda: |-
                      id(bool_dim_or_bright) = (true);
              # toggle relay in case either wifi or api are not connected
              else:
                - switch.toggle: shelly_relay

I’m trying to figure out how to toggle cold or warm light with double click using lambda.
But I’m not sure how to configure the condition so double click would just toggle bool_warm_or_cold true or false.

Hi, which is better to trigger the long press?
on_multi_click or on_press?
The dimming should stop once the button is released with on_multi_click?

I have edited the code.
In my version, the last dimming direction is saved. So if you dim upwards and then dim down again, the light is dimmed downwards.
With off/on the light has the last birghtness instead of 1.0

still one bug, if you dim to 0 and switch on the brightness will be 1.0, but in this case the lastDirection has the wrong value, you need to dim 2 times.

globals:
   - id: lastDirection
     type: bool
     restore_value: no
     initial_value: 'true'

binary_sensor:
  - platform: gpio
    pin: GPIO4
    id: light_0_touch
    on_click:
      then:
        - if:
            condition:
              light.is_off: light_0
            then:
              light.turn_on: 
                id: light_0
                #brightness: 1.0
            else:
              light.turn_off: light_0
    on_press:
      then:
      - if:
          condition: 
            lambda: 'return id(lastDirection) == false;'
          then:
          - delay: 0.5s
          - while:
              condition:
                binary_sensor.is_on: light_0_touch
              then:
                - light.dim_relative:
                    id: light_0
                    relative_brightness: 2%
                    transition_length: 0.2s
                - lambda: 'id(lastDirection) = true;'
                - delay: 0.1s
          else:
          - delay: 0.5s
          - while:
              condition:
                and:
                  - binary_sensor.is_on: light_0_touch
                  - light.is_on: light_0
              then:
                - light.dim_relative:
                    id: light_0
                    relative_brightness: -2%
                    transition_length: 0.2s
                - lambda: 'id(lastDirection) = false;'
                - delay: 0.1s

light:
  - platform: monochromatic
    name: "Licht Dummy"
    id: light_0
    output: light_0_out

# Example output entry
output:
  - platform: esp8266_pwm
    id: light_0_out
    pin: GPIO3
    inverted: true
2 Likes