Skip to content

Instantly share code, notes, and snippets.

@noelbundick
Last active November 17, 2024 06:21
Show Gist options
  • Save noelbundick/a086a3dc8a36894c7fdae8d930da7826 to your computer and use it in GitHub Desktop.
Save noelbundick/a086a3dc8a36894c7fdae8d930da7826 to your computer and use it in GitHub Desktop.
Home Assistant desired state
automation light:
- id: 'lights_process_desired_state'
alias: "[Lights] Process desired state"
mode: parallel
max: 50
trigger:
- platform: state
entity_id:
- binary_sensor.lights_office_desired_state
- binary_sensor.many_many_others_desires_state
condition:
- condition: template
value_template: "{{ trigger.to_state.attributes['enabled'] and trigger.entity_id not in state_attr('group.disabled_desired_state_sensors', 'entity_id') }}"
action:
- service: >
light.turn_{{ states(trigger.entity_id) }}
data_template:
entity_id: "{{ state_attr(trigger.entity_id, 'target_entity_id') }}"
- unique_id: lights
binary_sensor:
- name: "[Lights:Office] Desired state"
unique_id: office
attributes:
enabled: "{{ is_state('input_boolean.office_automations', 'on') }}"
target_entity_id: light.office
delay_on: "{{ '00:00:00' if is_state('sun.sun', 'below_horizon') else '00:00:05' }}"
delay_off: "{{ '00:00:00' if is_state('sun.sun', 'below_horizon') else '00:00:05' }}"
state: >
{% set is_night = is_state('sun.sun', 'below_horizon') %}
{% set is_occupied = is_state('binary_sensor.office_aqara_occupancy', 'on') %}
{% set transition_state = states('sensor.shades_office_main_transition_desired_state') %}
{% set blackout_state = states('sensor.shades_office_main_blackout_desired_state') %}
{% if not is_occupied %}
False
{% elif is_night %}
True
{% else %}
False
{% endif %}
# this one is too bonkers not to share - but it shows how complex you can get if you so desire
# some of the referenced sensors are themselves templates based on azimuth/elevation of the sun, my home's lat/long, and the physical orientation & layout of my windows :sweat-smile:
- name: "[Shades:Office] Main transition desired state"
unique_id: office_main_transition
attributes:
enabled: "{{ is_state('input_boolean.office_automations', 'on') and is_state('input_boolean.office_is_blackout_half_lowered', 'off') }}"
target_entity_id: cover.office_main_transition
state: >
{% set current = now() %}
{% set is_home_changed = [as_local(states.group.family.last_changed), today_at('00:00:00')] | max %}
{% set office_morning = today_at(states('input_datetime.office_morning')) %}
{# HACK: Add 1 minute to occupied_changed, because groups seem to boot up later after a HA restart #}
{% set occupied_changed = as_local(states.binary_sensor.office_occupied.last_changed) + timedelta(minutes=1) %}
{% set is_occupied_today = occupied_changed > is_home_changed and occupied_changed > office_morning %}
{% set blackout_used_today = states.sensor.shades_office_main_blackout_desired_state.last_changed > today_at('00:00:00') %}
{% set azimuth = state_attr('sun.sun', 'azimuth') | float %}
{% set open_state = 'Open' if is_state('input_boolean.office_allow_open_shade', 'on') and not blackout_used_today else 'Stripes' %}
{% if is_state('sun.sun', 'below_horizon') %}
Closed
{% elif is_state('group.family', 'not_home') %}
Closed
{% elif is_state('sensor.shades_office_main_blackout_desired_state', 'Closed') %}
Closed
{% elif current < office_morning %}
Closed
{% elif not is_occupied_today and is_state('binary_sensor.office_occupied', 'off') %}
Closed
{% elif current >= today_at(states('input_datetime.common_evening')) %}
Closed
{% elif open_state == 'Stripes' and is_state('binary_sensor.office_occupied', 'off') %}
Closed
{% elif is_state('binary_sensor.shades_front_sun', 'off') %}
{{ open_state }}
{% elif is_state('binary_sensor.shades_front_sun', 'on') and is_state('binary_sensor.sunny', 'off') %}
{{ open_state }}
{% elif is_state('binary_sensor.shades_front_sun', 'on') %}
Closed
{% else %}
Unavailable
{% endif %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment