Salut,
J’ai galéré comme un chien (ou un rat, ou les deux) pendant une journée pour réussir à passer une valeur amenée à changer (hum, une variable donc) depuis Home Assistant vers un petit contrôleur ESP-32, géré par ESPHOME. Donc si ça peut aider, voici mon code et quelques commentaires, mais d’abord le contexte.
Je prépare une centrale d’alarme + ouverture de porte, hébergée sur cet ESP-32, lequel sera installé tout près de la porte pour permettre des capteurs et actions filaires (ce sera un Olimex connecté en RJ-45 Ethernet, et il est doté d’une prise pour batterie LIPO).
Dans ce cadre, on a vite besoin d’indicateurs qui témoignent du statut de l’alarme (armée, en cours d’armement/désarmement, désarmée), pareil pour la porte (locked ou pas, commande reçue par HA mais en chemin Bluetooth pendant 2 ans), etc. Et on a besoin surtout que ça se remarque en un clin d’oeil. Pour ça, il me faut quelques leds de couleur, et on arrive au problème : je souhaite pouvoir décider du tempo de clignotement depuis Home Assistant (depuis Node Red, en fait).
Bien sûr, je pourrais créer autant d’entités dans ESPHOME que je souhaite de clignotements différents, mais c’est pas très propre, et surtout, si je souhaite un nouveau genre de clignotement, je dois reflasher l’ESP-32.
J’ai d’abord cru que passer une bête variable serait facile… mais non, vraiment pas (en tout cas pour moi).
Dans le code qui suit, je crée dans HA puis dans ESPHOME les deux variables souhaitées, à savoir BLINKON
(durée de LED allumée) et BLINKOFF
(durée de LED éteinte, vous avez compris).
Je sépare ces deux variables pour avoir la main sur des durées différentes en ON et OFF. Ce n’est pas indispensable, mais je trouve très élégant d’avoir des LEDs qui par exemple sont majoritairement éteintes, et clignotent juste très brièvement toutes les 5 secondes, par exemple (ça décrit intuitivement très bien l’état d’un appareil où tout va bien).
Je souhaite 3 LEDs (vert, jaune, rouge), clignotantes ou fixes, au choix. Les LEDs fixes sont de simples switch:
Enfin, le troisième point concerne le node « Call Service » de Nodered.
Bon, je ne suis vraiment pas développeur, j’ai juste chiné des petits bouts sur Internet, donc c’est sûrement améliorable. N’hésitez pas à proposer des choses.
1. Dans configuration.yaml de Home Assistant
Dans HA, les variables sont nommées input_number
et doivent être déclarées dans la configuration :
input_number:
blinkon:
name: blinkon
initial: 250
min: 50
max: 10000
step: 1
blinkoff:
name: blinkoff
initial: 250
min: 50
max: 10000
step: 1
Il faut redémarrer HA pour que ce soit pris en compte.
2. Dans ESPHOME
esphome:
name: node-mcu
esp8266:
board: esp01_1m
# Enable logging
logger:
level: debug
# Enable Home Assistant API
api:
encryption:
key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=" #très longue suite de nombres et chiffres, générée par ESPHOME à la création du device. On en a besoin lorsque HA repère et intègre l'appareil.
ota:
password: "aaaaaaaaaaaaaaaaaaaaaaaaaaa" #généré automatiquement aussi
#paramétrage du WIFI. Plus tard dans mon cas, ce sera Ethernet. On ne peut pas utiliser les deux en même temps.
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Node-Mcu Fallback Hotspot"
password: "aaaaaaaaaaaaa" #généré automatiquement
# Optional manual IP - pas indispensable, mais prudent
manual_ip:
static_ip: 192.168.0.55
gateway: 192.168.0.1
subnet: 255.255.255.0
captive_portal:
#création des variables de durée pour les blinks. C'est la variable qui sera utilisée dans le paramètre DELAY plus bas.
globals:
- id: blinkon_interval
type: int
restore_value: no #pas besoin de conserver cette valeur puisque c'est Nodered qui l'envoie à chaque clignotement demandé.
initial_value: '250' #on pourrait s'en passer aussi, mais j'ai toujours peur de plantages éventuels si on ne met pas au moins une valeur dedans
- id: blinkoff_interval
type: int
restore_value: no
initial_value: '250'
#passage d'une variable HA vers une variable EH
sensor:
- platform: homeassistant
id: blinkon_from_ha
entity_id: input_number.blinkon
# blinkon_from_ha n'est donc pas une variable, mais un capteur virtuel, qu'il va falloir transformer en variable. C'est la fonction des lignes qui suivent :
on_value:
then:
- globals.set:
id: blinkon_interval
value: !lambda 'return int(x);'
# Voilà, on a maintenant placé la valeur du capteur dans la variable qu'on va utiliser pour DELAY. On recommence l'opération pour Blinkoff :
- platform: homeassistant
id: blinkoff_from_ha
entity_id: input_number.blinkoff
on_value:
then:
- globals.set:
id: blinkoff_interval
value: !lambda 'return int(x);'
##################################
# Création de 3 simples switches #
##################################
switch:
- platform: gpio
pin: 16 # bien entendu, modifier en fonction du contrôleur
name: "Vert"
icon: mdi:AlarmLightOutline # ceci ne marche pas encore chez moi, mais je le laisse juste pour qu'on voie qu'on peut aussi paramétrer l'icone ici.
- platform: gpio
pin: 5
name: "Jaune"
icon: mdi:AlarmLightOutline
- platform: gpio
pin: 4
name: "Rouge"
icon: mdi:AlarmLightOutline
##################################
# Création du Blink vert # Le coeur de l'histoire est ici.
##################################
# Juste remarquer ici qu'il s'agit d'un Switch supplémentaire, et qu'il faut faire attention à l'indentation qui doit être alignée sur les autres switches ci-dessus.
- platform: gpio
pin: 16 # même pin que pour les LEDs fixes. Ca me paraît évident maintenant, mais pas quand j'ai cherché !
id: greenblink
icon: mdi:AlarmLightOutline
# Voici maintenant l'automation (template) qui permet de faire clignoter une LED.
- platform: template
name: "Blinking LED Green"
optimistic: yes
id: blinkgreenledtemplate
turn_on_action:
- while:
condition:
lambda: 'return true;'
then:
- switch.turn_on: greenblink
- delay: !lambda "return id(blinkon_interval);" # Et voilà PAF ! on fait appel à la variable déclarée au début et modifiée par le Sensor actionné par Node Red. Faites bien gaffe à la syntaxe. Ca m'a pris 3h d'essais erreurs en lisant les Logs de l'ESP32 que j'avais passés en "Verbose". "Low code" qu'ils disaient...
- switch.turn_off: greenblink
- delay: !lambda "return id(blinkoff_interval);"
turn_off_action:
- switch.turn_off: greenblink
###########################
# Création du Blink jaune #
###########################
- platform: gpio
pin: 5
id: yellowblink
icon: mdi:AlarmLightOutline
- platform: template
name: "Blinking LED Yellow"
optimistic: yes
id: blinkyellowledtemplate
turn_on_action:
- while:
condition:
lambda: 'return true;'
then:
- switch.turn_on: yellowblink
- delay: !lambda 'return id(blinkon_interval);'
- switch.turn_off: yellowblink
- delay: !lambda 'return id(blinkoff_interval);'
turn_off_action:
- switch.turn_off: yellowblink
###########################
# Création du Blink rouge #
###########################
- platform: gpio
pin: 4
id: redblink
icon: mdi:AlarmLightOutline
- platform: template
name: "Blinking LED Red"
optimistic: yes
id: blinkredledtemplate
turn_on_action:
- while:
condition:
lambda: 'return true;'
then:
- switch.turn_on: redblink
- delay: !lambda 'return id(blinkon_interval);'
- switch.turn_off: redblink
- delay: !lambda 'return id(blinkoff_interval);'
turn_off_action:
- switch.turn_off: redblink
3. Dans NODERED
Le seule chose à comprendre ici est qu’il faut utiliser un node « Call Service », avec ces paramètres :
Pour l’instant, j’utilise un node séparé pour la commande de « Blink » proprement dite, mais j’imagine qu’on doit pouvoir réunir les deux instructions sous un même node.
Si vous avez des suggestions, je suis preneur
Michel