J'ai souvent parlé de planification des convecteurs et du climatiseur. Depuis un an je tourne sur deux installations avec ce dont j'avais parlé ici en utilisant le moteur de planification Schedy. Schedy était très bien en son temps et il palliait à des lacunes de Home Assistant. Mais il y a quelques restrictions et son auteur ne le fait plus évoluer. En fait ça se comprend car on peut maintenant à peu près faire la même chose avec le mode choose:
et quelques lignes de yaml, et ainsi supprimer une dépendance à un outil externe. Et plus c'est simple, moins il y a de chances de dysfonctionnements.
Je vais donc changer de moteur, par contre je vais réutiliser toutes les entités que j'avais crée pour Schedy, ce qui dans l'absolu en fait une solution réversible. Attention, cet article a été remanié, donc si vous vous étiez inspiré de la première version il sera judicieux de repartir à zéro...
Voici donc ce que j'ai fait pour le climatiseur, plus complexe qu'un simple radiateur car on va gérer les modes chauffage et refroidissement ainsi que le débrayage en manuel.
input_select:
comfort_ac:
name: Modes du climatiseur
icon: mdi:form-select
options:
- Refroidissement
- Chauffage
- Manuel
- "Off"
On va utiliser deux automations par pièce ou appareil, la première va gérer les multiples déclencheurs (trigger:
), les modes (input_select:
) et surtout les exclusions liées au mode de vie (absence de courte ou longue durée, sommeil, fenêtres ouvertes, etc...
Si aucune exclusion n'est validée et selon le mode en cours on lance la seconde automation dans le mode sélectionné. Si on est en mode Manuel, on ne fait rien, mais la seconde automation ne s'exécutera pas.
- id: 56ee275e-3f52-4d88-a862-5e21f5708a82
description: Comfort - AC - Immediate
alias: "Comfort - AC - Immediate"
mode: restart
trigger:
- platform: state
entity_id:
- input_number.heating_ac_temperature_confort_1
- binary_sensor.heating_ac_1
- input_boolean.to_away
- binary_sensor.life_windows_and_doors_delayed
- input_boolean.to_sleep
- binary_sensor.lionel_geo
- input_select.comfort_ac
- [...] ⚠️ A compléter
condition:
action:
- choose:
- conditions: # 0 OFF
- condition: or
conditions:
- "{{ is_state('binary_sensor.life_windows_and_doors_delayed', 'on') }}"
- "{{ is_state('input_select.comfort_ac', 'Off') }}"
- "{{ is_state('input_boolean.presence_ac', 'off') }}"
sequence:
- service: climate.set_hvac_mode
data:
hvac_mode: 'off'
target:
entity_id: climate.daikin
- conditions: # 01 - COOL OFF
- condition: or
conditions:
- "{{ is_state('input_boolean.thermostats_away', 'on') }}"
- "{{ is_state('input_boolean.to_away', 'on') }}"
- "{{ is_state('binary_sensor.lionel_geo', 'off') }}"
- condition:
- "{{ is_state('input_select.comfort_ac', 'Refroidissement') }}"
sequence:
- service: climate.set_hvac_mode
data:
hvac_mode: 'off'
target:
entity_id: climate.daikin
- conditions: # 02 - COOL SLEEP
- "{{ is_state('input_boolean.to_sleep', 'on') }}"
- "{{ is_state('input_select.comfort_ac', 'Refroidissement') }}"
sequence:
- service: climate.set_hvac_mode
data:
hvac_mode: 'cool'
target:
entity_id: climate.daikin
- service: climate.set_temperature
data:
temperature: "{{ states('input_number.heating_ac_temperature_eco') }}"
target:
entity_id: climate.daikin
- conditions: # 03 - HEAT ECO
- condition: or
conditions:
- "{{ is_state('input_boolean.to_away', 'on') }}"
- "{{ is_state('input_boolean.to_sleep', 'on') }}"
- "{{ is_state('binary_sensor.lionel_geo', 'off') }}" # input_boolean.presence_lionel_geo
- condition:
- "{{ is_state('input_select.comfort_ac', 'Chauffage') }}"
sequence:
- service: climate.set_hvac_mode
data:
hvac_mode: 'heat'
target:
entity_id: climate.daikin
- service: climate.set_temperature
data:
temperature: "{{ states('input_number.heating_ac_temperature_eco') }}"
target:
entity_id: climate.daikin
- conditions: # 04 - HEAT AWAY
- "{{ is_state('input_boolean.thermostats_away', 'on') }}"
- "{{ is_state('input_select.comfort_ac', 'Chauffage') }}"
sequence:
- service: climate.set_hvac_mode
data:
hvac_mode: 'heat'
target:
entity_id: climate.daikin
- service: climate.set_temperature
data:
temperature: "{{ states('input_number.heating_ac_temperature_away') }}"
target:
entity_id: climate.daikin
default:
- choose:
- conditions: "{{ is_state('input_select.comfort_ac', 'Refroidissement') }}"
sequence:
- service: climate.set_hvac_mode
data:
hvac_mode: 'cool'
target:
entity_id: climate.daikin
- service: automation.trigger
target:
entity_id: "automation.comfort_ac"
- conditions: "{{ is_state('input_select.comfort_ac', 'Chauffage') }}"
sequence:
- service: climate.set_hvac_mode
data:
hvac_mode: 'heat'
target:
entity_id: climate.daikin
- service: automation.trigger
target:
entity_id: "automation.comfort_ac"
La seconde automation sert à ajuster la température de consigne, elle est appelée par la première pour une action immédiate et se relancera également toutes les 10 minutes afin de rattraper une action non exécutée, un redémarrage ou un actionneur qui n'a pas fait son travail. Ca compense la replanification qui faisait la force de Schedy.
Qu'elle soit appelée par la première ou qu'elle s'exécute via le time_pattern:
il ne se passera rien si toutes (and:
par défaut) les conditions ne sont pas remplies (les contraintes gérées dans la première automation). A noter que je place les conditions après action:
afin que ces conditions soient prises en compte même si cette automation est lancée manuellement.
Si aucune des conditions liées aux plages horaires actives n'est remplie (plages horaires définies par des binary_sensor:
dans le précédent article), alors l'action par défaut passe le thermostat en mode ECO.
automation:
- id: 0ff7454c-4592-4479-b2ae-40eaf3043853
description: Comfort - AC
alias: "Comfort - AC"
mode: restart
trigger:
- platform: time_pattern
minutes: "/10"
condition:
action:
- condition:
- "{{ not states('input_select.comfort_ac') in ('Manuel', 'Off') }}"
- "{{ is_state('binary_sensor.life_windows_and_doors_delayed', 'off') }}"
- "{{ is_state('binary_sensor.lionel_geo', 'on') }}"
- "{{ is_state('input_boolean.thermostats_away', 'off') }}"
- "{{ is_state('input_boolean.presence_ac', 'on') }}"
- "{{ is_state('input_boolean.to_away', 'off') }}"
- "{{ is_state('input_boolean.to_sleep', 'off') }}"
- choose:
- conditions: "{{ is_state('binary_sensor.heating_ac_1', 'on') }}" # Plages horaires
sequence:
- service: climate.set_temperature
data:
temperature: "{{ states('input_number.heating_ac_temperature_confort_1') }}"
target:
entity_id: climate.daikin
- conditions: [...] ⚠️ A Compléter
default:
- choose:
- conditions:
sequence:
- service: climate.set_temperature
data:
temperature: "{{ states('input_number.heating_ac_temperature_eco') }}"
target:
entity_id: climate.daikin
Et enfin l'automation qui gère le mode Manuel / Auto : Si on passe en manuel on désactive l'automation et j'ai fait le choix de passer le thermostat en off. Il est bien sur possible de le réactiver, mais il ne sera plus géré par la planification.
- id: 56dd275e-3f52-4d8ffa862-sejour
description: Comfort - Sejour - Mode Auto
alias: "Comfort - Sejour - Mode Auto"
trigger:
- platform: state
entity_id: automation.comfort_sejour_immediate
to: "on"
id: "on"
- platform: state
entity_id: automation.comfort_sejour_immediate
to: "off"
id: "off"
action:
- choose:
- conditions: "{{ trigger.id in ['on', 'xx'] }}"
sequence:
- service: automation.trigger
target:
entity_id: "automation.comfort_sejour_immediate"
- choose:
- conditions: "{{ trigger.id in ['off', 'xx'] }}"
sequence:
- service: climate.set_hvac_mode
data:
hvac_mode: "off"
target:
entity_id: climate.thermostat_sejour
Voilà, c'est finalement assez simple et il suffira ensuite de reproduire pour les autres pièces. Je vous conseille d'utiliser un fichier par pièce dans les packages. Les miens sont ici sur GitHub.
Un grand merci à Fabien, Mathieu et Philipp m'ont ouvert les yeux sur les possibilités offertes par choose:
et leur patience quand je sèche sur les templates...
Bonus :
La carte avec tous les modes : (je sais c'est long, à dupliquer selon le nombre de convecteurs).
type: vertical-stack
cards:
- type: custom:simple-thermostat
entity: climate.thermostat_sejour
layout:
mode:
icons: true
headings: false
names: true
step: row
hide:
temperature: true
state: true
sensors:
- entity: sensor.mi_sejour_temp
icon: mdi:thermometer
- entity: binary_sensor.state_openings_life
icon: mdi:door
- entity: sensor.sejour_puissance
icon: mdi:lightning-bolt
header:
toggle:
entity: automation.comfort_sejour_immediate
name: Manuel/Auto
name: Bureau
control:
- hvac
- type: history-graph
entities:
- entity: switch.sw13_sejour_1
name: ' '
hours_to_show: 24
refresh_interval: 0
- type: conditional
conditions:
- entity: automation.comfort_sejour_immediate
state: 'on'
card:
type: entities
entities:
- entities:
- entity: input_boolean.heating_sejour_enabled_1
name: NUIT
toggle: true
- entity: input_boolean.heating_sejour_enabled_2
name: MATIN
toggle: true
- entity: input_boolean.heating_sejour_enabled_3
name: MIDI
toggle: true
- entity: input_boolean.heating_sejour_enabled_4
name: SOIR
toggle: true
entity: climate.thermostat_sejour
name: Semaine
show_state: false
toggle: false
icon: mdi:calendar-range
type: custom:multiple-entity-row
state_color: true
- entities:
- entity: input_boolean.heating_sejour_enabled_1_d
name: NUIT
toggle: true
- entity: input_boolean.heating_sejour_enabled_2_d
name: MATIN
toggle: true
- entity: input_boolean.heating_sejour_enabled_3_d
name: MIDI
toggle: true
- entity: input_boolean.heating_sejour_enabled_4_d
name: SOIR
toggle: true
entity: climate.thermostat_sejour
name: Week-End
show_state: false
toggle: false
icon: mdi:calendar-range
type: custom:multiple-entity-row
state_color: true
- entities:
- entity: input_number.heating_sejour_temperature_eco
type: custom:numberbox-card
icon_plus: mdi:chevron-up
icon_minus: mdi:chevron-down
- entity: input_number.heating_sejour_temperature_away
type: custom:numberbox-card
icon_plus: mdi:chevron-up
icon_minus: mdi:chevron-down
- entity: binary_sensor.life_windows_and_doors_delayed
- label: Présence dans la pièce
type: section
- entity: input_boolean.presence_sejour
name: Présence
show_state: true
- entity: input_datetime.next_sejour_start
type: custom:multiple-entity-row
format: datetime
name: Arrivée
- entity: input_datetime.next_sejour_stop
type: custom:multiple-entity-row
format: datetime
name: Départ
head:
label: OPTIONS >
type: section
padding: 30
type: custom:fold-entity-row
title: PLANIFICATION
show_header_toggle: false
state_color: true
- type: conditional
conditions:
- entity: input_boolean.heating_sejour_enabled_1
state: 'on'
- entity: automation.comfort_sejour_immediate
state: 'on'
card:
type: custom:vertical-stack-in-card
title: Séjour / Semaine / Nuit
cards:
- entity: input_number.heating_sejour_temperature_confort_1
type: custom:numberbox-card
icon_plus: mdi:chevron-up
icon_minus: mdi:chevron-down
name: Température de confort
icon: false
- type: horizontal-stack
cards:
- entity: input_datetime.heating_sejour_start_1
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: glance
show_state: false
entities:
- binary_sensor.heating_sejour_1
- entity: input_datetime.heating_sejour_end_1
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: conditional
conditions:
- entity: input_boolean.heating_sejour_enabled_2
state: 'on'
- entity: automation.comfort_sejour_immediate
state: 'on'
card:
type: custom:vertical-stack-in-card
title: Séjour / Semaine / Matin
cards:
- entity: input_number.heating_sejour_temperature_confort_2
type: custom:numberbox-card
icon_plus: mdi:chevron-up
icon_minus: mdi:chevron-down
name: Température de confort
icon: false
- type: horizontal-stack
cards:
- entity: input_datetime.heating_sejour_start_2
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: glance
show_state: false
entities:
- binary_sensor.heating_sejour_2
- entity: input_datetime.heating_sejour_end_2
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: conditional
conditions:
- entity: input_boolean.heating_sejour_enabled_3
state: 'on'
- entity: automation.comfort_sejour_immediate
state: 'on'
card:
type: custom:vertical-stack-in-card
title: Séjour / Semaine / Midi
cards:
- entity: input_number.heating_sejour_temperature_confort_3
type: custom:numberbox-card
icon_plus: mdi:chevron-up
icon_minus: mdi:chevron-down
name: Température de confort
icon: false
- type: horizontal-stack
cards:
- entity: input_datetime.heating_sejour_start_3
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: glance
show_state: false
entities:
- binary_sensor.heating_sejour_3
- entity: input_datetime.heating_sejour_end_3
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: conditional
conditions:
- entity: input_boolean.heating_sejour_enabled_4
state: 'on'
- entity: automation.comfort_sejour_immediate
state: 'on'
card:
type: custom:vertical-stack-in-card
title: Séjour / Semaine / Soir
cards:
- entity: input_number.heating_sejour_temperature_confort_4
type: custom:numberbox-card
icon_plus: mdi:chevron-up
icon_minus: mdi:chevron-down
name: Température de confort
icon: false
- type: horizontal-stack
cards:
- entity: input_datetime.heating_sejour_start_4
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: glance
show_state: false
entities:
- binary_sensor.heating_sejour_4
- entity: input_datetime.heating_sejour_end_4
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: conditional
conditions:
- entity: input_boolean.heating_sejour_enabled_1_d
state: 'on'
- entity: automation.comfort_sejour_immediate
state: 'on'
card:
type: custom:vertical-stack-in-card
title: Séjour / Week-End / Nuit
cards:
- entity: input_number.heating_sejour_temperature_confort_1_d
type: custom:numberbox-card
icon_plus: mdi:chevron-up
icon_minus: mdi:chevron-down
name: Température de confort
icon: false
- type: horizontal-stack
cards:
- entity: input_datetime.heating_sejour_start_1_d
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: glance
show_state: false
entities:
- binary_sensor.heating_sejour_1_d
- entity: input_datetime.heating_sejour_end_1_d
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: conditional
conditions:
- entity: input_boolean.heating_sejour_enabled_2_d
state: 'on'
- entity: automation.comfort_sejour_immediate
state: 'on'
card:
type: custom:vertical-stack-in-card
title: Séjour / Week-End / Matin
cards:
- entity: input_number.heating_sejour_temperature_confort_2_d
type: custom:numberbox-card
icon_plus: mdi:chevron-up
icon_minus: mdi:chevron-down
name: Température de confort
icon: false
- type: horizontal-stack
cards:
- entity: input_datetime.heating_sejour_start_2_d
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: glance
show_state: false
entities:
- binary_sensor.heating_sejour_2_d
- entity: input_datetime.heating_sejour_end_2_d
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: conditional
conditions:
- entity: input_boolean.heating_sejour_enabled_3_d
state: 'on'
- entity: automation.comfort_sejour_immediate
state: 'on'
card:
type: custom:vertical-stack-in-card
title: Séjour / Week-End / Midi
cards:
- entity: input_number.heating_sejour_temperature_confort_3_d
type: custom:numberbox-card
icon_plus: mdi:chevron-up
icon_minus: mdi:chevron-down
name: Température de confort
icon: false
- type: horizontal-stack
cards:
- entity: input_datetime.heating_sejour_start_3_d
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: glance
show_state: false
entities:
- binary_sensor.heating_sejour_3_d
- entity: input_datetime.heating_sejour_end_3_d
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: conditional
conditions:
- entity: input_boolean.heating_sejour_enabled_4_d
state: 'on'
- entity: automation.comfort_sejour_immediate
state: 'on'
card:
type: custom:vertical-stack-in-card
title: Séjour / Week-End / Soir
cards:
- entity: input_number.heating_sejour_temperature_confort_4_d
type: custom:numberbox-card
icon_plus: mdi:chevron-up
icon_minus: mdi:chevron-down
name: Température de confort
icon: false
- type: horizontal-stack
cards:
- entity: input_datetime.heating_sejour_start_4_d
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true
- type: glance
show_state: false
entities:
- binary_sensor.heating_sejour_4_d
- entity: input_datetime.heating_sejour_end_4_d
type: custom:time-picker-card
layout:
align_controls: center
embedded: true
hide:
name: true
icon: true