Make a Multiple-Choice-Switch out of 1 button (Press once, Press twice in x (milli)seconds)

Hey Folks,

I have a few “Clickers” for my smart Lamps from IKEA (Tradfri) and managed to get them to work with “zigbee2mqtt” in Home-Assistant… I can use them as a trigger for automations already.

I would like to make a template-sensor or template-automation-trigger (or whatever is best) to check for multiple clicks within 1 Second… to trigger different things when it is clicked twice…

The clicker populates as Binary-Sensor and does briefly show the state “on”, when pressed.
After releasing, the state is blank (null).
It has no persistent “clicked” state. So every click is only seen as a short state change in the sensor.

My first Thought was to make a Template-Sensor which shows (and temporary saves) the amount of clicks within 1 second. (milliseconds would be even better)
An Automation then triggers if the template-value is “1”, and another automation if value is “2”.

This was my first attempt to a template-sensor like this:

platform: template
sensors:
  ikea_clicker1_on_count:
    friendly_name: Clicker1 Count
    value_template: >-
    {% set clicks = 0 %}
    {% set lastclicktime = 0 %}
    {% if is_state_attr('sensor.ikea_clicker_click', 'click', 'on') %}
        {% set clicks = 1 %}
        {% set currentclicktime=now().seconds %}
        {% if currentclicktime > (lastclicktime) %}
            {% if currentclicktime < (lastclicktime + 1) %}
                {% set clicks = 2 %}
            {% else %}
                {% set clicks = 1 %}
            {% endif %}
        {% endif %}
        {% set lastclicktime = currentclicktime %} 
    {% endif %}
    {{ clicks }}

I think I need a little help on that… because I hardly doubt that this will work…
Does anyone have better ideas on solving this?

How could you check, if an automation trigger (event) has come twice in a given time?
And would it even be accurate enough to notice two clicks within 1 second or less?

Kind Rergards from Germany!
o/

1 Like

I made some progress here… but still need help with formatting MQTT triggers.

The Zigbee2MQTT AddOn has a neat feature of adding an “elapsed” attribute to each mqtt message, checking how much Time ago (in ms) the topic was received last.

The MQTT Trigger could be my best way to fire an automation directly with both conditions (click: on and elapsed < 1000) (for a doubleclick only)

As my clicker sends multiple topics, for example one with all information in it:

Topic: zigbee2mqtt/IKEA Clicker
Payload: '{"battery":60,"click":"on","elapsed":1337,"linkquality":42,"update_available":true,"voltage":2800}'

whereas another only sends ‘on’ or ‘off’

Topic: zigbee2mqtt/IKEA Clicker/click
Payload: 'on'

as of now, the MQTT Trigger only triggers the second topic if I put it in like this

platform: mqtt
topic: "zigbee2mqtt/IKEA Clicker/click"
payload: 'on'

where the first one, conaining the long set of strings and numbers, wont trigger if I specify a ‘partly payload’:

platform: mqtt
topic: "zigbee2mqtt/IKEA Clicker"
payload: '{ "click":"on" }'

Actually the ‘payload’ section (format) is my problem here.

EDIT: (I even thought about skipping the necessity of the payload trigger completely, but then every button on that Clicker would trigger every related automation if not conditioned properly…)

What am I doing wrong?
How does the format for comparing with json formatted payload look like?

You might take a look at controllerx

1 Like

Hi @valet,

As @francisp recommended, ControllerX is able to do this without any boilerplate logic, you just need to focus on what you want to do when the controller is clicked, held, released, tapped twice, etc.

For example, if ControllerX is configured properly, the following configuration would by default (without the merge_mapping attribute):

  • Turn on/off your light with on and off button
  • Change brightness smoothly when holding the button.

In addition, with the merge_mapping attribute it would:

  • turn on full brightness when on clicked twice
  • turn on min brightness when off clicked twice
  • Turn on a scene when on clicked 3 times
  • Send a message to Telegram when off clicked 3 times
example_app:
  module: controllerx
  class: E1743Controller # Assuming your "IKEA Clicker" is an E1743 switch
  integration:
    name: z2m
    listen_to: mqtt
  controller: IKEA Clicker
  multiple_click_delay: 500 # default value
  merge_mapping:
    "on$2": on_full_brightness
    "off$2": on_min_brightness
    "on$3":
      service: scene.turn_on
      data:
        entity_id: scene.my_scene
    "off$3":
      service: notify.telegram
      data:
        message: A message to Telegram when off clicked 3 times

As you can see from the example, the combinations are endless and the clicks are configurable by action$number_of_times_clicked. Also if you want to change the delay for the multiple clicks to be recognized, you can change the multiple_click_delay attribute (500ms by default).

If you are interested in using it and you have problems setting it up, I can help you out if needed.

Documentation: https://xaviml.github.io/controllerx/
Repository: https://github.com/xaviml/controllerx
Community forum topic: ControllerX. Bring full functionality to light and media player controllers
Installable via HACS.

Regards,
Xavi M.

2 Likes

Sorry for bumping, but I had no opportunity to post this earlier.

First of all thanks for the hint about controllerX.
Although, is a very interesting project, maybe someone wants to know the solution to my problem without using 3rd party apps:

I ended up using the MQTT Binary-Sensor and the “elapsed” feature of MQTT (as statet above).

With that I had an extra sensor which came ON if the clicker was tapped twice within 1s, which I can use to trigger automations in opposite to the MQTT event itself (as for one-click only automations)

in configuration.yaml:

mqtt:
  binary_sensor:
    - name: "IKEA Clicker 1 Doubleclick OFF"
      state_topic: "zigbee2mqtt/IKEA Clicker 1"
      value_template: >-
        {% if (value_json.action == 'off') %}
          {% if (value_json.elapsed < 1000) %}
            ON
          {% else %}
            OFF
          {% endif %}
        {% endif %}
1 Like