Dela via


Självstudie: Konfigurera dina enheter från en backend-tjä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 ange ett målintervall för drifttemperaturen för en enhet eller samla in versionsinformation om den inbyggda programvaran från dina enheter.

Om du vill synkronisera tillståndsinformation 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 av IoT Hub i molnet där du kan fråga dem. En enhetstvilling innehåller önskade egenskaper, rapporterade egenskaper och taggar.

  • En önskad egenskap anges av ett bakgrundsprogram och läses av en enhet.
  • En rapporterad egenskap anges av en enhet och läses av en bakgrundsapplikation.
  • En tagg anges av ett bakgrundsprogram och skickas aldrig till en enhet. Du använder taggar för att organisera dina enheter.

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

Diagram över enhetstvillingar på enheten och i molnet.

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änd önskade egenskaper för att skicka tillståndsinformation till din simulerade enhet.
  • Använd rapporterade egenskaper för att ta emot tillståndsinformation från din simulerade enhet.

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

Förutsättningar

  • Den här handledningen använder 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 Ansluta till IoT Hub (MQTT).

Konfigurera Azure-resurser

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

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 , som du kan ändra till en region närmare dig. Skriptet hämtar anslutningssträngen för IoT Hub-tjänsten, vilken används i bakdelsexemplet 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

I den här självstudien används en simulerad enhet med namnet MyTwinDevice. Följande skript lägger till den här enheten i ditt identitetsregister och hämtar dess 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 tillståndsinformation från ett serverdelsprogram till en enhet. I det här avsnittet ser du 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 önskade egenskaper på alla sätt som passar ditt program. I det här exemplet används en toppnivåegenskap som kallas fanOn och de återstående egenskaperna grupperas i separata komponenter. Följande JSON-kodfragment visar strukturen för de avsedda egenskaper som används i den här handledningen. 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 enhetsexempelkoden som tar emot önskade egenskaper går du till mappen iot-hub/Tutorials/DeviceTwins i exempel-Node.js projekt som du laddade ned. Öppna sedan filen SimulatedDevice.js i en 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 enheten med IoT-hubben fick du en enhetsanslutningssträng som utdata. En enhetsanslutningssträng används av enheten för att autentisera med dess registrerade identitet i molnet. Följande kod ansluter till din IoT-hubb med hjälp av 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 önskade egenskapsuppdateringar som svarar på uppdateringar på olika nivåer i JSON-hierarkin. Den här hanteraren ser till exempel alla önskade egenskapsändringar som skickas till enheten från ett serverdelsprogram. Deltavariabeln innehåller önskade egenskaper 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 bara 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 klimatnoden under komponenter två egenskaper, minTemperature och maxTemperature.

En enhets lokala tvillingobjekt lagrar en fullständig uppsättning önskade och rapporterade egenskaper. Deltat som skickas från serverdelen kan bara uppdatera en delmängd av önskade egenskaper. I följande kodfragment, om den simulerade enheten tar emot en uppdatering till bara en av minTemperature och maxTemperature, använder den 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 åtgärder för att infoga, uppdatera och ta bort

Önskade egenskaper som skickas från serverdelen anger inte vilken åtgärd som utförs på en viss önskad egenskap. Koden måste härleda åtgärden från den aktuella uppsättningen önskade egenskaper som lagras lokalt och de ändringar som skickas från hubben.

Följande kodfragment visar hur den simulerade enheten hanterar infognings-, uppdaterings- och borttagningsåtgärder 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 implementerar hanterare för att ta emot önskade egenskapsuppdateringar. Det här avsnittet visar hur du skickar önskade egenskapsändringar till en enhet från ett serverdelsprogram.

Om du vill visa den simulerade enhetsexempelkoden som tar emot önskade egenskaper går du till mappen iot-hub/Tutorials/DeviceTwins i exempel-Node.js projekt som du laddade ned. Öppna sedan filen ServiceClient.js i en textredigerare.

Följande kodfragment 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 kodfragment visar olika önskade egenskapskorrigeringar 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 kodfragment 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 backend-applikation tar emot tillståndsinformation från en enhet som rapporterar egenskaper. En enhet anger de rapporterade egenskaperna och skickar dem till din hubb. En backend-applikation kan läsa de aktuella värdena för de rapporterade egenskaperna från den digitala tvilling som lagras i din hub.

Skicka rapporterade egenskaper från en enhet

Du kan skicka uppdateringar till rapporterade egenskapsvärden som en patch. Följande kodfragment visar en mall för korrigeringen som den simulerade enheten skickar. Den simulerade enheten uppdaterar fälten i korrigeringen 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 korrigeringen 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

En backend-applikation får åtkomst till de rapporterade aktuella egenskapsvärdena för en enhet genom enhetstvillingen. Följande kodfragment visar hur serverdelsprogrammet läser de rapporterade egenskapsvärdena 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 de simulerade enhets- och serverdelsprogrammen behöver du enhets- och tjänstanslutningssträngarna. Du antecknade anslutningssträngarna när du skapade resurserna i början av den här handledningen.

Om du vill köra det simulerade enhetsprogrammet öppnar du ett gränssnitt eller kommandotolksfönster och navigerar till mappen iot-hub/Tutorials/DeviceTwins i Node.js projekt som du laddade ned. Kör sedan följande kommandon:

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

Om du vill köra serverdelsprogrammet öppnar du ett annat gränssnitt eller kommandotolksfönster. Gå sedan till mappen iot-hub/Tutorials/DeviceTwins i Node.js projekt som du laddade ned. 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 av den önskade egenskapen maxTemperature . Du kan se hur både toppnivåhanteraren och klimatkomponenthanterare körs:

Skärmbild som visar hur både toppnivåhanteraren och klimatkomponentens hanterare körs.

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

Skärmbild som visar utdata från serverdelsprogrammet och visar hur det skickar en uppdatering.

Observera rapporterade ändringar av egenskaper

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

Skärmbild visar hur den simulerade enheten uppdaterar sin tvillingstatus.

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

Skärmbild som visar serverdelsprogrammet som tar emot de enhetsrapporterade egenskaperna.

Rensa resurser

Om du planerar att slutföra nästa självstudie, lämna kvar resursgruppen och IoT-hubben så att du kan å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 har du lärt dig hur du synkroniserar tillståndsinformation mellan dina enheter och din IoT-hubb. 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.