Pour exposer des méthodes de votre Arduino/ESP dans la Constellation, vous pouvez enregistrer et par la même occasion déclarer auprès de Constellation des MessageCallbacks avec la méthode registerMessageCallback.

Enregistrer un MessageCallback

Par exemple enregistrons un MessageCallback “HelloWorld” via une expression lambda C++ à l’initialisation de votre Arduino/ESP (c’est à dire dans la méthode setup()):

Enfin dans la boucle principal (loop), invoquez la méthode “constellation.loop” pour traiter et dispatcher les messages reçu par votre package virtuel :

Dès lors que votre Arduino/ESP recevra un message dont la clé (MessageKey) est “HelloWorld”, votre méthode associée (représentée ci-dessus par une lambda) sera invoquée.

Décrire son MessageCallback

Le MessageCallback enregistré ci-dessus est dit “caché”, car il n’est pas référencé sur Constellation ! Vous pouvez bien sur envoyer un message “HelloWorld” à votre package pour invoquer votre fonction lambda mais cela suppose que vous connaissez par avance que votre package a enregistré le MessageCallback ci-dessus nommé “HelloWorld”.

Pour enregistrer ET déclarer un MessageCallback vous devez ajouter un “MessageCallbackDescriptor” dans les arguments de la méthode. Par exemple pour reprendre notre exemple “HelloWorld” :

On a ici ajouté un “MessageCallbackDescriptor” en spécifiant la description de notre MC. Pour que la description du MC soit envoyée à Constellation, vous devez nécessairement publier le “Package Descriptor” à la fin de l’initialisation de votre Arduino/ESP par la ligne :

Maintenant, depuis la Console Constellation, ouvrez le “MessageCallback Explorer” et vous retrouvez un MC nommé “HelloWorld” pour votre package :

image

Vous pouvez cliquer sur le bouton “Invoke” pour envoyer un message “HelloWorld” au package “MyVirtualPackage” et donc invoquer le code de la lambda.

On retrouvera donc dans la Console Log Constellation un “Hello Constellation” tel que programmé dans la lambda (via un constellation.writeInfo)  :

image

Récupérer le contexte

Vous pouvez également récupérer le contexte de réception du message dans la fonction liée en ajoutant un argument « MessageContext » dans la signature du callback :

Le type “MessageContext” décrit de la façon suivante :

Avec :

Ainsi vous pouvez obtenir des informations sur le contexte de réception du message à savoir :

  • Si le message est dans une saga, si oui obtenir l’identifiant de la saga
  • Connaitre le scope dans lequel a été envoyé le message
  • Connaitre l’émetteur du message (ID de connexion, friendly name, …)

Par exemple, pour afficher le nom de l’émetteur (son FriendlyName) nous pourrions écrire :

En invoquant le MC depuis le “MessageCallback Explorer” en étant connecté sous l’utilisateur “seb”, nous obtiendrons dans les logs :

Décrire les paramètres de vos MessageCallbacks

Dans la philosophie des MessageCallbacks Constellation, un MessageCallback sert à invoquer des méthodes où la clé du message (MessageKey) est comme le nom d’une méthode.

Pour passer des paramètres à ces méthodes, on utilisera le contenu du message (Data).

Paramètres de types simples

Imaginez vouloir exposer une méthode “SayHello” qui prend en paramètre deux chaines de paramètres (= des types simples), le nom et prénom pour les afficher dans les logs.

On déclarera le MessageCallback suivant :

On a ajouté deux paramètres de type “String” dans le MessageCallbackDescriptor via la méthode “addParameter”. Dans le code de notre MessageCallback, nous exploitons les valeurs des paramètres via la propriété “Data” de notre message “json”.

Le 1er paramètre (json[« Data »][0]) étant ici le “FirstName” d’après la description et le 2ème (json[« Data »][1]) le “LastName”.

Attention :

  • lorsque plusieurs paramètres sont passés comme dans l’exemple ci-dessus, la propriété “Data” est un tableau contenant la valeur de chaque argument (ici [0] est “FirstName” et [1] le “LastName”)
  • Si un seul paramètre est passé dans votre MC, la propriété “Data” est la valeur de l’argument directement et non un tableau.

Vous pouvez tester votre MC depuis le “MessageCallback Explorer” :

image

image

Bien entendu vous pouvez déclarer un ou plusieurs paramètres de type différent.

Les types de base sont :

  • System.String
  • System.Char
  • System.Boolean
  • System.Int16
  • System.Int32
  • System.Int64
  • System.Double
  • System.Decimal
  • System.Float

Pour simplifier l’enregistrement des paramètres de type de base, vous pouvez les déclarer en utilisant la forme générique.

Par exemple pour un paramètre de type “String” on écrira :

Autre exemple pour ajouter des paramètres de type “Boolean” et “Int32” :

De ce fait notre MC “SayHello” pourrait s’écrire :

Paramètre de types complexes

Il est également possible de spécifier des objets complexes contenant des propriétés.

Reprenons l’exemple précédent “SayHello” sauf qu’au lieu de passer deux paramètres de type “simple”, passons qu’un seul paramètre : un objet contenant deux propriétés (LastName et FirstName).

Dans le MessageCallbackDescriptor de notre MessageCallback nous déclarons qu’un seul paramètre nommé “User” et de type “SampleUserData”.

Au niveau du code de notre MessageCallback, nous récupérons nos deux valeurs via le 1èr et unique paramètre (json[« Data »]) en accédant à la propriété “FirstName” et “LastName”.

Bien entendu pour que cela fonctionne il faut déclarer le type “SampleUserData” via la méthode “addMessageCallbackType” :

image

Il n’y a donc plus maintenant qu’un seul paramètre, un objet complexe contenant deux propriétés de type “string”. Vous pouvez d’ailleurs cliquez sur le type “SampleUserData” pour afficher sa description :

image

Noter que vous pouvez enregistrer et déclarer des MessagesCallbacks mixant paramètre simple et paramètre complexe :

Exposer des MessageCallbacks avec réponse : les sagas

Pour finir un MessageCallback peut retourner un message de réponse, c’est ce que l’on appelle les sagas. C’est un peu comme une méthode en programmation, elle peut être “procédure” (sans retour, un void) ou “fonction” (retourne un type simple ou complexe).

Votre Arduino/ESP peut également enregistrer des MC retournant une réponse. Pour cela deux choses sont nécessaire :

  • Appeler la méthode “sendReponse” dans votre callback pour envoyer la réponse
  • Appeler la méthode “setReturnType” sur le MessageCallbackDescriptor de votre MC pour déclarer le type de retour

Par exemple exposons un MessageCallback “Addition” pour réaliser des additions sur un Arduino/ESP. Ce MessageCallback prend en paramètre deux entiers et retourne le résultat de type entier (Int32) également :

Pour retourner une réponse vous devez disposer du contexte de réception du message (le “MessageContext”). Vous noterez qu’ici, nous testons que le message appartient bien à une saga afin de renvoyer la réponse car il ne sert à rien d’envoyer une réponse sans saga, il ne sera jamais reçu par l’émetteur.

En déclarant le type de retour (ici un Int32), le MessageCallback Explorer reconnait ce MC comme une saga. Vous pouvez donc envoyer le message dans une saga (c’est à dire avec un identifiant de Saga) ou non grâce à la case à cocher :

image

Si le message est envoyé dans une saga, notre code Arduino ci-dessus retournera une réponse, ici à la Console Constellation :

image

La Console Constellation vous présentera ici toutes informations quant à la réponse et au message initial.  On retrouve ici la réponse de notre addition :

image

Dans la Console Log, on retrouvera bien les logs produits par notre Arduino :

image

Vous pouvez également rejouer ce test mais cette fois ci en décochant la case “With Saga”, c’est à dire que nous invoquons le MC “Addition” sans n° de saga :

image

Dans la Console Log, notre Arduino réalise bien l’addition mais ne retourne pas de message de réponse car il ne dispose pas de n° de saga pour répondre :

image

Recevoir tous les messages dans une méthode

Vous pouvez aussi “attraper” tous les messages que votre package virtuel reçoit en définissant un “callback”, c’est à dire une fonction prenant en paramètre le message sous forme d’un JsonObject et qui sera appelée à chaque message reçu.

Par exemple, écrivez la méthode suivante pour afficher le “MessageKey” de chaque message reçu (si nécessaire n’hésitez pas à lire ou relire les fondamentaux du Messaging Constellation) :

Au “setup”, attachez cette méthode à la réception des messages (setMessageReceiveCallback) et abonnez-vous à la réception des messages (subscribeToMessage) :

Avec les expression lambda en C++, vous auriez pu aussi écrire directement :

Enfin dans la boucle principal (loop), invoquez la méthode “constellation.loop” pour traiter et dispatcher les messages reçu par votre package virtuel :

Par exemple, imaginez un ESP8266 avec 2 MessageCallbacks : “Restart” sans paramètre qui redémarre l’ESP et “SendCode” avec un objet JSON en paramètre pour envoyer un signal infrarouge.

Le code pourrait être :

Avec cette façon de faire, votre “MessageReceiveCallback” est invoqué à chaque message reçu mais c’est à vous de “dispatcher” les messages en fonction de leur “MessageKey”.

De plus côté Constellation, il n’y a aucun “Message Callback” déclaré sur Constellation, c’est a vous de connaitre les “MessageKey” que votre package virtuel acceptent, ici “SendCode” et “Restart” !

Obtenir contexte de réception

Comme pour l’enregistrement d’un MessageCallback, vous pouvez ajouter un 2ème argument de type MessageContext pour récupérer le contexte de réception du message.

Par exemple nous pourrions écrire très simplement :

S’abonner à un groupe Constellation

Jusqu’a présent votre package virtuel recevra les messages :

  • Du Scope “All” (c’est à dire tout le monde connecté à Constellation)
  • Du Scope “Others” si votre package n’est pas l’émetteur du message
  • Du Scope de votre sentinelle
  • Du Scope de votre package

Si nécessaire n’hésitez pas à lire ou relire les fondamentaux du Messaging Constellation.

Vous pouvez également vous abonner à des groupes pour recevoir les messages qui seraient envoyés dans ces groupes.

Pour cela il suffit d’invoquer la méthode “subscribeToGroup” en spécifiant le nom du groupe à joindre. Exemple :

Noter cependant que l’appartenance d’un package, virtuel ou non, à un groupe peut être défini au niveau de la configuration de la Constellation éditable simplement via la Console Constellation afin de pouvoir faire évoluer ces appartenances à la volée sans devoir reprogrammer vos Arduino/ESP.

MessageCallback : exposer des méthodes et recevoir des messages sur un Arduino/ESP
Editer la page sur GitHub
Étiqueté avec :                

Démarrez la discussion sur le forum Constellation