I was eyeing the Ikea remote to control stuff in my living room (that’s not yet implemented but it’s in my head) and this is just perfect! Thank you.
PS: Also great to see what can actually be done with automations
I don’t think I realized how game changing the new choose
and mode
features were going to be until now! I believe this could not have been accomplished sooner without custom Python code!
This is exactly what I set out looking for!
I have a couple Ikea bulbs with toggle switches, and most of the time find it pretty annoying that the bulbs turn back on to their previous light level. A double-click for full brightness would be perfect.
Any suggestion for max length for input_text.zha_click?
I felt like 0.5 seconds was a reasonable for delay between clicking a butting once to turn on a light and the light actually turning on. Much longer and you would be feeling impatient. You may have a use case for extending that delay, so give it a try and see how a single click feels.
Not the delay, the max text length of the field where the click info is stored. HA defaults it to 100, but I was guessing that’s probably too short. I changed it to 1000, but don’t really even know if I’m in the right ballpark. I’m guessing it depends on how many switches will be using it.
I had an epiphany! I was making this code more complex that I needed to. By using a counter
entity, and assuming I am unlikely to be taping multiple ZHA buttons within a half second of each other, I got rid of the complex input_text
field.
Here is my improved code for my three remotes!
automation:
alias: ZHA Button Click
id: zha_button_click
initial_state: true
mode: restart # Force restart to pickup double click
max_exceeded: silent
trigger:
platform: event
event_type: zha_event
action:
# Increment the counter then delay 0.5 second to allow for a second click to cancel the second action.
- service: counter.increment
entity_id: counter.zha_button_click
- delay:
seconds: 0.5
# Store the click count and reset the counter.
- variables:
click_count: '{{ states("counter.zha_button_click") }}'
- service: counter.reset
entity_id: counter.zha_button_click
# Retrieve the remaining values needed to determine which action was requested.
- variables:
remotes:
# Ikea
"ec:1b:bd:ff:fe:23:9c:ee": "remote_family_room"
# Xiaomi
"00:15:8d:00:01:2d:d7:c3": "button_printer_power"
"00:15:8d:00:02:83:e2:b6": "remote_bedroom_double_rocker"
manufacturers:
"ec:1b:bd:ff": "ikea"
"00:15:8d:00": "xiaomi"
device_ieee: '{{ trigger.event.data.device_ieee }}'
manufacturer: '{{ manufacturers[device_ieee[0:11]] }}'
remote: '{{ remotes[device_ieee] }}'
click_count: |
{% if manufacturer == "xiaomi" %}
{%- set count = trigger.event.data.args.value %}
{%- if count == False or count is not number %}
{{- 0 }}
{%- else %}
{{ count|int }}
{%- endif %}
{% else %}
{{ click_count }}
{%- endif %}
# Removed '(manufacturer == "xiaomi" and click_count == 0) to make printer button work.'
command: |
{% set command = trigger.event.data.command %}
{%- if (manufacturer == "hue" and command == "step")
or (manufacturer == "ikea" and command == "checkin")
or remote|trim == "" %}
{%- set command = "ignore" %}
{%- endif %}
{{- command }}
command_modifier: |
{% if manufacturer == "ikea" %}
{{ trigger.event.data.args[0] }}
{%- endif %}
# Only take action for commands other than "ignore".
- choose:
- conditions: '{{ command != "ignore" }}'
sequence:
# Take the requested action!
- service: script.zha_button_actions
data:
click_count: '{{ click_count }}'
command: '{{ command }}'
command_modifier: '{{ command_modifier }}'
manufacturer: '{{ manufacturer }}'
remote: '{{ remote }}'
script:
zha_button_actions:
sequence:
- choose:
# Printer Power Button
# * Xiaomi Mijia Wireless Switch (round)
- conditions: '{{ remote == "button_printer_power" }}'
sequence:
- service: switch.toggle
entity_id: switch.printers
# Family Room 5 button remote
# * IKEA Tradfri Remote Control
- conditions: '{{ remote == "remote_family_room" }}'
sequence:
- choose:
# Button: Power (middle)
- conditions:
- condition: template
value_template: '{{ command == "toggle" }}'
sequence:
- choose:
# Single Click
- conditions: '{{ click_count == 1 }}'
sequence:
# Toggle the fan.
- service: fan.toggle
entity_id: fan.family_room
# Double click
- conditions: '{{ click_count == 2 }}'
sequence:
- service: switch.toggle
entity_id: switch.tv_family_room
# Triple click
- conditions: '{{ click_count == 3 }}'
sequence:
- choose:
# The door is locked
- conditions: '{{ states("lock.front_door")|lower|trim == "locked" }}'
sequence:
- service: lock.unlock
entity_id: lock.front_door
- service: input_boolean.turn_on
entity_id: input_boolean.leave_unlocked
# The door is unlocked
default:
- service: input_boolean.turn_off
entity_id: input_boolean.leave_unlocked
- service: lock.lock
entity_id: lock.front_door
# Quadruple Click
- conditions: '{{ click_count == 4 }}'
sequence:
- service: input_boolean.toggle
entity_id: input_boolean.guest_mode
# Brightness Up (top)
- conditions: '{{ command == "step_with_on_off" }}'
sequence:
- choose:
# Single Click
- conditions: '{{ click_count == 1 }}'
sequence:
- service: light.turn_on
data:
entity_id: light.family_room
brightness_pct: 100
# Double click
- conditions: '{{ click_count == 2 }}'
sequence:
- service: light.turn_on
data:
entity_id: light.table_lamp
brightness_pct: 100
# Brightness down (bottom)
- conditions: '{{ command == "step" }}'
sequence:
- choose:
# Single Click
- conditions: '{{ click_count == 1 }}'
sequence:
- service: light.turn_off
entity_id:
- light.family_room
- light.table_lamp
# Double click
- conditions: '{{ click_count == 2}}'
sequence:
- service: light.turn_off
entity_id: light.table_lamp
###############################
# SINGLE CLICK / HOLD BUTTONS #
###############################
# Single Click: Arrow left (right)
- conditions: '{{ command == "press" and command_modifier == 256 }}'
sequence:
- service: light.turn_on
data:
entity_id: light.family_room_floor_lamp
brightness_pct: 100
# Single Click: Arrow right (left)
- conditions: '{{ command == "press" and command_modifier == 257 }}'
sequence:
- service: light.turn_off
entity_id: light.family_room_floor_lamp
# Hold: Brightness Up (top)
- conditions: '{{ command == "move" }}'
sequence:
- service: light.turn_on
data:
entity_id:
- light.family_room
- light.table_lamp
brightness_step_pct: "-20"
# Hold: Brightness down (bottom)
- conditions: '{{ command == "move_with_on_off" }}'
sequence:
- service: light.turn_on
data:
entity_id:
- light.family_room
- light.table_lamp
brightness_step_pct: "20"
# Hold: Arrow left (left)
- conditions: '{{ command == "hold" and command_modifier == 3329 }}'
sequence:
- service: light.turn_on
data:
entity_id: light.family_room_floor_lamp
brightness_step_pct: "-20"
# Hold: Arrow right (right)
- conditions: '{{ command == "hold" and command_modifier == 3328 }}'
sequence:
- service: light.turn_on
data:
entity_id: light.family_room_floor_lamp
brightness_step_pct: "20"
# Bedroom Double Switch
# * Xiaomi Double Rockers, Battery Powered
- conditions: '{{ remote == "remote_bedroom_double_rocker" }}'
sequence:
- choose:
# Single Click: Left
- conditions: '{{ command == "left_single" }}'
sequence:
- service: light.toggle
entity_id: light.bedroom
# Single Click: Right
- conditions: '{{ command == "right_single" }}'
sequence:
- service: light.toggle
entity_id: light.brian
# Single Click: Both
- conditions: '{{ command == "both_single" }}'
sequence:
- service: light.toggle
entity_id: light.glowforge
# Double Click: Left
- conditions: '{{ command == "left_double" }}'
sequence:
- service: switch.toggle
entity_id: switch.sound_machine
# Double Click: Right
- conditions: '{{ command == "right_double" }}'
sequence:
- service: switch.toggle
entity_id: switch.bedroom_fan
# Double Click: Both
- conditions: '{{ command == "both_double" }}'
sequence:
- service: switch.toggle
entity_id:
- switch.sound_machine
- switch.bedroom_fan
Just to be clear:
ZHA integration so no additional hub or gateway is required for this integration, is it correct?
I’m currently using Conbee II for all my zigbee integrations, it would be great to use it for this remote, too.
Thanks!
-f
I am also using a Conbee II with the ZHA integration. I think that answers your question.
Hi,
Thank you for your post! I have been trying to understand it for hours now and no luck . I am very new to Hassio and coding in general. I wanted to add a double click to my TRADFRI Switch on/off - the simple rocker switch with dimmer they have - to go to max brightness on my TRADFRI light.
Can you please help me ? I am literally drowning in this. I didn’t even manage to create the script and helper to store the click data . I am very new to Hassio and coding in general. I wanted to add a double click to my TRADFRI Switch on/off - the simple rocker switch with dimmer they have - to go to max/min brightness on my TRADFRI light.
Can you please help me ? I am literally drowning in this. I didn’t even manage to create the script and helper to store the click data .
Thank you for your help! That’s huge!
I created this complex coding example before Blueprints existed. Have you seen this Blueprint? This claims to work as a dimmer.
Thank you! Yes, I am using this blueprint. But it’s not supporting double clicks which would be awesome for going to max brightness immediately and not waiting for the slow gradient dimming.
Could u descripe how u did setup the event functions for duble click ?
Thank you for asking! I failed to remember to update my example code here and on my blog, but I did post an optimized version of this code a few posts above this one.
The following line causes the Automation to restart (before taking any more actions). (Read more about Automation Modes.)
mode: restart
I optimized this code to count the number of clicks which occur within 0.5 seconds of each other, before taking actions based on which button was clicked and how many times it was clicked.
To minimize up front processing, I start with the assumption that any zha_event
s are probably button click events. So I don’t do any filtering at this point.
trigger:
platform: event
event_type: zha_event
The first action increments a counter
.
- service: counter.increment
entity_id: counter.zha_button_click
The delay
of 0.5 seconds allows for another click to occur before continuing. Should another click occur before another action is taken, this automation will restart.
- delay:
seconds: 0.5
Next I store the number of clicks in a variable
, then reset the button click counter to zero.
- variables:
click_count: '{{ states("counter.zha_button_click") }}'
- service: counter.reset
entity_id: counter.zha_button_click
After that all of the details about which action was requested is sorted out in the variables:
section.
- The
remote:
variable decides if the event came from one of my remotes (and which remote sent the clicks). - Since some remotes handle click counts internally the
click_count:
variable sorts out which count value to use. - The
command:
variable stores the requested command or decides if the event should be ignored as an event unrelated to remote button clicks.
Finally the choose:
action passes the processed variables to the zha_button_actions
script.
Now that you understand how the automation works, if you read through the script you will notice the comments do a pretty thorough job of explaining which choose:
condition applies a command sequence to which remote button event.
Many thanks @BrianHanifin , I have been somewhat baffled by how to access and interpret the output of a new MOEs 4 gang Scene Switch I’ve bought to evaluate.
What’s got me stumped amongst the otherwise very erudite explanation of your art, is how you determined and stored the device variables values. This bit here:
- variables:
remotes:
# Ikea
"ec:1b:bd:ff:fe:23:9c:ee": "remote_family_room"
# Xiaomi
"00:15:8d:00:01:2d:d7:c3": "button_printer_power"
"00:15:8d:00:02:83:e2:b6": "remote_bedroom_double_rocker"
manufacturers:
"ec:1b:bd:ff": "ikea"
"00:15:8d:00": "xiaomi"
I presume this info is found by watching the zha_events coming through, but, pardon my ignorance, how do you do that?
You are exactly right! Admittedly this code is more advanced than most users will need. I like to try to challenge my programming abilities from time to time, so I created a script that could handle my various remotes.
Using the following guide, you can create your own automation to handle unique button presses.
- Go to Developer Tools > Events.
- Under Listen to events type
zha_event
. - Click Start listening.
- Press a button on your MOES Switch.
The event created by pressing the center button once on my IKEA 5 button remote:
{
"event_type": "zha_event",
"data": {
"device_ieee": "ec:1b:bd:ff:fe:23:9c:ee",
"unique_id": "ec:1b:bd:ff:fe:23:9c:ee:1:0x0006",
"device_id": "fc6086430b1711eba700f15cccf019c9",
"endpoint_id": 1,
"cluster_id": 6,
"command": "toggle",
"args": []
},
.
.
.
}
There you can gather the information which is unique to your button presses for each device. For this button I see the "device_ieee"
is the unique identifier for this remote. The unique "command"
identifying which button was pressed is "toggle"
.
Pressing the Top button outputs this event:
{
"event_type": "zha_event",
"data": {
"device_ieee": "ec:1b:bd:ff:fe:23:9c:ee",
"unique_id": "ec:1b:bd:ff:fe:23:9c:ee:1:0x0008",
"device_id": "fc6086430b1711eba700f15cccf019c9",
"endpoint_id": 1,
"cluster_id": 8,
"command": "step_with_on_off",
"args": [
0,
43,
5
]
},
.
.
.
}
By looking for the differences between all of the events I was able to determine most of this remote’s button presses can be distinguished by simply using the "command"
values. However, in this case the right and left buttons are identified with the same "press"
command. Looking for further differences I noticed the first "args"
value was 256
for the right button, and 257
for the left button.
Every button’s "data"
will be a bit different. As long as you can identify a consistent value difference between each button press, you can create code to handle each unique press.
P.S. My code is intended to allow Home Assistant to count multiple rapid button presses in remotes which immediately report single clicks. Some remotes handle multi-clicks internally, which makes this code unnecessary. So try double and triple clicking your buttons to see if it’s event reports how many times the button was clicked. If your remote handles multiple button clicks internally, then the extra complexity of this script is unnecessary for you.
Many thx @BrianHanifin for the detailed reply,
Much appreciated. I will give that a go shortly.
I have also been trying via the zigbee2mqtt platform using a ConBee II, and although the device will pair there aren’t currently working device or conversion definitions available. It looks pretty daunting following the procedures documented for that platform to integrate a new device.
I attempted to give that a go @BrianHanifin , but nothing shows up.
The device is paired though only one of four switches actually gets registered:
If you are not using ZHA, then you will never see a zha_event trigger. According to the zigbee2mqtt documentation there isn’t an event, instead you have to trigger from an state change.
Thanks for sharing!
It actually took me some time to get it running as I’m quite a noob in HA, but I think I managed.
Important note which was missing is to add a counter! From Settings->Device&Services → Helpers → one needs to add a counter with ID “zha_button_click” with some min/max values (I used 0/20). Otherwise the script doesn’t work.
That’s a good point @lega4! At the time of this post, helpers could only be defined in the configuration.yaml file. That’s a nice reminder of how far Home Assistant has come.
I’m glad you were able to find it useful!