I have created a pyscript solution to dim lights with a single pushbutton: as long as you keep pushing the button, the brightness slowly increases or decreases. When you release the button, the light stays at the brightness of that moment.
I use this script with:
a Shelly 2.5 module, with pushbuttons connected to both inputs;
But it should work with any dimmable light and any pushbutton that can be read as a binary input.
I couldn’t get pyscript’s @state_trigger working, and decided to use an ordinary automation rule and call the python function as a service. So, here’s my script:
directions = {}
@service
def increase_decrease(switch_id, lamp_id):
"""Increase or decrease the brightness as long as the button is pressed"""
log.info(f"Increase/decrease - switch: {switch_id}, lamp: {lamp_id}")
step = 16
if not lamp_id in directions:
directions[lamp_id] = True
counter = 0
current_state = state.get(switch_id)
while current_state == "on" and counter < 1000:
current_state = state.get(switch_id)
current_brightness = int(state.get(f"{lamp_id}.brightness"))
if current_brightness >= 254:
directions[lamp_id] = False
elif current_brightness <= 16:
directions[lamp_id] = True
log.debug(f"current state: {current_state}, current brightness: {current_brightness}, direction: {directions[lamp_id]}")
change = step if directions[lamp_id] else -1 * step
light.turn_on(entity_id=lamp_id, brightness=current_brightness+change)
counter += 1
task.sleep(0.2)
current_brightness = int(state.get(f"{lamp_id}.brightness"))
log.info(f"finished; brightness is now {current_brightness}.")
And here’s a snippet from my automations.yaml, so you can see how to call the service:
It works with entity id’s, you can also use the entity id from a light group. (light.sfeerverlichting in my example is actually a group.)
It took me a while to figure out to which log pyscript writes. It turns out to be home-assistant.log. This one can be viewed via the UI at settings > logs, but I find it more convenient to connect via SSH and use the command:
Thanks for letting me know! Would you mind sharing what type of hardware you are using and what adjustments you made? That info might be of help for others…
Pushing buttons events are gathered from rs485 bus using mysensors library. They distinguish type of press, how many clicks happend or wheather it was long press and send this information over the bus (V_SCENE_ON). Number 10 means, long press started.
I had to apply fast-dirty boundaries to make adjustment more friendly, sorry.
directions = {}
@service
def increase_decrease(switch_id, lamp_id):
"""Increase or decrease the brightness as long as the button is pressed"""
step = 4
if not lamp_id in directions:
directions[lamp_id] = True
counter = 0
directions[lamp_id] = not directions[lamp_id]
current_action = int(state.get(switch_id + ".V_SCENE_ON"))
log.info(f"Increase/decrease - switch: {switch_id}, lamp: {lamp_id}")
while current_action == 10 and counter < 1000:
current_action = int(state.get(switch_id + ".V_SCENE_ON"))
current_brightness = int(state.get(f"{lamp_id}.dmx_values"))
current_light_state = state.get(f"{lamp_id}")
if current_light_state == "off":
current_brightness = 45
if current_brightness >= 180:
directions[lamp_id] = False
elif current_brightness <= 45:
directions[lamp_id] = True
change = step if directions[lamp_id] else -1 * step
light.turn_on(entity_id=lamp_id, brightness=current_brightness+change, transition=0)
counter += 1
task.sleep(0.1)
current_brightness = int(state.get(f"{lamp_id}.dmx_values"))
log.info(f"finished; brightness is now {current_brightness}.")
Hey Bart,
Thank you for sharing this. I’m bloody new to HA and wanted exactly this behaviour.
Right now I’m using it with Slashback’s “Short long double click” on the long press.
Quite a learning curve to get pyscript and everything running when you are not knowing your way around in a software.
Anyway, I can see the brightness slider moving in HA UI, but the light itself is not changing unless I release the button. I’m using ESPhome lights on a ESP01s board.
Would you know a way to publish the new brightness to the light itself while still pressing the button.
Cheers,
Klaus
I am using this with Zigbee lights (using the ZHA integration). With Zigbee lights, the lights do change while the button is pressed. So this must be something specific to your ESPhome setup. I don’t have any experience with that, so I can’t help you with it.
That’s hard to say. It looks like this unit has an input and can switch a light on and off. However, it does not dim a light. So you’ll need a dimmable bulb at least. And it needs to be possible to decouple the button input from the switched output. I know Shelly modules can do that, but I don’t know about this unit. The documentation of the unit should give some clarity on this.
@bartkummel thanks for sharing this, I was looking how to do exactly the same thing.
Did you ever get the @state_trigger to work? I think I might have a solution as I was trying to do exactly the same for my Shelly devices. It looks like the trigger to use is binary_sensor.{name}_channel_n_input . However by default this is disabled by the integration, however if I enable it and and do the following I get the kwargs dumped to the logs
Here you can look at the click_type to determine if it was a short or long click
Edit: Note, the shelly.click method works, only if the device is set up as a momentary switch, where as the first would work if the switch are not set up as a momentary switch, this is due to Homeassistant not having binary sensors for momentary switch events.
@kingamajick Thanks for sharing! I have switched to another approach in the meantime, but this is undoubtedly very useful for other people using the combination of pyscript and Shelly!