Files
zorruno-homeassistant/packages/lounge_blind_control.yaml
T
2026-05-23 23:53:04 +12:00

369 lines
11 KiB
YAML

###############################################################################
# PACKAGE: Lounge Blinds - Sunrise / Sunset Automation
###############################################################################
#
# VERSION:
# v1.2 - 2026-05-08
# - Updated input_boolean.lounge_blinds control logic.
# - input_boolean.lounge_blinds ON now closes the blinds.
# - input_boolean.lounge_blinds OFF now opens the blinds.
# - Removed the sync guard helper.
# - Added state checks so cover feedback does not create command loops.
#
# v1.1 - 2026-05-08
# - Added input_boolean.lounge_blinds as a manual control/status helper.
# - Added cover state sync back to input_boolean.lounge_blinds.
#
# v1.0 - 2026-05-08
# - Initial package.
# - Opens lounge blinds at sunrise.
# - Closes lounge blinds at sunset.
# - Includes sunrise/sunset minute offsets.
# - Includes repeated command attempts for Zigbee reliability.
# - Opens blinds in list order: A, B, C.
# - Closes blinds in reverse list order: C, B, A.
#
# NOTES:
# - input_boolean.lounge_blinds is treated as:
# ON = blinds closed
# OFF = blinds open
#
# - Turning input_boolean.lounge_blinds ON will close the blinds.
# - Turning input_boolean.lounge_blinds OFF will open the blinds.
# - If all blinds are closed by another method, the boolean will turn ON.
# - If all blinds are opened by another method, the boolean will turn OFF.
# - If blinds are in a mixed/partial state, the boolean is left unchanged.
#
# - The blind entity list is inside:
# script.lounge_blinds_run_sequence
# script.lounge_blinds_sync_status
# automation.lounge_blinds_control_from_input_boolean
#
# - If you add more blinds, update the blind list in those three places.
#
###############################################################################
input_boolean:
lounge_blinds:
name: Lounge Blinds Closed
icon: mdi:blinds
input_number:
lounge_blinds_sunrise_offset_minutes:
name: Lounge Blinds Sunrise Offset
icon: mdi:weather-sunset-up
min: -180
max: 180
step: 1
mode: box
unit_of_measurement: min
initial: 0
lounge_blinds_sunset_offset_minutes:
name: Lounge Blinds Sunset Offset
icon: mdi:weather-sunset-down
min: -180
max: 180
step: 1
mode: box
unit_of_measurement: min
initial: 0
lounge_blinds_per_blind_delay_seconds:
name: Lounge Blinds Per-Blind Delay
icon: mdi:timer-outline
min: 0
max: 60
step: 1
mode: box
unit_of_measurement: sec
initial: 2
lounge_blinds_command_repeats:
name: Lounge Blinds Command Repeats
icon: mdi:repeat
min: 1
max: 5
step: 1
mode: box
initial: 2
lounge_blinds_retry_delay_seconds:
name: Lounge Blinds Retry Delay
icon: mdi:timer-refresh-outline
min: 0
max: 120
step: 1
mode: box
unit_of_measurement: sec
initial: 10
input_datetime:
lounge_blinds_next_open_time:
name: Lounge Blinds Next Open Time
has_date: true
has_time: true
lounge_blinds_next_close_time:
name: Lounge Blinds Next Close Time
has_date: true
has_time: true
script:
lounge_blinds_update_sun_times:
alias: Lounge Blinds - Update Sun Times
mode: single
sequence:
- variables:
sunrise_offset_seconds: >
{{ states('input_number.lounge_blinds_sunrise_offset_minutes') | int(0) * 60 }}
sunset_offset_seconds: >
{{ states('input_number.lounge_blinds_sunset_offset_minutes') | int(0) * 60 }}
next_sunrise_timestamp: >
{{ as_timestamp(state_attr('sun.sun', 'next_rising')) + sunrise_offset_seconds }}
next_sunset_timestamp: >
{{ as_timestamp(state_attr('sun.sun', 'next_setting')) + sunset_offset_seconds }}
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.lounge_blinds_next_open_time
data:
datetime: >
{{ next_sunrise_timestamp | timestamp_custom('%Y-%m-%d %H:%M:%S', true) }}
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.lounge_blinds_next_close_time
data:
datetime: >
{{ next_sunset_timestamp | timestamp_custom('%Y-%m-%d %H:%M:%S', true) }}
lounge_blinds_run_sequence:
alias: Lounge Blinds - Run Open/Close Sequence
mode: queued
fields:
blind_action:
name: Blind Action
description: Use open or close.
required: true
selector:
select:
options:
- open
- close
sequence:
- variables:
blind_list:
- cover.lounge_blind_a_xbl11
- cover.lounge_blind_b_xbl12
- cover.lounge_blind_c_xbl13
command_repeats: >
{{ states('input_number.lounge_blinds_command_repeats') | int(2) }}
retry_delay_seconds: >
{{ states('input_number.lounge_blinds_retry_delay_seconds') | int(10) }}
per_blind_delay_seconds: >
{{ states('input_number.lounge_blinds_per_blind_delay_seconds') | int(2) }}
- repeat:
count: "{{ command_repeats }}"
sequence:
- choose:
- conditions:
- condition: template
value_template: "{{ blind_action == 'open' }}"
sequence:
- repeat:
for_each: "{{ blind_list }}"
sequence:
- action: cover.open_cover
target:
entity_id: "{{ repeat.item }}"
- delay:
seconds: "{{ per_blind_delay_seconds }}"
- conditions:
- condition: template
value_template: "{{ blind_action == 'close' }}"
sequence:
- repeat:
for_each: "{{ blind_list | reverse | list }}"
sequence:
- action: cover.close_cover
target:
entity_id: "{{ repeat.item }}"
- delay:
seconds: "{{ per_blind_delay_seconds }}"
- if:
- condition: template
value_template: "{{ repeat.index < command_repeats }}"
then:
- delay:
seconds: "{{ retry_delay_seconds }}"
- action: script.lounge_blinds_sync_status
lounge_blinds_sync_status:
alias: Lounge Blinds - Sync Status
mode: queued
sequence:
- variables:
blind_list:
- cover.lounge_blind_a_xbl11
- cover.lounge_blind_b_xbl12
- cover.lounge_blind_c_xbl13
blind_states: >
{{ expand(blind_list) | map(attribute='state') | list }}
all_blinds_closed: >
{{ blind_states | select('eq', 'closed') | list | count == blind_list | count }}
all_blinds_open: >
{{ blind_states | select('eq', 'open') | list | count == blind_list | count }}
- choose:
- conditions:
- condition: template
value_template: >
{{ all_blinds_closed and is_state('input_boolean.lounge_blinds', 'off') }}
sequence:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.lounge_blinds
- conditions:
- condition: template
value_template: >
{{ all_blinds_open and is_state('input_boolean.lounge_blinds', 'on') }}
sequence:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.lounge_blinds
automation:
- id: lounge_blinds_update_sun_times
alias: Lounge Blinds - Update Sun Times
mode: restart
trigger:
- platform: homeassistant
event: start
- platform: time
at: "00:05:00"
- platform: state
entity_id:
- input_number.lounge_blinds_sunrise_offset_minutes
- input_number.lounge_blinds_sunset_offset_minutes
action:
- action: script.lounge_blinds_update_sun_times
- id: lounge_blinds_open_at_sunrise
alias: Lounge Blinds - Open At Sunrise
mode: single
trigger:
- platform: time
at: input_datetime.lounge_blinds_next_open_time
action:
- action: script.lounge_blinds_run_sequence
data:
blind_action: open
- id: lounge_blinds_close_at_sunset
alias: Lounge Blinds - Close At Sunset
mode: single
trigger:
- platform: time
at: input_datetime.lounge_blinds_next_close_time
action:
- action: script.lounge_blinds_run_sequence
data:
blind_action: close
- id: lounge_blinds_control_from_input_boolean
alias: Lounge Blinds - Control From Input Boolean
mode: restart
trigger:
- platform: state
entity_id: input_boolean.lounge_blinds
to: "on"
- platform: state
entity_id: input_boolean.lounge_blinds
to: "off"
action:
- variables:
blind_list:
- cover.lounge_blind_a_xbl11
- cover.lounge_blind_b_xbl12
- cover.lounge_blind_c_xbl13
blind_states: >
{{ expand(blind_list) | map(attribute='state') | list }}
all_blinds_closed: >
{{ blind_states | select('eq', 'closed') | list | count == blind_list | count }}
all_blinds_open: >
{{ blind_states | select('eq', 'open') | list | count == blind_list | count }}
- choose:
- conditions:
- condition: state
entity_id: input_boolean.lounge_blinds
state: "on"
- condition: template
value_template: "{{ not all_blinds_closed }}"
sequence:
- action: script.lounge_blinds_run_sequence
data:
blind_action: close
- conditions:
- condition: state
entity_id: input_boolean.lounge_blinds
state: "off"
- condition: template
value_template: "{{ not all_blinds_open }}"
sequence:
- action: script.lounge_blinds_run_sequence
data:
blind_action: open
- id: lounge_blinds_sync_input_boolean_from_cover_states
alias: Lounge Blinds - Sync Input Boolean From Cover States
mode: restart
trigger:
- platform: homeassistant
event: start
- platform: state
entity_id:
- cover.lounge_blind_a_xbl11
- cover.lounge_blind_b_xbl12
- cover.lounge_blind_c_xbl13
to: "open"
- platform: state
entity_id:
- cover.lounge_blind_a_xbl11
- cover.lounge_blind_b_xbl12
- cover.lounge_blind_c_xbl13
to: "closed"
action:
- action: script.lounge_blinds_sync_status