Compartir vía


Tutorial: Configuración de los dispositivos desde un servicio back-end

Como parte del ciclo de vida del dispositivo, pueda que necesite configurar sus dispositivos IoT desde el servicio de backend. Cuando envíe una configuración deseada a los dispositivos, también recibirá actualizaciones de estado y cumplimiento de esos mismos dispositivos. Por ejemplo, puede establecer un intervalo de temperatura operativo de destino para un dispositivo o recopilar información de la versión de firmware de los dispositivos.

Para sincronizar la información de estado entre un dispositivo y un centro de IoT, use dispositivos gemelos. Un dispositivo gemelo es un documento JSON, asociado a un dispositivo específico y almacenado por IoT Hub en la nube, donde puede consultarlos . Un dispositivo gemelo contiene propiedades deseadas, propiedades notificadas y etiquetas.

  • Una aplicación back-end establece una propiedad deseada y la lee un dispositivo.
  • Un dispositivo establece una propiedad informada y una aplicación back-end la lee.
  • Una etiqueta es establecida por una aplicación de servidor y nunca se envía a un dispositivo. Las etiquetas se usan para organizar los dispositivos.

En este tutorial se muestra cómo usar las propiedades deseadas y notificadas para sincronizar la información de estado.

Diagrama de dispositivos gemelos en el dispositivo y en la nube.

En este tutorial, realizará las siguientes tareas:

  • Cree un centro de IoT y agregue un dispositivo de prueba al registro de identidades.
  • Use las propiedades deseadas para enviar información de estado al dispositivo simulado.
  • Use las propiedades notificadas para recibir información de estado del dispositivo simulado.

Si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.

Prerrequisitos

  • En este tutorial se usa la CLI de Azure para crear recursos en la nube. Si ya tiene un centro de IoT con un dispositivo registrado en él, puede omitir esos pasos. Hay dos maneras de ejecutar comandos de la CLI:

  • Las dos aplicaciones de ejemplo que se ejecutan en este tutorial se escriben mediante Node.js. Necesita Node.js v10.x.x o posterior en su máquina de desarrollo.

    • Puede descargar Node.js para varias plataformas desde nodejs.org.

    • Puede comprobar la versión actual de Node.js en el equipo de desarrollo mediante el comando siguiente:

      node --version
      
  • Clona o descarga el proyecto de ejemplo de Node.js desde ejemplos de Azure IoT para Node.js.

  • Asegúrese de que está abierto el puerto 8883 del firewall. En el ejemplo de dispositivo de este tutorial se usa el protocolo MQTT, que se comunica a través del puerto 8883. Este puerto puede bloquearse en algunos entornos de red corporativos y educativos. Para obtener más información y formas de solucionar este problema, consulte Conexión a IoT Hub (MQTT).

Configuración de los recursos de Azure

Para completar este tutorial, la suscripción de Azure debe contener un centro de IoT con un dispositivo agregado al registro de identidades del dispositivo. La entrada del registro de identidad del dispositivo permite que el dispositivo simulado que ejecute en este tutorial se conecte al centro.

Si aún no tiene una instancia de IoT Hub configurada en su suscripción, puede configurar una con el siguiente script de la CLI. Este script usa el nombre tutorial-iot-hub con un número aleatorio anexado para el nombre del centro de IoT. Puede reemplazar este nombre por su propio nombre único global al ejecutarlo. El script crea el grupo de recursos y el hub en la región Centro de EE. UU, que puede cambiar a una región más cercana a usted. El script recupera la cadena de conexión de servicio del centro de IoT, que se utiliza en el ejemplo de back-end para conectar con el centro de IoT:

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

En este tutorial se usa un dispositivo simulado denominado MyTwinDevice. El script siguiente agrega este dispositivo al registro de identidad y recupera su cadena de conexión:

# 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

Enviar información de estado a un dispositivo

Las propiedades deseadas se usan para enviar información de estado desde una aplicación back-end a un dispositivo. En esta sección, verá cómo:

  • Configure un dispositivo para recibir y procesar las propiedades deseadas.
  • Enviar propiedades deseadas desde una aplicación back-end a un dispositivo.

Propiedades deseadas como ejemplo

Puede estructurar las propiedades deseadas de cualquier manera que sea conveniente para la aplicación. En este ejemplo se usa una propiedad de nivel superior denominada fanOn y agrupa las propiedades restantes en componentes independientes. El siguiente fragmento de código JSON muestra la estructura de las propiedades deseadas que usa este tutorial. El código JSON se encuentra en el archivo desired.json.

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

Recepción de propiedades deseadas en una aplicación de dispositivo

Para ver el código de ejemplo de dispositivo simulado que recibe las propiedades deseadas, vaya a la carpeta iot-hub/Tutorials/DeviceTwins en el proyecto de ejemplo Node.js que descargó. A continuación, abra el archivo SimulatedDevice.js en un editor de texto.

En las secciones siguientes se describe el código que se ejecuta en el dispositivo simulado que responde a los cambios de propiedad deseados enviados desde la aplicación back-end.

Recupera el objeto gemelo del dispositivo

Cuando registró el dispositivo con el centro de IoT, obtuvo una cadena de conexión de dispositivo como salida. El dispositivo usa una cadena de conexión de dispositivo para autenticarse con su identidad registrada en la nube. El siguiente código se conecta a tu centro de IoT usando una cadena de conexión de dispositivo:

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

El código siguiente obtiene un gemelo desde el objeto de cliente:

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

Creación de controladores

Puede crear controladores para las actualizaciones de propiedades deseadas que responden a las actualizaciones en distintos niveles de la jerarquía JSON. Por ejemplo, este controlador ve todos los cambios de propiedad deseados enviados al dispositivo desde una aplicación back-end. La variable delta contiene las propiedades deseadas enviadas desde el back-end de la solución:

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

El controlador siguiente solo reacciona a los cambios realizados en la propiedad deseada 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}';
});

Controladores para varias propiedades

En el json de propiedades deseadas de ejemplo para este tutorial, el nodo climático en componentes contiene dos propiedades, minTemperature y maxTemperature.

El objeto gemelo local de un dispositivo almacena un conjunto completo de propiedades deseadas y notificadas. El delta enviado desde el back-end podría actualizar solo un subconjunto de propiedades deseadas. En el siguiente fragmento de código, si el dispositivo simulado recibe una actualización de solo uno de minTemperature y maxTemperature, usa el valor del gemelo local para el otro valor para configurar el dispositivo:

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

Control de las operaciones de inserción, actualización y eliminación

Las propiedades deseadas enviadas desde el back-end no indican qué operación se está realizando en una propiedad deseada determinada. El código debe deducir la operación del conjunto actual de propiedades deseadas almacenadas localmente y los cambios enviados desde el centro.

En el fragmento de código siguiente se muestra cómo controla el dispositivo simulado las operaciones de inserción, actualización y eliminación en la lista de componentes de las propiedades deseadas . Puede ver cómo usar valores NULL para indicar que se debe eliminar un componente:

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

Envío de propiedades deseadas desde una aplicación back-end

Ha visto cómo un dispositivo implementa controladores para recibir actualizaciones de propiedades deseadas. En esta sección se muestra cómo enviar los cambios de propiedad deseados a un dispositivo desde una aplicación back-end.

Para ver el código de ejemplo de dispositivo simulado que recibe las propiedades deseadas, vaya a la carpeta iot-hub/Tutorials/DeviceTwins en el proyecto de ejemplo Node.js que descargó. A continuación, abra el archivo ServiceClient.js en un editor de texto.

En el fragmento de código siguiente se muestra cómo conectarse al registro de identidades del dispositivo y acceder al gemelo para un dispositivo específico:

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

En el fragmento de código siguiente se muestran diferentes revisiones de propiedades deseadas que la aplicación back-end envía al dispositivo:

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

En el fragmento de código siguiente se muestra cómo la aplicación back-end envía una actualización de propiedad deseada a un dispositivo:

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

Recepción de información de estado de un dispositivo

La aplicación back-end recibe información de estado de un dispositivo como propiedades notificadas. Un dispositivo configura las propiedades reportadas y las envía a su concentrador. Una aplicación back-end puede leer los valores actuales de las propiedades notificadas desde el dispositivo gemelo almacenado en el centro.

Envío de propiedades notificadas desde un dispositivo

Puede enviar actualizaciones a valores de propiedad notificada tales como una revisión. En el siguiente fragmento se presenta una plantilla para el parche que envía el dispositivo simulado. El dispositivo simulado actualiza los campos del parche antes de enviarlos al hub.

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

El dispositivo simulado emplea la función siguiente para enviar el parche que contiene las propiedades notificadas al hub.

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

Procesar propiedades reportadas

Una aplicación back-end tiene acceso a los valores de propiedad notificada actuales para un dispositivo a través del dispositivo gemelo. En el fragmento de código siguiente se muestra cómo la aplicación back-end lee los valores de propiedad notificados para el dispositivo simulado:

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

Ejecución de las aplicaciones

En esta sección, ejecutará las dos aplicaciones de ejemplo para observar que una aplicación back-end envía actualizaciones de propiedades deseadas a una aplicación de dispositivo simulado.

Para ejecutar el dispositivo simulado y las aplicaciones back-end, necesita las cadenas de conexión de dispositivo y servicio. Usted tomó nota de las cadenas de conexión cuando creó los recursos al principio de este tutorial.

Para ejecutar la aplicación de dispositivo simulado, abra una ventana del shell o del símbolo del sistema y vaya a la carpeta iot-hub/Tutorials/DeviceTwins en el proyecto Node.js que descargó. A continuación, ejecute los siguientes comandos:

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

Para ejecutar la aplicación backend, abra otro shell o ventana de línea de comandos. A continuación, vaya a la carpeta iot-hub/Tutorials/DeviceTwins en el proyecto de Node.js que descargó. A continuación, ejecute los siguientes comandos:

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

Observar las actualizaciones de las propiedades deseadas

En la captura de pantalla siguiente se muestra la salida de la aplicación de dispositivo simulado y se resalta cómo controla una actualización de la propiedad deseada maxTemperature . Puede ver cómo se ejecutan tanto el controlador de nivel superior como los controladores de componentes climáticos:

Captura de pantalla que muestra cómo se ejecutan tanto el controlador de nivel superior como los controladores de componentes climáticos.

En la captura de pantalla siguiente se muestra la salida de la aplicación back-end y se resalta cómo envía una actualización a la propiedad deseada maxTemperature :

Captura de pantalla que muestra la salida de la aplicación back-end y resalta cómo envía una actualización.

Observar las actualizaciones de propiedades notificadas

La siguientes captura de pantalla muestra el resultado de la aplicación de dispositivo simulado y resalta cómo envía una actualización de la propiedad notificada al centro:

Captura de pantalla que muestra al dispositivo simulado actualizando su estado de gemelo.

En la captura de pantalla siguiente se muestra la salida de la aplicación back-end y se resalta cómo recibe y procesa una actualización de propiedad notificada desde un dispositivo:

Captura de pantalla que muestra la aplicación back-end que recibe las propiedades notificadas del dispositivo.

Limpieza de recursos

Si tiene pensado completar el siguiente tutorial, deje el centro de IoT y el grupo de recursos para volver a usarlos más tarde.

Si ya no necesita el centro de IoT, elimínelo y el grupo de recursos en el portal. Para ello, seleccione el grupo de recursos tutorial-iot-hub-rg que contiene el centro de IoT y seleccione Eliminar.

Como alternativa, use la CLI:

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

Pasos siguientes

En este tutorial, ha aprendido a sincronizar la información de estado entre sus dispositivos y su IoT Hub. Pase al siguiente tutorial para aprender a usar dispositivos gemelos para implementar el proceso de actualización de dispositivos.