[MQTT] Comment fonctionne le module mqtt?

Ok cool, les miens sont flashés.

C’est cool les petites surprises qui arrivent comme ça quand Gladys se met à jour :wink:
je n’ai pas de module sonoff à la maison mais ca fait plaisir quand même de voir de nouveaux modules arrivés ^^

1 « J'aime »

Salut @New,
tout d’abord, voici le lien de la document Gladys : A privacy-first, open-source home assistant | Gladys Assistant

Le informations utiles à ton commencent à la section Créer un périphérique.

Dans un premier temps, tu dois écrire un programme capable de publier des message MQTT depuis ton Arduino, et renseigner les informations de ton broker.
Une fois que ton Arduino peut se connecter au broker et y publier un message, tu peux suivre les instructions suivantes.

Tu as 2 manières de déclarer un device dans Gladys :

  1. Ton Arduino créé le device automatiquement dans Gladys
    • Lors du démarrage, le Arduino envoie le message de création du device du le topic /gladys/master/device/create avec toutes les informations nécessaires. Cependant, pour connaître toutes les informations, il est indispensable d’entrer dans le code de Gladys afin de renseigner correctement les valeurs.
{
  "name": "Arduino",
  "external_id": "mqtt:mon-arduino",
  "should_poll": false,
  "features": [
    {
      "name": "Temperature",
      "external_id": "mqtt:arduino:temperature",
      "category": "temperature-sensor",
      "type": "decimal",
      "read_only": true,
      "has_feedback": false,
      "min": -50,
      "max": 125
    }
  ]
}
  1. Tu créé ton device manuellement depuis l’interface de Gladys (intégration MQTT) :
    mqtt_demo

Ensuite, dans tous les cas, ton Arduino doit pouvoir envoyer l’état / les valeurs des devices.
Pour cela, il va devoir publier sur le topic gladys/master/device/state/update (section Envoyer un nouvel état de périphérique de la documentation) un message comme celui-ci :

{
  "device_feature_external_id": "mqtt:arduino:temperature",
  "state": 17
}

La valeur device_feature_external_id doit correspondre à :

  1. la valeur external_id de la nouvelle feature
  2. la valeur du champ Feature external ID*

Dis moi si ça t’a été utile, je reste disponible.

Le JSON n’est pas un format reconnu en C++, tu as des librairies qui te permettent de transformer un object en JSON, sinon tu dois créer ta chaîne de caractère à la main :

      String message = "{\"device_feature_external_id\":\"mqtt:sensor/temperature\",\"state\":\"";
      message += String(t).c_str();
      message += "\"}";

Salut,
Le correctif Sonoff vient d’être fusionné.
Si tu peux mettre à jour et tester à nouveau :wink:

Merci.

1 « J'aime »

Wait, les builds ne sont pas encore passé, ça met environ 1h à builder! Il faut attendre encore.

Build à suivre ici:

Salut
Sa fonctionne nickel ! merci !

Les MàJ ce sont fait automatiquement c’est top !

2 « J'aime »

Bonjour @AlexTrovato,

Je suis passé ce jour à Gladys v4 suite à l’intégration d’un module mqtt fonctionnel visiblement. J’étais resté sur la v3 car j’utilise un module mqtt développé avec mon cousin côté Gladys, et moi même côté Arduino. Celui-ci permettait d’envoyer un scan sur mes 6 arduino pour avoir les nouveaux périphériques installés et les associaient aux pièces et maison existantes ou les créaient si besoin.
J’ai donc regardé la documentation mqtt pour Gladys v4 et je m’aperçois que la pièce ainsi que la maison ne sont pas renseignés.

Je construisais mon JSON ainsi :

Code Arduino v3 - Création périphériques / Pièces / Maison
for(int i =0; i < NBREDEVICETYPES ; i++) //NBREDEVICETYPES; i++)
  {  
    JsonObject Devices = doc.to<JsonObject>(); 
    Devices["houseName"]            = devicesParams[i][ROOM_HOUSE];
    Devices["roomName"]             = devicesParams[i][DEVICE_ROOM];
    Devices["deviceName"]           = devicesParams[i][DEVICE_ROOM]; //devicesParams[i][DEVICE_NAME];
    Devices["deviceIdentifier"]     = (String)device_Identifier + "/" + devicesParams[i][DEVICE_ROOM]; //devicesParams[i][DEVICE_NAME];
    Devices["deviceProtocol"]       = device_Protocol;
    Devices["deviceService"]        = device_Service;
    Devices["deviceTypeName"]       = (String)devicesParams[i][DEVICETYPE_IDENTIFIER] + "" + (String)devicesParams[i][DEVICETYPE_NAMESUPP] + " " + (String)devicesParams[i][DEVICE_ROOM];
    Devices["deviceTypeIdentifier"] = devicesParams[i][DEVICETYPE_IDENTIFIER];
    Devices["deviceTypeType"]       = devicesParams[i][DEVICETYPE_TYPE];
    Devices["deviceTypeUnit"]       = devicesParams[i][DEVICETYPE_UNIT];
    Devices["deviceTypeMin"]        = devicesParams[i][DEVICETYPE_MIN];
    Devices["deviceTypeMax"]        = devicesParams[i][DEVICETYPE_MAX];
    Devices["deviceTypeSensor"]     = devicesParams[i][DEVICETYPE_SENSOR];
    Devices["deviceTypeCategory"]   = devicesParams[i][DEVICETYPE_CATEGORY];

    char JSON_SEND[ 1024 ];
    serializeJson(Devices, JSON_SEND); //serializeJsonPretty
    client.publish(MQTT_DEVICE_REGISTER_TOPIC, JSON_SEND);
    delay(DELAI_ATTENTE);
    doc.clear();
    JsonObject Vidage = doc.to<JsonObject>();
    serializeJson(Vidage, JSON_SEND);
  };

Pourrais-tu m’aiguiller sur la méthode à utiliser pour reprendre mon code pour ton service ? Est-il possible d’ajouter cet esprit de création des pièces associé à une maison (ma maison est décomposée en 5 “maisons” : la Maison, un Bâtiment perso, un Bâtiment Professionnel, un terrain et un Camping).

Ensuite, dans l’exemple :

Exemple v4 - Créer un périphérique
{
  "name": "New Lamp",
  "external_id": "philips-hue:1",
  "should_poll": false,
  "features": [
    {
      "name": "On/Off",
      "category": "light",
      "type": "binary",
      "read_only": false,
      "has_feedback": false,
      "min": 0,
      "max": 1
    }
  ]
}

Je suppose que le “name” n’est pas forcément unique (ce qui m’arrange). Mais en ce qui concerne le “external_id” je pensais que c’était le nom qu’on appellera dans le chat box ou en vocal par la suite ? Mais je dois me tromper … A quoi sert le “:1” à la suite et est-ce codifié ?
Enfin, pourrais-tu m’expliquer ce que sont “should_poll”: false et “has_feedback”: false ? Pour le second, j’ose supposer que Gladys sera en attente d’un retour d’état du périphérique, par exemple : je demande d’allumer la lampe du salon, Gladys envoi sur le topic “gladys/master/device/state/update” ? (pas plutôt “gladys/master/device/cmd” ?) et attend un retour d’état sur le topic “gladys/master/device/state/update” ?

Enfin, et désolé pour la longueur du post, sur le dernier exemple :

Exemple v4 - Envoyer un nouvel état de périphérique
{
  "device_feature_external_id": "philips-hue:1:binary",
  "state": 1
}

Toujours la même question pour le “:1” ^^ mais surtout, doit on obligatoirement repréciser le type, ici binary dans le json ?

Merci beaucoup d’avance pour tout ces éclaircissements, qui me permettront de me lancer définitivement dans la V4.
N’hésite pas à me demander si tu as besoin d’avoir mon codage Arduino, ou bien le codage de mon cousin de la v3 pour la création des pièces automatiquement (enfin c’est peut-être trop différent sur la v4)

Bien cordialement.

Salut @Terdious,

Afin de créer un nouveau périphérique, il faut envoyer un message sur le topic /gladys/master/device/create, et selon ton code, le construire de la manière suivante :

    // La maison est gérée directement par la pièce, ce champ n'est pas prise en compte
    // Devices["houseName"]            = devicesParams[i][ROOM_HOUSE];
    // La pièce n'est plus gérée par son nom, mais par son ID interne
    Devices["room-id"]             = devicesParams[i][DEVICE_ROOM_ID];
    // Nom du device, directement par 'name' non plus par 'deviceName'
    Devices["name"]           = devicesParams[i][DEVICE_ROOM]; //devicesParams[i][DEVICE_NAME];
    // 'deviceIdentifier' n'existe plus, mais nous le remplacerons par 'external_id' prefixe par 'mqtt:'
    Devices["external_id"]     = (String) "mqtt:" + device_Identifier + "/" + devicesParams[i][DEVICE_ROOM]; //devicesParams[i][DEVICE_NAME];
    // 'deviceProtocol' n'existe plus
    // Devices["deviceProtocol"]       = device_Protocol;
    // 'deviceService' est remplacé par 'service_id' (ID interne du service MQTT)
    Devices["service_id"]        = device_Service;

    /**
     * Les données 'deviceType' sont remplacées par les 'features'
     * Tu devras générer un tableau d'objets 'features', avec les correspondances suivantes :
     * 'deviceTypeName'           => 'name'
     * 'deviceTypeIdentifier'     => 'external_id' (préfixé par 'mqtt:')
     * 'deviceTypeType'           => 'type'
     * 'deviceTypeUnit'           => 'unit'
     * 'deviceTypeMin'            => 'min'
     * 'deviceTypeMax'            => 'max'
     * 'deviceTypeSensor'         => 'read_only' (true si sensor)
     * 'deviceTypeCategory'       => 'category'
     */

Pour récupérer les ID internes, tu peux appeler les URL suivantes en HTTP :

  • pièces : /api/v1/room
  • service : /api/v1/services/mqtt

Ou regarde le debugger de ton navigateur lorsque tu navigues sur Gladys V4 pour avoir directement les réponses.

Ceci-dit, je ne suis pas sûr que le multi-maisons soit déjà pris en charge dans la V4.
@pierre-gilles pourra peut-être en dire plus ?


Le name est le nom du device (nom visuel principalement).
external_id correspond plutôt à l’identifiant unique de ton device.

Mais je ne suis pas convaincu que le chat de la V4 soit entièrement opérationnel.
@pierre-gilles pourra peut-être en dire plus ?

Il sert justement à rendre unique l’identifiant (ici, c’est le périphérique philips-hue n° 1, mais cela reste un exemple). Mais c’est à toi de déterminer quel sera l’identifiant unique du device que tu vas ajouter.
Dans ton cas, je conseille une composition avec l’adresse MAC de ton device mqtt:edd3b5306475. Cette adresse MAC est supposée unique, donc pas besoin d’ajouter :1.

should_poll identique à Gladys si la valeur du capteur doit être lue périodiquement.
Aujourd’hui, c’est utilisé par la caméra/vidéo, toutes les minutes, Gladys va récupérer l’image de la caméra. Ce n’est pas la caméra qui lui envoie l’image.

has_feedback n’est a utilisé que si le dévice est un actionneur (non un capteur), et si celui peut confirmer que son état à bien changer (une sorte d’accusé de réception / acknowledgement). Tu avais donc bien supposé avec un retour attendu par le périphérique.

La réponse n’est pas plus courte :wink:

Contrairement au cas précédant, ici il s’agit de l’identifiant unique de la feature, celui utilisé lors de la création du device (la valeur qui remplace deviceTypeIdentifier).
Tu peux y mettre n’importe quelle valeur, mais je te conseille de préfixer par l’ID du device, histoire d’être sûr d’avoir un ID unique à ce device (exemple "mqtt:edd3b5306475:" + devicesParams[i][DEVICETYPE_IDENTIFIER]).


Aujourd’hui, la V4 ne gère pas encore ce cas, mais tout est possible :wink:


Si tu as d’autres questions, ou qu’une de mes explications de te suffit pas, je reste à ta disposition.

Bon courage.
A+

Bonjour Alex et un grand merci pour ton retour.

Alors pour le 1er essai je l'ai écris ainsi :
void DEVICE_ADD()
{
/* Un message a été capté pour un scan des équipement */
  for(int i =0; i < NBREDEVICETYPES ; i++)
  {  
    JsonObject Devices = doc.to<JsonObject>();
    
    Devices["name"] = devicesParams[i][DEVICE_ROOM];
    Devices["external_id"] = "mqtt:" + (String)device_Identifier + ":" + devicesParams[i][DEVICE_ROOM]; //"philips-hue:1";
    Devices["should_poll"] = false;

    JsonObject Features = doc2.to<JsonObject>();
    Features["name"]=(String)devicesParams[i][DEVICETYPE_IDENTIFIER] + "" + (String)devicesParams[i][DEVICETYPE_NAMESUPP] + " " + (String)devicesParams[i][DEVICE_ROOM];
    Features["external_id"]= "mqtt:" + (String)device_Identifier + ":" + (String)devicesParams[i][DEVICETYPE_IDENTIFIER] + ":" + (String)devicesParams[i][DEVICETYPE_NAMESUPP] + (String)devicesParams[i][DEVICE_ROOM];
    Features["category"]=devicesParams[i][DEVICETYPE_CATEGORY];
    Features["type"]=devicesParams[i][DEVICETYPE_TYPE];
    Features["read_only"]=false;
    Features["has_feedback"]=false;
    Features["unit"]=devicesParams[i][DEVICETYPE_UNIT];
    Features["min"]=devicesParams[i][DEVICETYPE_MIN];
    Features["max"]=devicesParams[i][DEVICETYPE_MAX];
  
  JsonArray features = Devices.createNestedArray("features");
  features.add(Features);
      
    char JSON_SEND[ 1500 ];
    serializeJson(Devices, JSON_SEND); //serializeJsonPretty
    client.publish(MQTT_DEVICE_REGISTER_TOPIC, JSON_SEND);
    delay(DELAI_ATTENTE);
    doc.clear();
    JsonObject Vidage = doc.to<JsonObject>();
    serializeJson(Vidage, JSON_SEND);
  };
}

Ce qui donne ceci sur le broker :

/gladys/master/device/create {"name":"Maison DUBLEM","external_id":"mqtt:Arduino_Garage:Maison DUBLEM","should_poll":0,"features":[{"name":"Energie Totale Ph2 Maison DUBLEM","external_id":"mqtt:Arduino_Garage:EnergieTotalePh2:MaisonDUBLEM","category":"battery-sensor","type":"energy","read_only":0,"has_feedback":0,"unit":"KWh","min":"0","max":"99999"}]} 

Malheureusement, aucun logs dans « sudo docker logs gladys --details » comme si Gladys n’était pas inscrit sur le broker sur

Alors que pour le changement d’état :

gladys/master/device/state/update/Arduino_Garage/Maison DUBLEM {"Energie Ph2":2,"Energie Totale Ph2":1935.18}

Le device n’étant pas créé, j’ai une erreur, mais je le vois bien dans les logs :

2020-01-03T09:58:32+0100 <info> handleGladysMessage.js:20 (MqttHandler.handleGladysMessage) MQTT : Gladys topic gladys/master/device/state/update/Arduino_Garage/Maison DUBLEM not handled.

http://10.1.0.175/api/v1/room
Alors là je ne dois pas être doué, enfin il doit me manquer un truc car je tombe sur une page blanche avec écrit : « {« status »:401,« code »:« UNAUTHORIZED »,« message »:« No authorization header or api key found »} » !! Bon je comprends bien qu’il me manque des droits mais je ne sais pas où taper ^^

Bon du coup par cette méthode je pense avoir trouvé : « bd65d7b5-e4a8-4682-ac51-a561a284fac6 », pour autant, si je dois retrouver les ID de 40 ou 60 pièces ainsi, je ne suis pas arrivé ^^

De ce que je suis sûr : j’ai 4 maisons de créées actuellement avec chacunes une 10aine de pièces. Je les retrouves bien toutes dans la liste de choix de ton service mqtt.

Liste des room sur service MQTT

Après en effet, j’ai un bug sur le dashboard, ce n’est pas présenté de la même manière et je ne peux choisir qu’entre les 20 premières pièces classées par ordre alphabétique (donc 20 pièces des différentes house)

Liste des room sur le Dashboard

Ok, merci beaucoup pour toutes ces explications, je me doutais un peu mais je préférais être sûr ^^

Ok, on ne vas pas le déranger sur ce sujet, c’est un des points qui sera de tout de façon traité à un moment ou à un autre de tout de façon.

Désolé, je sèche sur la méthodologie du coup. De mon côté, c’est l’arduino qui va pousser « tout les x sec/min/hour ». Pour le coup il est vrai que je fais un traitement sur l’arduino, pour y retoucher par la suite, connexion usb obligatoire. Si je comprend bien, en mettant true, c’est Gladys qui va demander la valeur. Mais alors comment ça se passe derrière ? Je n’ai pas vu d’option dans la page du service MQTT ? Si ce n’est pas encore développé, doit-on régler un Timer quelque part, ou bien pour le moment je ne dois pas m’en occuper ?

Top ^^ C’est le cas de tout mes device ^^
Alors pour le coup cela m’amène à une question : le push de l’arduino se fait via le topic gladys/master/device/state/update, mais pour la commande ? n’y a-t-il pas un topic gladys/master/device/cmd ou autre ? Car pour mon traitement arduino, je suis paramétré comme ceci :

Topics Arduino
  // Déclarations MQTT - Générales - A définir selon l'usage
    #define MQTT_IP "10.1.0.175" //"10.5.0.50";                           /* Ou nom de serveur si externe */
    #define MQTT_DEVICE_SCAN_TOPIC "Gladys/scan"              // const char    MQTT_DEVICE_SCAN_TOPIC[]= "Gladys/scan";
    #define MQTT_DEVICE_REGISTER_TOPIC "/gladys/master/device/create"      // const char    MQTT_DEVICE_REGISTER_TOPIC[]= "Gladys/register";
    #define MQTT_COMMAND_TOPIC_PREFIX "gladys/master/device/cmd/update" // "Gladys/cmd"            // const String  MQTT_COMMAND_TOPIC_PREFIX= "Gladys/cmd";
    #define MQTT_STATE_TOPIC_PREFIX "gladys/master/device/state/update"            // const String  MQTT_STATE_TOPIC_PREFIX= "Gladys/state";
    #define device_Identifier "Arduino_Garage"             // const char*   device_Identifier="Arduino1_Batiment";
    #define NBREDESOUSTOPIC 5   

Ce qui permet qu’il ne relise pas ce que lui même à envoyé. Désolé je pose certainement des questions de débutant … !!

:sweat_smile:

Mon installation est entièrement composée d’Arduino (peut-être un peu de Netatmo par la suite pour la gestion des chauffage de chaudière) et donc en MQTT. Mon installation est ici : https://community.gladysassistant.com/t/interrogation-sur-les-possibilites-et-exposition-dun-projet-en-cours-avec-mqtt/2215
Si tu as besoin d’aide pour tester / ou voir le module que nous avions créé sur la v3 de Gladys, n’hésite pas à me dire.



Alors du coup oui j’ai quelques question subsidiaires suite à essai ^^

Essai 1 - Création d'un device par le service MQTT

J’ai testé de créer ça, pour faire une commande et récupérer le topic du post :


J’en ai créé 2 dans la même pièce pour voir la disposition et si on pouvait les piloter indépendamment.

Visiblement non puisque je n’ai qu’une seule commande ^^
2020-01-03 12_39_45-Window
J’ai ensuite lancé la commande qui monte bien les 2 light « On/Off » à 1 sur la visu
2020-01-03 12_40_04-Window
Mais après rafraîchissement de la page, aucune valeur…
2020-01-03 12_40_24-Window
Et dans les logs Gladys j’ai ça :

Réglage du service MQTT

Mon 2ème essai était la création des device de puis l’Arduino que je t’ai exposé au 1er point mais dont je n’ai aucun retour dans les logs … mais dont le broker affiche bien le message.

Si tu avais de quoi m’aiguiller pour ces 2 points ce serait top.

Encore un grand merci à toi et une nouvelle fois si besoin d’aide, faut que je me penche sur l’install dev de la V4, mais je m’y mettrais ^^ Je peux également fournir mon dev Arduino si besoin - Je pense notamment à la partie création de pièce.
A+

Cela veut-il dire que le device n’est pas créé ?

Attention, ce topic n’est pas pris en compte.
Il faut publier 1 message de mise à jour d’état par feature sur le topic gladys/master/device/state/update :

{
  "device_feature_external_id": "mqtt:Arduino_Garage:EnergieTotalePh2:MaisonDUBLEM",
  "state": 1935.18
}

Cela ne signifie pas que le device n’est pas créé, mais que le topic sur lequel tu publies ton message n’est pas reconnu par Gladys.

Donc 1ère étape, vérifie si ton device est bien créé. Tu pourras le trouver sur la page MQTT depuis le menu Intégrations.


Si tu mets true, tu t’attends à ce qu’un processus de récupération existe sur pour le service exploité par ton device. Dans notre cas, on traite des périphériques MQTT pures, donc rien n’existe pour que Gladys récupère la valeur, tu doit donc mettre false.

Attention, l’API MQTT décrite dans la documentation ne décrit pas le fonctionnement de devices MQTT, mais la manière dont on peut communiquer avec Gladys via MQTT (comme si on voulait le faire en HTTP avec une API REST).


Je ne suis pas sûr de bien comprendre.
Tu as des actionneurs sur ton arduino, et tu voudrais pouvoir les contrôler depuis Gladys ?
Si c’est bien ça, alors non, ce n’est pas encore géré, mais intéressant.

Cela rejoint aussi le point « Essai 1 - Création d’un device par le service MQTT ».

Quel réactivité ^^

En effet, le device n’est pas créé et les logs ne le font pas apparaitre

Edit : Mon erreur désolé, je publiais sur /gladys/master/device/create. et non gladys/master/device/create … un « / » de trop au début. Maintenant j’ai une erreur dans les logs, apparemment il me manque quelque chose : « t_device.service_id cannot be null » mais je ne vois pas cette feature dans la documentation API MQTT :

 2020-01-03T16:55:47+0100 <warn> functionsWrapper.js:15 (EventEmitter.<anonymous>) Error while executing function () { [native code] }
 2020-01-03T16:55:47+0100 <warn> functionsWrapper.js:16 (EventEmitter.<anonymous>) ValidationError [SequelizeValidationError]: notNull Violation: t_device.service_id cannot be null
     at /src/server/node_modules/sequelize/lib/instance-validator.js:74:15
     at tryCatcher (/src/server/node_modules/bluebird/js/release/util.js:16:23)
     at Promise._settlePromiseFromHandler (/src/server/node_modules/bluebird/js/release/promise.js:547:31)
     at Promise._settlePromise (/src/server/node_modules/bluebird/js/release/promise.js:604:18)
     at Promise._settlePromise0 (/src/server/node_modules/bluebird/js/release/promise.js:649:10)
     at Promise._settlePromises (/src/server/node_modules/bluebird/js/release/promise.js:729:18)
     at Promise._fulfill (/src/server/node_modules/bluebird/js/release/promise.js:673:18)
     at PromiseArray._resolve (/src/server/node_modules/bluebird/js/release/promise_array.js:127:19)
     at PromiseArray._promiseFulfilled (/src/server/node_modules/bluebird/js/release/promise_array.js:145:14)
     at Promise._settlePromise (/src/server/node_modules/bluebird/js/release/promise.js:609:26)
     at Promise._settlePromise0 (/src/server/node_modules/bluebird/js/release/promise.js:649:10)
     at Promise._settlePromises (/src/server/node_modules/bluebird/js/release/promise.js:729:18)
     at _drainQueueStep (/src/server/node_modules/bluebird/js/release/async.js:93:12)
     at _drainQueue (/src/server/node_modules/bluebird/js/release/async.js:86:9)
     at Async._drainQueues (/src/server/node_modules/bluebird/js/release/async.js:102:5)
     at Immediate.Async.drainQueues [as _onImmediate] (/src/server/node_modules/bluebird/js/release/async.js:15:14)
     at processImmediate (internal/timers.js:439:21) {
   name: 'SequelizeValidationError',
   errors: [
     ValidationErrorItem {
       message: 't_device.service_id cannot be null',
       type: 'notNull Violation',
       path: 'service_id',
       value: null,
       origin: 'CORE',
       instance: [t_device],
       validatorKey: 'is_null',
       validatorName: null,
       validatorArgs: []
     }
   ]
 }

Ma publication est :

gladys/master/device/create {"name":"Cave","external_id":"mqtt:Arduino_Garage:Cave","should_poll":0,"features":[{"name":"TempératureCave","external_id":"mqtt:Arduino_Garage:Température:Cave","category":"temperature-sensor","type":"thermometer","read_only":1,"has_feedback":0,"min":"-40","max":"80"}]}

Si tu vois quelque chose de ce côté là ?

Ok, c’est bon de ce côté là, j’avais bien compris la chose, mais n’avais pas fait les modifications côté Arduino, c’est vrai que mon exemple n’était pas très expressif. Pour le coup j’ai créé un périphérique manuellement et la valeur est bien mise à jour :

Dashboard avec valeurs NRJ et Puissance

D’ailleurs au passage, si j’arrive à créer les device par l’intermédiaire de la publication MQTT, par l’Arduino, le paramètre « Unit » sera-t-il pris en compte ? car il n’y a pas d’unité actuellement !!


Bien noté, c’est ce que je me disais. Du coup je garde bien mon fonctionnement actuel géré dans l’Arduino qui va envoyé par exemple la vitesse du vent toutes les 10 secondes, la puissance utilisée toute les minutes, l’énergie totale consommée toute les 1h etc.


Ah ok, donc il n’y a pas de commande de développée pour le moment !!
Oui c’est bien ça, n’utilisant que de l’Arduino en domotique, tout mes actionneurs sont également dessus. Nous l’avions développé dans la même veine sur la v3. Penses-tu qu’il soit compliqué de le développé de ton côté, ou souhaites-tu que je me penche dessus ?

Merci encore une fois pour tes réponses et ta réactivité.

Bien cordialement

Il te faut donc ajouter l’ID du service MQTT dans le device, et comme pour room_id, je te conseille de regarder dans ton navigateur pour trouver l’ID du service MQTT (depuis la page d’intégration MQTT).

Le paramètre unit doit exister dans une liste d’unités prédéfinies, qui se complète au fur à mesure. Voici la liste actuelle (tu devras mettre la valeur - en rouge) :

const DEVICE_FEATURE_UNITS = {
  CELSIUS: 'celsius',
  FAHRENHEIT: 'fahrenheit',
  PERCENT: 'percent',
  PASCAL: 'pascal',
  LUX: 'lux',
  KILOWATT: 'kilowatt',
  KILOWATT_HOUR: 'kilowatt-hour',
  AMPERE: 'ampere',
  VOLT: 'volt',
};

Issue créée sur GitHub

Post précédent

C’est parfait, merci pour toutes tes réponses, je vais tenter de m’en sortir avec tout ça, et je vais essayer d’apporter un coup de pouce pour le dev.
Je donnerais le retour pour le create une fois résolu.

Bonne soirée

Bon je n’ai pas réussi à trouver de service_id, pour autant la méthode d’inspection de page marche bien pour les room_id mais rien pour le service :

Image inspection html page Intégration

J’ai tout de même mis "service_id"="mqtt" pour voir et je passe à une autre erreur :

 2020-01-03T19:56:25+0100 <warn> functionsWrapper.js:15 (EventEmitter.<anonymous>) Error while executing function () { [native code] }
 2020-01-03T19:56:25+0100 <warn> functionsWrapper.js:16 (EventEmitter.<anonymous>) ForeignKeyConstraintError [SequelizeForeignKeyConstraintError]: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed
     at Query.formatError (/src/server/node_modules/sequelize/lib/dialects/sqlite/query.js:374:18)
     at Statement.afterExecute (/src/server/node_modules/sequelize/lib/dialects/sqlite/query.js:119:32)
     at Statement.replacement (/src/server/node_modules/sqlite3/lib/trace.js:19:31) {
   name: 'SequelizeForeignKeyConstraintError',
   parent: [Error: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed] {
     errno: 19,
     code: 'SQLITE_CONSTRAINT',
     sql: "INSERT INTO `t_device` (`id`,`service_id`,`name`,`selector`,`external_id`,`should_poll`,`created_at`,`updated_at`) VALUES ('ef30aa1c-9631-4342-b95c-32a5042939a3','mqtt','Maison DUBLEM','maison-dublem','mqtt:Arduino_Garage:Maison DUBLEM',0,'2020-01-03 18:56:25.619 +00:00','2020-01-03 18:56:25.619 +00:00');"
   },
   original: [Error: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed] {
     errno: 19,
     code: 'SQLITE_CONSTRAINT',
     sql: "INSERT INTO `t_device` (`id`,`service_id`,`name`,`selector`,`external_id`,`should_poll`,`created_at`,`updated_at`) VALUES ('ef30aa1c-9631-4342-b95c-32a5042939a3','mqtt','Maison DUBLEM','maison-dublem','mqtt:Arduino_Garage:Maison DUBLEM',0,'2020-01-03 18:56:25.619 +00:00','2020-01-03 18:56:25.619 +00:00');"
   },
   sql: "INSERT INTO `t_device` (`id`,`service_id`,`name`,`selector`,`external_id`,`should_poll`,`created_at`,`updated_at`) VALUES ('ef30aa1c-9631-4342-b95c-32a5042939a3','mqtt','Maison DUBLEM','maison-dublem','mqtt:Arduino_Garage:Maison DUBLEM',0,'2020-01-03 18:56:25.619 +00:00','2020-01-03 18:56:25.619 +00:00');",
   fields: undefined,
   table: undefined,
   value: undefined,
   index: undefined,
   reltype: undefined
 }
 2020-01-03T19:56:25+0100 <warn> functionsWrapper.js:15 (EventEmitter.<anonymous>) Error while executing function () { [native code] }
 2020-01-03T19:56:25+0100 <warn> functionsWrapper.js:16 (EventEmitter.<anonymous>) ForeignKeyConstraintError [SequelizeForeignKeyConstraintError]: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed
     at Query.formatError (/src/server/node_modules/sequelize/lib/dialects/sqlite/query.js:374:18)
     at Statement.afterExecute (/src/server/node_modules/sequelize/lib/dialects/sqlite/query.js:119:32)
     at Statement.replacement (/src/server/node_modules/sqlite3/lib/trace.js:19:31) {
   name: 'SequelizeForeignKeyConstraintError',
   parent: [Error: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed] {
     errno: 19,
     code: 'SQLITE_CONSTRAINT',
     sql: "INSERT INTO `t_device` (`id`,`service_id`,`name`,`selector`,`external_id`,`should_poll`,`created_at`,`updated_at`) VALUES ('48a0e37c-5bad-428d-9be5-625634afe49e','mqtt','Maison DUBLEM','maison-dublem','mqtt:Arduino_Garage:Maison DUBLEM',0,'2020-01-03 18:56:25.722 +00:00','2020-01-03 18:56:25.722 +00:00');"
   },
   original: [Error: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed] {
     errno: 19,
     code: 'SQLITE_CONSTRAINT',
     sql: "INSERT INTO `t_device` (`id`,`service_id`,`name`,`selector`,`external_id`,`should_poll`,`created_at`,`updated_at`) VALUES ('48a0e37c-5bad-428d-9be5-625634afe49e','mqtt','Maison DUBLEM','maison-dublem','mqtt:Arduino_Garage:Maison DUBLEM',0,'2020-01-03 18:56:25.722 +00:00','2020-01-03 18:56:25.722 +00:00');"
   },
   sql: "INSERT INTO `t_device` (`id`,`service_id`,`name`,`selector`,`external_id`,`should_poll`,`created_at`,`updated_at`) VALUES ('48a0e37c-5bad-428d-9be5-625634afe49e','mqtt','Maison DUBLEM','maison-dublem','mqtt:Arduino_Garage:Maison DUBLEM',0,'2020-01-03 18:56:25.722 +00:00','2020-01-03 18:56:25.722 +00:00');",
   fields: undefined,
   table: undefined,
   value: undefined,
   index: undefined,
   reltype: undefined
 }

Tu dois inspecter la page MQTT :wink:

@AlexTrovato, un grand merci pour ta méthodologie dans la résolution de mon problème, il est beaucoup plus intéressant de suivre les pistes sans pour autant avoir toutes les réponses dans les mains. Cela me permettra notamment de rechercher d’autres choses par la suite.

Donc je confirme que pour le create ça marche impeccable.
→ Par contre il faudrait peut-être revoir la documentation pour y insérer le service_id ainsi qu’en option le room_id et le unit non ?. Peut-être également la méthodologie pour retrouver les id correspondant du style :

Modification de la documentation API MQTT

Create a device

Topic

/gladys/master/device/create

Body:

The room_id and unit parameters are not mandatory because they will take additional memory on the arduino in particular, however they will allow you not to have to fill them again in the Gladys configuration page.

The room_id and service_id parameters (the second mandatory) can be retrieved from the / dashboard / integration / mqtt page:

- On chrome, right click then "inspect". In the "network" tab, select "mqtt" in the table. On the right you will see the service id. Select "house? Expand = rooms & order_dir = asc". On the right you will see your houses, by deploying these you will see the associated rooms as well as their id

{
  "name": "New Lamp",
  "service_id": "hch0-e8a5-j7r9k-8fb1-51800a151edc",
  "room_id": "bd65d7b5-e4a8-4682-ac51-a561a284fac6",
  "external_id": "philips-hue:1",
  "should_poll": false,
  "features": [
    {
      "name": "On/Off",
      "category": "light",
      "type": "binary",
      "read_only": false,
      "has_feedback": false,
      "unit": "celsius",
	  "min": 0,
      "max": 1
    }
  ]
}

You can also find the different parameters to use for categories, units, types, etc. on the github: Documentation utils/constants.

J’ai pu également récupérer toutes les room et grâce un petit prog en VBA (oui je sais ce n’est pas le plus performant, mais c’est l’outil avec lequel je suis le plus à l’aise ^^) et un tableau excel que je tenais à jour, j’ai pu reformer mon programme avec les id en quelques minutes.
Il n’y a plus qu’à repasser sur tout mes autres Arduino pour faire les modifications nécessaires ainsi que sur Gladys v3 pour pouvoir continuer d’utiliser les commandes (pour le moment) et les scénarios ^^

Bon du coup ce n’est pas encore fonctionnel pour moi car sur le dashboard, je ne peux toujours pas afficher toutes les pièces, mais je vais mettre un post sur un sujet qui pourrait correspondre.

Encore merci pour tout, je vais regarder si je peux te faire une proposition pour le publish, mais je n’ai pas encore le temps pour faire l’installation en développeur de Gladys pour le tester. Tu me diras si ça t’intéresse.

@AlexTrovato Je viens de poster une réponse sur la PR du MQTT setValue, je pense qu’il faut qu’on ait une réflexion plus générale par rapport à Gladys v4. Ne nous précipitons pas, il faut une définir une API solide et claire avant de se lancer dans le dev.

Je pense que le problème de @Terdious est un problème assez classique, et j’aimerais qu’on pense au flow utilisateur avant de faire du code.

Je ne sais pas si c’est plus simple de faire ça à l’écrit ou à l’oral, si tu as des dispos pour un petit call ça sera peut-être plus simple!

Salut @pierre-gilles, désolé pour tout ce temps de silence.
Je comprends le fait de devoir définir une API MQTT solide, et en effet, il ne faut pas faire ça à la va-vite.
En revanche, je vais un peu short en temps libre sur cette début d’année (en vrai, je n’ai pas de visibilité) pour ce genre de “gros travaux”. Surtout que je n’en aurai probablement pas l’utilité, donc je visualise assez peu le flow utilisateur possible.
Ma PR était sous la contrainte de @Terdious (je rigole). C’était surtout pour tenter de le débloquer.
Mais la meilleure solution reste vraiment de fournir une API digne de son nom.

Pas de soucis :slight_smile:

Je ne pense pas que ce soit un si gros développement, mais il faut juste bien définir l’API que l’on souhaite. Dès que j’ai du temps, je définirais et poserait les bases de cette API ! Si tu as du temps avant moi, n’hésite pas à créer un topic pour qu’on puisse en parler !