Automation override built into base components

Hi there.

I have some nice complex automation controlling my windows, skylights, shades, whole-house fans and lights. Input comes from temp sensors, dark sky, Sun positions etc.

I am now finding myself wanting to create smart override functions.For example - if my automations want to close a shade - but I am sitting there and want to override it this once, I want to reach over to the switch or ask alexa to open the shade. But a few minutes later the automation re-runs and closes it.

I find myself creating a lot of timers and input_booleans to implement an “override shade X” for 1 hour. I have to make a timer and a boolean and code it manually for every shade, light etc.

I am brain storming the idea of a second turn_on / turn_off interface for the base classes (light, cover etc). Lets call it automated_turn_on / automated_turn_off. Then the base class also has an override timer built into it and a attribute we can set with the time. Any time turn_on / turn_off is called, the timer is invoked and automated_turn_on / automated_turn_off is ignored until its expired.

like your logic could you share your code (brains)

why not just

add an action to a automation to turn off said automation

  - data:
      entity_id: automation.timer_cupboard_heater_on
    service: automation.turn_off

hard bit finding the LOGIC when to do it and when to turn it back on.

1 Like

OK, here are the gory details then…

My automations are actually a python_script (which I hope to move to app_daemon someday).
There is about ~200 lines of conditional code and I maintain an internal state variable so that multiple end devices work together. The point is that at the end of that 200 lines, for each device I end up with a decision to either

  • do nothing
  • open / turn on
  • close / turn off

And then I execute that decision on each device entity. To implement the override or suspend function i now have an extra conditional wrapping around it. This gives you the idea

if (ControlHouseFan):
  if (HouseFan == "on"):
    hass.services.call('fan', 'turn_on', service_data={ 'entity_id': 'fan.house_fan' }, blocking=True)
  elif (HouseFan == "off"):
     hass.services.call('fan', 'turn_off', service_data={ 'entity_id': 'fan.house_fan' }, blocking=True)

except you can do it with lists of entities and actions for those entities in a loop.

ControlHouseFan is the override condition, the automation only controls a particular device when it is allowed to. ControlHouseFan is a variable with the value of input_boolean.ControlHouseFan.

Then comes all this “regular automation” code to implement the input_boolean.ControlHouseFan, and this is what I seek to avoid for each device

This is only one device’s override, but it needs

  • an input boolean
  • an input select to start the suspend for a specified duration
  • a timer
  • two automations

Here is the automation code to give you the idea.
Not shown, but we also have definitions for the timer, input_boolean, input_select in other files.

- id: Suspend
  alias: suspend
  initial_state: true
  trigger:
    platform: state
    entity_id: input_select.suspend_climate
  condition:
    condition: or
    conditions:
      - condition: template
        value_template: "{{ not is_state('input_select.suspend_climate', 'Running') }}"
      - condition: template
        value_template: "{{ is_state('automation.call_manage_climate', 'off') }}"
  action:
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.ControlHouseFan
  - service: timer.start
    data_template:
      entity_id: timer.SuspendHouseFan
      duration: "{% if is_state('input_select.suspend_climate', '10 min') %}\n 600\n\
        {% elif is_state('input_select.suspend_climate', '30 min') %}\n 1800\n\
        {% elif is_state('input_select.suspend_climate', '1 hour') %}\n 3600\n\
        {% elif is_state('input_select.suspend_climate', '2 hour') %}\n 7400\n\
        {% elif is_state('input_select.suspend_climate', '4 hour') %}\n 14400\n\
        {% elif is_state('input_select.suspend_climate', '8 hour') %}\n 28800\n\
        {% elif is_state('input_select.suspend_climate', '24 hour') %}\n 86400\n\
        {% elif is_state('input_select.suspend_climate', 'Permanently') %}\n 31536000\n\
        {% else %}\n 10\n{% endif %}\n"
- id: Restore
  alias: restore
  initial_state: true
  trigger:
  - platform: event
    event_type: timer.finished
    event_data:
      entity_id: timer.suspend_climate
  action:      
  - service: input_boolean.turn_on
    data:
      entity_id: automation.ControlHouseFan

So my request is to be able to set an attribute on fan.house_fan (and other devices), call it “auto_suspend_time”. Then have that timer automatically kick in and prevent the execution of (new) services auto_turn_on / auto_turn_off.

The timer starts any time turn_on / turn off are called. But those regular services are not otherwise effected by the timer - because the regular switch should always work.

But calls to auto_turn_on / auto_turn_off would be ignored if the timer was activated.