Il presente articolo è stato tradotto automaticamente.

Azure Insider

Connetti il tuo dispositivo Internet delle cose al cloud

Bruno Terkaly
Steven Edouard

Bruno Terkaly, Ricardo Villalobos Recentemente abbiamo introdotto l'idea del collegamento di un dispositivo Internet of Things (IoT) — nel nostro caso Raspberry Pi — la nuvola (Microsoft Azure) per consegnare una notifica push al dispositivo mobile ogni volta che qualcuno suona il campanello a casa. Ciò consente di vedere chi è al vostro passo porta a casa da ovunque nel mondo usando il tuo dispositivo mobile.

Nell'articolo di settembre 2014, "zuppa alle noci: Da crudo Hardware al dispositivo di Cloud-Enabled"(msdn.microsoft.com/magazine/dn781356), abbiamo camminato attraverso il processo di integrazione del dispositivo a blob di archiviazione utilizzando servizi di Azure Mobile per ottenere una firma di accesso condiviso (SAS). Questo lascia il dispositivo direttamente caricare il file su un contenitore di stoccaggio senza alcun livello di servizio. Ora noi possiamo caricare la foto della nube, ma ci sono ancora alcune cose da fare per inviare una notifica al dispositivo.

Finora, servizi Mobile Azure e Azure Storage hanno sfruttato in questo progetto. Sarà anche necessario sfruttare le code di servizio autobus e servizi operazioni pianificate per inviare messaggi dal dispositivo Raspberry Pi al tuo dispositivo mobile. Questi due servizi saranno integrati con servizi di Mobile Azure, che ricevere messaggi dalla coda di servizio autobus e registrarli in un database. Nello spirito dell'open source e soluzioni new age, utilizziamo un database MongoDB ospitato e gestito da MongoLab che è possibile aggiungere gratuitamente come componente aggiuntivo di Azure.

Servizio Bus per la messaggistica distribuita

Nel contesto dell'informatica IoT, le funzionalità di accodarvi servizio autobus forniscono potenti astrazioni. Servizio autobus code supporta tra endpoint di messaggistica asincrona e possono scalare per supportare qualsiasi carico di lavoro. Esso permette anche applicazioni di comunicare tra la nube e locali senza che richiedono una rete virtuale, che può essere un incubo logistico e di sicurezza.

Abbiamo affrontato alcune di queste questioni nella colonna febbraio 2014, "The Windows Azure servizio Bus e the Internet of Things" (msdn.microsoft.com/magazine/dn574801). Azure offre un altro servizio di accodarvi chiamato code di archiviazione, che ha funzionalità simili, ma presenta alcune differenze chiave. Abbiamo scelto di andare con code di servizio autobus a causa della funzionalità del server di pubblicazione/Sottoscrittore, maggiore scalabilità nella gestione dei messaggi e la capacità di convertire facilmente in altri servizi del bus di servizio. Si può leggere di più sulle code di archiviazione a bit.ly/XSJB43.

Code di servizio autobus espongono un regolare RESTful API che supporta la possibilità di ricevere messaggi tramite polling lungo. Questa è una tecnica di aprire una connessione HTTP per un certo periodo di tempo. Tempo di polling è una grande tecnica per IoT scenari di calcolo poiché supporta il timeout. Questo consente a dispositivi chiudere connessioni fino al prossimo sondaggio lungo, fornendo sollievo alle risorse di rete e il consumo di potenza.

Avremo una relazione molti-a-uno dei dispositivi del campanello SmartDoor a un solo servizio mobile. Più specificamente, questa forma di pub/sub coinvolgerà molti editori di messaggio e solo un abbonato del singolo messaggio. In questo caso l'abbonato sarà il servizio mobile, che leggerò dalla coda. Uno o più dispositivi di SmartDoor sarà l'editore. È possibile fare il contrario, nel caso in cui si desidera inviare un messaggio al dispositivo.

Ci sono quattro tipi di modelli di comunicazione generalmente utilizzati in scenari di IoT. Come si può vedere Figura 1, uno o più dispositivi Raspberry Pi sono pubblicando i messaggi per le code di servizio autobus. Servizi Mobile azzurro è solo Sottoscrittore a code di servizio autobus.

Diagramma architettonica del Mobile azzurro servizi lettura da servizio Bus
Figura 1 Diagramma architettonica del Mobile azzurro servizi lettura da servizio Bus

Azzurre Mobile Services fornisce un'integrata utilità di pianificazione, che può pianificare operazioni a intervalli fissi. Ti leggiamo dalla coda servizio autobus a intervalli di 60 secondi. Controllare il nostro post sul blog al bit.ly/1o1nUrY per dettagliate informazioni sulla connessione dei servizi mobili a una coda di servizio autobus. Con la nostra attività pianificata, doorBellListener (vedere Figura 2), ti leggiamo dalla coda tramite il bus di servizio API in node. js Azure SDK con nostra stringa di connessione.

Figura 2 attività pianificata di Azure 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);
        }
      }

A causa della natura asincrona di node. js e il comportamento di inviare un messaggio di service bus tramite polling lungo, deve calcolare il valore di timeout passato a recieveQueueMessage, a seconda di quanto tempo è in corso questa istanza dell'operazione pianificata. Questo impedirà più istanze dell'attività in esecuzione contemporaneamente.

La cosa bella di servizio bus è che espone un'API RESTful. Non importa quale dispositivo si sta utilizzando, è possibile inviare che messaggi di esso. Azure ha SDK per i principali linguaggi come Python, Ruby, node. js e c#. Perché vogliamo che il codice da tradurre per qualsiasi piattaforma, useremo direttamente l'API RESTful.

Per poter inviare un messaggio, abbiamo bisogno di creare un criterio per la coda di servizio autobus. Questa politica è una chiave che permette alcune operazioni sul vostro bus di servizio. Ci sono un certo numero di politiche per qualsiasi coda specificata. Tenerne conto nel proprio dominio del problema.

Ci potrai generare una politica chiamata DevicePolicy che solo consente agli utenti di inviare messaggi alla coda di servizio autobus (Vedi Figura 3).

Questo assicura che se la chiave si ottiene mai nelle mani sbagliate, nessun altro può ascoltare i messaggi sul bus di servizio.

DevicePolicy Will inviare messaggi alla coda del Bus di servizio
Figura 3 DevicePolicy Will inviare messaggi alla coda del Bus di servizio

Il codice dispositivo per Raspberry Pi inviare un messaggio della coda di autobus del servizio è illustrato Figura 4.

Figura 4 l'invio di un messaggio che indica successo foto caricare

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);
  }

Si può vedere il codice completo del file program.cs presso bit.ly/1qFYAF2. In quel codice, non una richiesta POST nella coda di autobus servizio RESTful API e fornire un SAS, simile alla firma che abbiamo ricevuto da servizi di telefonia mobile per archiviazione blob. Questo SAS è composto da una chiave di crittografia utilizzando l'algoritmo SHA-256. Esso definisce la risorsa accede così come la data di scadenza SAS. Il createToken è un metodo semplice che costruisce la SAS basato sulla vostra chiave di accesso condiviso dalla politica DevicePolicy.

Dopo la costruzione della SAS, noi collocarlo in un'intestazione HTTP e inserire il messaggio serializzato (in formato JSON) nel corpo della richiesta. Dopo fatta la richiesta POST, un messaggio viene inviato alla coda di servizio autobus per indicare il successo upload di una foto. Il messaggio contiene il link per il blob caricato e un identificatore univoco per questo dispositivo di campanello che proviene dalle impostazioni dell'applicazione. Questo identificatore è reperibile nel file app. config xml, che si trova accanto all'ascoltatore campanello eseguibile:

<appSettings>
  <add key="DoorBellID" value="123456"/>
...
</appSettings>

Ora l'apparecchio sta inviando messaggi di service bus durante l'esecuzione. Andando alla scheda registro nella nostra pagina di destinazione Mobile servizi possiamo accedere l'output del registro di servizio dal vivo. Quando si esegue il codice c# in Visual Studio si può vedere che il servizio di telefonia mobile ha ottenuto il contenuto del messaggio attraverso l'output di log nel portale.

Sebbene Azure Mobile Services offre tavoli perfettamente buoni (sostenute da SQL Server) per l'archiviazione, stiamo andando per un approccio leggermente diverso. Utilizzeremo MongoDB come la nostra soluzione di database. MongoDB funziona molto bene con node. js, perché è un documento -­oriented database e assomiglia a un insieme di oggetti JSON in archiviazione. Leggere che più circa il MongoDB progetto open source presso mongodb.org. Useremo il MongoLab, un Database come fornitore di servizi (DaaS), per ospitare il nostro database.

Abbiamo bisogno del database per tenere traccia di un paio di cose:

  • Campanelli — un singolo dispositivo Raspberry Pi
  • Immagini — una singola foto scattata da un campanello

Dopo aver impostato il database MongoDB, possiamo usare la mangusta come nostro MongoDB Driver per il nostro codice di Azure Mobile Services node. js installando sul nostro cellulare servizi repository Git. Questo è lo stesso processo che abbiamo attraversato per installare il modulo nodo qs:

npm install mongoose

Spingendo il repository locale attiverà il servizio mobile per installare Mongoose relativo repository. Questo è quanto possiamo ottenere qualsiasi pacchetto di node. js in Azure Mobile Services. Come con ogni modulo node. js, possiamo fare riferimento utilizzando RequireJs e inizializzare mangusta con la nostra stringa di connessione MongoDB nella nostra attività pianificata:

var mongoose = require('mongoose');

Mangusta sarà responsabile della creazione di uno schema strutturato nel nostro database documento (vedere Figura 5). Useremo due entità: campanello e foto. Ogni oggetto campanello nel nostro database rappresenterà un dispositivo Raspberry Pi. Esso conterrà un identificatore univoco, doorBellID e una matrice di oggetti foto. Ogni foto contiene un link alla foto in archiviazione blob, come pure un timestamp generati dal servizio quando riceve un messaggio di servizio autobus.

Figura 5 schemi definiti in mangusta

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;

Esponiamo i campanello e foto schemi pubblicamente tramite la parola chiave delle esportazioni. Si noti come photoSchema viene interfogliato all'interno di doorbellSchema. Questo è quanto i dati verranno riflesse quando memorizzate nel database.

Ci potrai inserire il codice nella cartella condivisa del nostro repository dei servizi mobili. Questo ci permette di utilizzare gli schemi ovunque nel nostro servizio. Per fare riferimento gli schemi nella nostra attività pianificata, abbiamo solo bisogno di importarlo con un richiedono istruzione:

var schemas = require('../shared/schemas.js');

Ora possiamo usare questi schemi nella nostra attività pianificata per definire la nuova entità di database. Useremo una funzione specializzata per garantire noi sei connesso a MongoDB ed eseguire un callback. Dopo aver ricevuto un messaggio da service bus, il servizio di telefonia mobile dovrebbe:

  1. Controllare se il campanello con il doorBellID specificato nel messaggio esiste nel database.
  2. Se non esiste, creare una nuova entità di campanello con foto.
  3. Se esiste, solo di aggiungere la nuova foto a matrice di foto di campanello esistente.

Si può vedere la logica per questo nel codice in Figura 6.

Figura 6 logica per verificare il campanello e gestire foto

// 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;
  });
  });
});

Potete vedere una demo completa di doorbelllistener a bit.ly/VKrlYU.

Chiamiamo la funzione dbConnectAndExecute per garantire che stiamo collegati al nostro database MongoDB in MongoLabs. Poi abbiamo query sul database per un campanello con l'ID specificato nel messaggio. Se la query viene a vuoto, creiamo una nuova entità di campanello. Altrimenti, abbiamo aggiungere foto all'entità recuperata e salvare le modifiche al database.

Vedere ora Figura 7 cosa succede quando mandiamo un messaggio foto e servizio di autobus con il nostro dispositivo Raspberry Pi.

l'esito dell'invio di una foto e un messaggio
Figura 7 l'esito dell'invio di una foto e un messaggio

Controllando il log di servizi mobili nel portale dopo Raspberry Pi ha inviato che il messaggio Mostra la foto è stato elaborato e aggiunto al database.

Per buona misura, possiamo controllare il nostro database MongoDB affinché che noi stiamo effettivamente rilevamento le foto. MongoLab fornisce una ricca interfaccia di ispezione MongoDB attraverso il suo portale Web. Figura 8 Mostra ciò che l'entità del campanello possa apparire come dopo un paio di Foto upload.

MongoDB registrazione voci
Figura 8 MongoDB registrazione voci

Ora, Raspberry Pi è completamente integrato al nostro servizio cloud. Il dispositivo può caricare un file direttamente per archiviazione cloud, notificare il servizio cloud tramite bus di servizio e avere le informazioni archiviate in un database.

Il passo successivo in questa serie sarà l'integrazione un'applicazione mobile per il back-end nube con le notifiche push delle immagini. Useremo API personalizzate per superficie oggetti dal database all'app e integrare un API di terze parti per riconoscimento facciale immagine e un hub di notifica per le notifiche push di potenza. È possibile esaminare i repository di codice per costruire e modificare la soluzione da soli. Azure Mobile servizi back-end è al bit.ly/1mHCl0q. Troverete il codice Pi lampone al bit.ly/1l8aOtF.

Integrazione di dispositivi Raspberry PI verso il cloud estremità posteriore è critica. Sfruttando le tecnologie open source quali node. js ha senso in molti scenari dove si utilizza un leggero back-end alla scala per un gran numero di dispositivi.

Azure service bus fornisce un modo sicuro e conveniente per le periferiche connesse occasionalmente sfruttare un'infrastruttura di messaggistica affidabile che può adattarsi a molti clienti. Infine, sfruttando i negozi NoSQL è un modo popolare per rendere persistenti i dati e mantenere la sintassi JavaScript nativa nel livello dati e servizio di back-end node. js.


Steven Edouard è un developer evangelist di Microsoft. Prima, ha lavorato nel team di runtime .NET come software test engineer consegnando prodotti come il .NET Framework 4.5 e compilazione nativa .NET. Ora sua passione risiede nelle persone interessanti sulle illimitate potenzialità del cloud computing services attraverso dimostrazioni tecniche, contenuti online e presentazioni.

Bruno Terkaly è un developer evangelist per Microsoft. La sua profonda competenza deriva da anni di esperienza nel campo, scrivendo codice utilizzando una moltitudine di piattaforme, linguaggi, framework, SDK, librerie e API. Trascorre il tempo scrivere codice, blogging e dando le presentazioni dal vivo sulla creazione di applicazioni basate su cloud, in particolare utilizzando la piattaforma Microsoft Azure. Si può leggere il suo blog a blogs.msdn.com/b/brunoterkaly.

Grazie ai seguenti esperti tecnici Microsoft per la revisione di questo articolo: Gil Isaacs e Brent Stineman