A template sensor for each blind (aka cover) …
- name: "Blind balcony door"
state: >
{% if 0 < states('input_number.curr_posn_blind_balcony_door')|int < 100 %}
{{ states('input_number.curr_posn_blind_balcony_door')|int~"%" }}
{% else %}
{{ states('input_text.blinds_balcony_door_state') }}
{% endif %}
icon: >
{% if 0 < states('input_number.curr_posn_blind_balcony_door')|int < 100 %}
mdi:window-shutter-alert
{% elif is_state('input_text.blinds_balcony_door_state', 'closed') %}
mdi:window-shutter
{% elif is_state('input_text.blinds_balcony_door_state', 'open') %}
mdi:window-shutter-open
{% elif is_state('input_text.blinds_balcony_door_state', 'my') %}
mdi:window-shutter-alert
{% endif %}
Helpers for each blind …
- input_text.blinds_balcony_door_state
- input_number.curr_posn_blind_balcony_door
- button.pleated_blinds_my_position_? - provided by Overkiz integration to set ‘My Position’
One of each of these helpers …
- input_select.blinds - an entry in the list of options for each blind e.g. cover.balcony_door
- input_text.move2posn_blind
- input_number.targ_posn_blind_balcony
Scripts …
Important that you follow naming conventions I have used for entity ids. Script ‘blinds_my_open_close’ works out what entity ids it needs to use.
In ‘blind_move2posn_2’ there is a table, movement_time, that maps blind entity id to time to fully open/close each blind. Absolute accuracy is not needed when measuring the open/close times of the blinds. I used a stop watch.
blinds_my_open_close:
alias: Blinds My open/close
sequence:
- if:
- condition: template
value_template: '{% set input_text = ''input_text.blinds_'' ~ button | replace(''button.'','''') | replace(''_my_position'','''') ~ ''_state'' %}
{{ is_state(input_text,''my'') }}'
then:
- service: cover.open_cover
data: {}
target:
entity_id: '{% set cover = ''cover.'' ~ button | replace(''button.'','''') | replace(''_my_position'','''') %}
{{ cover }}'
else:
- service: button.press
data: {}
target:
entity_id: '{{ button }}'
mode: parallel
blind_move2posn_1:
alias: Blind move2posn 1
sequence:
- repeat:
for_each: '{{ expand(entity_id) | map(attribute=''entity_id'') | list }}'
sequence:
- service: script.turn_on
target:
entity_id: script.blind_move2posn_2
data:
variables:
target_position: '{{ target_position }}'
entity_id: '{{ repeat.item }}'
mode: parallel
blind_move2posn_2:
alias: Blind move2posn 2
sequence:
- variables:
current_position: '{{ states(entity_id|replace(''cover.'',''input_number.curr_posn_blind_'')) }}'
delta_position: '{{ target_position - current_position }}'
movement_time: "{% set time = { 'cover.balcony_window_1': '01:07.59',\n
'cover.balcony_door': '01:07.62',\n
'cover.balcony_window_2': '01:07.64',\n
'cover.terrace_window': '01:07.61',\n
'cover.terrace_door': '01:07.63'} %}\n
{{ as_timedelta(time[entity_id]) * (delta_position/100)|abs }}\n"
- choose:
- conditions:
- condition: template
value_template: '{{ target_position == 0 }}'
sequence:
- service: cover.open_cover
target:
entity_id: '{{ entity_id }}'
- conditions:
- condition: template
value_template: '{{ target_position == 100 }}'
sequence:
- service: cover.close_cover
target:
entity_id: '{{ entity_id }}'
default:
- choose:
- conditions:
- condition: template
value_template: '{{ delta_position > 0 }}'
sequence:
- service: cover.close_cover
target:
entity_id: '{{ entity_id }}'
- delay: '{{ movement_time }}'
- service: cover.stop_cover
target:
entity_id: '{{ entity_id }}'
- conditions:
- condition: template
value_template: '{{ delta_position < 0 }}'
sequence:
- service: cover.open_cover
data: {}
target:
entity_id: '{{ entity_id }}'
- delay: '{{ movement_time }}'
- service: cover.stop_cover
target:
entity_id: '{{ entity_id }}'
- service: input_number.set_value
data:
value: '{{ target_position }}'
target:
entity_id: '{{ entity_id|replace(''cover.'',''input_number.curr_posn_blind_'') }}'
mode: parallel
max: 10
Automation …
- id: '1675082731690'
alias: Move blind
description: ''
trigger:
- platform: state
entity_id:
- input_button.move_blind
condition: []
action:
- service: script.blind_move2posn_1
data:
target_position: '{{ states(''input_number.targ_posn_blind_balcony'') }}'
entity_id: '{{ states(''input_select.blinds'') }}'
mode: single
For your dashboard …
If you use these cards ‘as is’ you will need the hui-element custom card. Install from GitHub - thomasloven/lovelace-hui-element: 🔹 Use built-in elements in the wrong place using HACS.
type: entities
entities:
- type: custom:hui-element
card_type: grid
square: false
columns: 1
cards:
- type: grid
square: false
columns: 3
cards:
- type: button
show_name: true
show_icon: true
tap_action:
action: call-service
service: cover.toggle
data: {}
target:
entity_id: cover.terrace_window
double_tap_action:
action: call-service
service: script.blinds_my_open_close
data:
button: button.terrace_window_my_position
icon: ''
show_state: true
name: Terrace window
entity: sensor.blind_terrace_window
hold_action:
action: none
card_mod:
style: |
ha-card {
border: 0px;
}
- type: button
show_name: true
show_icon: true
tap_action:
action: call-service
service: cover.toggle
data: {}
target:
entity_id: cover.terrace_door
double_tap_action:
action: call-service
service: script.blinds_my_open_close
data:
button: button.terrace_door_my_position
entity: sensor.blind_terrace_door
name: Terrace door
show_state: true
icon: ''
card_mod:
style: |
ha-card {
border: 0px;
}
- type: button
show_name: true
show_icon: true
tap_action:
action: toggle
entity: ''
icon: 'null'
card_mod:
style: |
ha-card {
border: 0px;
}
- type: button
show_name: true
show_icon: true
tap_action:
action: call-service
service: cover.toggle
data: {}
target:
entity_id: cover.balcony_window_1
double_tap_action:
action: null
name: Balcony window 1
icon: ''
show_state: true
entity: sensor.blind_balcony_window_1
card_mod:
style: |
ha-card {
border: 0px;
}
- type: button
show_name: true
show_icon: true
tap_action:
action: call-service
service: cover.toggle
data: {}
target:
entity_id: cover.balcony_door
double_tap_action:
action: null
icon: ''
entity: sensor.blind_balcony_door
name: Balcony door
show_state: true
card_mod:
style: |
ha-card {
border: 0px;
}
- type: button
show_name: true
show_icon: true
tap_action:
action: call-service
service: cover.toggle
data: {}
target:
entity_id: cover.balcony_window_2
double_tap_action:
action: null
entity: sensor.blind_balcony_window_2
name: Balcony window 2
icon: ''
show_state: true
card_mod:
style: |
ha-card {
border: 0px;
}
- type: button
show_name: true
show_icon: true
tap_action:
action: call-service
service: cover.toggle
data: {}
target:
entity_id: cover.bed1_door
double_tap_action:
action: call-service
service: script.blinds_my_open_close
data:
button: button.bed1_door_my_position
entity: sensor.blind_bed1_door
name: Bedroom 1
icon: ''
show_state: true
card_mod:
style: |
ha-card {
border: 0px;
}
- type: button
show_name: true
show_icon: true
tap_action:
action: call-service
service: cover.toggle
data: {}
target:
entity_id: cover.bed2_window
double_tap_action:
action: call-service
service: script.blinds_my_open_close
data:
button: button.bed2_window_my_position
entity: sensor.blind_bed2_window
name: Bedroom 2
icon: ''
show_state: true
card_mod:
style: |
ha-card {
border: 0px;
}
- type: button
show_name: true
show_icon: true
tap_action:
action: toggle
icon: 'null'
card_mod:
style: |
ha-card {
border: 0px;
}
show_header_toggle: false
card_mod:
style: |
ha-card {
border: 3px solid grey;
padding: 0px;
background-color:;
}
and …
type: entities
entities:
- entity: input_select.blinds
icon: 'null'
name: Blind
- entity: input_number.targ_posn_blind_balcony
icon: 'null'
name: Target position
- entity: input_button.move_blind
Phew! I didn’t realise there was so much to it, apologies if I have missed something. Let me know how you get on.