Il y a 7 ans -
Temps de lecture 7 minutes
Atelier – Plateforme 1 – AWS (1/3)
Ca y est, le moment est venu. Nous avons construit un objet connecté, nous l’avons connecté à un service de télécommunication, il est maintenant temps d’exploiter nos données, à l’aide du plus puissant data center jamais créé, à savoir le Cloud.
Ne le cachons pas, aujourd’hui tous les fournisseurs proposent leurs services IoT. Ne nous le cachons pas non plus, derrière de très nombreux effets d’annonce, les premières expérimentations, même pour les plus avancés, sont franchement décevantes. Mais ne vendons pas la peau du nuage, et plongeons directement dans le vif du sujet.
Si je dis fournisseur cloud, mondialement connu, accessible avec n’importe quelle carte bleue, et proposant un service IoT, vous répondez ? Il y a un piège, plusieurs fournisseurs répondent à cette description… J’ajoute donc « que nous maitrisons et dont nous sommes partenaires »… J’ai nommé AWS.
Balbutions donc nos premiers scripts sur le Cloud IoT, avec les règles que nous nous sommes fixées.
Comme d’habitude, tout ce qui est réalisé ici est disponible sur le GitHub Xebia-France.
Et c’est déjà l’heure du premier mur
Ah oui, la lune de miel n’a pas duré longtemps. À peu près aussi longtemps que le chargement de la documentation. Le point d’entrée pour les objets dans AWS IoT est un SDK propriétaire, à installer directement sur l’objet. Il existe plusieurs SDK (C, Arduino Yun ou NodeJs), mais tous doivent être insérés dans l’appareil et donc coupler fortement l’objet et le fournisseur Cloud.
Passée cette première frayeur, on se rend rapidement compte que cela n’est « pas si pire » : le SDK AWS n’est qu’un wrapper autour du célèbre protocole de communication MQTT. Néanmoins, pour notre cas d’utilisation, il va falloir ruser. Nous l’avons vu, le seul point de sortie de Sigfox est un call back HTTP(S). Il va donc falloir convertir notre canal de communication HTTP(S) en un canal MQTT.
Un pont entre deux rives
Qu’à cela ne tienne, pas question de se laisser abattre à la première difficulté, nous nous lançons dans le développement d’un Sigfox To Mqtt Bridge. L’idée est toute simple : exposer un point d’entrée HTTPS, et collecter le JSON contenu dans le body pour le transmettre dans le corps d’un message MQTT. A priori rien de bien méchant, si tout est correctement documenté.
Première étape, exposer une API REST en HTTPS. Facile, en piochant dans le catalogue AWS, nous allons utiliser API Gateway, qui permet d’exposer facilement des API quelles qu’elles soient.
Deuxième question existentielle : que mettre derrière ? Le SDK AWS IoT se décline dans un grand nombre de langages ; nous n’avons donc que l’embarras du choix. Laissons donc les choix architecturaux nous dicter le langage. Nous sommes sur un prototype ; le nombre d’appels vers Sigfox et donc vers AWS devrait être très limité. Dans ce cas, pourquoi payer un serveur qui tourne 24/24 7/7, alors qu’AWS offre la fonctionnalité Lambda, pour laquelle la facturation se fait au temps d’exécution ? Autre point non négligeable, l’interfaçage entre Lambda et API Gateway est natif ! Lambda est disponible en Javascript et en Python. Bingo, nous optons par JavaScript, via NodeJs.
Pour la partie réception du callback HTTPS, rien de bien sorcier, AWS propose un modèle de handler qui permet de facilement router l’appel reçu par l’API Gateway directement dans votre code Node.
[js]exports.sigfoxHandler = function(event, context) {
// Log message received from Sigfox
console.log("Start process : message received : " + JSON.stringify(event, void 0, 2));
}[/js]
Ce simple morceau de code vous permet déjà de brancher Sigfox avec Lambda ! Pourquoi pas donc commencer à l’utiliser ? Une fois déployé dans AWS, vous êtes en mesure de récupérer une URL vers votre Lamba.
Rouvrez la page de vos callbacks Sigfox, dupliquez le callback que vous aviez réalisé pour Mockbin.
Et de manière assez immédiate, vous devriez voir vos messages Sigfox loggés dans AWS !
Euh…. Mais j’ai pas utilisé le module IoT là ??!!
En effet, il est possible de « faire de l’IoT » dans AWS (et chez tous les concurrents) en ignorant royalement leurs modules dédiés (et vu la stabilité de certains, nous ferions peut être mieux…). Mais telles ne sont pas les règles du jeu. Nous allons donc étoffer notre Lambda pour ajouter la gestion des objets.
Première étape, modifier légèrement l’URL du callback pour ajouter l’identifiant de l’objet dans la requête. Et pour plus facilement identifier les messages, nous allons ajouter le numéro de séquence Sigfox, qui est propre à chaque objet.
Il est maintenant temps d’ouvrir (enfin) le service IoT. Dans un premier temps, pas de piège, il suffit de créer un objet virtuel.
Cliquez ensuite sur votre objet nouvellement créé et cliquez sur « Connect a device ». Nous choisissons d’utiliser le SDK NodeJs (normal, nous allons « simuler » la connexion MQTT de notre objet dans notre bridge Lambda).
Nous voilà donc parti pour créer les certificats propres à notre objet, qui seront utilisés entre le bridge et la brique IoT. Pensez bien à sauvegarder l’intégralité des fichiers, sinon vous êtes bon pour recommencer.
Nous sommes maintenant prêts à créer notre bridge.
Les mains dans le SDK AWS pour Node.
Le SDK propose deux objets : le Device et le ThingShadow. Sachant que ThingShadow recouvre intégralement Device, et qu’il propose plus de fonctionnalités, nous allons utiliser ThingShadow. Pour information, ces deux objets ne sont finalement qu’un wrapper au dessus de MQTT.
Première étape, les chaines de connexion :
[js]var awsIot = require(‘aws-iot-device-sdk’);
var thingShadows = awsIot.thingShadow({
keyPath: ‘~/awsCerts/private.pem.key’,
certPath: ‘~/awsCerts/certificate.pem.crt’,
caPath: ‘~/awsCerts/root-CA.crt’,
clientId: ‘myAwsClientId’,
region: ‘eu-west-1’
});[/js]
Il va donc falloir embarquer nos certificats dans notre bridge, plutôt que dans notre objet. Pour cette première démonstration, cela ne pose pas de problème, mais on imagine bien qu’il faudra trouver une autre solution pour gérer des dizaine de milliers d’objets.
Nous proposerons une solution à ce problème dans la suite de cette série.
Pour ceux qui ont du mal à se repérer dans la documentation (et c’est notre cas), vous pourrez trouver le root-CA ici.
Affichons un parti pris : pour chaque appel reçu par la Lambda, nous allons connecter / déconnecter le ThingShadow. Nous pouvons donc envoyer les messages que Sigfox nous fait suivre dans le on(« connect »).
[js]thingShadows
.on(‘connect’, function() {
console.log(‘Connected to things instance, registering thing name’);
thingShadows.register( thingId, { ignoreDeltas: true, persistentSubscribe: true } );
console.log("Publish data to IoT");
event.idEvent = uuid.v4();
thingShadows.publish(‘data’, JSON.stringify(event, null, 2));
});[/js]
Le code de ce handler est disponible dans le fichier simpleUplink.js. Il est possible de le lancer en local via la commande
[bash]npm install
node runLocal.js[/bash]
N’oubliez pas de personnaliser les éléments suivants :
- votre device (via son id).
- vos clés de connexions (clé privée et certificat).
- le nom de votre clientId.
- éventuellement votre région.
Si vous êtes satisfait du résultat en local, vous pouvez zipper le tout (en incluant le répertoire node_modules) et déployer sur AWS Lambda. N’oubliez pas de changer le nom de votre handler en simpleUplink.handler.
Retour à AWS IoT… où sont mes données ????
Mettons maintenant en place notre première brique de debug (sans elle, force est de constater que la plateforme AWS IoT vous laisse aveugles et sourds sur son fonctionnement). Nous allons donc ajouter une règle.
Retournons donc dans AWS IoT, dans notre objet. Cliquez sur « Create a rule ».
Dans la section Query, pas de surprise, nous retrouvons un équivalent du bon vieux SQL. Nous allons prendre toutes les données (*) du topic data. Pour l’action, nous allons au plus simple : chaque évènement recu de la part de notre objet sera stocké sous forme de fichier dans un bucket S3 dédié (qu’il vous faudra préalablement créer). Pour le nom du fichier, faisons simple, utilisons un uuid généré dans le code Lambda (${idEvent}). Ajoutez un rôle, créez la règle et cela devrait commencer à rouler.
Les données de mon objets dans le cloud !
Et nous voici arrivés au terme de cette première étape. Que vous passiez en local, ou bien via Lambda (et Postman), ou encore via votre objet et le réseau Sigfox, vous devriez arriver au même résultat : l’évènement émis par votre objet est stocké sous forme de fichier JSON dans S3.
Si vous êtes arrivés jusque là, bravo. Mais il reste encore du chemin à parcourir, avec la découverte des Shadows, la gestion du downlink Sigfox et l’ajout par petites touches de nouveaux services. Mais ça, ce sera pour une prochaine fois.
Commentaire
7 réponses pour " Atelier – Plateforme 1 – AWS (1/3) "
Published by Julien Simon , Il y a 7 ans
Bon article. Une petite précision : pas question d’être sourd et aveugle pour debugger. Il suffit d’activer les logs pour tracer les messages, les appels aux règles, etc.
Voilà la doc : https://docs.aws.amazon.com/fr_fr/iot/latest/developerguide/cloud-watch-logs.html
Published by Pablo Lopez , Il y a 7 ans
Merci Julien pour ce commentaire et pour ce lien.
« Sourd et aveugle » est certes une formulation excessive. Tel n’était pas le sens de mon propos. Le reproche que l’on peut faire au module IoT, c’est qu’au niveau du Dashboard, sans activer de debug ou une sortie complémentaire, l’interface ne donne pas d’information sur la date de dernière connexion de l’objet ou bien sur la quantité de messages échangée. Certaines plateformes concurrentes proposent cette fonctionnalité « visuelle » qui permet de rapidement valider que l’objet est connecté au service sous-jacent.
Published by Quentin DESBOIS , Il y a 7 ans
Bonjour et merci pour l’article complet :)
Je suis intéressé par l’intégration des messages Sigfox avec AWS, j’ai donc suivi votre tutoriel… seulement je ne comprend pas tout.
Notamment la transition entre le callback Sigfox vers Lambda et le chapitre ‘Les mains dans le SDK AWS pour Node.’. Dans ce dernier chapitre vous expliquez comment envoyer directement les messages vers le mqtt de AWS IoT (grâce aux credentials), il n’y a donc plus de liens avec le backend de Sigfox.
Pouvez-vous m’expliquer ? Je cherche à comprendre comment effectuer un bridge entre Lambda et AWS IoT.
Sinon ne serait-il pas possible de modifier l’adresse de callback de sigfox pour pointer vers le restAPI endpoint du thing dans AWS IOT ? (à condition de renseigner les credentials dans les headers http sur Sigfox. PS: J’ai trouvé un axe de recherche à ce sujet en utilisant PostMAN qui permet de s’authentifier avec des AWS Signatures et donc de récupérer les chaines de caractères à intégrer dans le header du callback)
N’hésitez pas à me contacter par email pour que nous échangions, je souhaite intégrer des callbacks de serveur LoRa dans un second temps.
Published by Pablo Lopez , Il y a 7 ans
Bonjour Quentin.
Appeler le broker MQTT en HTTP directement depuis Sigfox pose selon moi un certain nombre de problèmes :
– en premier lieu, Sigfox ne gère (pour l’instant) pas la signature V4 AWS et il faut donc, comme vous l’avez suggéré, générer un token en dehors de Sigfox. Ce token a une durée de vie limitée, et il faudrait donc régulièrement retourner dans le backend Sigfox pour modifier le callback. Ce n’est pas une solution viable à long terme.
– autre soucis, cette méthode ne permet pas de gérer finement les devices. Par exemple, si je veux qu’un objet « piraté » cesse de m’envoyer des données, je n’ai qu’à invalider son certificat dans le back end AWS IoT pour qu’il ne puisse plus me polluer.
En ce qui concerne le lien entre le backend Sigfox et AWS IoT, cet article illustre la mise en place de la chaine suivante :
Backend Sigfox –(HTTPS POST)–> AWS Lambda –(MQTT via SDK)–> AWS IoT
Nous allons « prochainement » (à l’échelle des temps géologiques) proposer d’autres séries d’articles, sur Lora point à point, sur LoraWan, sur Bluemix et Azure.
Merci de votre fidélité à notre blog.
Published by Quentin DESBOIS , Il y a 7 ans
Merci Pablo pour les éclaircissements. J’étais dernièrement au SIdO à Lyon, et les employés du stand AWS m’ont laissé croire que Sigfox intégrerai bientôt un callback ‘AWS’ (tout comme Azure)…. à voir.
Concernant l’article, c’est ça que je ne comprend pas :
(MQTT via SDK) = le code NodeJS est bien placé dans le device (type Rpi par exemple) ?
Moi ce que j’ai compris c’est que les 2 sont séparés :
Backend Sigfox –(HTTPS POST)–> AWS Lambda
(MQTT via SDK)–> AWS IoT
Si je me place en entrée du point de vue du POST HTTP du callback Sigfox, comment faire le bridge entre Lambda et AWS IoT ?
Merci encore pour ta rapidité.
Published by Pablo Lopez , Il y a 7 ans
Dans notre exemple, le code NodeJS n’est pas placé dans le Device (nous avons émis comme postulat de base que l’objet connecté est indépendant de la plateforme à laquelle il se connecte), mais dans Lambda.
On a donc Objet -(code C++)-> Sigfox -(tambouille interne Sigfox)-> Callback -(HTTPS)-> Lambda -(MQTT)-> IoT
Published by Quentin DESBOIS , Il y a 7 ans
D’accord alors tout est clair dans ton tutoriel !
Je suis juste bloqué dans Lambda à la compilation, il ne trouve même pas la library aws-iot-device-sdk … j’ai une erreur :
« errorMessage »: « Cannot find module ‘aws-iot-device-sdk' »
Published by Pablo Lopez , Il y a 7 ans
Il faut utiliser la commande npm install.
Si tout fonctionne en local, il faut zipper l’ensemble des fichiers, en incluant le répertoire node_modules, et déployer ce zip sur Lambda
Published by Quentin DESBOIS , Il y a 7 ans
Aha merci :)
A la seconde où j’ai effectué cette opération en suivant ce lien : http://docs.aws.amazon.com/lambda/latest/dg/nodejs-create-deployment-pkg.html , j’ai vu le passage de l’article qui me disait ce que tu viens de me dire à l’instant … Désolé j’avais pas vu :(
C’est une étape assez peu intuitive finalement, tu devrais le surligner en gras.
Merci encore ! :)