Verbind uw Raspberry Pi-apparaat met de accelerator voor de externe bewakingsoplossing (Node.js)

In deze zelfstudie implementeert u een Chiller-apparaat dat de volgende telemetrie verzendt naar de accelerator voor de externe bewakingsoplossing:

  • Temperatuur
  • Druk
  • Vochtigheid

Ter vereenvoudiging genereert de code voorbeeldtelemetriewaarden voor de koelunit. U kunt het voorbeeld uitbreiden door echte sensoren te verbinden met uw apparaat en echte telemetrie te verzenden.

Het voorbeeldapparaat ook:

  • Verzendt metagegevens naar de oplossing om de mogelijkheden ervan te beschrijven.
  • Reageert op acties die zijn geactiveerd vanaf de pagina Apparaten in de oplossing.
  • Reageert op configuratiewijzigingen die worden verzonden vanaf de pagina Apparaten in de oplossing.

U hebt een actief Azure-account nodig om deze zelfstudie te voltooien. Als u geen account hebt, kunt u binnen een paar minuten een gratis proefaccount maken. Zie Gratis proefversie van Azure voor meer informatie.

Voordat u begint

Voordat u code voor uw apparaat schrijft, implementeert u de accelerator voor de externe bewakingsoplossing en voegt u een nieuw echt apparaat toe aan de oplossing.

De oplossingsversneller voor externe bewaking implementeren

Het Chiller-apparaat dat u in deze zelfstudie maakt, verzendt gegevens naar een exemplaar van de accelerator voor de externe bewakingsoplossing . Als u de accelerator voor de externe bewakingsoplossing nog niet hebt ingericht in uw Azure-account, raadpleegt u De versneller voor de externe bewakingsoplossing implementeren

Wanneer het implementatieproces voor de externe bewakingsoplossing is voltooid, klikt u op Starten om het oplossingsdashboard in uw browser te openen.

Het oplossingsdashboard

Uw apparaat toevoegen aan de externe bewakingsoplossing

Notitie

Als u al een apparaat in uw oplossing hebt toegevoegd, kunt u deze stap overslaan. De volgende stap vereist echter dat uw apparaat connection string. U kunt de connection string van een apparaat ophalen uit de Azure Portal of met behulp van het hulpprogramma az iot CLI.

Als een apparaat verbinding kan maken met de oplossingsversneller, moet het zich identificeren om te IoT Hub met geldige referenties. U hebt de mogelijkheid om het apparaat op te slaan connection string die deze referenties bevat wanneer u het apparaat aan de oplossing toevoegt. Verderop in deze zelfstudie neemt u het apparaat connection string op in uw clienttoepassing.

Als u een apparaat wilt toevoegen aan uw externe bewakingsoplossing, voert u de volgende stappen uit op de pagina Device Explorer in de oplossing:

  1. Kies + Nieuw apparaat en kies Vervolgens Real als het apparaattype:

    Echt apparaat toevoegen

  2. Voer de fysieke koelunit in als de apparaat-id . Kies de opties voor symmetrische sleutel en automatisch genereren van sleutels :

    Apparaatopties kiezen

  3. Kies Toepassen. Noteer vervolgens de waarden voor de primaire sleutel van de apparaat-id, de primaire sleutel en de verbindingsreeks :

    Referenties ophalen

U hebt nu een echt apparaat toegevoegd aan de accelerator voor de externe bewakingsoplossing en het apparaat connection string genoteerd. In de volgende secties implementeert u de clienttoepassing die gebruikmaakt van het apparaat connection string om verbinding te maken met uw oplossing.

De clienttoepassing implementeert het ingebouwde Chiller-apparaatmodel . Een apparaatmodel voor een oplossingsversneller geeft het volgende op over een apparaat:

  • De eigenschappen die het apparaat aan de oplossing rapporteert. Een Chiller-apparaat rapporteert bijvoorbeeld informatie over de firmware en locatie.
  • De typen telemetrie die het apparaat naar de oplossing verzendt. Een koelunit verzendt bijvoorbeeld temperatuur-, vochtigheids- en drukwaarden.
  • De methoden die u kunt plannen vanuit de oplossing om op het apparaat uit te voeren. Een Chiller-apparaat moet bijvoorbeeld de methoden Reboot, FirmwareUpdate, EmergencyValveRelease en IncreasePressure implementeren.

Deze zelfstudie laat zien hoe u een echt apparaat verbindt met de accelerator voor de externe bewakingsoplossing. In deze zelfstudie gebruikt u Node.js. Dit is een goede optie voor omgevingen met minimale resourcebeperkingen.

Als u liever een apparaat simuleert, raadpleegt u Een nieuw gesimuleerd apparaat maken en testen.

Vereiste hardware

Een desktopcomputer waarmee u extern verbinding kunt maken met de opdrachtregel op de Raspberry Pi.

Microsoft IoT Starter Kit voor Raspberry Pi 3 of gelijkwaardige onderdelen. In deze zelfstudie worden de volgende items uit de kit gebruikt:

  • Raspberry Pi 3
  • MicroSD-kaart (met NOOBS)
  • Een USB Minikabel
  • Een Ethernet-kabel

Vereiste desktopsoftware

U hebt de SSH-client op uw desktopcomputer nodig om u in staat te stellen de opdrachtregel op de Raspberry Pi op afstand te openen.

  • Windows bevat geen SSH-client. We raden u aan PuTTY te gebruiken.
  • De meeste Linux-distributies en Mac OS bevatten het opdrachtregelprogramma SSH. Zie SSH met Linux of Mac OS voor meer informatie.

Vereiste Raspberry Pi-software

Als u dit nog niet hebt gedaan, installeert u Node.js versie 4.0.0 of hoger op uw Raspberry Pi. In de volgende stappen ziet u hoe u Node.js v6 installeert op uw Raspberry Pi:

  1. Maak verbinding met uw Raspberry Pi met behulp van ssh. Zie SSH (Secure Shell) op de Raspberry Pi-website voor meer informatie.

  2. Gebruik de volgende opdracht om uw Raspberry Pi bij te werken:

    sudo apt-get update
    
  3. Gebruik de volgende opdrachten om een bestaande installatie van Node.js uit uw Raspberry Pi te verwijderen:

    sudo apt-get remove nodered -y
    sudo apt-get remove nodejs nodejs-legacy -y
    sudo apt-get remove npm  -y
    
  4. Gebruik de volgende opdracht om Node.js v6 te downloaden en te installeren op uw Raspberry Pi:

    curl -sL https://deb.nodesource.com/setup_6.x | sudo bash -
    sudo apt-get install nodejs npm
    
  5. Gebruik de volgende opdracht om te controleren of u Node.js v6.11.4 hebt geïnstalleerd:

    node --version
    

Een Node.js-oplossing maken

Voer de volgende stappen uit met behulp van de ssh verbinding met uw Raspberry Pi:

  1. Maak een map met de naam remotemonitoring in uw basismap op de Raspberry Pi. Navigeer naar deze map op de opdrachtregel:

    cd ~
    mkdir remotemonitoring
    cd remotemonitoring
    
  2. Voer de volgende opdrachten uit om de pakketten te downloaden en te installeren die u nodig hebt om de voorbeeld-app te voltooien:

    npm install async azure-iot-device azure-iot-device-mqtt
    
  3. Maak in de map een bestand met de remotemonitoring naam remote_monitoring.js. Open dit bestand in een teksteditor. Op de Raspberry Pi kunt u de nano of vi teksteditors gebruiken.

  4. Voeg in het bestandremote_monitoring.js de volgende require instructies toe:

    var Protocol = require('azure-iot-device-mqtt').Mqtt;
    var Client = require('azure-iot-device').Client;
    var Message = require('azure-iot-device').Message;
    var async = require('async');
    
  5. Voeg de volgende variabelendeclaraties achter de require-instructies toe. Vervang de waarde {device connection string} van de tijdelijke aanduiding door de waarde die u hebt genoteerd voor het apparaat dat u hebt ingericht in de externe bewakingsoplossing:

    var connectionString = '{device connection string}';
    
  6. Als u enkele basistelemetriegegevens wilt definiëren, voegt u de volgende variabelen toe:

    var temperature = 50;
    var temperatureUnit = 'F';
    var humidity = 50;
    var humidityUnit = '%';
    var pressure = 55;
    var pressureUnit = 'psig';
    
  7. Als u bepaalde eigenschapswaarden wilt definiëren, voegt u de volgende variabelen toe:

    var schema = "real-chiller;v1";
    var deviceType = "RealChiller";
    var deviceFirmware = "1.0.0";
    var deviceFirmwareUpdateStatus = "";
    var deviceLocation = "Building 44";
    var deviceLatitude = 47.638928;
    var deviceLongitude = -122.13476;
    var deviceOnline = true;
    
  8. Voeg de volgende variabele toe om de gerapporteerde eigenschappen te definiëren die naar de oplossing moeten worden verzonden. Deze eigenschappen bevatten metagegevens die moeten worden weergegeven in de webgebruikersinterface:

    var reportedProperties = {
      "SupportedMethods": "Reboot,FirmwareUpdate,EmergencyValveRelease,IncreasePressure",
      "Telemetry": {
        [schema]: ""
      },
      "Type": deviceType,
      "Firmware": deviceFirmware,
      "FirmwareUpdateStatus": deviceFirmwareUpdateStatus,
      "Location": deviceLocation,
      "Latitude": deviceLatitude,
      "Longitude": deviceLongitude,
      "Online": deviceOnline
    }
    
  9. Als u de resultaten van de bewerking wilt afdrukken, voegt u de volgende helperfunctie toe:

    function printErrorFor(op) {
        return function printError(err) {
            if (err) console.log(op + ' error: ' + err.toString());
        };
    }
    
  10. Voeg de volgende helperfunctie toe om de telemetriewaarden willekeurig te maken:

    function generateRandomIncrement() {
        return ((Math.random() * 2) - 1);
    }
    
  11. Voeg de volgende algemene functie toe om directe methode-aanroepen van de oplossing af te handelen. De functie geeft informatie weer over de directe methode die is aangeroepen, maar in dit voorbeeld wordt het apparaat op geen enkele manier gewijzigd. De oplossing maakt gebruik van directe methoden om te handelen op apparaten:

    function onDirectMethod(request, response) {
      // Implement logic asynchronously here.
      console.log('Simulated ' + request.methodName);
    
      // Complete the response
      response.send(200, request.methodName + ' was called on the device', function (err) {
        if (err) console.error('Error sending method response :\n' + err.toString());
        else console.log('200 Response to method \'' + request.methodName + '\' sent successfully.');
      });
    }
    
  12. Voeg de volgende functie toe om de directe methode-aanroepen van FirmwareUpdate vanuit de oplossing af te handelen. De functie controleert de parameters die zijn doorgegeven in de nettolading van de directe methode en voert vervolgens asynchroon een firmware-updatesimulatie uit:

    function onFirmwareUpdate(request, response) {
      // Get the requested firmware version from the JSON request body
      var firmwareVersion = request.payload.Firmware;
      var firmwareUri = request.payload.FirmwareUri;
    
      // Ensure we got a firmware values
      if (!firmwareVersion || !firmwareUri) {
        response.send(400, 'Missing firmware value', function(err) {
          if (err) console.error('Error sending method response :\n' + err.toString());
          else console.log('400 Response to method \'' + request.methodName + '\' sent successfully.');
        });
      } else {
        // Respond the cloud app for the device method
        response.send(200, 'Firmware update started.', function(err) {
          if (err) console.error('Error sending method response :\n' + err.toString());
          else {
            console.log('200 Response to method \'' + request.methodName + '\' sent successfully.');
    
            // Run the simulated firmware update flow
            runFirmwareUpdateFlow(firmwareVersion, firmwareUri);
          }
        });
      }
    }
    
  13. Voeg de volgende functie toe om een langlopende firmware-updatestroom te simuleren die de voortgang naar de oplossing rapporteert:

    // Simulated firmwareUpdate flow
    function runFirmwareUpdateFlow(firmwareVersion, firmwareUri) {
      console.log('Simulating firmware update flow...');
      console.log('> Firmware version passed: ' + firmwareVersion);
      console.log('> Firmware URI passed: ' + firmwareUri);
      async.waterfall([
        function (callback) {
          console.log("Image downloading from " + firmwareUri);
          var patch = {
            FirmwareUpdateStatus: 'Downloading image..'
          };
          reportUpdateThroughTwin(patch, callback);
          sleep(10000, callback);
        },
        function (callback) {
          console.log("Downloaded, applying firmware " + firmwareVersion);
          deviceOnline = false;
          var patch = {
            FirmwareUpdateStatus: 'Applying firmware..',
            Online: false
          };
          reportUpdateThroughTwin(patch, callback);
          sleep(8000, callback);
        },
        function (callback) {
          console.log("Rebooting");
          var patch = {
            FirmwareUpdateStatus: 'Rebooting..'
          };
          reportUpdateThroughTwin(patch, callback);
          sleep(10000, callback);
        },
        function (callback) {
          console.log("Firmware updated to " + firmwareVersion);
          deviceOnline = true;
          var patch = {
            FirmwareUpdateStatus: 'Firmware updated',
            Online: true,
            Firmware: firmwareVersion
          };
          reportUpdateThroughTwin(patch, callback);
          callback(null);
        }
      ], function(err) {
        if (err) {
          console.error('Error in simulated firmware update flow: ' + err.message);
        } else {
          console.log("Completed simulated firmware update flow");
        }
      });
    
      // Helper function to update the twin reported properties.
      function reportUpdateThroughTwin(patch, callback) {
        console.log("Sending...");
        console.log(JSON.stringify(patch, null, 2));
        client.getTwin(function(err, twin) {
          if (!err) {
            twin.properties.reported.update(patch, function(err) {
              if (err) callback(err);
            });      
          } else {
            if (err) callback(err);
          }
        });
      }
    
      function sleep(milliseconds, callback) {
        console.log("Simulate a delay (milleseconds): " + milliseconds);
        setTimeout(function () {
          callback(null);
        }, milliseconds);
      }
    }
    
  14. Voeg de volgende code toe om telemetriegegevens naar de oplossing te verzenden. De client-app voegt eigenschappen toe aan het bericht om het berichtschema te identificeren:

    function sendTelemetry(data, schema) {
      if (deviceOnline) {
        var d = new Date();
        var payload = JSON.stringify(data);
        var message = new Message(payload);
        message.properties.add('iothub-creation-time-utc', d.toISOString());
        message.properties.add('iothub-message-schema', schema);
    
        console.log('Sending device message data:\n' + payload);
        client.sendEvent(message, printErrorFor('send event'));
      } else {
        console.log('Offline, not sending telemetry');
      }
    }
    
  15. Voeg de volgende code toe om een clientexemplaren te maken:

    var client = Client.fromConnectionString(connectionString, Protocol);
    
  16. Voeg de volgende code toe aan:

    • Open de verbinding.

    • Stel een handler in voor de gewenste eigenschappen.

    • Gerapporteerde eigenschappen verzenden.

    • Registreer handlers voor de directe methoden. In het voorbeeld wordt een afzonderlijke handler gebruikt voor de directe methode voor firmware-updates.

    • Begin met het verzenden van telemetrie.

      client.open(function (err) {
      if (err) {
        printErrorFor('open')(err);
      } else {
        // Create device Twin
        client.getTwin(function (err, twin) {
          if (err) {
            console.error('Could not get device twin');
          } else {
            console.log('Device twin created');
      
            twin.on('properties.desired', function (delta) {
              // Handle desired properties set by solution
              console.log('Received new desired properties:');
              console.log(JSON.stringify(delta));
            });
      
            // Send reported properties
            twin.properties.reported.update(reportedProperties, function (err) {
              if (err) throw err;
              console.log('Twin state reported');
            });
      
            // Register handlers for all the method names we are interested in.
            // Consider separate handlers for each method.
            client.onDeviceMethod('Reboot', onDirectMethod);
            client.onDeviceMethod('FirmwareUpdate', onFirmwareUpdate);
            client.onDeviceMethod('EmergencyValveRelease', onDirectMethod);
            client.onDeviceMethod('IncreasePressure', onDirectMethod);
          }
        });
      
        // Start sending telemetry
        var sendDeviceTelemetry = setInterval(function () {
          temperature += generateRandomIncrement();
          pressure += generateRandomIncrement();
          humidity += generateRandomIncrement();
          var data = {
            'temperature': temperature,
            'temperature_unit': temperatureUnit,
            'humidity': humidity,
            'humidity_unit': humidityUnit,
            'pressure': pressure,
            'pressure_unit': pressureUnit
          };
          sendTelemetry(data, schema)
        }, 5000);
      
        client.on('error', function (err) {
          printErrorFor('client')(err);
          if (sendTemperatureInterval) clearInterval(sendTemperatureInterval);
          if (sendHumidityInterval) clearInterval(sendHumidityInterval);
          if (sendPressureInterval) clearInterval(sendPressureInterval);
          client.close(printErrorFor('client.close'));
        });
      }
      });
      
  17. Sla de wijzigingen op in het remote_monitoring.js-bestand .

  18. Als u de voorbeeldtoepassing wilt starten, voert u de volgende opdracht uit bij de opdrachtprompt op de Raspberry Pi:

    node remote_monitoring.js
    

Telemetrie van apparaten weergeven

U kunt de telemetrie bekijken die vanaf uw apparaat is verzonden op de pagina Device Explorer in de oplossing.

  1. Selecteer het apparaat dat u hebt ingericht in de lijst met apparaten op de pagina Device Explorer . In een deelvenster wordt informatie weergegeven over uw apparaat, inclusief een plot van de telemetrie van het apparaat:

    Apparaatdetails weergeven

  2. Kies Druk om de telemetrieweergave te wijzigen:

    Telemetrie van druk weergeven

  3. Als u diagnostische informatie over uw apparaat wilt weergeven, schuift u omlaag naar Diagnostische gegevens:

    Apparaatdiagnose weergeven

Reageren op uw apparaat

Als u methoden op uw apparaten wilt aanroepen, gebruikt u de pagina Device Explorer in de externe bewakingsoplossing. Implementeer bijvoorbeeld in de Chiller-apparaten van de externe bewakingsoplossing een methode Voor opnieuw opstarten .

  1. Kies Apparaten om naar de pagina Device Explorer in de oplossing te navigeren.

  2. Selecteer het apparaat dat u hebt ingericht in de lijst met apparaten op de pagina Device Explorer :

    Uw echte apparaat selecteren

  3. Als u een lijst met de methoden wilt weergeven die u op uw apparaat kunt aanroepen, kiest u Taken en vervolgens Methoden. Als u wilt plannen dat een taak op meerdere apparaten wordt uitgevoerd, kunt u meerdere apparaten in de lijst selecteren. In het deelvenster Taken ziet u de typen methoden die gebruikelijk zijn voor alle apparaten die u hebt geselecteerd.

  4. Kies Opnieuw opstarten, stel de taaknaam in op RebootPhysicalChiller en kies Vervolgens Toepassen:

    De firmware-update plannen

  5. Een reeks berichten wordt weergegeven in de console waarop uw apparaatcode wordt uitgevoerd terwijl het gesimuleerde apparaat de methode verwerkt.

Notitie

Als u de status van de taak in de oplossing wilt bijhouden, kiest u Taakstatus weergeven.

Volgende stappen

In het artikel De accelerator voor de externe bewakingsoplossing aanpassen worden enkele manieren beschreven om de oplossingsversneller aan te passen.