Ansluta enheten till acceleratorn fjärrövervakningslösning (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 kod för enheten distribuerar du acceleratorn Fjärrövervakningslösning 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 acceleratorn fjärrövervakningslösning

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

Instrumentpanelen för lösningen

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 enhetens anslutningssträng. Du kan hämta en enhets anslutningssträng från Azure Portal eller med hjälp av cli-verktyget az iot.

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 enhetens anslutningssträng 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 Device Explorer i lösningen:

  1. Välj + Ny enhet och välj sedan Verklig 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 värdena för Enhets-ID, Primärnyckel och Primärnyckel för anslutningssträng :

    Hämta autentiseringsuppgifter

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

Klientprogrammet implementerar den inbyggda kylaggregatsmodellen . En enhetsmodell för lösningsacceleratorn anger följande om en enhet:

  • Egenskaperna som enheten rapporterar till lösningen. En Kylaggregat-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 värden för temperatur, luftfuktighet och tryck.
  • De metoder som du kan schemalägga från lösningen för att köras på enheten. En kylaggregatenhet måste till exempel implementera metoderna Reboot, FirmwareUpdate, EmergencyValveRelease och IncreasePressure .

Den här självstudien visar hur du ansluter en riktig 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 kan du läsa Skapa och testa en ny simulerad enhet.

Skapa en Node.js lösning

Kontrollera att Node.js version 4.0.0 eller senare är installerad på utvecklingsdatorn. Du kan köra node --version på kommandoraden för att kontrollera versionen.

  1. Skapa en mapp med namnet remotemonitoring på utvecklingsdatorn. Navigera till den här mappen i kommandoradsmiljön.

  2. Kör följande kommandon för att ladda ned och installera de paket som du behöver för att slutföra exempelappen:

    npm init
    npm install async azure-iot-device azure-iot-device-mqtt --save
    
  3. Skapa en fil med remotemonitoring namnet remote_monitoring.jsi mappen . Öppna den här filen i en textredigerare.

  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 enheten 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 direkta metodanrop från lösningen. Funktionen visar information om direktmetoden 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 en kommandotolk:

    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 enheten rullar du ned till Diagnostik:

    Visa enhetsdiagnostik

Agera på enheten

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

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

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

    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 typer av metoder 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 jobbets status i lösningen väljer du Visa jobbstatus.

Nästa steg

I artikeln Anpassa lösningsacceleratorn för fjärrövervakning beskrivs några sätt att anpassa lösningsacceleratorn.