danobot / entity-controller

Home Assistant Entity and lighting controller for managing devices with timers, scripts, and sun-based time restrictions.
https://danobot.github.io/ec-docs/
GNU General Public License v3.0
294 stars 40 forks source link

Using door sensors to override delay on active entity controller #236

Closed MunkeyBalls closed 2 years ago

MunkeyBalls commented 3 years ago

Description

I'm trying to migrate my current setup in node-red to entity controller. There is one feature I cannot seem to implement with standard entity-controller. In my current setup I combine motion sensors with door sensors to turn lights on and control a timer which turns off the lights. The door & motion sensors control the same timer. Whenever a new event is fired, the timer will be reset with the new delay value provided by the sensor.

Because a door sensor usually gets triggered when a person leaves/enters a room, the timer to turn off the light caused by a door sensor is a lot shorter than a motion event. In case the person entered the room, the motion should be triggered right after, which overrides the short delay on the.

Take a look at the following scenario:

Person enters room:

Person leaves room:

This way, whenever someone leaves the room, the light can quickly turn off if there's no motion following.

I've tried playing around with multiple entity controllers (motion/door separated with different delays) controlling the same lights with different delays, but I'm running into issues with the blocked state. For example, if the lights are already turned on by the motion sensor, and I open the door, it will be blocked because the lights are already on. To get around this I tried using the block_timeout, which almost gets me to where I need to be, but after the entity controller for the door events turns off the lights the motion entity controller sits in "active_timer" state until the timer runs out, and will not turn on my lights until the timer ran out. I didn't expect this to work, and to be honest I'm a little confused as to how the block_timeout is supposed to work even after going through the documentation and seeing how it behaves. It almost seems to me like there is some weird behavior going on with some state switches (I might do some more digging and log a separate bug if it's the case).

Another thing I tried was using a script to turn off the light with the door sensor controller, but the same thing happened. Oddly enough, when I turn off the light manually, the states work exactly how I'd like (instead of active_timer, the state on the motion entity will be idle).

I'm wondering if there's already people doing something like this, or if it would be easy to implement. I think the way I'm trying to do it now with multiple entity_controllers for the same lights is a bit of a hack and prone to issues. I noticed there was a service added recently to clear the blocked state. Would it be possible to add a service to override the delay on a running entity controller? It's not ideal, but I could call this service from another automation/node-red. Another solution I was thinking about was adding some more options to the entity_controller yaml, where you can define another set of sensors with a different delay, which can override the already running delay.

I've tried working without this and embracing the backoff feature. But even though the backoff is great, it still leaves my lights on for a long time after someone leaves the room.

Configuration

mtn_peoplecave:
  sensor:
    - binary_sensor.pir_peoplecave_milight_fut105
  entities:
    - light.xmas
    - light.peoplecave_milight_fut105
  override:
    - input_boolean.pir_peoplecave_milight_fut105
  state_entities:
    - light.xmas
  delay: 60
  backoff: true
  backoff_factor: 1.5
  backoff_max: 600
  block_timeout: 5
    #start_time: 'sunset - 01:00:00'
    #end_time: 'sunrise + 01:00:00'

door_peoplecave:
  sensor:
    - binary_sensor.state_door_peoplecave
  entities:
  #  - light.xmas
    - light.peoplecave_milight_fut105
  #trigger_on_deactivate: script.peoplecave_lights_off
  override:
    - input_boolean.pir_peoplecave_milight_fut105
  state_entities:
    - light.xmas
  delay: 30
  block_timeout: 5

Steps to reproduce

Steps to reproduce the behavior:

  1. Wave hand like madman at motion sensor
  2. Leave the room via door like normal person

Expected behavior

This is how the component should work: Lights should turn off quickly after door sensor trigger

Actual Behaviour

This is what actually happened: Lights stay on until the initial timer expires

Logs

I might update this with a log of the "block_timeout" behaviour I see happening. 

Version

9.2.0
danobot commented 3 years ago

Have you tried asking on the community forum?

MunkeyBalls commented 3 years ago

I've posted the same question there now. You have any idea if what I'm achieving is possible with entity-controller? Thanks for sharing your code btw, it seems like a much cleaner solution for what I'm currently doing with a messy node-red flow.

MunkeyBalls commented 3 years ago

I've created a new "set_timer" service to set the controllers delay. Whenver a door is opened/closed the service is called via an automation. I've migrated most of my sensors/lights over to entity-controller and so far everything looks to be working great. I'll let it run for the coming days, if you are interested I can create a pull request.

danobot commented 3 years ago

yes please create a PR for it. What happens when a timer is already running?

MunkeyBalls commented 3 years ago

The timer is actually supposed to be running otherwise the service will not do anything. Currently it will set it back to the initial delay of the controller, but I'll try and add an optional parameter later so you are able to set a specific delay in the service call.

Imagine the scenario where after a lot of triggers combined with using back_off the active_timer is now at 10 mins. When leaving the room I open/close the door which fires an automation which calls the service to set the delay back to 30 sec (or whatever was the initial delay). If no further motion is triggered in the room (other people could be there) the light will turn off after 30s.

Ill do some more testing (i think I noticed some flicker here and there) and create a PR soon