Cet article a fait l'objet d'une traduction automatique.
Azure Insider
Connecter votre appareil IoT au nuage
Nous avons récemment introduit l'idée de brancher un dispositif Internet des objets (IDO) — dans notre cas le Raspberry Pi — vers le nuage (Microsoft Azure) pour fournir une notification push sur votre appareil mobile, chaque fois que quelqu'un sonne à votre porte à la maison. Cela vous permet de voir qui est à l'étape de votre porte d'entrée à la maison depuis n'importe où dans le monde à l'aide de votre appareil mobile.
Dans l'article de septembre 2014, "soupe à la noix : De matériels bruts à Cloud-Enabled Device"(msdn.microsoft.com/magazine/dn781356), nous avons marché à travers le processus d'intégration de l'appareil sur les blobs de stockage à l'aide de Services Mobile Azure pour obtenir une Signature d'accès partagé (SAS). Cela laisse l'appareil directement télécharger le fichier vers un conteneur de stockage sans n'importe quel niveau de service. Maintenant nous pouvons Télécharger la photo sur le nuage, mais il y a encore quelques petites choses à faire pour envoyer une notification à l'appareil.
Jusqu'ici, Services mobiles d'Azur et Azure Storage ont été mis à profit dans ce projet. Vous devrez également profiter des files d'attente de service autobus et services de tâches planifiées pour envoyer des messages de l'appareil de la Raspberry Pi sur votre appareil mobile. Ces deux services s'intégreront avec Azure Mobile Services, qui va recevoir des messages de la file d'attente du bus de service et de les enregistrer dans une base de données. Dans l'esprit de l'open source et solutions de l'ère nouvelle, nous allons utiliser une base de données MongoDB hébergé et maintenu par MongoLab que vous pouvez ajouter gratuitement comme un Add-on d'Azur.
Service Bus pour la messagerie distribuées
Dans le cadre du calcul d'ITO, les fonctionnalités de file d'attente de bus service fournissent des abstractions puissantes. Files d'attente de service autobus prend en charge asynchrone de messages entre les points de terminaison et qui s'adapte à l'appui de pratiquement n'importe quelle charge de travail. Il également permet aux applications de communiquer entre le nuage et le local sans nécessitant un réseau virtuel, qui peut être un cauchemar logistique et de sécurité.
Nous avons abordé certaines de ces questions dans la colonne de février 2014, « The Windows Azure Service Bus et the Internet of Things » (msdn.microsoft.com/magazine/dn574801). Azure propose un autre service de file d'attente appelé stockage files d'attente, qui a des fonctionnalités similaires, mais en diffère de plusieurs façons clés. Nous avons choisi d'aller avec les files d'attente de service autobus en raison de capacités de serveur de publication/abonné, une plus grande extensibilité dans la gestion des messages et la possibilité de facilement convertir à d'autres services de bus de service. Vous pouvez en savoir plus sur les files d'attente de stockage à bit.ly/XSJB43.
Files d'attente des bus service exposent une API RESTful régulière, qui prend en charge la capacité de recevoir des messages par l'interrogation de longue. Il s'agit d'une technique d'ouvrir une connexion HTTP pour une certaine période de temps. Long du scrutin est une grande technique pour IoT informatique, scénarios car il prend en charge les délais d'attente. Cela permet de dispositifs fermer les connexions jusqu'à ce que le prochain scrutin long, fournir des secours pour les ressources réseau et de la consommation de puissance.
Nous aurons une relation plusieurs-à-un des dispositifs de sonnette SmartDoor à un seul service mobile. Plus précisément, cette forme de pub/sub impliquera de nombreux éditeurs de message et seulement un abonné de message unique. L'abonné sera dans ce cas le service mobile, qui va donner lecture de la file d'attente. Un ou plusieurs dispositifs de SmartDoor sera l'éditeur. Il est tout à fait possible de faire l'inverse, dans le cas où vous souhaitez envoyer un message à l'appareil.
Il y a quatre types de modes de communication généralement utilisées dans les scénarios de l'ITO. Comme vous pouvez le voir dans Figure 1, un ou plusieurs dispositifs de Raspberry Pi publient des messages à des files d'attente du bus de service. Azur Services Mobile est le seul abonné aux files d'attente de service bus.
Figure 1 schéma Architectural d'Azur Mobile Services de lecture du Service Bus
Azur Mobile Services fournit un planificateur de tâches intégrés, qui peut planifier des tâches à intervalles fixes. Nous allons lire de la file d'attente du bus de service à un intervalle de 60 secondes. Consultez notre blog post à bit.ly/1o1nUrY pour plus d'informations sur les services mobiles de connexion à une file d'attente du bus de service. Avec notre tâche planifiée, doorBellListener (voir Figure 2), nous allons lire la file d'attente en utilisant le bus de service API dans le SDK Azure de Node.js avec notre chaîne de connexion.
La figure 2 une tâche planifiée d'Azur Mobile doorbellListener
// Get a reference to the azure module
var azure = require('azure');
// Get our service bus connection string
var connectionString = process.env.ServiceBusConnectionString;
// This task will run for 60 seconds so the initial timeout should be 60
var c_Timeout = 60;
function doorbellListener() {
//Get the current unix time in seconds
var date = new Date();
var time = date.getTime();
var startSeconds = time / 1000;
var sb = azure.createServiceBusService(connectionString);
listenForMessages(c_Timeout);
// Define a function that will listen for messages
// on the queue for number of seconds
function listenForMessages(seconds) {
console.log('Doorbell Listener Started for timeout: ' + seconds);
// Long poll the service bus for seconds
sb.receiveQueueMessage("smartdoor", { timeoutIntervalInS: seconds },
function(err, data) {
if(err){
// This path will get hit if we didn't get any messages
console.log(err);
}
else{
// We have received a message from a device
var ringNotification = JSON.parse(data.body);
console.log('recieved message from doorbell ' +
ringNotification.doorbellId + '
with image link ' + ringNotification.imagePointer)
function continueListeningForMessages(){
// Go back and listen for more messages for the duration of this task
var currentDate = new Date();
var currentSeconds = currentDate.getTime() / 1000;
console.log('currentSeconds ' + currentSeconds);
console.log('startSeconds ' + startSeconds);
// Compute the seconds between when we started this scheduled task and now
// This is the time that we will long-poll the service bus
var newTimeout = Math.round((c_Timeout - (currentSeconds - startSeconds)));
if(newTimeout > 0){
// Note: the receiveQueueMessage function takes ints no decimals!!
listenForMessages(newTimeout);
}
}
En raison de la nature asynchrone de Node.js et le comportement d'envoi d'un message vers le bus de service par l'intermédiaire du scrutin long, calculez la valeur de délai est passée à recieveQueueMessage, en fonction de combien de temps cette instance de la tâche planifiée a été exécuté. Ceci empêchera plusieurs instances de la tâche de s'exécuter simultanément.
La chose gentille au sujet de bus de service est qu'il expose une API RESTful. N'importe quel dispositif que vous utilisez, vous pouvez envoyer des que messages d'elle. Azure a SDK pour les principaux langages comme Python, Ruby, Node.js et c#. Parce que nous voulons que le code à être traduit dans n'importe quelle plateforme, nous allons utiliser directement l'API RESTful.
Pour envoyer un message, nous devrons créer une stratégie pour la file d'attente du bus de service. Cette politique est une clé qui permet à certaines opérations sur le bus de votre service. Il y a un certain nombre de conditions pour toute file d'attente donnée. En tenir compte dans votre propre domaine de problème.
Nous générerons une stratégie appelée DevicePolicy qui seulement permet aux utilisateurs d'envoyer des messages à la file d'attente des bus service (voir Figure 3).
Cela garantit que si la clé obtient jamais entre de mauvaises mains, personne d'autre ne peut écouter les messages sur le bus de service.
Figure 3 DevicePolicy Will envoyer des Messages à la file d'attente du Bus de Service
Le code de la Pi de framboise envoyer un message de la file d'attente du bus de service est indiqué dans Figure 4.
Figure 4 envoi d'un Message indiquant le succès Photo Télécharger
Console.WriteLine("Sending notification to service bus queue");
WebRequest sbRequest = WebRequest.Create(
"https://smartdoordemo.servicebus.Windows.net/smartdoorqueue/messages");
var headers = sbRequest.Headers;
sbRequest.Method = "POST";
using (var sbMessageStream = sbRequest.GetRequestStream())
{
string body = JsonConvert.SerializeObject(new DoorBellNotification()
{
doorBellID = deviceID,
imageUrl = photoResp.photoId
});
var bytes = Encoding.UTF8.GetBytes(body);
sbMessageStream.Write(bytes, 0, bytes.Length);
headers.Add("Authorization", createToken(
"https://smartdoordemo.servicebus.Windows.net/smartdoorqueue/
messages", "DevicePolicy",
ConfigurationManager.AppSettings["ServiceBusSharedAccessKey"]));
}
try
{
Console.WriteLine("Sending door bell notification for " + deviceID);
using (var response = sbRequest.GetResponse())
{
Console.WriteLine("Sucessfully Sent");
}
}
catch (Exception e)
{
Console.WriteLine("Couldn't post to service bus -" + e);
}
Vous pouvez voir le code complet de program.cs à bit.ly/1qFYAF2. Dans ce code, nous faire une demande POST sur la file d'attente des bus service API RESTful et fournir une SAS, semblable à la signature, que nous avons reçu de services mobiles pour le stockage blob. Ce SAS est composé d'une clé de chiffrement à l'aide de l'algorithme SHA-256. Il définit la ressource accédée ainsi que le délai d'expiration de SAS. La méthode createToken est une méthode simple qui construit le SAS basé sur votre clé d'accès partagé à la politique de DevicePolicy.
Après la construction de la SAS, nous placer dans un en-tête HTTP et placer le message sérialisé (dans le format JSON) dans le corps de la requête. Après la requête POST, un message est envoyé à la file d'attente du bus de service pour indiquer le téléchargement réussi d'une photo. Le message contient le lien vers le blob téléchargé et un identificateur unique pour cet appareil de sonnette qui vient des paramètres de l'application. Cet identifiant peut être connu dans le fichier app.config de xml, qui est assis à côté de l'auditeur de sonnette exécutable :
<appSettings>
<add key="DoorBellID" value="123456"/>
...
</appSettings>
Le dispositif est maintenant envoi de messages vers le bus de service lors de son exécution. En allant dans l'onglet journal dans notre page d'atterrissage Mobile Services nous pouvons accéder à la sortie de journal de service en direct. Lorsque nous exécutons le code c# en Visual Studio , vous pouvez voir que le service mobile a obtenu le contenu du message par le biais de la sortie du journal dans le portail.
Bien que les Services Mobile Azure offre parfaitement bonnes tables (soutenus par SQL Server) pour le stockage, nous allons pour une approche légèrement différente. Nous allons utiliser MongoDB comme notre solution de base de données. MongoDB fonctionne très bien avec Node.js parce que c'est un document -axé sur la base de données et ressemble à une collection d'objets JSON dans le stockage. Lire que plus d'infos sur le MongoDB projet open source à mongodb.org. Nous allons utiliser MongoLab, une base de données comme un prestataire de services (DaaS), d'accueillir notre base de données.
Nous avons besoin de la base de données pour suivre les quelques choses :
- Sonnettes — appareil Raspberry Pi unique
- Photos : une photo prise par une sonnette
Une fois que la base de données MongoDB est configuré, nous pouvons utiliser mangouste en tant que notre chauffeur MongoDB pour notre code d'Azur Mobile Services Node.js en l'installant à notre mobile services dépôt Git. C'est le même processus que nous avons traversé pour installer le module de nœud de qs :
npm install mongoose
En poussant le référentiel local va déclencher le service mobile pour installer le Mongoose dans son référentiel. C'est comment nous pouvons obtenir n'importe quel paquet de Node.js dans Azure Mobile Services. Comme pour chaque module de Node.js, nous pouvons le référencer à l'aide de RequireJs et initialiser Mongoose avec notre chaîne de connexion de MongoDB dans notre tâche planifiée :
var mongoose = require('mongoose');
Mangouste sera responsable de la création d'un schéma structuré dans notre base de données du document (voir Figure 5). Nous allons utiliser deux entités : sonnette et photo. Chaque objet de sonnette dans notre base de données représentera un dispositif Raspberry Pi. Il contient un identificateur unique, doorBellID et un tableau d'objets photo. Chaque photo contient un lien vers la photo en stockage blob, mais aussi un horodatage généré par le service lorsqu'il reçoit un message de bus de service.
Figure 5 schémas définis dans Mongoose
var photoSchema = mongoose.Schema({
url : String,
timestamp: String
});
var doorbellSchema = mongoose.Schema({
doorBellID: String,
photos: [photoSchema]
});
var Photo = mongoose.model('Photo', photoSchema)
var DoorBell = mongoose.model('DoorBell', doorbellSchema);
// Expose these schemas
exports.DoorBell = DoorBell;
exports.Photo = Photo;
Nous exposons les schémas sonnette et Photo publiquement via le mot-clé des exportations. Remarquez comment il est entrelacé photoSchema dans doorbellSchema. C'est la façon dont les données se reflétera lorsqu'il est conservé dans la base de données.
Nous allons placer ce code dans le dossier partagé de notre référentiel de services mobiles. Cela nous permet d'utiliser les schémas n'importe où dans notre service. Pour faire référence aux schémas de notre tâche planifiée, nous avons juste besoin de l'importer avec une déclaration :
var schemas = require('../shared/schemas.js');
Maintenant nous pouvons utiliser ces schémas dans notre tâche planifiée pour définir de nouvelles entités de base de données. Nous utiliserons une fonction spécialisée pour s'assurer que nous sommes connectés à MongoDB et exécuter un rappel. Après avoir reçu un message provenant du bus de service, le service mobile devrait :
- Vérifier si la sonnette de la porte avec le doorBellID spécifié dans le message existe dans la base de données.
- S'il n'existe pas, créer une nouvelle entité de sonnette avec la photo.
- S'il n'existe pas, simplement ajouter la nouvelle photo en tableau photo de la sonnette existante.
Vous pouvez voir la logique pour cela dans le code de Figure 6.
Logique de la figure 6 pour vérifier la sonnette et de gérer les photos
// Create database entry for this image
dbConnectAndExecute(function(err){
if(err){
console.log('could not record image to database -' + err);
return;
}
DoorBell.findOne({ doorBellID: ringNotification.doorBellID},
function(err, doorbell){
if(err){
return console.error(err);
}
if(doorbell === null){
console.log('Doorbell not found in DB, creating a new one');
// Take the entire body's json, assuming it fits into this schema
var entityObject = {
doorBellID : ringNotification.doorBellID,
photos : []
};
entityObject.photos.push({
url : ringNotification.imageUrl,
// Set timestamp to current server time
timestamp : ((new Date()).getTime()).toString()
})
var doorbell = new DoorBell(entityObject);
}
else{
// We already have this device in the database—add a picture
doorbell.photos.push({
url : ringNotification.imageUrl,
// Set timestamp to current server time
timestamp : ((new Date()).getTime()).toString()
});
}
// Commit changes to db
doorbell.save(function (err, entity) {
if(err){
return console.error(err);
}
console.log('sucessfully created new entity for: ' + entity);
return;
});
});
});
Vous pouvez voir une démonstration complète de doorbelllistener à bit.ly/VKrlYU.
Nous appelons la fonction dbConnectAndExecute pour s'assurer que nous sommes connectés à notre base de données MongoDB en MongoLabs. Ensuite, nous nous interrogeons la base de données pour une sonnette avec l'ID spécifié dans le message. Si la requête est vide, nous créons une nouvelle entité de sonnette. Dans le cas contraire, nous avons ajouter la photo à l'entité de récupérations et valider les modifications sur la base de données.
Maintenant voir dans Figure 7 que se passe-t-il lorsque nous envoyons un message photo et service de bus avec notre dispositif Raspberry Pi.
Figure 7 le résultat de l'envoi d'un Message et une Photo
Inspecter le journal des services mobiles dans le portail après que Raspberry Pi a envoyé que le message montre la photo a été traitée et ajouté à la base de données.
Pour faire bonne mesure, nous pouvons vérifier notre base de données MongoDB pour s'assurer que nous sommes en fait suivi les photos. MongoLab fournit une interface de contrôle de MongoDB riche via son portail Web. Figure 8 montre ce que l'entité de la sonnette peut ressembler après quelques ajouts de photos.
Figure 8 MongoDB enregistrement entrées
Maintenant, Raspberry Pi est entièrement intégré à notre service de Cloud Computing. L'appareil peut télécharger un fichier directement pour le stockage en nuage, de notifier le service cloud via le bus de service et d'avoir les informations stockées dans une base de données.
La prochaine étape de cette série intégrera une application mobile à l'arrière du nuage avec les notifications de transmission des images. Nous allons utiliser l'API personnalisé de surface des objets de la base de données à l'app et d'intégrer une API de fournisseur tiers pour reconnaissance faciale d'image et d'un système de notification pour alimenter les notifications push. Vous pouvez examiner les dépôts de code pour créer et modifier la solution vous-même. L'Azure Mobile Services back-end est à bit.ly/1mHCl0q. Vous trouverez le Code Pi framboise à bit.ly/1l8aOtF.
Intégrant les dispositifs Raspberry PI pour back-ends de nuages est critique. S'appuyant sur des technologies open source comme Node.js est logique dans de nombreux scénarios où vous utilisez un léger back-end pour adapté à un grand nombre d'appareils.
Le bus de service Azure fournit un moyen sûr et pratique pour les périphériques connectés occasionnellement tirer parti d'une infrastructure de messagerie fiable qui s'adapte à nombreux clients. Enfin, s'appuyant sur des magasins de NoSQL est un moyen populaire pour rendre persistantes les données et conserver la syntaxe JavaScript native dans la couche de données et service de back-end Node.js.
Steven Edouard est un développeur chez Microsoft. Auparavant, il a travaillé sur l'équipe du runtime .NET comme ingénieur de test logiciel fournissant des produits comme le .NET Framework 4.5 et .NET Compilation Native. Sa passion réside maintenant à des personnes passionnantes sur le potentiel illimité du cloud computing services par le biais de démonstrations techniques, des contenus en ligne et des présentations.
Bruno Terkaly est développeur pour Microsoft. Ses connaissances approfondies sont issues d'années d'expérience dans le domaine, au cours desquelles il a écrit du code à l'aide d'une multitude de plateformes, de langages, d'infrastructures, de SDK, de bibliothèques et d'API. Il passe temps écriture de code, de blogs et de donner des présentations en direct sur la création d'applications basées sur un nuage, plus précisément à l'aide de la plateforme Azure de Microsoft. Vous pouvez consulter son blog à l'adresse blogs.msdn.com/b/brunoterkaly.
Merci aux experts techniques Microsoft suivants d'avoir relu cet article : Gil Isaacs et Brent Stineman