hugobloem / stateful_scenes

Stateful Scenes in Home Assistant (Home Kit scene compatible)
MIT License
37 stars 5 forks source link

Stateful switch entity immediately turns off #85

Open kdkavanagh opened 1 week ago

kdkavanagh commented 1 week ago

After turning the switch on, it seems to immediately turn itself off... The lights all turn on correct and stay on despite the stateful switch turning off. Only happens for some of the stateful switches, not all. Anything I can look at to debug?

Kitchen - Medium Stateful Scene turned off triggered by service Switch: Turn on
7:23:44 PM - Now - admin
Kitchen - Medium Stateful Scene turned on triggered by service Switch: Turn on
7:23:44 PM - Now - admin
kdkavanagh commented 1 week ago

Ah I see there's already good debug logging, just need to enable it. Guessing that my Adaptive Lighting configs are interfering with the light after scene activate. Will close for now / reopen if that's not it

kdkavanagh commented 1 week ago

Okay while the adaptive lighting integration was indeed messing with things (fixed by setting adaptive lighting setting adapt_only_bare_turn_on), there still seems to be an issue with entities that handle scene.activate in multiple steps. For example, when I activate a scene, this light seems to first turn itself on with brightness=1, then sets the brightness to the target setting:

image

Because this integration sets is_on=True right away when the scene switch is activated (https://github.com/hugobloem/stateful_scenes/blob/main/custom_components/stateful_scenes/StatefulScenes.py#L254), this causes flickering of the switch state. First it's set to on "manually" in the line above, then the first event above is received, setting the switch to off, only to be toggled on again by the second event above.

If my interpretation is correct, I can think of two ways to fix:

  1. Dont manually set the switch state ever - only rely on the state inferred from the child entities. Not too desirable I suppose since there could be a lag between turning the switch on and having it actually show as on.
  2. Continue to set the switch to on "manually" but set some sort of "debounce" time where received events that would turn the switch off are ignored
kdkavanagh commented 1 week ago

More testing reveals option 1 wont solve the issue. Seeing cases where the first transition is to the correct state, followed by one to brightness: 1 before a final update putting it back in the correct state. You can see the associated stateful_scene switch updates all occurring after

image

(Unsure where the brightness: 1 update is coming from. This is for a light in Z2M via mqtt. Turning the light on directly in Z2M doesnt yield this same pattern, so must be something in HA / possibly related to activating a scene. In any case, this is a separate problem)

kdkavanagh commented 1 week ago

The debounce idea seems to work... Basically added a asyncio.sleep(0.2) to the event handler callback before the schedule_state() call, ignoring the event payload completely. Then, in the switch.update method, requery the entities' states directly, basically deferring the read of the entity's state from the event callback itself until 200ms after the event callback.

This could be improved to only requery the entity that was updated + still checking in the event to see if an "interesting" attribute has changed / ignoring the event if not.

image

Cheerpipe commented 1 week ago

Hi.

I am new using this integration (starting just today) and i have a lot of problems where a state scene switch should be/stay on but it turns on/off instantly when using the switch.

Might you share the changes u did to add the debounce to test?

Thanks in advance.

kdkavanagh commented 1 week ago

It hasn't been foolproof, annoyingly, but certainly better than before. Id guess that increasing the denounce timeout would improve things further.

I'll put together a PR tonight or tmrw so you can see the changes

Cheerpipe commented 1 week ago

I am not a python developer but i was able to do some changes to test your approach.

I added a 1 second delay and disimissed new_state payload on the callback event handler in favor to a entity state query and indeed it works every time. I see this more like a workaround than a propper fix but at least it works.

Some lights do more than one service call and state change and stateful scenes integration misses some of these changes and end with an outdated state to check against scenes, Don't know if it is a stategful scenes bug, a home assistant bug or a bad approbach to check for changes.

Another thing i saw is restore state on deactivate use last state before a change when activating a scene and not the state before a scene is activated. It could lead to integration restoring a wrong state. Grab states before scene is activated could be a better way to implement restore after deactivate.

kdkavanagh commented 1 week ago

Agreed on that latter point about snapshotting before activating. I'll add that to my PR - sorry I couldn't get to that yesterday evening

Cheerpipe commented 1 week ago

It's better to wait for good code than rush for bad one.

kdkavanagh commented 1 week ago

@Cheerpipe see PR above