[ESP8266] Publier un Message Callback dans l'Explorer

Hello,

Je programme un ESP-01 afin d’y exposer deux méthodes.
Je suis la documentation: https://developer.myconstellation.io/client-api/arduino-esp-api/recevoir-des-messages-et-exposer-des-methodes-messagecallback-sur-arduino-esp/

J’ai déclaré mes deux callbacks dans setup():

constellation.registerMessageCallback("Ping",
    MessageCallbackDescriptor().setDescription("Reply Pong !"),
    [](JsonObject& json)
    {
      constellation.writeInfo("Pong !");
    });

  constellation.registerMessageCallback("HelloWorld",
    MessageCallbackDescriptor().setDescription("Hello World !"),
    [](JsonObject& json) {
      constellation.writeInfo("Hello Constellation !");
   });
  constellation.declarePackageDescriptor();

Dans le Console log:

[ESP.LightUnderTVConsole/Switch] 7:13:40 PM : Hello Constellation [ESP.LightUnderTVConsole/Switch] 7:13:40 PM : Hello Constellation, I'm 'ESP.LightUnderTVConsole ! [ESP.LightUnderTVConsole/Switch] 7:13:40 PM : Subscribing to message. subscriptionId=14ff54bf-6955-41ef-a732-1b6bac1a25a3 [ESP.LightUnderTVConsole/Switch] 7:13:40 PM : Subscribing to message. subscriptionId=a303739c-0b8f-4a01-8bd2-3b82f7220f33 [ESP.LightUnderTVConsole/Switch] 7:13:40 PM : Declaring PackageDescriptor for Switch (Quelques minutes plus tard ...) [Server/WebApiManager] 7:18:41 PM : HTTP session '14ff54bf-6955-41ef-a732-1b6bac1a25a3' timeout [Server/WebApiManager] 7:18:41 PM : HTTP session 'a303739c-0b8f-4a01-8bd2-3b82f7220f33' timeout

Cependant, dans le Message Callbacks Explorer, il n’y a rien.
Une idée?

Merci,
Julien.

Ci-dessous, la trace générée par l’ESP8266 avec le mode:

WiFi connected. IP: 192.168.1.28 [INFO] WriteLog(Info) : Hello Constellation [INFO] WriteLog(Info) : Hello Constellation, I'm 'ESP.LightUnderTVConsole ! [DEBUG] GET: //rest/constellation/SubscribeToMessage?SentinelName=ESP.LightUnderTVConsole&PackageName=Switch&AccessKey=90e6613fa4bbcbecb2b72d39d27069796748457e [DEBUG] Raw message: : [DEBUG] Return code: 0 [DEBUG] GET: //rest/constellation/SubscribeToMessage?SentinelName=ESP.LightUnderTVConsole&PackageName=Switch&AccessKey=90e6613fa4bbcbecb2b72d39d27069796748457e [DEBUG] Raw message: : [DEBUG] Return code: 204 [DEBUG] POST: //rest/constellation/DeclarePackageDescriptor?SentinelName=ESP.LightUnderTVConsole&PackageName=Switch&AccessKey=90e6613fa4bbcbecb2b72d39d27069796748457e POST //rest/constellation/DeclarePackageDescriptor?SentinelName=ESP.LightUnderTVConsole&PackageName=Switch&AccessKey=90e6613fa4bbcbecb2b72d39d27069796748457e HTTP/1.1 Host: 192.168.1.10 Content-Length: 94 Content-Type: application/json Connection: keep-alive

{“PackageName”:“Switch”,“MessageCallbacks”:[],“MessageCallbackTypes”:[],“StateObjectTypes”:[]}

En fouillant dans la librairie, j’ai remarqué que la fonction subscribeToMessage me retournait 0.
Si je “force” le return à true, de cas les MessageCallbacks sont envoyées et je les retrouve dans Message Callbacks Explorer.
Par contre, elles ne fonctionnent pas mais ça permet de d’affiner les recherches.

Ce que j’en conclu pour l’instant, c’est que l’ESP demande un subscribeToMessage et que le serveur ne lui retourne pas de SubscriptionId.

Ce qui est étrange, c’est que quand je fais moi-même le GET:
192.168.1.10:8088/rest/constellation/SubscribeToMessage?SentinelName=ESP.LightUnderTVConsole&PackageName=Switch&AccessKey=90e6613fa4bbcbecb2b72d39d27069796748457e
J’obtiens bien des SubscriptionId (ex.: “424db243-dc1d-4c32-8d51-cae93f6d5c8e”).

Je continuerai à regarder demain.
Julien.

Bonjour Julien,

En effet problème étrange ! Merci pour l’analyse ça donne pas mal d’info pour investiguer ! En effet le mode “debug” de la lib Arduino est bien utile :wink:

Comme tu l’as remarqué, pour que les MC soient bien enregistrés via la méthode “registerMessageCallback” (et donc déclarés dans Constellation afin d’être visible dans le MC Explorer), il faut que la méthode “subscribeToMessage” retourne “true”, c’est à dire qu’il obtient bien un ID d’abonnement (subscriptionId).

Dans tes logs, comme il n’obtient pas d’ID d’abonnement, les MC ne sont pas enregistrés et donc le package descriptor est vide ce qui explique l’absence des MC dans la Console.
D’ailleurs il y a un double “:” dans les logs de debug du “raw message” que je devrais corriger (https://github.com/myconstellation/constellation-arduino/blob/master/Constellation.h#L276) !

Cependant dans les logs du 1er post il y a bien un subscriptionId et même deux (car deux registerMessageCallback) ce qui n’est pas normal au passage : l’ID est sauvegardé dans _msgSubscriptionId (ligne 580) et donc les autres “registerMessageCallback” ne devrait pas redemander d’abonnement (voir le if ligne 575).

Les deux sessions tombent en TO car pas de requete dessus ! Il y a bien un “constellation.loop()” dans la méthode “loop” ??

J’avoue être un peu dans le flou, il faudrait que vous puissez recommancer les investigations avec les logs debug en essayant de trouver un scénario qu’on puisse reproduire.

Bien à vous,

Salut,

Merci de ton retour.
J’ai un peu avancé dans l’analyse.

Je te propose d’améliorer le délai entre l’appel entre l’appel du writeRequest et du readResponse (https://github.com/myconstellation/constellation-arduino/blob/master/Constellation.h#L203). Actuellement, il y a un délai de 10ms. Le serveur n’a pas encore répondu que readResponse retourne 0.

Exemple d’amélioration:

// Wait a response
unsigned long timeout = millis();
while (_netClient->available() == 0) {
    if (millis() - timeout > DEFAULT_REQUEST_TIMEOUT) {
        log_info("Timeout reached");
        return false;
    }
}

En hard-codant un delay(1000), j’obtiens des réponses mais elles semblent mal formatées (il y a des caractères artefacts).

WiFi connected. IP: 192.168.1.28 [INFO] WriteLog(Info) : Hello Constellation [INFO] WriteLog(Info) : Hello Constellation, I'm 'ESP-LightUnderTVConsole ! [DEBUG] GET: //rest/constellation/SubscribeToMessage?SentinelName=ESP-LightUnderTVConsole&PackageName=Switch&AccessKey=90e6613fa4bbcbecb2b72d39d27069796748457e [DEBUG] Raw message: : 26 "99066587-b8ab-4e9d-b7a5-d547adc94705" 0

[DEBUG] Return code: 200
[INFO] SubscribeToMessage:OK - Subscription Id = 6
"99066587-b8ab-4e9d-b7a5-d547adc9

Je vais m’ouvrir un telnet et déterminer si la réponse est “réellement” mal formatée ou si c’est un soucis dans une librairie.

OK, j’ai trouvé la source du problème.
J’ai affiché texto ce que retourne le server:

[DEBUG] GET: //rest/constellation/SubscribeToMessage?SentinelName=ESP-LightUnderTVConsole&PackageName=Switch&AccessKey=90e6613fa4bbcbecb2b72d39d27069796748457e HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Server: Mono-HTTPAPI/1.0 Date: Wed, 07 Jun 2017 15:55:59 GMT Transfer-Encoding: chunked Keep-Alive: timeout=15,max=97

26
“a06f97ef-7208-4722-bf4b-87d138c3a666”
0

La subtilité est en gras. Je reçois des messages fractionnés.
26: indique la longueur en HEX de la portion de texte suivante. En décimal: 38, à savoir SUBSCRIPTIONID_SIZE + 2 (ce qui est attendu)

La librairie n’est pas configurée pour parser les messages fractionnées.
Je vois possibilités:

  1. Forcer le server à envoyer des messages complets, pas de chunked
  2. Faire évoluer la librairie Constellation (vers l'infini et l'au-delà)

Qu’en penses-tu ?

Astuce: au lieu de lire char-by-char, j’ai trouvé la fonction:

String line = client->readStringUntil('\r');

qui peut aider à lire la réponse. Reste à voir en terme de performance/mémoire.

Julien.

Salut,

J’ai fixé le problème.
J’ai réécrit la fonction readResponse afin de prendre en compte le formatage « Transfer-Encoding: chunked ».

Tu trouveras ma proposition:

Maintenant, cela fonctionne :slight_smile:

WiFi connected. IP: 
192.168.1.14
[INFO] WriteLog(Info) : Hello Constellation
[INFO] WriteLog(Info) : Hello Constellation, I'm 'ESP-LightUnderTVConsole !
[DEBUG] GET: //rest/constellation/SubscribeToMessage?SentinelName=ESP-LightUnderTVConsole&PackageName=Switch&AccessKey=90e6613fa4bbcbecb2b72d39d27069796748457e
[DEBUG] Raw message: : "e2f013b5-c436-4769-8139-fd3ec0886d81"
[DEBUG] Return code: 200
[INFO] SubscribeToMessage - length: = 38
[INFO] SubscribeToMessage:OK - Subscription Id = e2f013b5-c436-4769-8139-fd3ec0886d81
[DEBUG] POST: //rest/constellation/DeclarePackageDescriptor?SentinelName=ESP-LightUnderTVConsole&PackageName=Switch&AccessKey=90e6613fa4bbcbecb2b72d39d27069796748457e
POST //rest/constellation/DeclarePackageDescriptor?SentinelName=ESP-LightUnderTVConsole&PackageName=Switch&AccessKey=90e6613fa4bbcbecb2b72d39d27069796748457e HTTP/1.1
Host: 192.168.1.10
Content-Length: 236
Content-Type: application/json
Connection: keep-alive

{"PackageName":"Switch","MessageCallbacks":[{"MessageKey":"Ping2","Description":"Reply Pong !","Parameters":[]},{"MessageKey":"HelloWorld2","Description":"Hello World !","Parameters":[]}],"MessageCallbackTypes":[],"StateObjectTypes":[]}

[DEBUG] Return code: 0

Hello Julien,

Merci beaucoup pour ton investigation et pour ta solution.

Très étonné que les réponses soient “chunkées”, à mon avis il s’agit de l’implémentation de Mono des middlewares OWIN car je n’ai jamais vu ca dans mes devs !

En tout cas, parfait pour la lib, je vais regarder çà avec beaucoup d’attention pour pouvoir mettre à jour la lib Arduino Constellation afin de gérer cette particularité !

Encore merci pour ta contribution,

Bien à toi,
Sébastien