Självstudier: Konfigurera dina enheter från en serverdelstjänst

Som en del av enhetens livscykel kan du behöva konfigurera dina IoT-enheter från serverdelstjänsten. När du skickar en önskad konfiguration till dina enheter vill du också ta emot status- och efterlevnadsuppdateringar från dessa enheter. Du kan till exempel ställa in ett måldrifttemperaturområde för en enhet eller hämta versionsinformation för den fasta programvaran från dina enheter.

Om du vill synkronisera statusinformation mellan en enhet och en IoT-hubb använder du enhetstvillingar. En enhetstvilling är ett JSON-dokument som är associerat med en specifik enhet och lagras i IoT-hubben i molnet där du kan frågan det. En enhetstvilling innehåller önskade egenskaper, rapporterade egenskaper och taggar.

  • En önskad egenskap anges av ett serverdelsprogram och läss av en enhet.
  • En rapporterad egenskap anges av en enhet och läss av ett serverdelsprogram.
  • En tagg anges av ett serverdelsprogram och skickas aldrig till en enhet. Använd taggar för att organisera din enhet.

Den här självstudien visar hur du använder önskade och rapporterade egenskaper för att synkronisera tillståndsinformation.

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

I den här självstudien utför du följande åtgärder:

  • Skapa en IoT-hubb och lägg till en testenhet i identitetsregistret.
  • Använda önskade egenskaper för att skicka statusinformation till den simulerade enheten.
  • Använda rapporterade egenskaper för att ta emot statusinformation från den simulerade enheten.

Om du inte har någon Azure-prenumeration skapar du ett kostnadsfritt konto innan du börjar.

Förutsättningar

  • I den här självstudien används Azure CLI för att skapa molnresurser. Om du redan har en IoT-hubb med en enhet registrerad på den kan du hoppa över dessa steg. Det finns två sätt att köra CLI-kommandon:

  • De två exempelprogram som du kör i den här självstudien skrivs med Node.js. Du behöver Node.js v10.x.x eller senare på utvecklingsdatorn.

    • Du kan ladda ned Node.js för flera plattformar från nodejs.org.

    • Du kan kontrollera den aktuella versionen av Node.js på utvecklingsdatorn med följande kommando:

      node --version
      
  • Klona eller ladda ned exempelprojektet Node.js från Azure IoT-exempel för Node.js.

  • Kontrollera att port 8883 är öppen i brandväggen. Enhetsexemplet i den här självstudien använder MQTT-protokoll, som kommunicerar via port 8883. Den här porten kan blockeras i vissa företags- och utbildningsnätverksmiljöer. Mer information och sätt att kringgå det här problemet finns i Anslut ing to IoT Hub (MQTT).

Ställa in Azure-resurser

För att slutföra den här kursen måste din Azure-prenumeration innehålla en IoT-hubb med en enhet som har lagts till i enhetsidentitetsregistret. Posten i enhetsidentitetsregistret gör att den simulerade enheten som du kör i den här kursen kan ansluta till din hubb.

Om du inte redan har konfigurerat en IoT-hubb i din prenumeration kan du konfigurera en med följande CLI-skript. Det här skriptet använder namnet tutorial-iot-hub med ett slumpmässigt nummer som läggs till för IoT Hub-namnet. Du kan ersätta det här namnet med ditt eget globalt unika namn när du kör det. Skriptet skapar resursgruppen och hubben i regionen USA, centrala, vilket du kan ändra till en region som ligger närmare till dig. Skriptet hämtar din anslutningssträng för IoT-hubbtjänsten, som du använder i serverdelexemplet för att ansluta till din IoT-hubb:

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

Den här kursen använder en simulerad enhet som heter MyTwinDevice. Med följande skript lägger du till den här enheten till din identitetsregistret och hämtar sin anslutningssträng:

# 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

Skicka tillståndsinformation till en enhet

Du använder önskade egenskaper för att skicka statusinformation från ett serverdelprogram till en enhet. I det här avsnittet visas hur du:

  • Konfigurera en enhet för att ta emot och bearbeta önskade egenskaper.
  • Skicka önskade egenskaper från ett serverdelsprogram till en enhet.

Exempel på önskade egenskaper

Du kan strukturera dina önskade egenskaper på ett sätt som passar ditt program. Det här exemplet används en toppnivåegenskap som heter fanOn och grupperar de övriga egenskaperna i separata komponenter. Följande JSON-kodfragment visar strukturen för önskade egenskaper som används i den här självstudien. JSON finns i filen desired.json.

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

Ta emot önskade egenskaper i ett enhetsprogram

Om du vill visa den simulerade enhetens exempelkod som tar emot egenskaper, navigera till mappen iot-hubb/Tutorials/DeviceTwins i exempelprojektet för Node.js som du hämtat. Öppna SimulatedDevice.js i en valfri textredigerare.

I följande avsnitt beskrivs koden som körs på den simulerade enheten som svarar på önskade egenskapsändringar som skickas från serverdelsprogrammet.

Hämta enhetens tvillingobjekt

När du registrerade din enhet med IoT-hubben fick du en enhet anslutningssträng som utdata. En enhet anslutningssträng används av enheten för att autentisera med dess registrerade identitet i molnet. Använd följande kod för att ansluta till din IoT-hubb med en enhetsanslutningssträng:

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

Följande kod hämtar en tvilling från klientobjektet:

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

Skapa hanterare

Du kan skapa hanterare för uppdateringar av önskade egenskaper som kan hantera uppdateringar på olika nivåer i JSON-hierarkin. Till exempel ser den här hanteraren alla önskade egenskapsändringar som skickas till enheten från ett serverdelsprogram. Variabeln delta innehåller de önskade egenskaperna som skickas från lösningens serverdel:

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

Följande hanterare reagerar endast på ändringar som gjorts i den önskade egenskapen 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}';
});

Hanterare för flera egenskaper

I JSON-exemplet för önskade egenskaper för den här självstudien innehåller klimatnodenunder komponenter två egenskaper, minTemperature och maxTemperature.

En enhet som har lokala tvillingobjekt lagrar en fullständig uppsättning önskade och rapporterade egenskaper. Delta som skickas från en slutpunkt kanske endast uppdaterar en delmängd av egenskaperna. I följande kodavsnitt, om den simulerade enheten tar emot en uppdatering för antingen minTemperature eller maxTemperature, används värdet i den lokala tvillingen för det andra värdet för att konfigurera enheten :

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

Hantera infogning, uppdatering och borttagning

De egenskaper som skickas från serverdelen indikerar vilken åtgärd som utförs på en viss önskad egenskap. Din kod måste härleda åtgärden från den aktuella uppsättningen egenskaper som lagras lokalt och de ändringar som skickas från hubben.

Följande utdrag visar hur den simulerade enheten infogar, uppdaterar och tar bort i listan över komponenter i önskade egenskaper. Du kan se hur du använder null-värden för att ange att en komponent ska tas bort:

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

Skicka önskade egenskaper från ett serverdelsprogram

Du har sett hur en enhet använder hanterare för att ta emot uppdateringar av önskade egenskaper. Det här avsnittet visar hur du skickar önskade egenskapsändringar till en enhet från ett serverdelsprogram.

Om du vill visa den simulerade enhetens exempelkod som tar emot egenskaper, navigera till mappen iot-hubb/Tutorials/DeviceTwins i exempelprojektet för Node.js som du hämtat. Öppna ServiceClient.js i en valfri textredigerare.

Följande kodavsnitt visar hur du ansluter till enhetsidentitetsregistret och får åtkomst till tvillingen för en specifik enhet:

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

Följande utdrag visar olika korrigeringsfiler för önskade egenskaper som serverdelsprogrammet skickar till enheten:

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

Följande utdrag visar hur serverdelsprogrammet skickar en önskad egenskapsuppdatering till en enhet:

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

Ta emot tillståndsinformation från en enhet

Ditt serverdelsprogram tar emot statusinformation från en enhet som rapporterade egenskaper. En enhet anger de rapporterade egenskaperna och skickar dem till din hubb. Ett serverdelsprogram kan läsa de aktuella värdena för de rapporterade egenskaperna från enhetstvillingen som lagras i din hubb.

Skicka rapporterade egenskaper från en enhet

Du kan skicka uppdateringar till rapporterade egenskapsvärden som en korrigeringsfil. Följande kodfragment visar en mall för korrigeringsfilen som den simulerade enheten skickar. Den simulerade enheten uppdaterar fälten i korrigeringsfilen innan den skickas till hubben:

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

Den simulerade enheten använder följande funktion för att skicka korrigeringsfilen som innehåller de rapporterade egenskaperna till hubben:

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

Bearbeta rapporterade egenskaper

Ett serverdelsprogram har åtkomst till de aktuella rapporterade egenskapsvärdena för en enhet via tvillingenheten. Följande utdrag visar hur serverdelsprogrammet läser rapporterade egenskapsvärden för den simulerade enheten:

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

Kör programmen

I det här avsnittet kör du de två exempelprogrammen för att se när ett serverdelsprogram skickar önskade egenskapsuppdateringar till ett simulerat enhetsprogram.

Om du vill köra simulerade enhetsprogram och serverdelsprogram behöver du anslutningssträngar för enheten och tjänsten. Du antecknade anslutningssträngar när du skapade resurserna i början av den här kursen.

Om du vill köra det simulerade enhetsprogrammet, öppna ett gränssnitt eller kommandotolkfönster och navigera till mappen iot-hub/Tutorials/DeviceTwins i Node.js-projektet som du hämtade. Kör sedan följande kommandon:

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

Öppna ett annat fönster för gränssnitt eller en kommandotolk för att köra serverdelsprogrammet. Navigera sedan till mappen iot-hub/Tutorials/DeviceTwins i Node.js-projektet som du hämtade. Kör sedan följande kommandon:

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

Observera önskade egenskapsuppdateringar

Följande skärmbild visar utdata från det simulerade enhetsprogrammet och visar hur det hanterar en uppdatering för den önskade egenskapen maxTemperature. Du kan se hur både toppnivåhanteraren och klimatkomponenthanteraren körs:

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

Följande skärmbild visar utdata från det serverdelsprogrammet och visar hur det skickar en uppdatering för den önskade egenskapen maxTemperature:

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

Observera rapporterade egenskapsuppdateringar

Följande skärmbild visar utdata från det simulerade enhetsprogrammet och visar hur det skickar en rapporterad egenskapsuppdatering till din hubb:

Screenshot that shows the simulated device updating its twin state.

Följande skärmbild visar utdata från serverdelsprogrammet och visar hur det tar emot och bearbetar en rapporterad egenskapsuppdatering från en enhet:

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

Rensa resurser

Om du planerar att slutföra nästa självstudie lämnar du resursgruppen och IoT-hubben för att återanvända dem senare.

Om du inte behöver IoT-hubben längre kan du ta bort den och resursgruppen i portalen. Om du vill göra det väljer du resursgruppen tutorial-iot-hub-rg som innehåller din IoT-hubb och väljer Ta bort.

Du kan också använda CLI:

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

Nästa steg

I den här självstudien beskrivs hur du synkroniserar statusinformation mellan dina enheter och din IoT Hub. Gå vidare till nästa självstudie för att lära dig hur du använder enhetstvillingar för att implementera processen för enhetsuppdatering.