Home Assistant, planification, encore...

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

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.

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...

 

Ajouter un commentaire

Loading