Répartir le fichier configuration.yaml en plusieurs fichiers

Ceci est une traduction de la documentation : Splitting up the configuration - Home Assistant

Pour approfondir vos connaissances, n’hésitez pas à lire le tutoriel de @McFly :


Introduction

Vous utilisez Home Assistant depuis un certain temps déjà et votre fichier configuration.yaml devient incompréhensible, ou tout simplement, vous voulez commencer avec l’approche distribué de ce fichier. Voici comment commencer scinder le configuration.yaml en morceaux plus compréhensibles (lire : pour les humains).

Tout d’abord, plusieurs membres de la communauté ont nettoyé (lire : sans clés/mots de passe API, etc.) les versions de leurs configurations disponibles pour consultation, vous pouvez en voir la liste ici, et certains membres de HACF disponible dans la Awesome List disponible ici.

Avant de vous jeter dessus, prenez le temps de lire ce qui suit. Ça facilitera la compréhension, surtout quand il n’y a pas de commentaire (assez explicite) dans les fichiers.

Maintenant, malgré le fait que nous allons découper le fichier configuration.yaml dans les explications plus bas, ce fichier va dans tous les cas continuer à exister, bien que sous forme bien moins encombrante, voir presque complètement dénudé.

Dans cette version plus légère, nous aurons encore besoin de ce que l’on pourrait appeler le code principal (exemple) :

homeassistant:
  # Name of the location where Home Assistant is running
  name: "My Home Assistant Instance"
  # Location required to calculate the time the sun rises and sets
  latitude: 37
  longitude: -121
  # 'metric' for Metric, 'us_customary' for US Customary
  unit_system: us_customary
  # Pick yours from here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  time_zone: "America/Los_Angeles"
  customize: !include customize.yaml

Notez que chaque ligne après homeassistant: est indentée de deux (2) espaces. Comme les fichiers de configuration de Home Assistant sont basés sur le langage YAML, l’indentation et l’espacement sont importants. Notez également que l’entrée apparemment étrange après customize:

!include customize.yaml est la déclaration qui indique à Home Assistant d’insérer le contenu de customize.yaml à ce moment-là. C’est ainsi que nous allons pouvoir décomposer un fichier monolithique et difficile à lire (lorsqu’il devient volumineux) en morceaux plus faciles à gérer.

Maintenant, avant de commencer à répartir les différents composants, examinons les autres intégrations (dans notre exemple) qui resteront dans le fichier de base :

history:
frontend:
logbook:
http:
  api_password: "ImNotTelling!"

ifttt:
  key: ["nope"]

mqtt:
  sensor:
    - name: "test sensor 1"
      state_topic: "test/some_topic1"
    - name: "test sensor 2"
      state_topic: "test/some_topic2"

Comme pour le code principal, l’indentation fait la différence. Les en-têtes d’intégration (par exemple : mqtt:) doivent être alignés à gauche (sans indentation), et le paramètre (sensor) doit être indenté de deux (2) espaces. a liste - sous la clé sensor doit être indentée de deux (2) espaces supplémentaires suivis d’un espace unique. La liste des capteurs mqtt contient deux (2) configurations contenant deux (2) clés chacune.

Notez qu’il est techniquement possible de séparer ces intégrations de ce fichier. A vous de mesurer les avantages/inconvénients pour de si petites et " uniques" intégrations.
Vous remarquerez également le symbole # (dièse). Il débute une ligne de commentaire, dans la mesure où ce qui suit sur la même ligne ne sera pas interprété. Cela améliore la lisibilité du fichier, permet de désactiver des fonctionnalités ou de laisser une explication sur ce qui l’entoure.

Supposons désormais qu’un fichier vierge ait été créé dans le répertoire de configuration de Home Assistant pour chacun des éléments suivants :

automation.yaml
zone.yaml
sensor.yaml
switch.yaml
device_tracker.yaml
customize.yaml

automation.yaml contiendra tous les détails d’intégration de l’automatisation. zone.yaml contiendra les détails d’intégration de la zone, etc. Ces fichiers peuvent être nommés de la façon que vous désirez, mais leur donner des noms correspondant à leur fonction facilitera le suivi, et le partage avec les autres membres (aussi bien pour avoir de l’aide que pour aider quelqu’un d’autre).

Ce qui induit que le fichier configuration.yaml doit contenir les lignes suivantes :

automation: !include automation.yaml
zone: !include zone.yaml
sensor: !include sensor.yaml
switch: !include switch.yaml
device_tracker: !include device_tracker.yaml

L’imbrication des !include (le fait d’avoir un !include dans un fichier qui est lui-même !include) fonctionnera.
Certaines intégrations supportent plusieurs !includes de haut niveau, cela inclut les intégrations définissant un domaine IoT, par exemple light, switch, sensor ainsi que les intégrations automation, script et template, si vous donnez un label différent à chacune d’entre elles. La configuration des autres intégrations peut être divisée en utilisant des paquets. Pour en savoir plus sur les paquets, voir la page Paquets.

Exemple de clés de premier niveau multiples pour la plateforme light :

light:
- platform: group
  name: "Bedside Lights"
  entities:
    - light.left_bedside_light
    - light.right_bedside_light

# define more light groups in a separate file
light groups: !include light-groups.yaml

# define some light switch mappings in a different file
light switches: !include light-switches.yaml

Avec !include light-groups.yaml pouvant ressembler à ceci :

- platform: group
  name: "Outside Lights"
  entities:
    - light.porch_lights
    - light.patio_lights

Et !include light-switches.yaml à cela :

- platform: switch
  name: "Patio Lights"
  entity_id: switch.patio_lights

- platform: switch
  name: "Floor Lamp"
  entity_id: switch.floor_lamp_plug

Très bien, nous avons donc les intégrations uniques et les déclarations d’inclusion dans le fichier de base, mais que peut-on mettre dans ces fichiers supplémentaires ?
Regardons un exemple issu de la documentation officielle d’Home Assistant, device_tracker.yaml :

- platform: owntracks
- platform: nmap_tracker
  
  home_interval: 3
  hosts: 192.168.2.0/24

  track_new_devices: true
  interval_seconds: 40
  consider_home: 120

Ce petit exemple illustre le fonctionnement des fichiers fractionnés. Dans ce cas, nous commençons avec deux entrées de suivi de périphérique (owntracks et nmap). Ces fichiers suivent le « style 1 », c’est-à-dire une entrée de tête alignée entièrement à gauche (- platform: owntracks) suivie des entrées de paramètres indentées de deux espaces.

Voici un autre exemple de configuration, avec une sonde (sensor) plus complexe :

### sensor.yaml
### METEOBRIDGE #############################################
- platform: tcp
  name: "Outdoor Temp (Meteobridge)"
  host: 192.168.2.82
  timeout: 6
  payload: "Content-type: text/xml; charset=UTF-8\n\n"
  value_template: "{{value.split (' ')[2]}}"
  unit: C
- platform: tcp
  name: "Outdoor Humidity (Meteobridge)"
  host: 192.168.2.82
  port: 5556
  timeout: 6
  payload: "Content-type: text/xml; charset=UTF-8\n\n"
  value_template: "{{value.split (' ')[3]}}"
  unit: Percent

#### STEAM FRIENDS ##################################
- platform: steam_online
  api_key: ["not telling"]
  accounts:
    - 76561198012067051

#### TIME/DATE ##################################
- platform: time_date
  display_options:
      - "time"
      - "date"
- platform: worldclock
  time_zone: Etc/UTC
  name: "UTC"
- platform: worldclock
  time_zone: America/New_York
  name: "Ann Arbor"

Vous remarquerez que cet exemple comprend une section de paramètres secondaires (sous la section STEAM) ainsi qu’un meilleur exemple de la façon dont les commentaires peuvent être utilisés pour décomposer les fichiers en sections.
Tous les éléments ci-dessus peuvent être appliqués lors de la division de fichiers à l’aide de paquets. Pour en savoir plus en savoir plus sur les paquets, consultez la page Paquets.

Si vous avez des problèmes, consultez le fichier home-assistant.log dans le répertoire de configuration ainsi que vos indentations. Si malgré tout, ça ne fonctionne pas, n’hésitez pas à poser vos questions sur ce forum ou sur Discord.

Débogage de fichiers de configuration

Si vous disposez de nombreux fichiers de configuration, Home Assistant fournit une interface en ligne commande (CLI) qui vous permet de voir comment c’est interprété, chaque type d’installation sa propre section. Ces commandes sont utilisables via l’add-on SSH & Web Terminal :

  • Lister tous les fichiers chargés : hass --script check_config --files
  • Visualisation de la configuration d’un composant : hass --script check_config --info light
  • Ou la configuration de tous les composants : hass --script check_config --info all
    Vous pouvez obtenir de l’aide sur la ligne de commande en utilisant : hass --script check_config --help

Utilisation avancée

Il existe quatre options avancées pour inclure des répertoires entiers en une seule fois. Veuillez noter que vos fichiers doivent porter l’extension de fichier .yaml, le format .yml n’est pas pris en charge.
Cela vous permettra d’ !include des fichiers avec des extensions .yml depuis les fichiers .yaml ; sans que ces fichiers .yml soient importés par les commandes suivantes elles-mêmes.

  • !include_dir_list renvoie le contenu d’un répertoire sous forme de liste, chaque contenu de fichier étant une entrée dans la liste. Les entrées de la liste sont classées selon l’ordre alphanumérique des noms des fichiers.
  • !include_dir_named renverra le contenu d’un répertoire sous la forme d’un dictionnaire qui met en correspondance nom de fichier => contenu du fichier.
  • !include_dir_merge_list renvoie le contenu d’un répertoire sous forme de liste en fusionnant tous les fichiers (qui doivent contenir une liste) en une seule grande liste.
  • !include_dir_merge_named renverra le contenu d’un répertoire sous forme de dictionnaire en chargeant chaque fichier et en le fusionnant dans un grand dictionnaire.

Ces options fonctionnent de façon récursive. À titre d’exemple, en utilisant !include_dir_list automation, comprendra les 6 fichiers indiqués suivant :

.
└── .homeassistant
    ├── automation
    │   ├── lights
    │   │   ├── turn_light_off_bedroom.yaml
    │   │   ├── turn_light_off_lounge.yaml
    │   │   ├── turn_light_on_bedroom.yaml
    │   │   └── turn_light_on_lounge.yaml
    │   ├── say_hello.yaml
    │   └── sensors
    │       └── react.yaml
    └── configuration.yaml (non inclus)

Voir ci-dessous pour les exemples de chacune des options.

Exemple : !include_dir_list

À l’origine, seulement le fichier configuration.yaml contenant :

automation:
  - alias: "Automation 1"
    trigger:
      platform: state
      entity_id: device_tracker.iphone
      to: "home"
    action:
      action: light.turn_on
      target:
        entity_id: light.entryway
  - alias: "Automation 2"
    trigger:
      platform: state
      entity_id: device_tracker.iphone
      from: "home"
    action:
      action: light.turn_off
      target:
        entity_id: light.entryway

Avec cette option, cela devient :

  • configuration.yaml :
automation: !include_dir_list automation/presence/
  • automation/presence/automation1.yaml :
alias: "Automation 1"
trigger:
  platform: state
  entity_id: device_tracker.iphone
  to: "home"
action:
  action: light.turn_on
  target:
    entity_id: light.entryway
  • automation/presence/automation2.yaml :
alias: "Automation 2"
trigger:
  platform: state
  entity_id: device_tracker.iphone
  from: "home"
action:
  action: light.turn_off
  target:
    entity_id: light.entryway

Il est important de noter que chaque fichier ne doit contenir qu’une seule entrée lorsque vous utilisez !include_dir_list.

Exemple : !include_dir_named

À l’origine, seulement le fichier configuration.yaml contenant :

alexa:
  intents:
    LocateIntent:
      action:
        action: notify.pushover
        data:
          message: "Your location has been queried via Alexa."
      speech:
        type: plaintext
        text: >
          {%- for state in states.device_tracker -%}
            {%- if state.name.lower() == User.lower() -%}
              {{ state.name }} is at {{ state.state }}
            {%- endif -%}
          {%- else -%}
            I am sorry. Pootie! I do not know where {{User}} is.
          {%- endfor -%}
    WhereAreWeIntent:
      speech:
        type: plaintext
        text: >
          {%- if is_state('device_tracker.iphone', 'home') -%}
            iPhone is home.
          {%- else -%}
            iPhone is not home.
          {% endif %}

Avec cette option, cela devient :

  • configuration.yaml :
alexa:
  intents: !include_dir_named alexa/
  • alexa/LocateIntent.yaml :
action:
  action: notify.pushover
  data:
    message: "Your location has been queried via Alexa."
speech:
  type: plaintext
  text: >
    {%- for state in states.device_tracker -%}
      {%- if state.name.lower() == User.lower() -%}
        {{ state.name }} is at {{ state.state }}
      {%- endif -%}
    {%- else -%}
      I am sorry. Pootie! I do not know where {{User}} is.
    {%- endfor -%}
  • alexa/WhereAreWeIntent.yaml :
speech:
  type: plaintext
  text: >
    {%- if is_state('device_tracker.iphone', 'home') -%}
      iPhone is home.
    {%- else -%}
      iPhone is not home.
    {% endif %}

Exemple !include_dir_merge_list

À l’origine, seulement le fichier configuration.yaml contenant :

automation:
  - alias: "Automation 1"
    trigger:
      - platform: state
        entity_id: device_tracker.iphone
        to: "home"
    action:
      - action: light.turn_on
        target:
          entity_id: light.entryway
  - alias: "Automation 2"
    trigger:
      - platform: state
        entity_id: device_tracker.iphone
        from: "home"
    action:
      - action: light.turn_off
        target:
          entity_id: light.entryway

Avec cette option, cela devient :

  • configuration.yaml :
automation: !include_dir_merge_list automation/
  • automation/presence.yaml :
- alias: "Automation 1"
  trigger:
    - platform: state
      entity_id: device_tracker.iphone
      to: "home"
  action:
    - action: light.turn_on
      target:
        entity_id: light.entryway
- alias: "Automation 2"
  trigger:
    - platform: state
      entity_id: device_tracker.iphone
      from: "home"
  action:
    - action: light.turn_off
      target:
        entity_id: light.entryway

Il est important de noter que lorsque vous utilisez !include_dir_merge_list, vous devez inclure une liste dans chaque fichier (chaque élément de la liste est désigné par un trait d’union [-]). Et que chaque fichier peut contenir une ou plusieurs entrées.

Exemple : !include_dir_merge_named

À l’origine, seulement le fichier configuration.yaml contenant :

group:
  bedroom:
    name: "Bedroom"
    entities:
      - light.bedroom_lamp
      - light.bedroom_overhead
  hallway:
    name: "Hallway"
    entities:
      - light.hallway
      - thermostat.home
  front_yard:
    name: "Front Yard"
    entities:
      - light.front_porch
      - light.security
      - light.pathway
      - sensor.mailbox
      - camera.front_porch

Avec cette option, cela devient :

  • configuration.yaml :
group: !include_dir_merge_named group/
  • group/interior.yaml :
bedroom:
  name: "Bedroom"
  entities:
    - light.bedroom_lamp
    - light.bedroom_overhead
hallway:
  name: "Hallway"
  entities:
    - light.hallway
    - thermostat.home
  • group/exterior.yaml :
front_yard:
  name: "Front Yard"
  entities:
    - light.front_porch
    - light.security
    - light.pathway
    - sensor.mailbox
    - camera.front_porch

Exemple : combiner !include_dir_merge_list avec automations.yaml

Vous voulez passer à l’étape avancée et diviser vos automatismes, mais vous voulez quand même pouvoir créer des automatismes depuis l’interface graphique ?
Comme indiqué plus haut, il est possible d’imbriquer les includes. Voici comment nous pouvons faire cela pour les automatismes.

L’utilisation d’étiquettes comme manual ou ui permet d’utiliser plusieurs clés dans la configuration :
configuration.yaml :

# automations faites à la main
automation manual: !include_dir_merge_list automations/

# automations créées via l’interface graphique
automation ui: !include automations.yaml

MAJ 12/05/2021 : pour correspondre à la mise à jour de la documentation (n° commit : 2a083a8)
MAJ 12/11/2023 : pour correspondre à la dernière version de la documentation
MAJ 22/12/2023 : pour correspondre à la dernière version de la documentation
MAJ 14/08/2024 : Les service sont désormais des action (2024.8)

2 « J'aime »

Super post. Mériterait de le mettre dans les tutoriels officiel. Un petit mot sur les packages ?
Actuellement je ne regroupe plus par fichier automation: Script: … mais plutôt par projet via les packages. L’avantage est de trouver au même endroit toutes les sensors, automation script … du projet.

1 « J'aime »

C’est déjà dans Home Assistant - Tutoriels & Partages:upside_down_face:

Non car ici c’est la traduction :fr: de la documentation concernant la configuration partagée.

La méthode package est abordé dans ce tutoriel : Organisation du fichier configuration.yaml

C’est dans la partie utilisation avancée de cette documentation.
Ainsi, que dans le tuto de @McFly cité par @Clemalex

Bon même si la discussion date un peu, il y a eu un update fin 2023
Du coup je me permets d’y poser ma question

Du coup je crée un fichier pour y mettre ma conf perso
Bon j’ai repris pour de la facilité les infos de la présentation pour les deux capteurs

J’ajoute ensuite dans le configuration.yaml la ligne pour inclure mon fichier
Sauf erreur je ne vois cela expliqué nul part
yaml002

La première question que j’ai en faîtes c’est à quoi correspond ce qui est avant les deux points
Du coup j’ai essayé avec ces deux syntaxes :

test: !include 0test.yaml
0test: !include 0test.yaml

Et j’ai ces erreurs


J’en conclu qu’il faut une intégration test ou 0test
Mais du coup que faut-il mettre exactement ? L’un de vous peut-il me faire un refresh la dessus ?

Par avance merci

@+

Je pense que tu mets pas les lignes au bon endroit mais on voit pas ton config complet. Il faut les mettre sous home assistant : ou indente deux espaces.

Pourquoi tu inclus les yaml automation, scene et scripts ?

Le début de mon fichier configuration.yaml
Les 11 premières lignes sont les lignes par défaut, j’y ai jamais touché

Alors j’ai contourné le pb car depuis hier au soir ça me chauffait les oreilles :rofl:

J’ai crée un folder à la racine, j’ai mis le fichier test.yaml dedans

Et dans le configuration.yaml j’ai ajouté ceci
le homeassistant: est nécessaire

image

@Lychee
Bonjour :wave:t2:

Tu te fourvoies sur l’utilisation des includes.

En gros, les entêtes comme :

automation: 
  ...
script: 
  ...
scene: 
  ...
input_number:  
  ...
template:  
  ...
sensor:  
  ...
switch: 
  ...
utility_meter:  
  ...
http:
  ...

sont des en-têtes système, tu ne peux pas les renommer, car ils correspondent à un point particulier de la configuration.

Si tu veux déporter ces élements, pas de soucis, tu peux les mettres en includes, mais dans les fichiers .yaml que tu vas créer, il ne faut pas répéter l’en-tête.
Ainsi pour ton mqtt, il faudrait que tu fasses ça :

  1. Tu crées un dossier que je nomme separate_yaml dans le dossier config de HA :

  2. Dans configuration.yaml, tu mets :

mqtt: !include /config/separate_yaml/mqtt.yaml
  1. Dans le fichier /config/separate_yaml/mqtt.yaml, tu mets :
sensor
  - name: "test sensor 1"
    state_topic: "test/some_topic1"
  - name: "test sensor 2"
    state_topic: "test/some_topic2"

Si tu as besoin de séparer encore plus, par exemple avec les template, tu peux aussi faire un include de dossier comme tu as fait avec le packages :

template: !include_dir_merge_list /config/separate_yaml/templates

Ta méthode fonctionne, mais elle est un peu brutale, et sans finesse :wink:
Je pense que séparer comme je le propose est plus logique et moins source de problèmes.

2 « J'aime »

Comment ça je suis brutal :rofl: :rofl: :rofl:
Ouais j’aime bien y envoyer

Ok je vais, à tête reposée, demain matin matin prendre en compte ton retour
Merci beaucoup

1 « J'aime »

Je fais aussi comme @MilesTEG1

2 « J'aime »

Bonjour.
Si ça peut aider quelqu’un (car ayant consulté aussi votre sujet pour tenter de résoudre un problème perso sur les sensors), j’ai fait un résumé dans ce post de la solution adoptée (traite uniquement des sensors, mais est peut-être utile pour le problème de @Lychee).

1 « J'aime »

Avec un peu de retard
Merci Patrick_MX