2018-01-10
Mise à jour 2018-01-17
Voice Recognition on the Orange Pi Zero (DietPi Armbian)

Profitant des soldes de Noël, j'ai acheté un Google Home Mini pour fins d'expérimentation et d'inspiration. Entre autre je voulais qu'il prenne en charge localement mes commutateurs Wi-Fi Sonoff. Des articles sur le Web et des communications dans les forums laissaient miroiter cette possibilité en vertu de l'émulation Hue de Philips facilement activée dans le micrologiciel Tasmota de Theo Arends. Malheureusement Google (ou faut-il dire Alphabet ?) a éliminé cette fonctionnalité du Home Mini.

Il est encore possible d'utiliser le Home Mini comme interface vocale pour commander des dispositifs de domotique si ceux-ci peuvent être contrôlés avec des requêtes HTML grâce au service Web IFTTT. Ce service gratuit fait la jonction entre différents autres services Web. Ainsi il devient possible de faire parvenir à mon logiciel de domotique des requêtes HTML correctement formatées pour activer les dispositifs domotiques à partir de commandes vocales correctement dictées. Dans ce qui suit, j'explique comment j'ai fait en utilisant Domoticz mais les principes s'appliquent à tout autre logiciel de domotique.

Table des matières

  1. Les principes du fonctionnement de IFTTT
  2. HTTPS, TLS/SSL et Domoticz
  3. Création d'un nom de domaine dynamique
  4. Mise à jour de l'adresse IP de destination
  5. Réacheminement de ports TCP
  6. Test et sécurité
  7. Création d'applets IFTTT
  8. Constatations

  1. Les principes du fonctionnement de IFTTT
  2. IFTTT (IF This Then That) est un service web gratuit utilisé pour provoquer une action (then that) à la suite d'un événement déclencheur (if this). Parmi la liste des très nombreux déclencheurs possibles, on retrouve Google Assistant. Et parmi les actions possibles, on peut envoyer une requête HTML avec WebHooks.

    Alors le principe est simple.

    Pour ce qui est de Domoticiz, l'URL de cette requête ressemblera à quelque chose comme

    https://utilisateur:mot-de-passe@adresse-de-domoticz:443/json.htm?type=command&param=udevice&idx=37&nvalue=1

    Évidemment pour que cela fonctionne, il faudrait que le serveur de IFTTT qui est quelque part aux États-Unis ou peut-être au Canada puisse communiquer avec le Raspberry Pi qui est l'hôte du serveur Domoticz sur le réseau local. J'ai pris la peine de donner une adresse IP fixe à l'interface WiFi de mon Raspberry Pi, 192.168.1.22, pour facilement retrouver le serveur domotique sur le réseau local. Mais adresse n'est pas visible à l'extérieur du réseau local. En effet, tous les ordinateurs et autres dispositifs branchés sur le réseau local qui communiquent avec des sites sur l'Internet passent par une seule adresse IP qui est fournie par mon fournisseur d'accès à Internet (FAI).

    On peut facilement connaître cette adresse. Plusieurs sites, dont What Is My IP Address et mon-ip.com l'affiche. Malheureusement, on ne peut pas se fier à cette adresse, car elle est affectée de façon dynamique par le FAI et peut changer de temps en temps. En réalité, elle me semble particulièrement stable dans mon cas et je pourrais sans doute l'utiliser pour fins de test.

    En pratique, il est préférable d'utiliser un service DNS dynamique (DDNS ou DynDNS). DNS est le système des noms de domaine. C'est le système qui transforme le nom d'un site Web tel www.google.com en une adresse IP (172.217.6.4 ou 2607:f8b0:4009:809::2004 selon qu'on désire IPv4 ou IPv6). Certains sites offrent un service, souvent gratuit, qui associe un nom de domaine à une adresse IP. Ces sites mettent à jour les adresses IP dans leur base de données à intervalles réguliers. Donc, on mettra dans la requête HTML le nom de domaine obtenu du service DNS. Le système DNS traduira ce nom en adresse IP qui sera mis à jour chaque fois que le FAI affecte une adresse IP différente au serveur de domotique.

    C'est quelque chose que j'avais déjà fait il y a quelques années vers les débuts de mon utilisation d'Active Home Pro de X10. Alors ce logiciel fonctionnait sur un très bruyant ordinateur Windows XP qui devait toujours être en marche. J'avais obtenu un DNS dynamique de no-ip si ma mémoire est juste et l'on m'avait donné un petit logiciel qui roulait en permanence sur l'ordinateur Windows pour acheminé vers no-ip tout changement de l'adresse IP donnée par mon FAI.

    Il y a une autre petite complication, mais déjà on peut voir ce qu'il faut faire.

    1. Obtenir un nom de domaine dynamique auprès d'un fournisseur, de préférence gratuitement.
    2. Installer le logiciel de mise à jour de l'adresse IP du FAI sur un ordinateur qui fonctionne en permanence sur le réseau local. Ou, si l'on est chanceux, faire l'équivalent avec le routeur obtenu du FAI.
    3. Rediriger le port TCP 443 utilisé par Domoticz vers le le Raspberry Pi. C'est la petite complication mentionnée ci-dessus.
    4. Obtenir un compte auprès de IFTTT.com.
    5. Créer des applets IFTTT, un pour activer et un second pour désactiver chaque dispositif du système domotique à contrôler avec Google Home.

  3. HTTPS, TLS/SSL et Domoticz
  4. L'utilisation du protocole HTTP sécurisé s'impose pour éviter que soient diffusés en texte clair le nom d'utilisateur et le mot de passe du serveur de domotique. C'est ce qui se produirait si l'on utilisait le protocole HTTP comme j'avais fait l'erreur de proposer dans une version antérieure de ce billet.

    Je ne m'étais jamais vraiment préoccupé de la sécurité des connexions à mon serveur de domotique auparavant. Ce dernier est branché à un réseau local qui n'était pas accessible de l'extérieur. Ainsi quand il était question d'utiliser des requêtes HTML envoyées à Domoticz j'utilisais le protocole HTTP non sécurisé vers le port TCP 8080. Il me faudra être plus attentif à la sécurité puisque le réseau local sera dorénavant accessible de l'Internet. Il devient important d'exiger un mot de passe pour tout accès aux serveurs sur le réseau local et que toute communication soit chiffrée.

    Heureusement, Domoticz est accessible avec le protocole HTTPS depuis la version 2.2563 publiée en 2015-06-14. Par défaut ces versions plus récentes du logiciel acceptent les connexions chiffrées sur le port 443, comme je le montrais dans les billets intitulés Domoticz sur un Orange Pi Zero, un aperçu / 9. Installation de Domoticz et Domoticz sur un Raspberry Pi - « Déjà Vu All Over Again » / 10. Installation de Domoticz. Cependant, il est préférable de vérifier que HTTPS est pris en charge.

    pi@domo:~ $ cat /etc/init.d/domoticz.sh #! /bin/sh ### BEGIN INIT INFO # Provides: domoticz # Required-Start: $network $remote_fs $syslog # Required-Stop: $network $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Home Automation System # Description: This daemon will start the Domoticz Home Automation System ### END INIT INFO # Do NOT "set -e" PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin DESC="Domoticz Home Automation System" NAME=domoticz USERNAME=pi PIDFILE=/var/run/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME DAEMON=/home/pi/domoticz/$NAME DAEMON_ARGS="-daemon" #DAEMON_ARGS="$DAEMON_ARGS -daemonname $NAME -pidfile $PIDFILE" DAEMON_ARGS="$DAEMON_ARGS -www 8080" DAEMON_ARGS="$DAEMON_ARGS -sslwww 443" #DAEMON_ARGS="$DAEMON_ARGS -log /tmp/domoticz.txt" #DAEMON_ARGS="$DAEMON_ARGS -syslog" ...

    Si on a -sslwww 0 alors HTPPS n'est pas activé. Alors il faut éditer le fichier en tant que l'utilisateur root.

    pi@domo:~ $ sudo nano /etc/init.d/domoticz.sh

    Il faut arrêter puis repartir Domoticz pour que toute modification prenne effet.

  5. Création d'un nom de domaine dynamique
  6. Je suis parmi les chanceux qui ont reçu un routeur de leur FAI qui prend en charge la mise à jour d'un service de nom de domaine dynamique. Conséquemment, j'ai choisi freedns.afraid.org comme fournisseur parmi ceux pris en charge par le routeur (CGN3ACSMR Cable Modem de Hitron). no-ip était une autre possibilité qui semble tout aussi simple à utiliser.

    Voici les étapes à suivre pour créer un nom de domaine dynamique chez FreeDNS.

    1. Aller sur le site de freedns.afraid.org/ Je recommande de lire les pages pour tous (For Everybody) en particulier la FAQ. Puis cliquer sur [ Dynamic DNS ] dans le menu pour les membres (For Members:) puis cliquer sur le lien pour créer un compte (Setup an account here).

      Ou cliquer ici.

    2. Sélectionner le forfait gratuit nommé Starter

    3. Créer un compte en fournissant l'information demandée : prénom (First Name), nom (Last Name), un nom d'utilisateur (UserID, dont on ne se servira pas, semble-t-il), un mot de passe (Password) qu'il faut confirmer dans le champ suivant et une adresse de courriel qui doit être valide.
    4. Ensuite il faut deviner exactement quelles lettres sont affichées (je pense qu'elles sont toujours des majuscules) puis il faut cocher qu'on est d'accord avec les conditions d'utilisation du site.

      Cliquer sur le bouton Send activation email pour qu'un message d'activation vous soit expédié à l'adresse de courriel fournie plus haut.

    5. Il faut maintenant attendre de recevoir le message de FreeDNS. Quand celui-ci arrive, cliquer le lien d'activation qu'il contient.

      Je ne me souviens plus très bien ce qui se produit alors. Fort probablement, que vous serez redirigé dans le nouveau compte. Sinon, il suffit de cliquer sur un choix pour membre pour ouvrir le compte nouvellement créé.

    6. Aller dans le menu [ Subdomains ] et cliquer sur un des liens pour ajouter un sous domaine (Add) ou cliquer directementici.

    7. a
    8. Dans ce formulaire, il faut spécifier le sous-domaine et puis sélectionner le domaine qui formeront l'adresse Web de l'ordinateur qui accueille le serveur de domotique. Dans mon exemple, j'ai entré modomo comme sous-domaine et j'ai choisi twilightparadox.com.

      Cela veut dire que l'URL du serveur Web de Domoticz sera modomo.twilightparadox.com. Tant qu'il n'y a pas de changement, le système de noms de domaine traduira ce nom en l'adresse IP affichée dans le champ Destination. Inutile de changer ce champ. Quant aux autres champs, ils ne sont d'intérêt que pour les comptes payants.

      Lisez la réponse à la question 13 de la FAQ pour ce qui est du choix d'un domaine. Vous verrez qu'il est préférable de choisir parmi les noms affichés dans la liste déroulante.

      Il faut que la combinaison <Subdomain>.<Domain> constitue un nom unique dans l'Internet. L'unicité du domaine est assurée, mais twilightparadox.com, qui est le plus petit des domaines publics du site, contient déjà près de 22 000 sous domaines. Un peu d'imagination sera peut-être de rigueur dans le choix du nom du sous-domaine.

      Entrer les lettres affichées dans le dernier champ et appuyez sur le bouton pour sauvegarder (Save!) l'entrée que vous avez créé.

    9. Il faut maintenant récupérer la clé nécessaire pour mettre à jour l'adresse IP associée au nom de domaine créé à l'étape précédente. Si nécessaire cliquer sur [ Dynamic DNS ] dans le menu gauche pour voir la liste des entrées crées.

      Copier l'adresse du lien Direct URL pour obtenir quelque chose comme
      http://freedns.afraid.org/dynamic/update.php?abcVNIH3VWWbH7XM234EmY3jNFDQabm92xy8.
      La clé est la partie après php?. Sauvegarder cette clé quelque part de sécuritaire.

  7. Mise à jour de l'adresse IP de destination
  8. Tel que mentionné, le routeur s'occupe de mettre à jour l'adresse IP auprès de FreeDNS. Il y a un onglet nommé DDNS dans les Paramètres de base où l'information nécessaire à cette opération est entrée.

    On peut voir que le fournisseur de service est FreeDNS (en fait default@freedns.afraid.org). J'ai entrer mon nom d'utilisateur et mon mot de passe du compte chez FreeDNS mais selon les instructions qu'on trouve sur le site de FreeDNS j'aurais pu mettre guest ou n'importe quoi d'autre.

    L'important est de bien spécifier le nom d'hôte qui doit être le nom de domaine et la clé séparés d'une virgule:
    modomo.twilightparadox.com,abcVNIH3VWWbH7XM234EmY3jNFDQabm92xy8

    Après j'ai cliqué sur le bouton ACTIVER pour activer le DDNS et puis j'ai appuyé sur Enregistrer les modifications. Dès lors, le routeur affiche le message [EN ATTENTE] qu'on peut voir sur la figure. Après un certain temps, ce message a été remplacé par une confirmation du succès de l'opération. Quelques secondes plus tard, ce message de confirmation disparaissait ainsi que la clé.

    Maintenant je peux avoir confiance que dès que le FAI change le IP qui m'est affecté, le routeur en informera FreeDNS. Et si je comprends le sens du dernier champ, le router enverra un message de mise à jour au moins une fois par semaine quand aucun changement du IP ne se produit.

    Si je ne pouvais déléguer cette tâche au routeur, alors j'installerais un script sur le Raspberry Pi qui accueille mon système de domotique et que cron exécuterait régulièrement. On trouve plusieurs exemples sur le site de FreeDNS.

  9. Réacheminement de port
  10. Maintenant une requête HTML peut se rendre au routeur, mais comment se rendra-t-elle au serveur Web de Domoticz sur le Raspberry Pi ? C'est le rôle du port TCP assigné à ce serveur. On sait que pour rejoindre ce serveur d'un autre ordinateur il faut utiliser comme adresse: 192.168.1.22:8080 (HTTP) ou 99.236.12.115:443 (HTTPS). Le nombre après les deux points, 8080 ou 443, identifie le port TCP c'est-à-dire le point de terminaison de la communication basé sur le protocole TCP. La requête HTML sera divisée en paquets IP dont chacun contiendra l'adresse IP et le numéro de port. Le routeur aura la responsabilité d'acheminer ces paquets vers le Raspberry Pi.

    Dans notre cas, le routeur recevra une requête HTML de IFTTT adressée à 99.236.12.115:443 et il la transmettra sur le réseau local avec l'adresse 192.168.1.22:443. Encore faut-il que le routeur soit au courant de la bonne destination locale. Cette traduction se nomme le réacheminement de ports. Les routeurs se chargent de cette fonction en ayant une table d'équivalence. Pour des raisons de sécurité, très peu des 65536 ports possibles sont réacheminés. La table de mon routeur contenait cinq règles que je ne vous montrerais pas:

    J'ai cliquer sur le bouton Ajouter une règle pour ajouter l'adresse du Raspberry Pi et le port 443 comme destination de tous les paquets IP (transmis par le protocole UDP ou TCP) qu'importe leur provenance s'ils ont comme port 443.

    Seul le port TCP utilisé pour les requêtes de type HTTP sécurisé devrait être réacheminé. Par défaut, il s'agit du port 443. On pourrait aussi réacheminer le port 8080 pour le protocole HTTP non sécurisé, mais cela est fortement déconseillé puisque les requêtes faites avec ce protocole sont transmises en texte clair et que cela exposerait le nom d'utilisateur et le mot de passe du serveur Domoticz.

    Une fois l'information complétée, il faut cliquer sur le bouton Appliquer, puis vérifier que cette nouvelle règle est dorénavant dans la table et qu'elle est activée.

    Voilà, c'est fini pour le routeur si tout est correct. Heureusement on peut facilement vérifier que c'est le cas avant de procéder à la dernière étape.

  11. Test et sécurité
  12. Pour tester ce système de conversions d'adresses, il suffit d'envoyer des requêtes HTML au nom de domaine créé ci-dessus comme le fera IFTTT plus tard.

    Avant de faire cette vérification, il convient de s'assurer qu'un minimum de sécurité est en place du côté du serveur Domoticz. Si ce n'est pas déjà fait, ajouter un identifiant et un mot de passe dans la section Sécurité

    On accède à la page Système en cliquant sur l'onglet Réglagles puis sur Paramètres dans le menu déroulant.

    Pour fins de ce billet, l'identifiant sera fifi et le mot de passe brindacier. De plus, l'index Domoticz de la lampe contrôlée avec Google Home est 17 et le domaine dynamique créé pour atteindre le serveur de domotique est modomo.twilightparadox.com. Donc la requête

    https://fifi:brindacier@modomo.twilightparadox.com:443/json.htm?type=command&param=udevice&idx=17&nvalue=1

    allume la lampe. Il suffit de changer nvalue=1 à nvalue=0 pour éteindre la lampe. On peut utiliser l'utilitaire curl pour envoyer la requête et afficher le résultat.

    michel@hp:~$ curl -k "https://fifi:brindacier@modomo.twilightparadox.com:443/json.htm?type=command&param=udevice&idx=17&nvalue=1" { "status" : "OK", "title" : "Update Device" }

    Si l'on obtient le «OK» comme affiché ci-dessus, on devrait voir que Domoticz a allumé la lampe et que le statut de la lampe virtuel dans l'interface Web du logiciel reflète cet état.

    L'option -k ou --insecure avec curl est nécessaire. En son absence on obtient le résultat suivant.

    michel@hp:~$ curl "https://fifi:brindacier@modomo.twilightparadox.com:443/json.htm?type=command&param=udevice&idx=17&nvalue=1" curl: (60) SSL certificate problem: self signed certificate More details here: https://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" ... michel@hp:~$

    Le certificat SSL utilisé par Domoticz est rejeté par curl car est autosigné. Heureusement, l'option -k n'empêche pas le chiffrement de l'échange, il ne fait que contourner la vérification du certificat.

    On devrait vérifier qu'il est maintenant impossible de contacter le serveur Domoticz avec le protocole HTPP même en ayant le bon nom d'utilisateur et le bon mot de passe.

    michel@hp:~$ curl "http://fifi:brindacier@modomo.twilightparadox.com:8080/json.htm?type=command&param=udevice&idx=17&nvalue=1" curl: (7) Failed to connect to fyniac.mooo.com port 8080: Connexion refusée

    On peut maintenant passer à la création des applets IFTTT pour permettre à Google Home de contrôler des dispositifs à l'aide de Domoticz.

  13. Création d'applets IFTTT
  14. On ne peut pas faire grand-chose sur le site IFTTT tant que l'on a pas un compte. Cette étape a été très rapide puisque j'ai procédé par l'entremise de mon compte Google (Sign in with Google) alors que j'étais déjà connecté à ce dernier. Je ne sais pas si cela facilite l'utilisation de Google Home Assistant par après.

    La programmation d'un applet IFTTT se fait avec des clics de la souris un peu comme on peut utiliser Blockly pour gérer les événements dans Domoticz. L'expliquer l'utilisation ce type de système est souvent plus compliquer que l'utilisation elle-même. Je vais essayer de montrer comment procéder en onze images, mais il me semble que si l'on sait deux choses alors on peut aller de l'avant pour créer un applet très intuitivement. Les deux choses à savoir sont

    J'ajouterai un conseil: faire le minimum, ne pas chercher à remplir tous les champs.

    Démarche pour créer un applet.

    1. Pour créer un nouvel applet, cliquer sur My Applets puis sur New Applet.

    2. Cliquer sur +this pour définir le déclencheur.

    3. Sélectionner Google Assistant comme service déclencheur en cliquant sur son carré qu'on trouve parmi la liste des tous les services déclencheurs. La façon la plus rapide de le retrouver est d'entrer le début du nom dans la boîte de recherche. En cliquant sur le carré on passe à l'étape suivante.

    4. Parmi les quatre déclencheurs associés au service Google Assistant, sélectionner le premier : Dites une phrase simple (Say a simple phrase)

    5. Il suffit maintenant d'écrire la phrase qu'on dira à Mme Google pour allumer une lampe particulière. On peut spécifier jusqu'à trois phrases. Il faut choisir ces phrases avec un peu de soin. D'une part, si l'on veut allumer plus d'une lampe, un commandement aussi vague que « allume la lampe » ne peut pas fonctionner. D'autre part, il y a déjà des phrases programmées dans Google Home pour contrôler des dispositifs commerciaux comme ceux de Philips, WeMo, Belkin etc. A titre d'exemple, l'utilisation du mot «lumière» cause des problèmes. On peut choisir la langue comme le français (French). Enfin, if faut créer le déclencher en cliquant sur le bouton Create trigger.

    6. Cliquer sur +that pour définir l'action à prendre

    7. À l'instar du choix du service déclencheur, il faut choisir le service action. Dans notre cas Webhooks.

    8. Il n'y a qu'une seule action possible avec ce service. Cliquer sur faire une requête Web (Make a web request) pour continuer.

    9. Ajouter la requête déjà testée ci-dessus. Il n'y a pas de guillemets. On peut ignorer le reste des champs. Cliquer sur Create action,

    10. Pour compléter, il faut cliquer sur le bouton Finish à l'écran suivant. Toutefois, je préfère ne pas recevoir un message à chaque utilisation de l'applet (désactiver Receive notification when this Applet runs).

    11. La création de l'applet se termine avec son affichage. Comme on peut voir, il est activé (On). On peut le désactiver sans l'éliminer. On peut aussi modifier l'applet, maintenant ou ultérieurement, en cliquant sur la roue dentée en haut à droite de l'applet.

    On vérifie cette dernière étape en éveillant Mme Google et en prononçant la phrase magique: «OK Google, allume la lampe". Si ça fonctionne, il faut créer un autre applet pour éteindre la lampe. On aura qu'à refaire toutes ces étapes en utilisant une phrase différente pour déclencher l'action et en changeant le «1» à «0» à la fin de l'URL de requête.

    Certains se plaignent du temps qui s'écoule avant que la lumière s'allume ou s'éteigne après une commande vocale. En ce qui me concerne, le délai est tout à fait acceptable. D'ailleurs il se pourrait que ce soit la combinaison Domoticz sur un Raspberry Pi B+ qui soit la cause principale des retards d'exécution. Je pourrai mieux juger en attelant le Raspberry Pi 3 à cette tâche de nouveau.

  15. Constatations
  16. Je suis plutôt rétif par rapport aux modes, mais force est de constater que cette fois je fais partie du troupeau. Toutefois, je ne suis pas certain de continuer d'utiliser le Google Home Mini pour contrôler mon système domotique. Je n'aime pas exposer mon réseau local à l'Internet. Surtout que dernièrement, Google m'avisait qu'à quatre mille kilomètres d'ici on a essayé d'entrer dans un compte de courriel que j'utilise pour la domotique, et ce avec le bon mot de passe!

    Les modifications de Google à ses logiciels privilégient les approches infonuagiques c'est-à-dire les solutions commerciales au détriment des bricoleurs. D'ailleurs, pourquoi Alphabet réduirait-il le marché de Samsung ou Leviton pour des ponts vers leur matériel connecté alors qu'il n'offre pas encore de produits concurrentiels ? Donc je n'ai aucun espoir que Google Home revienne en arrière pour prendre en charge du matériel domotique localement.

    Actuellement, il est encore possible d'utiliser la reconnaissance vocale comme interface à mon système de domotique sans exposer mon réseau local à l'Internet. Puisque je ne peux programmer le Google Home Mini, cela se fait avec un autre ordinateur du réseau local qui utilise un moteur de reconnaissance vocale externe. Ce sera le sujet d'un prochain billet.