J’ai trouvé… cela est possible depuis la version 2023.4 : 2023.4: Custom template macros, and many more new entity dialogs! - Home Assistant
Dans /homeassistant/custom_templates j’ai créé le fichier msg_proximity.jinja
{% macro msg_content(prox_zone, person_tmp, device_name, message) %}
{{ state_attr( person_tmp, 'friendly_name' ) }} reçoit le message :
{{message}}
Notification vers notify.mobile_app_{{ device_name }}
{{ state_attr( person_tmp, 'friendly_name' ) }} est à {{ (distance( prox_zone, person_tmp ) * 1000) | int }} m
{% endmacro %}
Je l’utilise pour envoyer une notification vers un mobile avec un code de ce type
alias: Envoie une notification ciblé
service: notify.mobile_app_s23_de_joel
data:
title: "{{titre}}"
message: |-
{% from 'msg_proximity.jinja' import msg_content %}
{{ msg_content(prox_zone, person_tmp, device_name, message) }}
data:
persistent: "{{persistant}}"
sticky: "{{affichage}}"
notification_icon: "{{icone}}"
icon_url: "{{illustration}}"
color: "{{couleur}}"
clickAction: "{{click}}"
subject: "{{resume}}"
Cet exemple est tiré du script que je suis en train de finaliser (partagé en fin de message).
Il permet de ne pas déranger un utilisateur qui serait en dehors de la zone de surveillance. Les notifications sont libérées à son entrée dans la zone (la machine à lavée est fini, ça tombe bien tu arrive à la maison)
L’idée est tirée de Horizon Domotique : https://www.youtube.com/watch?v=chJylIK0ASo
Pour coller au plus près à un HA out-the-box je n’ai pas ajouté de nouvel outil comme appdaemon ou nodered. C’est parfois plus compliqué mais j’y arrive (et apprend beaucoup)
Ce script permet de gérer jusqu’à 6 personnes ou appareils.
Si c’est une personne, il récupère l’appareil à notifier. Si la personne à plusieurs appareils, c’est celui entrant dans la zone qui sera notifié.
Les traces sont postées comme notification persistante dans HA pour superviser les retours (c’est désactivable)
Je n’ai pas tout validé mais c’est opérationnel à 90% (la macro sera totalement différente en prod)
Amusez-vous bien avec
Script notification avec proximité et macro Jinja
alias: Notification avec proximity
sequence:
- alias: Notif persistante si LOG ou pas de CIBLE
if:
- condition: or
conditions:
- alias: LOG est activé
condition: template
value_template: "{{ log == true }}"
- alias: CIBLE vide ou n'est pas défini
condition: template
value_template: "{{ cible == '' or cible is not defined }}"
then:
- alias: Gestion TAG pour notification persistante HA
if:
- condition: template
value_template: "{{ tag is defined }}"
then:
- alias: "Notification persistante dans HA avec écrasement "
service: notify.persistent_notification
data:
title: "{{titre}}"
message: "{{ now().strftime('%H:%M:%S') }}<br>{{message}}"
data:
notification_id: "{% if tag is defined %}{{tag}} test{% endif %}"
else:
- alias: "Notification persistante dans HA sans écrasement "
service: notify.persistent_notification
data:
title: "{{titre}}"
message: "{{ now().strftime('%H:%M:%S') }}<br>{{message}}"
- alias: Notif mobile vers CIBLE présente
if:
- condition: template
value_template: "{{ cible is defined }}"
then:
- parallel:
- alias: Entrée n°1 de CIBLE
if:
- alias: Si entrée n°1 de CIBLE existe
condition: template
value_template: "{{ cible.entity_id[0] is defined }}"
then:
- alias: Variables Personne/Appareil et Zone
variables:
person_tmp: "{{cible.entity_id[0]}}"
prox_zone: "{{prox_zone.entity_id}}"
- alias: Attendre si hors zone
if:
- alias: La CIBLE est à plus de xx mètres de la zone
condition: template
value_template: >-
{% if prox_zone is defined and prox_distance is defined %}
{{ (distance( prox_zone, person_tmp ) * 1000) | int >
prox_distance | float(0) }} {% endif %}
then:
- alias: Attendre arrivée dans la zone de surveillance
wait_for_trigger:
- alias: Lorsque CIBLE est à moins de xx mètres de la zone
platform: template
value_template: >-
{{ (distance( prox_zone, person_tmp ) * 1000) | int <
prox_distance | float(0) }}
continue_on_timeout: false
timeout:
hours: 18
minutes: 0
seconds: 0
milliseconds: 0
- alias: Identification de l'appareil mobile à notifier
variables:
device_name: >
{{ expand(person_tmp) | map(attribute='attributes.source') |
list | join | replace('device_tracker.', '') }}
- alias: Notification si l'appareil mobile est connu
if:
- alias: L'appareil mobile est trouvé
condition: template
value_template: "{{ device_name != '' }}"
then:
- alias: Envoie une notification ciblé
service: notify.mobile_app_s23_de_joel
data:
title: "{{titre}}"
message: >-
{% from 'msg_proximity.jinja' import msg_content %}
{{ msg_content(prox_zone, person_tmp, device_name,
message) }}
data:
persistent: "{{persistant}}"
sticky: "{{affichage}}"
notification_icon: "{{icone}}"
icon_url: "{{illustration}}"
color: "{{couleur}}"
clickAction: "{{click}}"
subject: "{{resume}}"
tag: "{{tag}}"
- alias: Entrée n°2 de CIBLE
if:
- alias: Si entrée n°2 de CIBLE existe
condition: template
value_template: "{{ cible.entity_id[1] is defined }}"
then:
- alias: Variables Personne/Appareil et Zone
variables:
person_tmp: "{{cible.entity_id[1]}}"
prox_zone: "{{prox_zone.entity_id}}"
- alias: Attendre si hors zone
if:
- alias: La CIBLE est à plus de xx mètres de la zone
condition: template
value_template: >-
{% if prox_zone is defined and prox_distance is defined %}
{{ (distance( prox_zone, person_tmp ) * 1000) | int >
prox_distance | float(0) }} {% endif %}
then:
- alias: Attendre arrivée dans la zone de surveillance
wait_for_trigger:
- alias: Lorsque CIBLE est à moins de xx mètres de la zone
platform: template
value_template: >-
{{ (distance( prox_zone, person_tmp ) * 1000) | int <
prox_distance | float(0) }}
continue_on_timeout: false
timeout:
hours: 18
minutes: 0
seconds: 0
milliseconds: 0
- alias: Identification de l'appareil mobile à notifier
variables:
device_name: >
{{ expand(person_tmp) | map(attribute='attributes.source') |
list | join | replace('device_tracker.', '') }}
- alias: Notification si l'appareil mobile est connu
if:
- alias: L'appareil mobile est trouvé
condition: template
value_template: "{{ device_name != '' }}"
then:
- alias: Envoie une notification ciblé
service: notify.mobile_app_s23_de_joel
data:
title: "{{titre}}"
message: >-
{% from 'msg_proximity.jinja' import msg_content %}
{{ msg_content(prox_zone, person_tmp, device_name,
message) }}
data:
persistent: "{{persistant}}"
sticky: "{{affichage}}"
notification_icon: "{{icone}}"
icon_url: "{{illustration}}"
color: "{{couleur}}"
clickAction: "{{click}}"
subject: "{{resume}}"
tag: "{{tag}}"
- alias: Entrée n°3 de CIBLE
if:
- alias: Si entrée n°3 de CIBLE existe
condition: template
value_template: "{{ cible.entity_id[2] is defined }}"
then:
- alias: Variables Personne/Appareil et Zone
variables:
person_tmp: "{{cible.entity_id[2]}}"
prox_zone: "{{prox_zone.entity_id}}"
- alias: Attendre si hors zone
if:
- alias: La CIBLE est à plus de xx mètres de la zone
condition: template
value_template: >-
{% if prox_zone is defined and prox_distance is defined %}
{{ (distance( prox_zone, person_tmp ) * 1000) | int >
prox_distance | float(0) }} {% endif %}
then:
- alias: Attendre arrivée dans la zone de surveillance
wait_for_trigger:
- alias: Lorsque CIBLE est à moins de xx mètres de la zone
platform: template
value_template: >-
{{ (distance( prox_zone, person_tmp ) * 1000) | int <
prox_distance | float(0) }}
continue_on_timeout: false
timeout:
hours: 18
minutes: 0
seconds: 0
milliseconds: 0
- alias: Identification de l'appareil mobile à notifier
variables:
device_name: >
{{ expand(person_tmp) | map(attribute='attributes.source') |
list | join | replace('device_tracker.', '') }}
- alias: Notification si l'appareil mobile est connu
if:
- alias: L'appareil mobile est trouvé
condition: template
value_template: "{{ device_name != '' }}"
then:
- alias: Envoie une notification ciblé
service: notify.mobile_app_s23_de_joel
data:
title: "{{titre}}"
message: >-
{% from 'msg_proximity.jinja' import msg_content %}
{{ msg_content(prox_zone, person_tmp, device_name,
message) }}
data:
persistent: "{{persistant}}"
sticky: "{{affichage}}"
notification_icon: "{{icone}}"
icon_url: "{{illustration}}"
color: "{{couleur}}"
clickAction: "{{click}}"
subject: "{{resume}}"
tag: "{{tag}}"
- alias: Entrée n°4 de CIBLE
if:
- alias: Si entrée n°4 de CIBLE existe
condition: template
value_template: "{{ cible.entity_id[3] is defined }}"
then:
- alias: Variables Personne/Appareil et Zone
variables:
person_tmp: "{{cible.entity_id[3]}}"
prox_zone: "{{prox_zone.entity_id}}"
- alias: Attendre si hors zone
if:
- alias: La CIBLE est à plus de xx mètres de la zone
condition: template
value_template: >-
{% if prox_zone is defined and prox_distance is defined %}
{{ (distance( prox_zone, person_tmp ) * 1000) | int >
prox_distance | float(0) }} {% endif %}
then:
- alias: Attendre arrivée dans la zone de surveillance
wait_for_trigger:
- alias: Lorsque CIBLE est à moins de xx mètres de la zone
platform: template
value_template: >-
{{ (distance( prox_zone, person_tmp ) * 1000) | int <
prox_distance | float(0) }}
continue_on_timeout: false
timeout:
hours: 18
minutes: 0
seconds: 0
milliseconds: 0
- alias: Identification de l'appareil mobile à notifier
variables:
device_name: >
{{ expand(person_tmp) | map(attribute='attributes.source') |
list | join | replace('device_tracker.', '') }}
- alias: Notification si l'appareil mobile est connu
if:
- alias: L'appareil mobile est trouvé
condition: template
value_template: "{{ device_name != '' }}"
then:
- alias: Envoie une notification ciblé
service: notify.mobile_app_s23_de_joel
data:
title: "{{titre}}"
message: >-
{% from 'msg_proximity.jinja' import msg_content %}
{{ msg_content(prox_zone, person_tmp, device_name,
message) }}
data:
persistent: "{{persistant}}"
sticky: "{{affichage}}"
notification_icon: "{{icone}}"
icon_url: "{{illustration}}"
color: "{{couleur}}"
clickAction: "{{click}}"
subject: "{{resume}}"
tag: "{{tag}}"
- alias: Entrée n°5 de CIBLE
if:
- alias: Si entrée n°5 de CIBLE existe
condition: template
value_template: "{{ cible.entity_id[4] is defined }}"
then:
- alias: Variables Personne/Appareil et Zone
variables:
person_tmp: "{{cible.entity_id[4]}}"
prox_zone: "{{prox_zone.entity_id}}"
- alias: Attendre si hors zone
if:
- alias: La CIBLE est à plus de xx mètres de la zone
condition: template
value_template: >-
{% if prox_zone is defined and prox_distance is defined %}
{{ (distance( prox_zone, person_tmp ) * 1000) | int >
prox_distance | float(0) }} {% endif %}
then:
- alias: Attendre arrivée dans la zone de surveillance
wait_for_trigger:
- alias: Lorsque CIBLE est à moins de xx mètres de la zone
platform: template
value_template: >-
{{ (distance( prox_zone, person_tmp ) * 1000) | int <
prox_distance | float(0) }}
continue_on_timeout: false
timeout:
hours: 18
minutes: 0
seconds: 0
milliseconds: 0
- alias: Identification de l'appareil mobile à notifier
variables:
device_name: >
{{ expand(person_tmp) | map(attribute='attributes.source') |
list | join | replace('device_tracker.', '') }}
- alias: Notification si l'appareil mobile est connu
if:
- alias: L'appareil mobile est trouvé
condition: template
value_template: "{{ device_name != '' }}"
then:
- alias: Envoie une notification ciblé
service: notify.mobile_app_s23_de_joel
data:
title: "{{titre}}"
message: >-
{% from 'msg_proximity.jinja' import msg_content %}
{{ msg_content(prox_zone, person_tmp, device_name,
message) }}
data:
persistent: "{{persistant}}"
sticky: "{{affichage}}"
notification_icon: "{{icone}}"
icon_url: "{{illustration}}"
color: "{{couleur}}"
clickAction: "{{click}}"
subject: "{{resume}}"
tag: "{{tag}}"
- alias: Entrée n°6 de CIBLE
if:
- alias: Si entrée n°6 de CIBLE existe
condition: template
value_template: "{{ cible.entity_id[5] is defined }}"
then:
- alias: Variables Personne/Appareil et Zone
variables:
person_tmp: "{{cible.entity_id[5]}}"
prox_zone: "{{prox_zone.entity_id}}"
- alias: Attendre si hors zone
if:
- alias: La CIBLE est à plus de xx mètres de la zone
condition: template
value_template: >-
{% if prox_zone is defined and prox_distance is defined %}
{{ (distance( prox_zone, person_tmp ) * 1000) | int >
prox_distance | float(0) }} {% endif %}
then:
- alias: Attendre arrivée dans la zone de surveillance
wait_for_trigger:
- alias: Lorsque CIBLE est à moins de xx mètres de la zone
platform: template
value_template: >-
{{ (distance( prox_zone, person_tmp ) * 1000) | int <
prox_distance | float(0) }}
continue_on_timeout: false
timeout:
hours: 18
minutes: 0
seconds: 0
milliseconds: 0
- alias: Identification de l'appareil mobile à notifier
variables:
device_name: >
{{ expand(person_tmp) | map(attribute='attributes.source') |
list | join | replace('device_tracker.', '') }}
- alias: Notification si l'appareil mobile est connu
if:
- alias: L'appareil mobile est trouvé
condition: template
value_template: "{{ device_name != '' }}"
then:
- alias: Envoie une notification ciblé
service: notify.mobile_app_s23_de_joel
data:
title: "{{titre}}"
message: >-
{% from 'msg_proximity.jinja' import msg_content %}
{{ msg_content(prox_zone, person_tmp, device_name,
message) }}
data:
persistent: "{{persistant}}"
sticky: "{{affichage}}"
notification_icon: "{{icone}}"
icon_url: "{{illustration}}"
color: "{{couleur}}"
clickAction: "{{click}}"
subject: "{{resume}}"
tag: "{{tag}}"
fields:
description:
selector:
text:
multiline: true
name: Description
default: |-
- tester avec une cible sans gps
- Notification SANS TAG pendant le DEV
description: >-
Retient les notifications jusqu'à retour en zone de la personne ou de
l'appareil mobile
cible:
name: Cible
description: >-
Quelles personnes ou appareils notifier ? Vide envoie une notification
persistante dans HA
selector:
target: {}
required: false
default:
entity_id:
- person.joel
- person.nina
prox_zone:
selector:
target: {}
name: Zone
default:
entity_id: zone.home
description: Si vide, pas de détection retour zone
prox_distance:
selector:
number:
min: 1
max: 10000
step: 10
name: Distance
default: 200
description: Si vide, pas de détection retour zone
message:
selector:
template: {}
name: Message
required: true
description: Possible d'utiliser du HTML
titre:
selector:
text: null
name: Titre
default: Titre facultatif
tag:
selector:
text: null
name: Tag
description: Pour remplacer une notification du même tag
icone:
selector:
icon: {}
name: Icône
couleur:
selector:
text: {}
name: Couleur
description: Couleur de fond de l'icône
illustration:
selector:
text: null
name: Illustration
description: Illustration placée à droite de la notification
resume:
selector:
text: null
name: Résumé
description: Texte court affiché quand la notification n'est pas déroulée
affichage:
selector:
boolean: {}
name: Affichage
description: Rester affiché après ouverture de la notification
persistant:
selector:
boolean: {}
name: Persistant
description: >-
Force l'affichage, doit être effacer par une autre notification. Ne
fonctionne plus depuis Android 14 et doit être renvoyé par "swipe
notification"
click:
selector:
text: null
name: Click
description: Action suite au clic
log:
selector:
boolean: {}
name: log
description: Ajouter une notification persistante dans HA
mode: parallel
icon: mdi:bell-badge
max: 100