additional esphome devices and fixes
This commit is contained in:
@@ -0,0 +1,368 @@
|
||||
###############################################################################
|
||||
# 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
|
||||
Reference in New Issue
Block a user