Anslut Raspberry Pi-enheten till acceleratorn för fjärrövervakningslösningen (Node.js)

I den här självstudien implementerar du en kylaggregatsenhet som skickar följande telemetri till acceleratorn Fjärrövervakningslösning:

  • Temperatur
  • Lufttryck
  • Luftfuktighet

För enkelhetens skull genererar koden exempeltelemetrivärden för kylaggregatet. Du kan utöka exemplet genom att ansluta verkliga sensorer till din enhet och skicka verklig telemetri.

Exempelenheten:

  • Skickar metadata till lösningen för att beskriva dess funktioner.
  • Svarar på åtgärder som utlöses från sidan Enheter i lösningen.
  • Svarar på konfigurationsändringar som skickas från sidan Enheter i lösningen.

Du behöver ett Azure-konto för att slutföra den här självstudiekursen. Om du inte har något konto kan skapa du ett kostnadsfritt utvärderingskonto på bara några minuter. Mer information om den kostnadsfria utvärderingsversionen av Azure finns Kostnadsfri utvärderingsversion av Azure.

Innan du börjar

Innan du skriver någon kod för enheten distribuerar du acceleratorn för fjärrövervakningslösningen och lägger till en ny verklig enhet i lösningen.

Distribuera acceleratorn för fjärrövervakningslösningen

Kylaggregatet som du skapar i den här självstudien skickar data till en instans av acceleratorn Fjärrövervakningslösning. Om du inte redan har etablerat acceleratorn för fjärrövervakningslösningen i ditt Azure-konto kan du läsa Distribuera lösningsacceleratorn för fjärrövervakning

När distributionsprocessen för fjärrövervakningslösningen är klar klickar du på Starta för att öppna lösningsinstrumentpanelen i webbläsaren.

Lösningsinstrumentpanelen

Lägga till enheten i fjärrövervakningslösningen

Anteckning

Om du redan har lagt till en enhet i din lösning kan du hoppa över det här steget. Nästa steg kräver dock din enhetsanslutningssträng. Du kan hämta en enhets anslutningssträng från Azure Portal eller med hjälp av az iot CLI-verktyget.

För att en enhet ska kunna ansluta till lösningsacceleratorn måste den identifiera sig för att IoT Hub med giltiga autentiseringsuppgifter. Du har möjlighet att spara enhetsanslutningssträngen som innehåller dessa autentiseringsuppgifter när du lägger till enheten i lösningen. Du inkluderar enhetsanslutningssträngen i klientprogrammet senare i den här självstudien.

Om du vill lägga till en enhet i fjärrövervakningslösningen utför du följande steg på sidan Enhetsutforskaren i lösningen:

  1. Välj + Ny enhet och välj sedan Real som Enhetstyp:

    Lägga till en riktig enhet

  2. Ange Fysisk kylaggregat som enhets-ID . Välj alternativen Symmetrisk nyckel och Generera nycklar automatiskt :

    Välj enhetsalternativ

  3. Välj Använd. Anteckna sedan primärnyckelvärdena enhets-ID, primärnyckel och anslutningssträng :

    Hämta autentiseringsuppgifter

Nu har du lagt till en verklig enhet i acceleratorn för fjärrövervakningslösningen och noterat dess enhetsanslutningssträng. I följande avsnitt implementerar du klientprogrammet som använder enhetsanslutningssträngen för att ansluta till din lösning.

Klientprogrammet implementerar den inbyggda Chiller-enhetsmodellen . En lösningsacceleratorenhetsmodell anger följande om en enhet:

  • Egenskaperna som enheten rapporterar till lösningen. En Chiller-enhet rapporterar till exempel information om dess inbyggda programvara och plats.
  • De typer av telemetri som enheten skickar till lösningen. En kylaggregat skickar till exempel temperatur-, luftfuktighets- och tryckvärden.
  • De metoder som du kan schemalägga från lösningen för att köras på enheten. En kylaggregatsenhet måste till exempel implementera metoderna Reboot, FirmwareUpdate, EmergencyValveRelease och IncreasePressure .

Den här självstudien visar hur du ansluter en verklig enhet till acceleratorn Fjärrövervakningslösning. I den här självstudien använder du Node.js, vilket är ett bra alternativ för miljöer med minimala resursbegränsningar.

Om du föredrar att simulera en enhet läser du Skapa och testa en ny simulerad enhet.

Nödvändig maskinvara

En stationär dator som gör att du kan fjärransluta till kommandoraden på Raspberry Pi.

Microsoft IoT Starter Kit för Raspberry Pi 3 eller motsvarande komponenter. I den här självstudien används följande objekt från paketet:

  • Raspberry Pi 3
  • MicroSD-kort (med NOOBS)
  • En USB Mini-kabel
  • En Ethernet-kabel

Nödvändig skrivbordsprogramvara

Du behöver en SSH-klient på din stationära dator så att du kan fjärråtkomst till kommandoraden på Raspberry Pi.

Obligatorisk Raspberry Pi-programvara

Om du inte redan har gjort det installerar du Node.js version 4.0.0 eller senare på Raspberry Pi. Följande steg visar hur du installerar Node.js v6 på Raspberry Pi:

  1. Anslut till Raspberry Pi med .ssh Mer information finns i SSH (Secure Shell)Raspberry Pi-webbplatsen.

  2. Använd följande kommando för att uppdatera Raspberry Pi:

    sudo apt-get update
    
  3. Använd följande kommandon för att ta bort alla befintliga installationer av Node.js från Raspberry Pi:

    sudo apt-get remove nodered -y
    sudo apt-get remove nodejs nodejs-legacy -y
    sudo apt-get remove npm  -y
    
  4. Använd följande kommando för att ladda ned och installera Node.js v6 på Raspberry Pi:

    curl -sL https://deb.nodesource.com/setup_6.x | sudo bash -
    sudo apt-get install nodejs npm
    
  5. Använd följande kommando för att kontrollera att du har installerat Node.js v6.11.4:

    node --version
    

Skapa en Node.js lösning

Utför följande steg med hjälp av ssh anslutningen till Raspberry Pi:

  1. Skapa en mapp med namnet remotemonitoring i din hemmapp på Raspberry Pi. Navigera till den här mappen på kommandoraden:

    cd ~
    mkdir remotemonitoring
    cd remotemonitoring
    
  2. Om du vill ladda ned och installera de paket som du behöver för att slutföra exempelappen kör du följande kommandon:

    npm install async azure-iot-device azure-iot-device-mqtt
    
  3. Skapa en fil med remotemonitoring namnet remote_monitoring.jsi mappen . Öppna den här filen i en textredigerare. På Raspberry Pi kan du använda nano textredigerarna eller vi .

  4. Lägg till följande require instruktioner i filenremote_monitoring.js:

    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. Lägg till följande variabeldeklarationer efter require-instruktionerna. Ersätt platshållarvärdet {device connection string} med det värde som du antecknade för den enhet som du etablerade i fjärrövervakningslösningen:

    var connectionString = '{device connection string}';
    
  6. Om du vill definiera vissa bastelemetridata lägger du till följande variabler:

    var temperature = 50;
    var temperatureUnit = 'F';
    var humidity = 50;
    var humidityUnit = '%';
    var pressure = 55;
    var pressureUnit = 'psig';
    
  7. Om du vill definiera vissa egenskapsvärden lägger du till följande variabler:

    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. Lägg till följande variabel för att definiera de rapporterade egenskaper som ska skickas till lösningen. Dessa egenskaper omfattar metadata som ska visas i webbgränssnittet:

    var reportedProperties = {
      "SupportedMethods": "Reboot,FirmwareUpdate,EmergencyValveRelease,IncreasePressure",
      "Telemetry": {
        [schema]: ""
      },
      "Type": deviceType,
      "Firmware": deviceFirmware,
      "FirmwareUpdateStatus": deviceFirmwareUpdateStatus,
      "Location": deviceLocation,
      "Latitude": deviceLatitude,
      "Longitude": deviceLongitude,
      "Online": deviceOnline
    }
    
  9. Om du vill skriva ut åtgärdsresultat lägger du till följande hjälpfunktion:

    function printErrorFor(op) {
        return function printError(err) {
            if (err) console.log(op + ' error: ' + err.toString());
        };
    }
    
  10. Lägg till följande hjälpfunktion som ska användas för att randomisera telemetrivärdena:

    function generateRandomIncrement() {
        return ((Math.random() * 2) - 1);
    }
    
  11. Lägg till följande allmänna funktion för att hantera direktmetodanrop från lösningen. Funktionen visar information om den direktmetod som anropades, men i det här exemplet ändras inte enheten på något sätt. Lösningen använder direkta metoder för att agera på enheter:

    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. Lägg till följande funktion för att hantera FirmwareUpdate-direktmetodanrop från lösningen. Funktionen verifierar de parametrar som skickas i direktmetodens nyttolast och kör sedan asynkront en uppdateringssimulering för inbyggd programvara:

    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. Lägg till följande funktion för att simulera ett långvarigt uppdateringsflöde för inbyggd programvara som rapporterar förloppet tillbaka till lösningen:

    // 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. Lägg till följande kod för att skicka telemetridata till lösningen. Klientappen lägger till egenskaper i meddelandet för att identifiera meddelandeschemat:

    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. Lägg till följande kod för att skapa en klientinstans:

    var client = Client.fromConnectionString(connectionString, Protocol);
    
  16. Lägg till följande kod i:

    • Öppna anslutningen.

    • Konfigurera en hanterare för önskade egenskaper.

    • Skicka rapporterade egenskaper.

    • Registrera hanterare för direktmetoderna. Exemplet använder en separat hanterare för direktmetoden för uppdatering av inbyggd programvara.

    • Börja skicka telemetri.

      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. Spara ändringarna i remote_monitoring.js filen.

  18. Starta exempelprogrammet genom att köra följande kommando i kommandotolken på Raspberry Pi:

    node remote_monitoring.js
    

Visa enhetstelemetri

Du kan visa telemetrin som skickas från enheten på sidan Device Explorer i lösningen.

  1. Välj den enhet som du etablerade i listan över enheter på sidan Device Explorer . En panel visar information om din enhet, inklusive ett diagram över enhetens telemetri:

    Se enhetsinformation

  2. Välj Tryck för att ändra telemetrivisningen:

    Visa trycktelemetri

  3. Om du vill visa diagnostikinformation om din enhet rullar du ned till Diagnostik:

    Visa enhetsdiagnostik

Agera på din enhet

Om du vill anropa metoder på dina enheter använder du sidan Device Explorer i fjärrövervakningslösningen. I fjärrövervakningslösningen implementerar till exempel kylaggregatet en omstartsmetod .

  1. Välj Enheter för att gå till sidan Device Explorer i lösningen.

  2. Välj den enhet som du etablerade i listan över enheter på sidan Device Explorer :

    Välj din riktiga enhet

  3. Om du vill visa en lista över de metoder som du kan anropa på enheten väljer du Jobb och sedan Metoder. Om du vill schemalägga ett jobb som ska köras på flera enheter kan du välja flera enheter i listan. Panelen Jobb visar de metodtyper som är gemensamma för alla enheter som du har valt.

  4. Välj Starta om, ange jobbnamnet till RebootPhysicalChiller och välj sedan Använd:

    Schemalägg uppdateringen av den inbyggda programvaran

  5. En sekvens med meddelanden visas i konsolen som kör enhetskoden medan den simulerade enheten hanterar metoden.

Anteckning

Om du vill spåra status för jobbet i lösningen väljer du Visa jobbstatus.

Nästa steg

I artikeln Anpassa acceleratorn fjärrövervakningslösning beskrivs några sätt att anpassa lösningsacceleratorn.