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

J’ai déjà fais la conception donc le plus dur est déjà fait !

https://twitter.com/gladysproject/status/962603559555649536

Complètement, comme dit @jibaku, c’est beaucoup plus light qu’en HTTP, ça va très très vite

Et surtout c’est bi-directionnel

Ca me semble important comme truc pour assurer une stabilité de Gladys et faire en sorte d’avoir des modules tous développés de la même manière. J’espère que c’est tout en haut de ta to do list… :wink:

@Hamtaro : si j’ai déjà fais la conception + une partie de l’implementation, c’est que ça l’est ! :wink:

1 « J'aime »

@MathieuA : En plein boulot sur le MQTT je me posais justement la question du module Z-wave. Si jamais on décide de déporter le module Z-wave hors de Gladys à l’avenir, comment on ferait si on veut avoir des vues customs pour ce module ? Pour ça que je voulais bosser sur le MQTT avant, pour avoir une vision là dessus aussi ^^

J’ai du mal à voir comment ça pourrait se goupiller tout ça… soit on standardise pour que tout passe par MQTT ( comme je fais actuellement pour tous les modules ), mais ça ça veut dire pas de vue custom

Soit pour la vue custom on a pas trop le choix de mettre un frontend custom dans Gladys à un moment ou un autre (je me vois mal envoyer le HTML via MQTT au démarrage du module… quoique :stuck_out_tongue: )

Bref, si quelqu’un a une idée là dessus ^^

Pourquoi forcément passer par Gladys ?
Si le module est déporté il peux aussi très bien fonctionner comme un mini serveur qui affiche sa propre page web non ?
A ce moment là Gladys envoi l’ordre de démarrer le mini serveur de config et redirige l’utilisateur vers cette page la (ça peux même ce faire avec un iframe )

Une fois la config terminé Gladys envoi l’ordre de tuer le serveur. :slight_smile:

Oulà le problème c’est que là on apporte énormément de complexité à un module qui devait être simplifié justement :smiley:

Qui dit page web dit :

  • Internationalisation
  • SSL et compagnie (proxy nginx)

C’est justement ce qu’on veut éviter, l’objectif c’est que Gladys centralise la vue, et que les modules ne soient que des petits drivers distants !

Et surtout ça serait top que la communication Gladys <-> module distant soit 100% en MQTT

Car l’objectif de ces modules c’est d’avoir justement des petits modules distants qui ne sont pas exposés à internet ni accessible en HTTP

La seule solution que je vois c’est la standardisation…

Exemple: Le module Z-wave déclare qu’il a 12 fonctions via MQTT, et Gladys créé une page de configuration custom avec ces 12 boutons, mais bon c’est pas hyper sexy on pourra pas s’amuser avec la vue

Ah bah la tu rajoute énormément de contraintes techniques :stuck_out_tongue:

Dans ce cas là je vois que deux possibilités !

  1. Soit tu envoi l’HTML complet avec le controller et les commandes qui vont avec
  2. Soit il faut créer une vue générique auquel chaque développeur devra s’adapter et selon les données envoyée par le module, Gladys construis la vue, mais bon ça risque d’être compliqué pour gèrer tout les cas et même pour le côté développement du module…

Il y aurait bien une troisième méthode mais je doute que ça soit la meilleur :thinking:

Je te la donne quand même au cas où elle t’inspire →

Les modules se compose en deux partie

  1. La première est la partie générale, la partie driver qui s’installe sur n’importe quel périphérique
  2. Et le seconde est la partie config qui elle s’installe du côté Gladys avec juste les assets et la vue custom qui utilise l’API MQTT de Gladys pour communiquer avec son maître

Évidement c’est à Gladys de faire la différence lors de l’installation du module. Grâce à une certaine hiérarchisation par exemple…

Mm j’avais les mêmes 3 idées en tête ^^

Je pense que pour l’instant on va choisir la solution 4 : Garder le module Z-Wave en interne pour l’instant :smiley:

Sinon des trois, la solution la plus crédible pour moi c’est la dernière! C’est la plus cohérente, parce que du coup ça veut dire que le développeur du module contrôle la vue + le driver distant, et c’est pas forcément beaucoup plus de dev. A investiguer :slight_smile:

1 « J'aime »

Si on garde le module Zwave en interne ma vue custom ne fonciotnnera pas :joy:

Hein ? ^^ Ta vue custom on va l’intégrer dans le module hein !

Bah oui mais pour ça il faut que le module puisse charger ses assets donc a moins que t’ai un truc dans les cartons en attendant la partie MQTT ses assets ne seront pas chargés ^^

Ah oui oui mais ça c’est prévu !

1 « J'aime »

Yo guys ! Je sors un premier draft du module gladys-mqtt-adapter (pas encore de code dispo, juste de la spec), c’est une dépendance NPM qui permettra de créer très facilement des modules Gladys remote, juste à ajouter la dépendance et à suivre les instructions :slight_smile:

J’ai publié ça sur GitHub, pour ceux que ça intéresse =>

2 « J'aime »

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:

5 « J'aime »

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:)

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!

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 !

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 !

1 « J'aime »

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!

6 « J'aime »