Schéma : le volume de l'enceinte est mémorisé, l'annonce passe à 30 %, puis le volume d'avant est rétabli.
| | | | | |

Home Assistant en français avec Piper : une voix locale, au bon volume

Avant de commencer. Faire une sauvegarde complète de Home Assistant avant de modifier quoi que ce soit. Créer les nouveaux scripts à côté de l’existant, et ne les brancher sur les automatisations qu’une fois testés.

À quoi ça sert

Ce guide montre comment faire parler Home Assistant en français avec Piper, une voix qui tourne sur la machine elle-même, sans service en ligne. Il règle aussi trois problèmes concrets : une annonce trop forte ou trop faible, une enceinte en veille qui ne dit pas son volume, et une annonce qui part dans la mauvaise pièce.

Ce qu’il faut avoir

  • Home Assistant (testé en version 2026.9).
  • Le module complémentaire Piper et son intégration Wyoming.
  • Une enceinte compatible Google Cast.

Les entités à remplacer

Dans les blocsÀ remplacer par
tts.piperle moteur Piper
media_player.enceinte_garagel’enceinte qui doit parler
media_player.enceinte_bureauune autre enceinte, pour l’exemple des fichiers préparés
script.nouveau_garage_annoncecréé à l’étape 3 (le même que dans le guide de la lampe de garage)
script.nouveau_bureau_annonce_prepareecréé à l’étape 6
bureau-22-preparee.mp3 et suivantsles fichiers déposés dans My media, un par phrase

Les étapes

1. Choisir une voix française

Piper propose plusieurs voix françaises. Celles vues dans l’installation de test : fr_FR-gilles-low, fr_FR-mls-medium, fr_FR-mls_1840-low, fr_FR-siwis-low, fr_FR-siwis-medium, fr_FR-tom-medium et fr_FR-upmc-medium. Les écouter dans Médias, Synthèse vocale, puis garder la même partout. Les exemples utilisent fr_FR-tom-medium.

2. Faire une annonce simple

L’action de base, à essayer dans Outils de développement, Actions :

action: tts.speak
target:
  entity_id: tts.piper
data:
  media_player_entity_id: media_player.enceinte_garage
  message: "La lumière s'éteint dans une minute."
  language: fr_FR
  cache: true
  options:
    voice: fr_FR-tom-medium

3. Régler le volume, puis le rétablir

Schéma : le volume de l'enceinte est mémorisé, l'annonce passe à 30 %, puis le volume d'avant est rétabli.

Une annonce part au volume du moment. Si l’enceinte a servi à écouter de la musique fort, l’annonce est forte aussi. Ce script règle l’enceinte à 30 %, parle, attend la fin de la phrase, puis remet le volume d’avant :

nouveau_garage_annonce:
  alias: nouveau_garage_annonce
  description: Annonce sur l'enceinte du garage à 30 % de volume, puis rétablit le volume d'avant (0.30 s'il était illisible).
  mode: queued
  max: 5
  fields:
    message:
      name: Message
      required: true
      selector:
        text: {}
  sequence:
  - variables:
      volume_avant: '{{ state_attr(''media_player.enceinte_garage'', ''volume_level'') }}'
  - variables:
      volume_lisible: '{{ volume_avant is number and 0 <= volume_avant <= 1 }}'
      volume_retour: '{{ volume_avant if (volume_avant is number and 0 <= volume_avant <= 1) else 0.3 }}'
  - action: media_player.volume_set
    continue_on_error: true
    target:
      entity_id: media_player.enceinte_garage
    data:
      volume_level: 0.3
  - action: tts.speak
    continue_on_error: true
    target:
      entity_id: tts.piper
    data:
      media_player_entity_id: media_player.enceinte_garage
      message: '{{ message }}'
      language: fr_FR
      cache: true
      options:
        voice: fr_FR-tom-medium
  - wait_template: '{{ is_state(''media_player.enceinte_garage'', ''playing'') }}'
    timeout:
      seconds: 8
    continue_on_timeout: true
  - wait_template: '{{ not is_state(''media_player.enceinte_garage'', ''playing'') }}'
    timeout:
      seconds: 28
    continue_on_timeout: true
  - action: media_player.volume_set
    continue_on_error: true
    target:
      entity_id: media_player.enceinte_garage
    data:
      volume_level: '{{ volume_retour }}'

Points importants :

  • Attendre la fin de la lecture. L’action tts.speak rend la main tout de suite. Sans les deux attentes, le volume serait rétabli avant même que la phrase commence.
  • Chaque étape est indépendante (continue_on_error). Si le réglage du volume échoue, l’annonce part quand même. Si l’annonce échoue, le volume est quand même rétabli.
  • Appeler le script sans l’attendre, avec script.turn_on. Une automatisation qui attendrait la fin de la phrase serait retardée d’autant.

4. Le cas de l’enceinte en veille

Quand l’enceinte est en veille (état « off »), Home Assistant n’indique pas son volume. Le volume d’avant est donc illisible. Le script le voit (volume_lisible) et revient alors au volume de l’annonce, 30 %. Conséquence à connaître : après une première annonce sur une enceinte en veille, elle reste à 30 %. Constaté en usage réel. Dès que l’enceinte est sortie de veille, son volume redevient lisible et il est bien rétabli.

5. Vérifier que c’est la bonne enceinte

Le nom technique d’une enceinte peut tromper : une entité peut garder un ancien nom après un déménagement de l’appareil. Ce qui fait foi :

  • le nom de l’appareil et son modèle, dans Paramètres, Appareils et services ;
  • un test court, à une heure raisonnable, avec quelqu’un dans la pièce.

Home Assistant peut confirmer qu’une enceinte joue (état « playing »), pas que quelqu’un l’a entendue.

6. Des annonces préparées à l’avance

Une phrase fixe peut aussi être un fichier audio préparé à l’avance, par exemple une voix enregistrée. Le principe :

  1. Égaliser le niveau de tous les fichiers, pour qu’aucune phrase ne soit plus forte qu’une autre.
  2. Les déposer dans Médias, My media. Home Assistant les sert lui-même aux enceintes, comme il leur sert déjà les annonces Piper.
  3. Faire correspondre chaque message à son fichier, et garder Piper en repli : si le message n’a pas de fichier, ou si le fichier ne démarre pas en 8 secondes, Piper parle.
nouveau_bureau_annonce_preparee:
  alias: nouveau_bureau_annonce_preparee
  description: Annonce de l'heure au bureau à partir de fichiers préparés à l'avance, repli sur Piper. Volume jamais modifié.
  mode: queued
  max: 3
  fields:
    message:
      name: Message
      required: true
      selector:
        text: {}
  sequence:
  - variables:
      fichiers:
        Il est vingt-deux heures.: media-source://media_source/local/bureau-22-preparee.mp3
        Il est vingt-trois heures.: media-source://media_source/local/bureau-23-preparee.mp3
        Il est minuit.: media-source://media_source/local/bureau-00-preparee.mp3
        Il est une heure.: media-source://media_source/local/bureau-01-preparee.mp3
        Il est deux heures.: media-source://media_source/local/bureau-02-preparee.mp3
        Il est trois heures.: media-source://media_source/local/bureau-03-preparee.mp3
        Il est quatre heures.: media-source://media_source/local/bureau-04-preparee.mp3
        Il est cinq heures.: media-source://media_source/local/bureau-05-preparee.mp3
        Il est six heures.: media-source://media_source/local/bureau-06-preparee.mp3
  - variables:
      fichier: '{{ fichiers.get(message, '''') }}'
  - choose:
    - conditions:
      - condition: template
        value_template: '{{ fichier != '''' }}'
      sequence:
      - action: media_player.play_media
        continue_on_error: true
        target:
          entity_id: media_player.enceinte_bureau
        data:
          media_content_id: '{{ fichier }}'
          media_content_type: music
      - wait_template: '{{ is_state(''media_player.enceinte_bureau'', ''playing'') }}'
        timeout:
          seconds: 8
        continue_on_timeout: true
      - if:
        - condition: template
          value_template: '{{ not wait.completed }}'
        then:
        - action: tts.speak
          target:
            entity_id: tts.piper
          data:
            media_player_entity_id: media_player.enceinte_bureau
            message: '{{ message }}'
            language: fr_FR
            cache: true
            options:
              voice: fr_FR-tom-medium
          continue_on_error: true
        - wait_template: '{{ is_state(''media_player.enceinte_bureau'', ''playing'') }}'
          timeout:
            seconds: 8
          continue_on_timeout: true
    default:
    - action: tts.speak
      target:
        entity_id: tts.piper
      data:
        media_player_entity_id: media_player.enceinte_bureau
        message: '{{ message }}'
        language: fr_FR
        cache: true
        options:
          voice: fr_FR-tom-medium
      continue_on_error: true
    - wait_template: '{{ is_state(''media_player.enceinte_bureau'', ''playing'') }}'
      timeout:
        seconds: 8
      continue_on_timeout: true

Le repli est l’appel Piper d’origine : il ne dépend en rien de la lecture du fichier.

Le résultat attendu

L’enceinte dit la phrase en français, à 30 % du volume, puis revient à son volume d’avant. Une phrase sans fichier préparé part en Piper, sans silence.

Tester sans risque

  • Écouter la voix dans le navigateur : Médias, Synthèse vocale.
  • Lire la trace du script après un essai : on y voit volume_avant, volume_lisible et volume_retour.
  • Faire le premier essai sur l’enceinte à une heure raisonnable, une seule fois.

Si ça ne marche pas

  • Silence complet. Vérifier que l’enceinte est bien celle de la pièce (étape 5), et qu’elle n’est pas en sourdine.
  • Le volume ne revient pas. L’enceinte était en veille : c’est le cas de l’étape 4.
  • Annonce coupée. La phrase dure plus que l’attente de fin (28 secondes) : augmenter la valeur.
  • Fichier préparé muet. Si les fichiers sont servis par une autre machine, son pare-feu doit laisser passer l’enceinte. Les déposer dans la médiathèque de Home Assistant évite ce piège.

Revenir en arrière

Les scripts sont des ajouts. Pour revenir, rebrancher les automatisations sur l’appel tts.speak d’origine, puis supprimer ou laisser dormir les scripts : ils ne font rien tant qu’on ne les appelle pas.

Ce qui est vérifié en usage réel, et ce qui ne l’est pas

Vérifié le 1er octobre 2026 : l’annonce Piper à 30 % sur une enceinte en veille, avec le volume illisible puis rétabli à 30 % ; la même annonce sur une enceinte réveillée, avec le volume d’avant lu puis rétabli ; les annonces réelles déclenchées par une lampe. Le dépôt des fichiers dans la médiathèque et leur lecture depuis une autre machine du réseau ont aussi été vérifiés.

Pas encore vérifié en usage réel : la lecture des fichiers préparés sur une enceinte, et le repli sur Piper quand un fichier manque.

Responsabilité. Ce guide décrit un montage réel, donné à titre d’exemple. Chaque installation est différente. L’adapter, le tester et l’utiliser se fait sous la responsabilité de la personne qui l’installe.

À lire aussi