💡 Single button on/off/dim switch v2

This is a generic blueprint usable:

  1. If you have a push button (which restores its position when released).
  2. In case your light entity is able to remember its brightness state (eg. not usable for “assumed state” lights).
12 Likes

Nice! Works perfectly! Thx!

1 Like

I have a hardware button, and I can connect an automation to it, but I cant use it for your blueprint.
Any advice on how to make this zigbee device usable for this?
Its a simple device, one button, connected through conbee 2.
All help is very much appreciated
Peace :v:

Currently, the automation relies on the fact, that a button changes to “on” state when pressed, remains in this state for XY milliseconds, and then changes back to “off” when released.

Contrary, the ZigBee buttons (those, which I had opportunity to test) works the way, that they send “events” containing pre-computed actions – something like “short press”, “long press”, “123ms long press”, “double click”. Because of this difference, I am afraid that most ZigBee devices will not be compatible with this automation.

But I can imagine that it could work if you had a ZigBee device which sends something like “pushed” and “released” events. It would be some extra work for me though. Could you please verify, whether this is the case for your button? We can consider improving this automation then.

Hi, tried this blueprints without success too, I also use physical button, here with a Zigbee Xiaomi button and effectively they use “short press”, “double press”, “long press”, etc. actions. I can’t see them in “Push buttons” menu, would be great to have the possibility to add them :wink:

If you are able to create a binary_sensor entity out of your button (or out of anything else), you can use it with this automation. If not, then unfortunately this automation by design cannot work with it (see the description above).

If you watch history, the binary_sensor must look like this:


Notice overall short timespan and two very short presses: 1 second + one even shorter.

For Xiaomi button, I would try Xiaomi Binary Sensor integration.

im trying to get my zigbee button work with that blueprint, but the input required is a Binary_sensor

my Kone button output when pressed

https://www.toptal.com/developers/hastebin/ahefilebiq

how can i integrate the button to work with this blueprint
thanks

Hi, please see the explanation above (💡 Single button on/off/dim switch - #4 by tomasbedrich).

If your button fires 2 events, one when pressed and the other one when released, it is possible. Otherwise not.

it has three seprate events code:
https://www.toptal.com/developers/hastebin/asexijafes.yaml

found out how to add a binary button in yaml

############ From /config/configuration.yaml #################


template:
  trigger:
    platform: event
    event_type: zha_event
    event_data:
      device_ieee: 14:b4:57:ff:fe:07:64:8d
      unique_id: 14:b4:57:ff:fe:07:64:8d:1:0x0006
      device_id: 6ac46058f87fd735b0ebf94af2dde705
      endpoint_id: 1
      cluster_id: 6
      command: single
      args:
        press_type: single
        command_id: 128
  binary_sensor:
    - name: kone Binary Button
      state: "true"  

just not sure how to add three events to one binary_sensor

It seems to me that you are thinking in the right direction. There are only a few details to tune:

  • I would suggest removing superfluous event_data and keep only the critical keys: device_ieee and command.
  • You will need to specify multiple triggers for the same binary_sensor: single, hold and release events.
  • A hack is probably needed to reset the state back to off after receiving single event. This is probably the hardest thing. If it is not possible using template-triggers because of that, I would try creating some helper + automation + binary sensor pointing to the helper value.
  • You will have to use templating to set binary_sensor.state. If you use Automation Trigger Variables - Home Assistant, I assume the state could look somehow like this: state: "{{ trigger.event.data.command == 'hold' ? 'on' : 'off' }}"

In the end, it may look like this (not tested, not guaranteed!):

template:
  trigger:

    # events
    - platform: event
      event_type: zha_event
      event_data:
        device_ieee: 14:b4:57:ff:fe:07:64:8d
        command: single
    - platform: event
      event_type: zha_event
      event_data:
        device_ieee: 14:b4:57:ff:fe:07:64:8d
        command: hold
    - platform: event
      event_type: zha_event
      event_data:
        device_ieee: 14:b4:57:ff:fe:07:64:8d
        command: release

    # hack! monitoring itself to return back from 'single' event
    # don't know if it's going to work
    - platform: state
      entity_id: binary_sensor.kone_binary_button # <-- adjust
      attribute: last_command
      to: single
      for:
        milliseconds: 50  # <-- assuming that your button reports 50ms press as 'single' - adjust as needed
      id: hackish_reset_trigger

  binary_sensor:
    - name: kone Binary Button
      state: "{{ (trigger.id == 'hackish_reset_trigger' or trigger.event.data.command == 'release') ? 'off' : 'on' }}"
      attributes:
        last_command: "{{ trigger.id == 'hackish_reset_trigger' ? 'reset' : trigger.event.data.command }}"

Is there any way to modify the blueprint so that it doesn’t have the brightness threshold?

I have a push button switch connected to a Samotech 309 dimmer module, it’s default behaviour is to dim up and down regardless of the current brightness level. Each subsequent hold of the button, dims it in the opposite direction to the previous hold of the button.

It wouldn’t be hard. You need to create a helper in HA to remember what was the last direction of dimming, update the helper each time the automation is triggered and finally update the condition section to decide based on the helper value.

thanks for the quick reply.

if it’s not too much of an ask, is there any chance you can show how to do that, not much of a coder (at all) and this would be very much appreciated.

cheers

Create a “Toggle” helper in Settings, then try this variation of a blueprint:

blueprint:
  name: Single button dim switch
  description: Switch a light on/off by pressing a button.
    Dim it up/down (depending on it's current state) by holding the same button.
  domain: automation
  input:
    button:
      name: Push button
      description:
        Entity representing a physical push button (which restores its position
        when released). It must emit a square signal on press.
        This automation is triggered by its falling edge.
      selector:
        entity:
          domain: binary_sensor
    light:
      name: Light
      selector:
        entity:
          domain: light
    hold_threshold:
      name: Hold threshold
      description: Time to consider button is being held, instead of just pushed.
      default: "0.8"
      selector:
        number:
          min: "0.05"
          max: "10"
          step: "0.05"
          unit_of_measurement: s
    direction_helper:
      name: Direction helper
      description: If the helper is True (= last dim direction was up), the light is going to dim down when holding the button and vice versa.
      selector:
        entity:
          domain: input_boolean
    brightness_step_pct:
      name: Brightness step
      description: Percentage brightness increase/decrease in each transition step.
      default: "20"
      selector:
        number:
          min: "1"
          max: "100"
          unit_of_measurement: "%"
    transition_step_length:
      name: Transition step lenght
      description: Length of each transition step.
      default: "0.1"
      selector:
        number:
          min: "0"
          max: "5"
          step: "0.01"
          unit_of_measurement: s

mode: single

trigger:
  - platform: state
    entity_id: !input button
    to: "on"

action:
  - variables:
      brightness_step_pct_positive: !input brightness_step_pct
  - variables:
      brightness_step_pct_negative: "{{ brightness_step_pct_positive|int * -1 }}"
  - wait_for_trigger:
      - platform: state
        entity_id: !input button
        to: "off"
        from: "on"
    timeout: !input hold_threshold
    continue_on_timeout: true
  - choose:
      - conditions:
          # when no trigger came (button has not been switched back to
          # off state during timeout) = button is being held
          - condition: template
            value_template: "{{ wait.trigger == none }}"
        sequence:
          - choose:
              - conditions:
                  # when last direction is on (= up)
                  - condition: state
                    entity_id: !input direction_helper
                    state: "on"
                sequence:
                  # dim down
                  - service: input_boolean.turn_off
                    entity_id: !input direction_helper
                  - repeat:
                      while:
                        - condition: state
                          entity_id: !input button
                          state: "on"
                      sequence:
                        - service: light.turn_on
                          data:
                            transition: !input transition_step_length
                            brightness_step_pct: "{{ brightness_step_pct_negative }}"
                          entity_id: !input light
            default:
              # otherwise, dim up
              - service: input_boolean.turn_on
                entity_id: !input direction_helper
              - repeat:
                  while:
                    - condition: state
                      entity_id: !input button
                      state: "on"
                  sequence:
                    - service: light.turn_on
                      data:
                        transition: !input transition_step_length
                        brightness_step_pct: "{{ brightness_step_pct_positive }}"
                      entity_id: !input light

    # when trigger came (button has been released within timeout)
    default:
      - service: light.toggle
        entity_id: !input light
2 Likes

Just implemented and it works perfectly and mirrors the default behaviour of the physical button connected to the SM309 module.

I can’t thank you enough for helping me with this, enormously appreciated.

Hi Tomas,
I can’t get this working. When I hold the button it starts to dim up or down depends on last state, but it does 2 or 3 steps only and then it gets stuck up for a while ant it doesn’t react to button at all. After some time (~10s) it’s like it does the rest of work - dim, toggle on or off.
Am I doing something wrong? Please help.

- id: '1700328129721'
  alias: livingroom dim
  description: ''
  use_blueprint:
    path: tomasbedrich/single-button-on-off-dim-switch.yaml
    input:
      button: binary_sensor.livingroom_left_button
      light: light.livingroom
      hold_threshold: 0.7
      direction_helper: input_boolean.light_livingroom
      brightness_step_pct: 5
      transition_step_length: 0.2

Thanks

Hey, my guess is that your light is overloaded by enormous number of changes requested per second. Try higher value for brightness_step_pct. What light you use?

Well, I tried brightness_step_pct 30% and 50% (what is useless), and it does exactly 2 steps, 3rd step after 3s and next after 20s. Also I tried transition_step_length up to 1s with about the same result.
Both light and switch is esphome.

Hi Tomas
I have the same problem as Jiri (ESP Home, Sonoff M5, binary sensor assigned to the button and zigbee CCT LED Driver)

SOLVED:

  1. The delay command is missing from both repeat sections
  2. And also a condition for a brightness value greater than zero

Can you please share exact changes made?