Sommaire
Connecter une page HTML avec l’API Javascript
Vous pouvez soit utiliser le gestionnaire de package Nuget depuis Visual Studio pour installer la dernière version du package “Constellation.Javascript” et ses dépendances :
Ou bien utiliser (ou copier en local) les scripts des CDN en ajoutant dans votre code HTML les balises suivantes :
1 2 3 |
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script> <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/signalr/jquery.signalr-2.2.2.min.js"></script> <script type="text/javascript" src="https://cdn.myconstellation.io/js/Constellation-1.8.2.min.js"></script> |
Une fois les scripts ajoutés dans votre page vous devez initialiser le client Constellation en spécifiant l’URL de votre serveur Constellation, la clé d’accès et le “Friendly name” de votre page :
1 |
var constellation = $.signalR.createConstellationConsumer("http://localhost:8088", "123456789", "Test API JS"); |
Vous pouvez créer une clé d’accès depuis la Console Constellation ou en éditant le fichier de configuration du serveur.
Enfin ajoutons un handler sur le changement d’état de la connexion pour afficher le message “Je suis connecté” dans la console de votre navigateur par exemple lorsque la connexion à Constellation est établie :
1 2 3 4 5 |
constellation.connection.stateChanged(function (change) { if (change.newState === $.signalR.connectionState.connected) { console.log("Je suis connecté"); } }); |
Il ne reste plus qu’à lancer la connexion en invoquant la méthode Start :
1 |
constellation.connection.start(); |
Et voilà, votre page est connectée à votre Constellation.
Envoyer des messages et invoquer des MessageCallbacks
Envoyer des messages
Pour envoyer des messages et donc invoquer des MessageCallbacks vous devez utiliser la méthode “constellation.server.sendMessage” en spécifiant :
- Le scope
- La clé du message
- Le contenu du message (= les paramètres du MessageCallback)
Par exemple, avec le package Nest déployé dans votre Constellation, on retrouvera un MessageCallback “SetTargetTemperature” pour piloter la température de consigne d’un thermostat Nest.
N’hésitez pas à utiliser le MessageCallback Explorer pour découvrir l’ensemble des MessageCallbacks exposés par les packages de votre Constellation.
Pour invoquer le MessageCallback “SetTargetTemperature” depuis votre page Web en passant en paramètre l’ID du thermostat et la température de consigne :
1 |
constellation.server.sendMessage({ Scope: 'Package', Args: ['Nest'] }, 'SetTargetTemperature', 'thermostatId', 19); |
Vous pouvez également passer plusieurs arguments à votre MC combinant type simple et type complexe.
Par exemple le MC “ShowNotification” du package Xbmc permettant d’afficher une notification sur une interface Kodi/XBMC prend deux paramètres : le nom d l’hôte XBMC (un type string) et le détail de la notification à afficher (un type complexe) :
1 |
constellation.server.sendMessage({ Scope: 'Package', Args: ['Xbmc'] }, 'ShowNotification', xbmcName, { "Title":"Hello", "Message":"Hello from JS" }); |
Bien entendu vous pouvez invoquer des MessageCallbacks de n’importe quel package, réel (programme Linux/Windows) ou virtuel (Arduino/ESP) ou même sur d’autres consommateurs (pages Web par exemple).
Ainsi vos pages Web peuvent, en envoyant des messages, invoquer des méthodes sur n’importe quel système connecté dans votre Constellation.
Par exemple dans l’article sur les ESP/Arduinos, notre ESP8266 exposait un MC “Reboot” pour redémarrer la puce. Si l’on souhaite redémarrer notre Arduino/ESP depuis une page Web, il suffit d’envoyer un message sans paramètre au bon scope. Par exemple :
1 |
constellation.server.sendMessage({ Scope: 'Sentinel', Args: ['MyArduino'] }, 'Reboot'); |
Ici le scope est “Sentinel” avec l’argument “MyArduino”, c’est à dire que le message “Reboot” sera envoyé à tous les packages de la sentinelle “MyArduino”.
Les scopes peuvent être :
- Sentinel
- Package
- Group
- Others
- All
La propriété “Args” de l’objet scope est un tableau contenant le nom des groupes, des sentinelles ou packages en fonction du type de scope sélectionné. Seuls les scopes “All” et “Others” n’ont pas besoin d’argument.
Envoyer des messages avec réponse : les sagas
Les Sagas permettent de lier des messages et donc de créer des couples de “requêtes / réponses”.
Avec la libraire JavaScript, il est possible d’envoyer des messages dans une saga et d’enregistrer un callback pour traiter la réponse.
Par exemple, le package “NetworkTools” expose un MC “Ping” permettant de réaliser un ping réseau. Le résultat du ping est retourné dans un message de réponse (un Int64 représentant le temps du réponse du ping) :
De ce fait pour réaliser un ping vers « www.google.fr » depuis une page Web :
1 2 3 |
constellation.server.sendMessageWithSaga(function(response) { console.log("Ping %s ms", response.Data); }, { Scope: 'Package', Args: ['NetworkTools'] }, 'Ping', "www.google.fr"); |
Souvenez-vous de notre package virtuel de notre ESP8266 / Arduino, on exposait un MessageCallback “Addition” capable de réaliser une addition locale (sur le CPU de l’Arduino ou ESP) en prenant en paramètre deux entiers. Le résultat était retourné dans la saga.
1 2 3 |
constellation.server.sendMessageWithSaga(function(response) { console.log("Le resultat de 40+2 par l'Arduino est %s", response.Data); }, { Scope: 'Sentinel', Args: ['MyArduino'] }, 'Addition', 40, 2); |
Ainsi vos pages Web peuvent invoquer des méthodes et exploiter la réponse de tous les systèmes connectés sur Constellation exposant des MessageCallbacks.
Recevoir des messages
Une page Web connectée sur Constellation peut elle même recevoir des messages et donc exposer des MessageCallbacks que d’autres consommateurs (autres pages Web) ou packages (réels et virtuels) pourront invoquer.
Ceci dit un consommateur tel qu’une page Web n’a pas réellement d’existence. Autrement dit elle n’a pas d’identité et donc ne peut recevoir que des messages adressés à un groupe qu’elle devra joindre.
Pour joindre un groupe vous devez utiliser la méthode “subscribeMessages“ (et “unSubscribeMessages” pour en sortir). Vous pouvez joindre autant de groupe que vous souhaitez.
Par exemple, pour ajouter votre page au groupe “Demo” :
1 |
constellation.server.subscribeMessages("Demo"); |
Vous pourrez ensuite recevoir les messages envoyés dans ce groupe en ajoutant un handler sur le “onReceiveMessage” :
1 2 3 |
constellation.client.onReceiveMessage(function (message) { console.log("Message recu !", message); }); |
Dans ce handler vous recevrez TOUS les messages (quelque soit la clé du message).
Vous avez aussi un moyen plus simple consistant à définir un handler pour une clé de message spécifiquement via la méthode “registerMessageCallback”.
Par exemple :
1 2 3 4 5 6 |
constellation.client.registerMessageCallback("ChangeTitle", function (msg) { document.title = msg.Data; }); constellation.client.registerMessageCallback("HelloWorld", function (msg) { alert("Hello World"); }); |
Ici on enregistre deux MessageCallbacks.
Si votre page reçoit un MessageCallback “HelloWorld”, une alerte sera ouverte, si elle reçoit un MessageCallback “ChangeTitle”, le titre de votre page sera modifié avec l’argument passé dans le MC.
Imaginez par exemple que vous ouvrez une page Web en plein écran sur différents devices dont vous n’avez pas de contrôle (par exemple des écrans Dashboard). Sur cette page vous affichez différentes données en temps réel, par exemple basées sur les StateObjects Constellation.
Vous modifiez votre page et vous souhaitez donc la rafraîchir sur tous les navigateurs qui ont ouvert votre page pour recharger la nouvelle version.
Pour ce faire, vous pouvez facilement exposer un MessageCallback “ReloadMe” qui recharge la page avec le code :
1 2 3 |
constellation.client.registerMessageCallback("ReloadMe", function (msg) { location.reload(); }); |
Puis vous ajoutez votre page dans le groupe “ControlPage” :
1 |
constellation.server.subscribeMessages("ControlPage"); |
Dans ce fait, vous pouvez maintenant créer une page “cachée” avec un bouton pour invoquer le MessageCallback “ReloadMe” sur le groupe “ControlPage” afin de recharger toutes les navigateurs qui ont ouvert votre page par la ligne :
1 |
constellation.server.sendMessage({ Scope:'Group', Args:['ControlPage'] }, "ReloadMe", {}); |
Bien entendu, comme vos pages HTML peuvent enregistrer autant de MessageCallbacks qu’elles souhaitent et que ces MessageCallbacks sont invocables depuis n’importe quel système connecté à Constellation, d’autres pages Web, des objets à base d’Arduino, ESP ou autre, des programmes Python, .NET, etc… vous pouvez imaginer tout type d’usage.
Consommer des StateObjects
Pour consommer des StateObjects produits par des packages (virtuels ou réels) de votre Constellation, vous avez deux méthodes : l’évènement “onUpdateStateObject” ou les StateObjectLinks.
La première méthode consiste à enregistre un ou plusieurs handlers sur l’évènement “onUpdateStateObject” :
1 2 3 |
constellation.client.onUpdateStateObject(function (stateobject) { console.log(stateobject); }); |
Les handlers seront déclenchés à chaque mise à jour ou interrogation des StateObjects de votre page quelque soit le StateObject.
Pour interroger un ou plusieurs StateObjects à un instant T vous disposez de la méthode “requestStateObjects”.
Pour vous abonner aux mises à jour d’un ou plusieurs StateObjects, vous disposez de la méthode “subscribeStateObjects” (et “unSubscribeStateObjects” pour vous désabonner).
Enfin la méthode “requestSubscribeStateObjects” réalise un “requestStateObjects” et un “subscribeStateObjects” c’est à dire que la méthode demande la valeur actuelle du ou des StateObjects et s’abonne auprès du serveur Constellation pour être notifiée des mises à jour.
Toutes ces méthodes prennent en paramètre : le nom de la sentinelle, le nom du package, le nom du StateObject et le type du StateObject. Vous pouvez utiliser le wildcard “*” pour ne pas appliquer de filtre (plus d’information ici).
Par exemple, pour récupérer tous les StateObjects du package “Demo” quelque soit la sentinelle et pour s’abonner aux mises à jour de ces StateObjects :
1 |
constellation.server.requestSubscribeStateObjects("*", "Demo", "*", "*"); |
L’autre méthode consiste à enregistrer un (ou plusieurs) StateObjectLink. Cela permet de lier une fonction à un abonnement.
Par exemple :
1 2 3 4 5 6 7 |
constellation.client.registerStateObjectLink("*", "HWMonitor", "/intelcpu/0/load/0", "*", function (so) { // Code A }); constellation.client.registerStateObjectLink("*", "Demo", "*", "*", function (so) { // Code B }); |
Ci-dessus le code A sera invoqué dès qu’un SO nommé « /intelcpu/0/load/0” et produit par le package “HWMonitor” est modifié alors que le code B sera déclenché dès qu’un StateObject du package “Demo” est modifié.
Démarrez la discussion sur le forum Constellation