Être alerté si la pluie est attendue dans moins d'une heure

Dans le même état d’esprit que le partage de mon automatisation pour les alertes météo, je vous partage une autre automatisation pour être alerté de l’arrivée de la pluie.

Préliminaires:

  • Il faut avoir l’intégration Météo-France installée et configurée pour la ville à surveiller. La ville doit être couverte par les prévisions de pluie à une heure.
  • Avoir un système de notification configuré dans Home Assistant (par exemple Telegram).
  • Avoir un système de Text-To-Speech (TTS) configuré dans Home Assistant (Google Home par exemple)

Fonctionnement:

  • Je veux recevoir une notification (sur Telegram) qui m’informe si de la pluie est attendue dans la prochaine heure avec l’heure estimée de la pluie.
  • Je veux qu’a chaque mise à jour de l’heure estimée, une nouvelle notification soit envoyée.
  • Une fois que la pluie est prévue dans moins de 5 minutes, je considère qu’il pleut et je ne veux plus recevoir de nouvelle notification jusqu’à ce que plus de pluie soit attendue dans la prochaine heure.
  • Je veux aussi envoyer un message audio sur le Google Home du salon, 5 minutes avant la pluie pour alerter ceux qui sont présents.

Implémentation:
Voici le code complet de mon automatisation. Vous trouverez les explications après ce bloc.

- alias: Alerte quand pluie attendue
  description: Envoie des notifications quand la pluie est attendue dans l'heure
  id: 30f4e5a8-df44-11ea-87d0-0242ac130003
  trigger:
    platform: state
    entity_id: sensor.home_next_rain
  action:
    - choose:
        - conditions:
            # If rain is expected and notification are not stop by the input_boolean...
            - "{{ trigger.to_state.state != 'unknown' }}"
            - condition: state
              entity_id: input_boolean.stop_rain_notification
              state: 'off'
          sequence:
            - choose:
                - conditions:
                    # If estimated time change...
                    # ... Send a notification on Telegram
                    - "{{ trigger.to_state.state != trigger.from_state.state }}"
                  sequence:
                    - service: notify.telegram
                      data:
                        message: >
                          La pluie est attendue à {{ as_timestamp(states('sensor.home_next_rain'))
                          | timestamp_custom('%H:%M', True) }}.
            - choose:
                - conditions:
                    # If rain is expected in less than 5 mintues...
                    # ... Stop future notification and send a notification on Google Home
                    - "{{ state_attr('sensor.home_next_rain', '1_hour_forecast')['0 min'] != 'Temps sec' }}"
                  sequence:
                    - service: input_boolean.turn_on
                      data:
                        entity_id: input_boolean.stop_rain_notification
                    # If current time is between 10h00 and 21h30...
                    # ... Send a notification on Google Home
                    - condition: time
                      before: '21:30:00'
                      after: '10:00:00'
                    - service: tts.google_translate_say
                      data:
                        entity_id: media_player.google_home
                        message: "Chers résidents, la pluie est attendue dans quelques minutes."
        - conditions:
            # If rain is no more expected...
            # ... Send a notification on Telegram and allow future notifications
            - "{{ trigger.to_state.state == 'unknown' }}"
            - "{{ trigger.from_state.state != 'unknown' }}"
          sequence:
            - service: notify.telegram
              data:
                message: "Plus de pluie attendue dans la prochaine heure."
            - service: input_boolean.turn_off
              data:
                entity_id: input_boolean.stop_rain_notification

Explications:
Une seule automatisation suffit pour implémenter celà. J’utilise les dernières fonctionnalités implémentées récemment dans HA core pour les scripts: choose et template shorthand.

Chaque automatisation a des paramètres d’identifications:

  • Un nom avec la clé alias
  • Une description avec la clé description mais dont le contenu n’est pas encore visible pour les automatisation en mode YAML. Pour les automatisations configurée dans L’UI cette clé est éditable et visible.
  • Un identifiant unique avec la clé id. Vous pouvez générer des identifiants uniques à l’aide ce site .

En ajoutant un identifiant unique, vous débloquez certaines fonctionnalités dans l’interface graphique (personnalisation, vue des liens avec les sensors utilisés, etc.)

- alias: Alerte quand pluie attendue
  description: Envoie des notifications quand la pluie est attendue dans l'heure
  id: 30f4e5a8-df44-11ea-87d0-0242ac130003

Pour définir les paramètres de déclenchement d’une automatisation, il faut utiliser la clé trigger. Dans le cas de cette automatisation, je la déclenche sur le changement d’état du sensor home_next_rain créé par l’intégration Météo-France.

Bon à savoir: même si l’état ne change pas mais qu’un attribut du sensor change, le trigger lance l’automatisation.

Si vous voulez découvrir tous les triggers disponibles, vous pouvez consulter la page trigger de la doc.

Notre automatisation est maintenant déclenchée. Contrairement à l’exemple sur les alertes météo, je ne rajoute pas de clé condition juste après le trigger. En fait je vais utiliser l’instruction choose qui permet d’avoir plusieurs embranchement dans la logique du script (équivalent de if/elif/ else en Python)

  action:
    - choose:

Dans la suite du script j’utilise à plusieurs endroit un booléen (input_boolean.stop_rain_notification) qui me permet de suivre si les notifications doivent être bloquées ou non (cf. description de la logique).

Deux embranchements sont possibles:

  1. De la pluie est attendue dans moins d’une heure et le booléen ne bloque pas les notifications.
  2. L’état du sensor home_next_rain revient à la valeur unknown ce qui veut dire que plus de pluie n’est attendue dans la prochaine heure.

Pour le premier cas j’implémente deux conditions sous forme de liste. Toutes les conditions listées doivent être vraies pour déclencher les actions décrites dans la clé séquence associée.
La première condition utilisant la notation {{ ... }} permet d’offrir plus rapidement une condition basée sur un template Jinja.
La deuxième est une condition pour vérifier la valeur de l’état du booléen.

        - conditions:
            - "{{ trigger.to_state.state != 'unknown' }}"
            - condition: state
              entity_id: input_boolean.stop_rain_notification
              state: 'off'

Pour le second cas, il ya deux conditions au format raccourci (shorthand) qui permettent de vérifier que le sensor qui a déclenché l’automatisation est passé (au moment du déclenchement) d’un état différent de unknown (c-a-d que de la pluie était attendue) à un l’état unknown(c-a-d qu’il ny’a plus de pluie prévue dans la prochaine heure).

        - conditions:
            - "{{ trigger.to_state.state == 'unknown' }}"
            - "{{ trigger.from_state.state != 'unknown' }}"

Si toutes les conditions du premier cas sont remplies (rappel: De la pluie est attendue dans moins d’une heure et le booléen ne bloque pas les notifications) nous voulons que:

  1. Si l’heure estimé de la pluie change, une notification est envoyée sur Telegram.
  2. S’il pleut dans moins de 5 minutes, un message audio est envoyé sur la Google Home et nous passons le booléen qui bloque les prochaines notifications à vraie.

Les actions qui permettent de réaliser cette logique sont dans la première clé sequence:. Là aussi nous allons utiliser l’instruction choose (2 fois).

Comme nous avons déjà détaillé son fonctionnement au dessus, je vais aller un peu plus vite.

Donc dans ce premier bloc, nous testons si l’état du sensor qui a déclenché l’automatisation (home_next_rain) a bien changé: il y a donc une nouvelle heure estimée de pluie. Dans ce cas j’utilise un service lié à l’intégration Télégram pour envoyer une notification personnalisée avec l’heure estimée au format HH:MM)

            - choose:
                - conditions:
                    - "{{ trigger.to_state.state != trigger.from_state.state }}"
                  sequence:
                    - service: notify.telegram
                      data:
                        message: >
                          La pluie est attendue à {{ as_timestamp(states('sensor.home_next_rain'))
                          | timestamp_custom('%H:%M', True) }}.

C’est la seule possibilité que nous avons mis dans ce bloc choose donc si la valeur de l’état n’a pas changé, rien ne se passe et nous passons au second bloc choose.

Dans ce bloc, la condition permet de contrôler une valeur spécifique du dictionnaire stocké dans l’attribut 1_hour_forecast associé au sensor home_next_rain. Si la valeur correspondant à la prévision dans moins de 5 minutes est différente de Temps sec, je considère qu’il va pleuvoir très prochainement.

            - choose:
                - conditions:
                    - "{{ state_attr('sensor.home_next_rain', '1_hour_forecast')['0 min'] != 'Temps sec' }}"

Dans ce cas j’appelle deux services.
Un premier pour mettre le booléen (qui permet de bloquer les notifications) à vrai. Je n’attend donc plus de nouvelle notification car maintenant la pluie est là.
Le second service envoie le message audio sur la Google Home si auparavant une condition vérifiant que les horaires sont acceptables est bien remplie.

                  sequence:
                    - service: input_boolean.turn_on
                      data:
                        entity_id: input_boolean.stop_rain_notification
                    - condition: time
                      before: '21:30:00'
                      after: '10:00:00'
                    - service: tts.google_translate_say
                      data:
                        entity_id: media_player.google_home
                        message: "Chers résidents, la pluie est attendue dans quelques minutes."

Pour terminer ces explications nous n’avons plus qu’à voir les actions associées au second cas dans le premier embranchement correspondant à « L’état du sensor home_next_rain revient à la valeur unknown ce qui veut dire que plus de pluie n’est attendue dans la prochaine heure ».

Dans ce cas j’utilise un service pour envoyer une notification m’indiquant que l’épisode de pluie est terminé. Un second service change la valeur du booléen qui bloquait les notifications pour en permettre de nouvelles si la pluie revient.

          sequence:
            - service: notify.telegram
              data:
                message: "Plus de pluie attendue dans la prochaine heure."
            - service: input_boolean.turn_off
              data:
                entity_id: input_boolean.stop_rain_notification

J’espère que cela aura été utile à certains d’entre vous. Je suis ouvert à vos questions et commentaires.

Si vous voulez voir d’autres automatisations, direction ma configuration sur GitHub

8 « J'aime »

Hello @oncleben31,

Je t’avais piqué ce bout de code en fouillant tant ton repo il y a quelques mois (Août) ! Et ça marchait du tonnerre ! Est ce que tu as fait des modifications depuis ?

Merci pour le partage !

Oui, j’ai mergé deux automatisations et j’ai modifié un peu la logique pour avoir moins de notifications sur Telegram.
J’en ai profité pour faire un peu de refactorisation.

1 « J'aime »

Merci pour le partage.

Bonjour,
j’ai adapté ce tuto pour mon utilisation mais je ne reçois pas de notification.
j’ai supprimer la partie Google car je veux que des notifications sur mon smartphone.
pouvez vous m’aidé?
Merci

voici le code

- id: 30f4e5a8-df44-11ea-87d0-0242ac130003
  alias: Alerte quand pluie attendue
  description: Envoie des notifications quand la pluie est attendue dans l'heure
  trigger:
  - platform: state
    entity_id: sensor.courlay_next_rain
  action:
  - choose:
    - conditions:
      - condition: template
        value_template: '{{ trigger.to_state.state != ''unknown'' }}'
      - condition: state
        entity_id: input_boolean.stop_rain_notification
        state: 'off'
      sequence:
      - choose:
        - conditions:
          - condition: template
            value_template: '{{ trigger.to_state.state != trigger.from_state.state
              }}'
          sequence:
          - service: notify.telegram_groupe
            data:
              message: 'La pluie est attendue à {{ as_timestamp(states(''sensor.courlay_next_rain''))
                | timestamp_custom(''%H:%M'', True) }}.

                '
      - choose:
        - conditions:
          - condition: template
            value_template: '{{ state_attr(''ssensor.courlay_next_rain'', ''1_hour_forecast'')[''0
              min''] != ''Temps sec'' }}'
          sequence:
          - service: input_boolean.turn_on
            data:
              entity_id: input_boolean.stop_rain_notification
    - conditions:
      - condition: template
        value_template: '{{ trigger.to_state.state == ''unknown'' }}'
      - condition: template
        value_template: '{{ trigger.from_state.state != ''unknown'' }}'
      sequence:
      - service: notify.telegram_groupe
        data:
          message: Plus de pluie attendue dans la prochaine heure.
      - service: input_boolean.turn_off
        data:
          entity_id: input_boolean.stop_rain_notification
  mode: single

en faite je reçois que ça comme notification alors que quand je l’ai mis en place j’avais bien de la pluie de prévu

      - choose:
        - conditions:
          - condition: template
            value_template: '{{ state_attr(''ssensor.courlay_next_rain'', ''1_hour_forecast'')[''0
              min''] != ''Temps sec'' }}'

tu as un s en trop sur l’entité ssensor.courlay_next_rain au lieu de sensor.courlay_next_rain

merci j’avais, pas vu ça mais ça ne fonctionne toujours pas toujours que c’est notification et pas les pluie

image

Ajoute ceci en première action pour déboguer :

- service: persistent_notification.create
  data:
    message: "L'entité **{{trigger.from_state.state.name}}** *({{trigger.from_state.state.entity_id}})* vient de passer de : \n '{{trigger.from_state.state}}' \n à \n '{{trigger.to_state.state}}'"
    title: "DEBUG Automatisation"
    notification_id: "{{ (range(1, 9999)|random) }}"

Ensuite, il attendre que l’automatisation s’éxécute d’elle même, car l’utilisation des trigger.from\to_state n’est pas compatible avec le déclenchement fait par l’interface car le déclencheur n’existe pas à ce moment…
(voir la :information_source: de cette page )

j’ai ce message quand je veux ajouter en 1er action le code que tu ma donné:
image

Tu peux déboguer en forçant la valeur des états et des attributs dans l’onglet Etats de la section outils de développement .

C’est comme ca que je fais.

1 « J'aime »

Attention il y a un ou plusieurs bug ouverts sur l’IHM de création d’automatisation si vous alternez entre la vue YAML et la vue classique.
Si vous copiez un code YAML sans trop comprendre son contenu, faites le dans l’IHM en mode YAML, enregistrez le mais si vous revenez en mode standard n’enregistrez pas les modifications.

Je t’avoues que je l’ai écrit rapidement et ne l’est pas du tout testé…

Je suis au boulot, donc ça attendra ce soir pour ma part.

Effectivement, j’étais parti sur le fait d’informer que l’execution manuelle ne marche pas dans le cas de l’utilisation des données contenu dans le déclencheur :+1:

très bien pas de problème je vais attendre je suis moi même au boulot :stuck_out_tongue:

Après une pause café passé sur le forum (car les collègues sont en vacances… :sob:) :

    #DEBUG
    - service: persistent_notification.create
      data:
        message: "L'entité **{{trigger.from_state.name}}** *({{trigger.from_state.entity_id}})* vient de passer de : \n '{{trigger.from_state.state}}' \n à \n '{{trigger.to_state.state}}'"
        title: "DEBUG Automatisation"
        notification_id: "{{ (range(1, 9999)|random) }}"
    #DEBUG

il y avait un ‹ trigger.from_state .state. name › de trop :+1:, mais sans rapport avec ton erreur.

J’ai pris ton automatisation, et ajouter donc le débogage :

- id: 30f4e5a8-df44-11ea-87d0-0242ac130003
  alias: Alerte quand pluie attendue
  description: Envoie des notifications quand la pluie est attendue dans l'heure
  trigger:
  - platform: state
    entity_id: sensor.courlay_next_rain
  action:
  #DEBUG
  - service: persistent_notification.create
    data:
      message: "L'entité **{{trigger.from_state.name}}** *({{trigger.from_state.entity_id}})* vient de passer de : \n '{{trigger.from_state.state}}' \n à \n '{{trigger.to_state.state}}'"
      title: "DEBUG Automatisation"
      notification_id: "{{ (range(1, 9999)|random) }}"
  #DEBUG
  - choose:
    - conditions:
      - condition: template
        value_template: '{{ trigger.to_state.state != ''unknown'' }}'
      - condition: state
        entity_id: input_boolean.stop_rain_notification
        state: 'off'
      sequence:
      #DEBUG
      - service: persistent_notification.create
        data:
          message: "Déclencheur différent de 'unknown'"
          title: "DEBUG Automatisation"
          notification_id: "{{ (range(1, 9999)|random) }}"
      #DEBUG
      - choose:
        - conditions:
          - condition: template
            value_template: '{{ trigger.to_state.state != trigger.from_state.state
              }}'
          sequence:
          #DEBUG
          - service: persistent_notification.create
            data:
              message: "Déclencheur différent de l'état précédent, la pluie arrive !"
              title: "DEBUG Automatisation"
              notification_id: "{{ (range(1, 9999)|random) }}"
          #DEBUG
          - service: notify.telegram_groupe
            data:
              message: 'La pluie est attendue à {{ as_timestamp(states(''sensor.courlay_next_rain''))
                | timestamp_custom(''%H:%M'', True) }}.

                '
      - choose:
        - conditions:
          - condition: template
            value_template: '{{ state_attr(''ssensor.courlay_next_rain'', ''1_hour_forecast'')[''0
              min''] != ''Temps sec'' }}'
          sequence:
          #DEBUG
          - service: persistent_notification.create
            data:
              message: "La pluie est là !"
              title: "DEBUG Automatisation"
              notification_id: "{{ (range(1, 9999)|random) }}"
          #DEBUG
          - service: input_boolean.turn_on
            data:
              entity_id: input_boolean.stop_rain_notification
    - conditions:
      - condition: template
        value_template: '{{ trigger.to_state.state == ''unknown'' }}'
      - condition: template
        value_template: '{{ trigger.from_state.state != ''unknown'' }}'
      sequence:
      #DEBUG
      - service: persistent_notification.create
        data:
          message: "Plus de pluie dans l'heure..."
          title: "DEBUG Automatisation"
          notification_id: "{{ (range(1, 9999)|random) }}"
      #DEBUG
      - service: notify.telegram_groupe
        data:
          message: Plus de pluie attendue dans la prochaine heure.
      - service: input_boolean.turn_off
        data:
          entity_id: input_boolean.stop_rain_notification
  mode: single

Je te confirme que ce code fonctionne car je l’ai testé :wink:

:warning: je n’ai rien modifié à la logique, du coup, une question me vient :

  • As tu bien créé le booléen input_boolean.stop_rain_notification ?
    Car sans lui, tu ne verras que la première notification…

J’aimerai bien trouver un moyen de le faire sans le input_boolen.

1 « J'aime »

Et pourquoi ne pas utiliser les scènes ?

Une utilisation ici.
Et conditionner sur le fait de son existence ?

ah non j’avais pas fait le input boolean :frowning:
par contre j’ai un autre problème lol

image

je pense a voir trouvé j’ai changer le fuseau horaire