[NEWS] Multi-instances & prochaine génération de modules Gladys!


#41

Salut à tous!

Après un week-end complet à bosser sur le MQTT dans Gladys, je suis heureux de vous présenter mon travail afin d’avoir vos retours :slight_smile: Rien n’est encore définitif, ni publié en prod, tout est sur Github.

1. Le concept

Pour rappel, le concept c’est au lieu d’avoir un module installé localement sur Gladys, il sera possible à l’avenir d’avoir des modules détachés de Gladys, des petits programmes qui font leur vie tout seul, et qui communique avec Gladys via un broker MQTT.

Un broker MQTT, c’est quoi ? C’est un bus d’événement où il y a des “publishers” et des “subscribers”. Les publishers publient des événements (ou jobs) dans une queue, et le ou les “listeners” récupèrent ces événements. Cela permet d’avoir une communication dans les deux sens entre Gladys et les modules.

Voilà un petit dessin de l’architecture que je veux mettre en place :

( Bon moi et le dessin c’est pas ça :stuck_out_tongue: )

Le principe, c’est qu’un module peut tourner sur Raspberry Pi déporté, et communiquer avec Gladys quasiment aussi bien que lorsqu’il tournait dans Gladys.

2. Le développement

J’ai donc développé dans 3 repos différents ce week-end:

  • Dans Gladys
  • Dans le module gladys-mqtt ( c’est qui qui va s’occuper en interne de faire la communication entre Gladys et les modules distants )
  • Un nouveau module NPM, le gladys-mqtt-adapter, qui lui va permettre à des modules de devenir compatible MQTT en quelques lignes de codes

3. Les topics

D’un côté, nous avons des topics MQTT dédiés à l’instance “master” de Gladys, qui permettent à tous ces modules de communiquer avec Gladys directement.

Les topics côté master sont les suivants :

  • “gladys/master/heartbeat” : Pour signaler au maitre que le Raspberry Pi distant tourne toujours.
  • “gladys/master/module/heartbeat” : Pour signaler au maitre que le module distant tourne toujours
  • “gladys/master/machine/create” : Pour déclarer un nouveau Raspberry Pi distant via MQTT
  • “gladys/master/event/create”: Pour créer un événement
  • “gladys/master/device/create”: Pour créer un device
  • “gladys/master/devicestate/create”: Pour créer un deviceState
  • “gladys/master/notification/install”: Pour déclarer un nouveau type de notification

Côté module:

Déjà, côté module, les topics sont un peu différents car ils sont préfixés par : gladys/machine/MACHINE_ID/module/MODULE_SLUG/

Afin que chaque module puisse avoir ses queues à lui, et pas se prendre les pinceaux avec les queues des voisins :slight_smile:

Voilà les topics disponibles pour l’instant :

  • “gladys/machine/MACHINE_ID/module/MODULE_SLUG/devicetype/exec” : Quand Gladys veut modifier un deviceType distant (allumer une ampoule, etc…)
  • “gladys/machine/MACHINE_ID/module/MODULE_SLUG/notify” : Quand Gladys veut notifier (parler par exemple) via un module distant
  • “gladys/machine/MACHINE_ID/module/install” : Demande au manager de modules d’installer un nouveau module à distance (pas encore disponible en réalité, j’ai pas encore codé le manager :stuck_out_tongue: )
  • “gladys/machine/MACHINE_ID/module/uninstall” : Demande au manager de désinstaller un module à distance (idem)
  • “gladys/machine/MACHINE_ID/module/upgrade”: Demande au manager de mettre à jour un module (idem)

4. En pratique

En pratique, rassurez vous, vous n’avez rien à savoir de tout ça ! Tout est cablé tout seul :stuck_out_tongue:

J’ai par exemple adapté le module “speak”. Voilà son nouveau fichier index-mqtt.js :

var say = require('./lib/say');

var gladysMqttAdapter = require('gladys-mqtt-adapter')({
    MACHINE_ID: process.argv[2],
    MQTT_URL: process.argv[3],
    MQTT_USERNAME: process.argv[4],
    MQTT_PASSWORD: process.argv[5],
    MODULE_SLUG: process.argv[6] 
});

// we create the notification type on the DB side if it does not exist
gladysMqttAdapter.on('connect', function(){
    gladysMqttAdapter.notification.install({service: 'speak', name: 'Speak'});
});

gladysMqttAdapter.on('message-notify', function(data){
    if(data.message) {
        say({
            text: data.message.text,
            language: data.user.language
        });
    } else if(data.notification) {
        say({
            text: data.notification.text,
            language: data.user.language
        });
    }
});

Code disponible sur GitHub

Super simple non ? :stuck_out_tongue:

La mécanique de publication dans des topics MQTT/listen dans d’autres topics, les heartbeats, etc, est 100% géré par le module gladys-mqtt-adapter, donc il y a rien à faire !

Petite remarque : J’ai volontairement créé un fichier index-mqtt.js au lieu de modifier le fichier index.js directement. L’objectif est de pouvoir avoir des modules capable de s’exécuter aussi bien dans le core de Gladys que à distance, afin de pouvoir répondre aux besoins de chacun :slight_smile:

5. Références

6. La suite

Mon objectif maintenant, c’est d’avoir vos retours, c’est de tester de rendre certains modules “compatible MQTT”, et de voir ce que ça donne! Une fois que ça sera moins un POC et qu’on sera sûr que c’est bon pour partir en prod, je ferais une release qui intègrera tout ça :rocket:

Un peu de rêve: L’objectif ultime de tout ça, c’est de permettre par exemple d’avoir des petits Raspberry Pi Zero partout dans la maison qui sont comme des Amazon Echo Dot, on leur pose une question, et Gladys répond dans la bonne pièce de la maison. Ils peuvent contrôler les périphériques autour d’eux, sans forcément faire tourner un Gladys complet. Bref: un Gladys multi instances distribués !

J’espère que ce mini article vous aura plu, j’ai hâte d’entendre vos retours :slight_smile:


#42

C’est pas mal ! T’as bien bossé !

Mais juste une question… tu dis

D’accord mais dans le cas par exemple ou j’ai speak installé en interne sur le maître et un autre speak installé en externe sur un esclave, comment Gladys fait la différence si tu crée le même type de notification ?

Je t’avoue que le fonctionnement reste encore un peu flou pour moi mais je comprendrais mieux en fouillant le code et en pratique. (j’aime pas la théorie c’est jamais la realité :stuck_out_tongue:)


#43

Bonne question, alors concrètement ce n’est pas possible, si tu installes le module “speak” en externe, tu ne l’installe pas en interne :stuck_out_tongue:

En revanche tu peux avoir le module installé plusieurs fois en externe ! :slight_smile: Et là c’est dans Gladys que Gladys fera le choix sur quelle “machine” elle veut te notifier (c’est pas encore codé ça par contre, mais c’est pas un gros bout)

Test un coup, c’est vraiment pas dur!


#44

Justement c’est ça que je veux savoir ! Comment tu fait ça ? Tu va au plus pertinent ? L’utilisateur devra définir une préférence ?
Parce que si par exemple l’utilisateur pose une question a un esclave évidemment Gladys répondra directement à l’esclave étant donné que c’est lui qui a lancé la requête, mais si Gladys veux simplement notifier quelque chose sans qu’on ne lui ai rien demandé comme par exemple via un scénario ?

J’ai pleins de choses à faire avant, notamment comprendre pourquoi mon module MQTT ne fonctionne pas :rofl:
Pour le moment je suis à fond sur mon install pour que tout soit près pour le week-end prochain mais après je repars à fond sur Gladys et je testerais tout ça !


#45

Pour l’instant j’ai juste pensé à ça :stuck_out_tongue: Mais c’est pas bête le point que tu soulève! J’ai pas de réponses pour l’instant.

ça pourrait être dans l’ordre de préférence des notifications, on pourrait avoir une liste comprenant le duo “type de module + machine”, pour pouvoir ordonner les notifications genre :

  1. Parle dans la chambre
  2. Parle dans le salon
  3. Texto

Etc…

Après je sais pas si c’est pertinent, j’avoue que j’ai pas de solutions là ! A réfléchir!

aha ça marche, c’est le plus important oui !


#46

bonjour,
et encore une fonctionnalité qui va être au top :+1:

Après je donne peut être une idée (en tout cas elle fonctionne sans problème chez moi :slight_smile: ) je joue dernièrement sur les fonctions vocales et donc ajoute pas mal de commandes vocales sur les différents modules.

J’ai le module Voice sur plusieurs raspberry et équipé de HP plus un micro à chaque fois.
Pour pallier au problème de recevoir dans la pièce où je parle à Gladys, j’ai donc dupliqué les 2 fichiers dans le brain ‘brain.answer_muet.js’ et ‘brain.classify_muet.js’ qui me permettent que de retourner les réponses possibles sans parler en local.

donc à chaque module Voice je défini donc s’il faut parler sur Gladys ou en local, mais j’y ai ajouter les fonctions du module Speak pour pouvoir donc parler en local étant donné que le module Voice reçoit les réponses possibles.

donc en fonction de ma sélection dans le fichier config, je vais appeler la fonction ‘brain.classify_muet’ ou ‘brain.classify’.

je sais pas si c’est la meilleur des solutions, mais elle à le mérite d’être fonctionnel sans trop modifier l’architecture.

pourquoi pas apporter le même fonctionnement avec le module MQTT ?


#47

Bonjour,

j’ai voulue installer speak, mais après l’installation gladys ce plante a cause de cett erreur : /index-mqtt.js.

Comment faire ?


#48

Ben moi, je felicite le travail que tu as fais, @pierre-gilles, même si je ne comprends rien à tout ça ! Le pire, c’est que je ne sais même pas par où commencer pour déchiffrer ce que vous avez échangé !
(D’ailleurs, si vous vez des pistes, je prends !)
Bref, juste des félicitations et remerciements pour le travail fait, certainement au détriment d’une vie personnel …


#49

Merci pour ton retour super positif @Jap93 ! :slight_smile:

Alors le problème des multiple Gladys-voice on l’a pas vraiment, ce qui va être fait c’est juste que Gladys voice va indiquer sur quelle machine la question a été posée, et ensuite Gladys répondra sur la même machine (facile!)

Le problème qu’à soulevé @MathieuA, c’est plus au niveau des scénarios. Si tu dis dans un scénario “Notifie moi”, on sait pas vraiment où parler dans la maison. Si gladys veut s’adresser à toi à un moment précis, elle sait pas forcément ou tu es dans la maison… Donc soit :

  • On parle partout
  • On définit une instance plus importante que les autres, mais bon j’aime pas trop ça

Hello ! Merci pour ton message, j’ai effectivement été un peu vite j’avais pas testé comment réagirait Gladys si on installait le module en local maintenant qu’on peut aussi l’installer à distance ^^ J’aurais appris quelque chose, je ne savais pas que sails.js loadait absolument tous les fichiers à la racine du module… je me coucherais moins bête.

J’ai corrigé le problème, ça ne devrait plus crasher

Merci @piznel ! :slight_smile: Alors je te conseille de regarder comment j’ai modifié le module speak par exemple (t’as juste le fichier “index-mqtt.js” à lire)

Et si tu es chaud de mettre en place un broker MQTT, et de brancher le module pour voir comment ça fonctionne

Après c’est très technique, et c’est clairement pas encore prêt pour de l’usage réel

Merci encore ! Pour la vie personnelle tu me coupes l’herbe sous le pied, j’ai une très good news qui arrive pour le projet, j’en parle dans les semaines qui suivent… :wink: #teasing J’en dis pas plus!