Zelfstudie: Uw apparaten configureren vanaf een back-endservice

Als onderdeel van de levenscyclus van het apparaat moet u mogelijk uw IoT-apparaten configureren vanuit uw back-endservice. Wanneer u een gewenste configuratie naar uw apparaten verzendt, wilt u ook status- en nalevingsupdates van deze apparaten ontvangen. U stelt bijvoorbeeld een doelbereik in voor de operationele temperatuur voor een apparaat of verzamelt firmwareversiegegevens van uw apparaten.

Om de statusgegevens tussen een apparaat en een IoT hub te synchroniseren, gebruikt u apparaatdubbels. Een apparaatdubbel is een JSON-document dat is gekoppeld aan een specifiek apparaat en door IoT Hub wordt opgeslagen in de cloud waar u ze kunt doorzoeken. Een apparaatdubbel bevat gewenste eigenschappen, gerapporteerde eigenschappen en labels.

  • Een gewenste eigenschap wordt ingesteld door een back-endtoepassing en gelezen door een apparaat.
  • Een gerapporteerde eigenschap wordt ingesteld door een apparaat en gelezen door een back-endtoepassing.
  • Een tag wordt ingesteld door een back-endtoepassing en wordt nooit naar een apparaat verzonden. U gebruikt labels om uw apparaten te organiseren.

In deze zelfstudie leert u hoe u de gewenste en gerapporteerde eigenschappen gebruikt om statusinformatie te synchroniseren.

Diagram of device twins on the device and in the cloud.

In deze zelfstudie voert u de volgende taken uit:

  • Een IoT hub maken en een testapparaat aan het identiteitsregister toevoegen.
  • Gewenste eigenschappen gebruiken om statusgegevens naar uw gesimuleerd apparaat te zenden.
  • Gerapporteerde eigenschappen gebruiken om statusgegevens van uw gesimuleerd apparaat te ontvangen.

Als u geen Azure-abonnement hebt, maakt u een gratis account voordat u begint.

Vereisten

  • In deze zelfstudie wordt de Azure CLI gebruikt om cloudresources te maken. Als u al een IoT-hub hebt waarop een apparaat is geregistreerd, kunt u deze stappen overslaan. Er zijn twee manieren om CLI-opdrachten uit te voeren:

  • De twee voorbeeldtoepassingen die u in deze zelfstudie uitvoert, worden geschreven met behulp van Node.js. Node.js v10.x.x of hoger moet zijn geïnstalleerd op uw ontwikkelcomputer.

    • U kunt Node.js voor meerdere platforms downloaden van nodejs.org.

    • Gebruik de volgende opdracht om de huidige versie van Node.js op uw ontwikkelcomputer te controleren:

      node --version
      
  • Kloon of download het voorbeeldproject Node.js van Azure IoT-voorbeelden voor Node.js.

  • Zorg ervoor dat de poort 8883 is geopend in uw firewall. In het apparaatvoorbeeld in deze zelfstudie wordt het MQTT-protocol gebruikt, dat communiceert via poort 8883. Deze poort is in sommige netwerkomgevingen van bedrijven en onderwijsinstellingen mogelijk geblokkeerd. Zie Verbinding maken met IoT Hub (MQTT) voor meer informatie en manieren om dit probleem te omzeilen.

Azure-resources instellen

Om deze zelfstudie te voltooien moet uw Azure-abonnement een IoT hub bevatten met een apparaat toegevoegd aan het apparaatidentiteitsregister. Met de vermelding in het apparaatidentiteitsregister kan het gesimuleerd apparaat dat u in deze zelfstudie uitvoert, verbinding maken met uw hub.

Als u nog geen IoT-hub hebt ingesteld in uw abonnement, kunt u er een instellen met het volgende CLI-script. Dit script maakt gebruik van de naam tutorial-iot-hub met een willekeurig getal dat is toegevoegd voor de naam van de IoT-hub. U kunt deze naam vervangen door uw eigen wereldwijd unieke naam wanneer u deze uitvoert. Het script maakt de brongroep en hub in de regio VS - centraal die u kunt wijzigen in een regio dichterbij. Met het script wordt uw verbindingsreeks voor de IoT hub, die u gebruikt in het back-endvoorbeeld om verbinding te maken met uw IoT hub:

let "randomIdentifier=$RANDOM*$RANDOM"  
hubname="tutorial-iot-hub-$randomIdentifier"
location=centralus

# Install the IoT extension if it's not already installed:
az extension add --name azure-iot

# Create a resource group:
az group create --name tutorial-iot-hub-rg --location $location

# Create your free-tier IoT hub. You can only have one free IoT hub per subscription.
# Change the sku to S1 to create a standard-tier hub if necessary.
az iot hub create --name $hubname --location $location --resource-group tutorial-iot-hub-rg --partition-count 2 --sku F1

# Make a note of the service connection string, you need it later:
az iot hub connection-string show --hub-name $hubname --policy-name service -o table

Deze zelfstudie gebruikt een gesimuleerd apparaat genaamd MyTwinDevice. Het volgende script voegt dit apparaat toe aan uw identiteitsregister en haalt de verbindingsreeks op:

# Create the device in the identity registry:
az iot hub device-identity create --device-id MyTwinDevice --hub-name $hubname --resource-group tutorial-iot-hub-rg

# Retrieve the device connection string, you need this later:
az iot hub device-identity connection-string show --device-id MyTwinDevice --hub-name $hubname --resource-group tutorial-iot-hub-rg -o table

Statusinformatie verzenden naar een apparaat

U gebruikt gewenste eigenschappen om statusgegevens vanuit een back-endsysteem naar een apparaat te zenden. In deze sectie kunt u zien hoe u:

  • Configureer een apparaat voor het ontvangen en verwerken van gewenste eigenschappen.
  • Verzend de gewenste eigenschappen van een back-endtoepassing naar een apparaat.

Voorbeeld gewenste eigenschappen

U kunt uw gewenste eigenschappen organiseren op elke manier die handig is voor uw toepassing. Dit voorbeeld gebruikt een eigenschap van het hoogste niveau genaamd fanOn en groepeert de overige eigenschappen in aparte componenten. In het volgende JSON-fragment ziet u de structuur van de gewenste eigenschappen die in deze zelfstudie worden gebruikt. De JSON bevindt zich in het desired.json-bestand.

{
  "fanOn": "true",
  "components": {
    "system": {
      "id": "17",
      "units": "farenheit",
      "firmwareVersion": "9.75"
    },
    "wifi" : { 
      "channel" : "6",
      "ssid": "my_network"
    },
    "climate" : {
      "minTemperature": "68",
      "maxTemperature": "76"
    }
  }
}

Gewenste eigenschappen ontvangen in een apparaattoepassing

Om de voorbeeldcode van het gesimuleerd apparaat te zien die gewenste eigenschappen ophaalt, navigeert u naar de map iot-hub/Tutorials/DeviceTwins in het voorbeeldproject in Node.js dat uw hebt gedownload. Open vervolgens het bestand SimulatedDevice.js in een teksteditor.

In de volgende secties wordt de code beschreven die wordt uitgevoerd op het gesimuleerde apparaat dat reageert op wijzigingen in de gewenste eigenschap die vanuit de back-endtoepassing worden verzonden.

Haal het object apparaatdubbel op

Wanneer u uw apparaat hebt geregistreerd bij de IoT-hub, hebt u een apparaat verbindingsreeks als uitvoer. Een apparaat verbindingsreeks wordt door het apparaat gebruikt om te verifiëren met de geregistreerde identiteit in de cloud. De volgende code verbindt met uw IoT hub met een apparaatverbindingsreeks:

// Get the device connection string from a command line argument
var connectionString = process.argv[2];

De volgende code haalt een dubbel op van het clientobject:

// Get the device twin
client.getTwin(function(err, twin) {
  if (err) {
    console.error(chalk.red('Could not get device twin'));
  } else {
    console.log(chalk.green('Device twin created'));

Handlers maken

U kunt handlers maken voor updates voor gewenste eigenschappen die reageren op updates op verschillende niveaus in de JSON-hiërarchie. Deze handler zorgt er bijvoorbeeld voor dat alle wijzigingen voor gewenste eigenschappen naar het apparaat worden verzonden vanuit een back-endtoepassing. De delta-variabele bevat de gewenste eigenschappen die zijn verzonden vanaf de back-endoplossing:

// Handle all desired property updates
twin.on('properties.desired', function(delta) {
    console.log(chalk.yellow('\nNew desired properties received in patch:'));

De volgende handler reageert alleen op wijzigingen die worden aangebracht aan de gewenste eigenschap fanOn:

// Handle changes to the fanOn desired property
twin.on('properties.desired.fanOn', function(fanOn) {
    console.log(chalk.green('\nSetting fan state to ' + fanOn));

    // Update the reported property after processing the desired property
    reportedPropertiesPatch.fanOn = fanOn ? fanOn : '{unknown}';
});

Handlers voor meerdere eigenschappen

In de JSON-voorbeeldeigenschappen voor deze zelfstudie bevat het klimaatknooppunt onder onderdelen twee eigenschappen, minTemperature en maxTemperature.

Een lokaal dubbel-object van een apparaat slaat een volledige reeks van gewenste en gerapporteerde eigenschappen op. De delta gezonden door het back-end updatet mogelijk maar een subset van gewenste eigenschappen. In het volgende codefragment, als het gesimuleerd apparaat een update ontvangt voor maar een van de minTemperature en maxTemperature, gebruikt het de waarde in de lokale dubbel voor de andere waarde om het apparaat te configureren:

// Handle desired properties updates to the climate component
twin.on('properties.desired.components.climate', function(delta) {
    if (delta.minTemperature || delta.maxTemperature) {
      console.log(chalk.green('\nUpdating desired tempertures in climate component:'));
      console.log('Configuring minimum temperature: ' + twin.properties.desired.components.climate.minTemperature);
      console.log('Configuring maximum temperture: ' + twin.properties.desired.components.climate.maxTemperature);

      // Update the reported properties and send them to the hub
      reportedPropertiesPatch.minTemperature = twin.properties.desired.components.climate.minTemperature;
      reportedPropertiesPatch.maxTemperature = twin.properties.desired.components.climate.maxTemperature;
      sendReportedProperties();
    }
});

Invoeg-, update- en verwijderbewerkingen verwerken

De gewenste eigenschappen die vanaf het back-end zijn verzonden geven niet aan welke bewerking wordt uitgevoerd op een bepaalde gewenste eigenschap. Uw code moet de bewerking afleiden uit de huidige set van gewenste eigenschappen die lokaal zijn opgeslagen en de wijzigingen die vanuit de hub zijn verzonden.

Het volgende fragment toont aan hoe het gesimuleerd apparaat invoeg-, update- en verwijderbewerkingen in de lijst van componenten in de gewenste eigenschappen verwerkt. U kunt zien hoe u null-waarden gebruikt om aan te geven dat een component moet worden verwijderd:

// Keep track of all the components the device knows about
var componentList = {};

// Use this componentList list and compare it to the delta to infer
// if anything was added, deleted, or updated.
twin.on('properties.desired.components', function(delta) {
  if (delta === null) {
    componentList = {};
  }
  else {
    Object.keys(delta).forEach(function(key) {

      if (delta[key] === null && componentList[key]) {
        // The delta contains a null value, and the
        // device has a record of this component.
        // Must be a delete operation.
        console.log(chalk.green('\nDeleting component ' + key));
        delete componentList[key];

      } else if (delta[key]) {
        if (componentList[key]) {
          // The delta contains a component, and the
          // device has a record of it.
          // Must be an update operation.
          console.log(chalk.green('\nUpdating component ' + key + ':'));
          console.log(JSON.stringify(delta[key]));
          // Store the complete object instead of just the delta
          componentList[key] = twin.properties.desired.components[key];

        } else {
          // The delta contains a component, and the
          // device has no record of it.
          // Must be an add operation.
          console.log(chalk.green('\nAdding component ' + key + ':'));
          console.log(JSON.stringify(delta[key]));
          // Store the complete object instead of just the delta
          componentList[key] = twin.properties.desired.components[key];
        }
      }
    });
  }
});

Gewenste eigenschappen verzenden vanuit een back-endtoepassing

U hebt gezien hoe een apparaat handlers implementeert voor het ontvangen van updates van gewenste eigenschappen. Deze sectie laat zien hoe u wijzigingen van gewenste eigenschappen naar een apparaat zend vanuit een back-endtoepassing.

Om de voorbeeldcode van het gesimuleerd apparaat te zien die gewenste eigenschappen ophaalt, navigeert u naar de map iot-hub/Tutorials/DeviceTwins in het voorbeeldproject in Node.js dat uw hebt gedownload. Open vervolgens het bestand ServiceClient.js in een teksteditor.

Het volgende codefragment toont hoe u verbinding maakt met een apparaatidentiteitsregister en de dubbel opent voor een specifiek apparaat:

// Create a device identity registry object
var registry = Registry.fromConnectionString(connectionString);

// Get the device twin and send desired property update patches at intervals.
// Print the reported properties after some of the desired property updates.
registry.getTwin(deviceId, async (err, twin) => {
  if (err) {
    console.error(err.message);
  } else {
    console.log('Got device twin');

Het volgende fragment toont verschillende patches voor gewenste eigenschappen die de back-endtoepassing naar het apparaat zend:

// Turn the fan on
var twinPatchFanOn = {
  properties: {
    desired: {
      patchId: "Switch fan on",
      fanOn: "false",
    }
  }
};

// Set the maximum temperature for the climate component
var twinPatchSetMaxTemperature = {
  properties: {
    desired: {
      patchId: "Set maximum temperature",
      components: {
        climate: {
          maxTemperature: "92"
        }
      }
    }
  }
};

// Add a new component
var twinPatchAddWifiComponent = {
  properties: {
    desired: {
      patchId: "Add WiFi component",
      components: {
        wifi: { 
          channel: "6",
          ssid: "my_network"
        }
      }
    }
  }
};

// Update the WiFi component
var twinPatchUpdateWifiComponent = {
  properties: {
    desired: {
      patchId: "Update WiFi component",
      components: {
        wifi: { 
          channel: "13",
          ssid: "my_other_network"
        }
      }
    }
  }
};

// Delete the WiFi component
var twinPatchDeleteWifiComponent = {
  properties: {
    desired: {
      patchId: "Delete WiFi component",
      components: {
        wifi: null
      }
    }
  }
};

Het volgende fragment toont hoe de back-endtoepassing een update van een gewenste eigenschap naar een apparaat verzend:

// Send a desired property update patch
async function sendDesiredProperties(twin, patch) {
  twin.update(patch, (err, twin) => {
    if (err) {
      console.error(err.message);
    } else {
      console.log(chalk.green(`\nSent ${twin.properties.desired.patchId} patch:`));
      console.log(JSON.stringify(patch, null, 2));
    }
  });
}

Statusinformatie ontvangen van een apparaat

Uw back-endtoepassing ontvangt statusgegevens van een apparaat als gerapporteerde eigenschappen. Een apparaat stelt de gerapporteerde eigenschappen in en zendt die terug naar uw hub. Een back-endtoepassing kan de huidige waarden van de gerapporteerde eigenschappen lezen van de apparaatdubbel die in uw hub is opgeslagen.

Gerapporteerde eigenschappen vanaf een apparaat verzenden

U kunt updates voor gerapporteerde eigenschappen verzenden als patch. Het volgende fragment toont een sjabloon voor de patch die het gesimuleerd apparaat verzendt. Het gesimuleerd apparaat updatet de velden in de patch voordat ze naar de hub worden verzonden:

// Create a patch to send to the hub
var reportedPropertiesPatch = {
  firmwareVersion:'1.2.1',
  lastPatchReceivedId: '',
  fanOn:'',
  minTemperature:'',
  maxTemperature:''
};

Het gesimuleerd apparaat gebruikt de volgende functie om de patch die de gerapporteerde eigenschappen bevat naar de hub te zenden:

// Send the reported properties patch to the hub
function sendReportedProperties() {
  twin.properties.reported.update(reportedPropertiesPatch, function(err) {
    if (err) throw err;
    console.log(chalk.blue('\nTwin state reported'));
    console.log(JSON.stringify(reportedPropertiesPatch, null, 2));
  });
}

Gerapporteerde eigenschap verwerken

Een back-endtoepassing opent de huidige waarden van gerapporteerde eigenschappen van een apparaat via de apparaatdubbel. Het volgende fragment toont hoe de back-endtoepassing de waarden leest van de gerapporteerde eigenschappen voor het gesimuleerd apparaat:

// Display the reported properties from the device
function printReportedProperties(twin) {
  console.log("Last received patch: " + twin.properties.reported.lastPatchReceivedId);
  console.log("Firmware version: " + twin.properties.reported.firmwareVersion);
  console.log("Fan status: " + twin.properties.reported.fanOn);
  console.log("Min temperature set: " + twin.properties.reported.minTemperature);
  console.log("Max temperature set: " + twin.properties.reported.maxTemperature);
}

De toepassingen uitvoeren

In deze sectie voert u de twee voorbeeldtoepassingen uit om te zien wanneer een back-endtoepassing gewenste eigenschapsupdates verzendt naar een gesimuleerde apparaattoepassing.

Om de gesimuleerd apparaat- en back-endtoepassingen uit te voeren, hebt u de verbindingsreeksen van het apparaat en de service nodig. U hebt de verbindingsreeksen genoteerd toen u aan het begin van deze zelfstudie de bronnen hebt gemaakt.

Om de gesimuleerd apparaattoepassing uit te voeren, opent u een shell of opdrachtpromptvenster en navigeert u naar de map iot-hub/Tutorials/DeviceTwins in het Node.js-project dat u hebt gedownload. Voer vervolgens de volgende opdrachten uit:

npm install
node SimulatedDevice.js "{your device connection string}"

Om de back-endtoepassing uit te voeren, opent u een ander(e) shell of opdrachtpromptvenster. Navigeer dan naar de map iot-hub/Tutorials/DeviceTwins in het Node.js-project dat u hebt gedownload. Voer vervolgens de volgende opdrachten uit:

npm install
node ServiceClient.js "{your service connection string}"

De gewenste updates van eigenschappen bekijken

De volgende schermafbeelding toont de uitvoer van de gesimuleerd apparaattoepassing en accentueert hoe het een update voor de gewenste eigenschap maxTemperature verwerkt. U kunt zien hoe zowel de handler van het hoogste niveau als de klimaatcomponenthandlers worden uitgevoerd:

Screenshot that shows how both the top-level handler and the climate component handlers run.

De volgende schermafbeelding laat de uitvoer van de back-endtoepassing zien en accentueert hoe die een update zendt naar de gewenste eigenschapmaxTemperature:

Screenshot that shows the output from the back-end application and highlights how it sends an update.

Gerapporteerde eigenschapsupdates bekijken

De volgende schermafbeelding toont de uitvoer van de gesimuleerd apparaattoepassing en accentueert hoe het een update voor de gerapporteerde eigenschap naar uw hub verzendt:

Screenshot that shows the simulated device updating its twin state.

De volgende schermafbeelding toont de uitvoer van de back-endtoepassing en laat zien hoe deze een update voor de gerapporteerde eigenschap van een apparaat ontvangt en verwerkt:

Screenshot that shows the back-end application receiving the device reported properties.

Resources opschonen

Als u van plan bent om de volgende zelfstudie te voltooien, laat u de resourcegroep en de IoT-hub staan om ze later opnieuw te gebruiken.

Als u de IoT-hub niet langer nodig hebt, verwijdert u deze en de resourcegroep in de portal. Hiervoor selecteert u de resourcegroep tutorial-iot-hub-rg die uw IoT-hub bevat en selecteert u Verwijderen.

Of gebruik de CLI:

# Delete your resource group and its contents
az group delete --name tutorial-iot-hub-rg

Volgende stappen

In deze zelfstudie hebt u geleerd hoe u statusgegevens synchroniseert tussen uw apparaten en uw IoT hub. Ga naar de volgende zelfstudie voor meer informatie over het gebruik van apparaatdubbels om het updateproces voor apparaten te implementeren.