Introducción a los dispositivos gemelos (Java)

Los dispositivos gemelos son documentos JSON que almacenan información acerca del estado del dispositivo, incluidos metadatos, configuraciones y condiciones. IoT Hub conserva un dispositivo gemelo por cada dispositivo que se conecta a él.

Nota

Las características descritas en este artículo solo están disponibles en el nivel estándar de IoT Hub. Para obtener más información sobre los niveles Básico y Estándar o Gratis de IoT Hub, consulte Elección del nivel adecuado de IoT Hub para la solución.

Use los dispositivos gemelos para:

  • Almacenar metadatos del dispositivo desde el back-end de la solución.

  • Notificar la información sobre el estado actual, como las funcionalidades y las condiciones disponibles (por ejemplo, el método de conectividad usado) de la aplicación del dispositivo.

  • Sincronizar el estado de flujos de trabajo de larga duración (como las actualizaciones del firmware y de la configuración) entre la aplicación del dispositivo y la del back-end.

  • Consultar los metadatos, la configuración o el estado del dispositivo.

Los dispositivos gemelos están diseñados para la sincronización y para consultar las condiciones y configuraciones del dispositivo. Para obtener más información sobre los dispositivos gemelos, incluyendo cuándo usarlos, consulte Comprenda los dispositivos gemelos.

Los centros de IoT almacenan dispositivos gemelos, que contienen los siguientes elementos:

  • Etiquetas. Metadatos de dispositivo a los que solo puede acceder el back-end de la solución.

  • Propiedades deseadas. Objetos JSON que puede modificar el back-end de la solución y puede observar la aplicación del dispositivo.

  • Propiedades notificadas. Objetos JSON que puede modificar la aplicación del dispositivo y que puede leer el back-end de la solución.

Las etiquetas y las propiedades no pueden contener matrices, pero pueden contener objetos anidados.

En la ilustración siguiente se muestra la organización del dispositivo gemelo:

Captura de pantalla de un diagrama de concepto de dispositivo gemelo.

Además, el back-end de la solución puede consultar los dispositivos gemelos en función de todos los datos descritos anteriormente. Para obtener más información acerca de los dispositivos gemelos, consulte Introducción a los dispositivos gemelos. Para más información sobre la consulta, consulte Lenguaje de consulta de IoT Hub.

En este artículo aprenderá a:

  • Use una aplicación de dispositivo simulado para notificar su canal de conectividad como propiedad notificada en el dispositivo gemelo.

  • Consultar dispositivos desde la aplicación de back-end mediante filtros en las etiquetas y propiedades que se han creado anteriormente.

En este artículo, creará dos aplicaciones de consola de Java:

  • add-tags-query:una aplicación de back-end que agrega etiquetas y consulta dispositivos gemelos.
  • simulated-device: una aplicación de dispositivo simulado que se conecta al centro de IoT y notifica su condición de conectividad.

Nota

Consulte los SDK de Azure IoT para obtener más información sobre las herramientas de SDK disponibles para compilar aplicaciones de dispositivo y back-end.

Requisitos previos

  • Una instancia de IoT Hub. Cree uno con la CLI o el Azure Portal.

  • Dispositivo registrado. Registre uno en el Azure Portal.

  • Java SE Development Kit 8. Asegúrese de seleccionar Java 8 en Long-term support (Soporte técnico a largo plazo) para obtener descargas de JDK 8.

  • Maven 3

  • Asegúrese de que está abierto el puerto 8883 del firewall. En el ejemplo de dispositivo de este artículo se usa el protocolo MQTT, que se comunica mediante el puerto 8883. Este puerto puede estar bloqueado en algunos entornos de red corporativos y educativos. Para más información y para saber cómo solucionar este problema, consulte el artículo sobre la conexión a IoT Hub (MQTT).

Obtención de la cadena de conexión de IoT Hub

En este artículo, se crea un servicio back-end que agrega propiedades deseadas a un dispositivo gemelo y luego consulta el registro de identidades para buscar todos los dispositivos con propiedades notificadas que se han actualizado en consecuencia. El servicio necesita el permiso Conectar al servicio para modificar las propiedades deseadas de un dispositivo gemelo y el permiso Lectura del Registro para consultar el registro de identidades. No hay ninguna directiva de acceso compartido predeterminada que contenga solo estos dos permisos, por lo que tendrá que crearla.

Para crear una directiva de acceso compartido que conceda los permisos Conexión del servicio y Lectura del Registro, y obtenga una cadena de conexión para esta directiva, siga estos pasos:

  1. En Azure Portal, seleccione Grupos de recursos. Seleccione el grupo de recursos donde se encuentra el centro y, a continuación, seleccione el centro en la lista de recursos.

  2. En el panel de la izquierda del centro, seleccione Directivas de acceso compartido.

  3. En el menú superior situado encima de la lista de directivas, seleccione Agregar una directiva de acceso compartida.

  4. En el panelAgregar una directiva de acceso compartida de la derecha, escriba un nombre descriptivo para la directiva, por ejemplo serviceAndRegistryRead. En Permisos, seleccione Lectura del Registro y Conexión del servicio, y después seleccione Agregar.

    Captura de pantalla que muestra cómo agregar una nueva directiva de acceso compartido.

  5. Seleccione la directiva nueva en la lista de directivas.

  6. Seleccione el icono de copia para Cadena de conexión principal y guarde el valor.

    Captura de pantalla que muestra cómo recuperar la cadena de conexión.

Para obtener más información sobre las directivas de acceso compartido y los permisos de IoT Hub, consulte Permisos y control del acceso.

Creación de una aplicación de dispositivo que actualiza las propiedades notificadas

En esta sección, creará una aplicación de consola de Java que se conecta al centro como myDeviceId y, luego, actualiza las propiedades notificadas de su dispositivo gemelo para confirmar que está conectada mediante una red de telefonía móvil.

  1. En la carpetaiot-java-twin-getstarted, cree un proyecto de Maven denominado simulated-device mediante el siguiente comando en el símbolo del sistema:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. En el símbolo del sistema, vaya a la nueva carpeta simulated-device.

  3. Con un editor de texto, abra el archivo pom.xml de la carpeta simulated-device y agregue las siguientes dependencias al nodo dependencies. Esta dependencia le permite usar el paquete iot-device-client en la aplicación para comunicarse con la instancia de IoT Hub.

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-device-client</artifactId>
      <version>1.17.5</version>
    </dependency>
    

    Nota

    Puede comprobar la versión más reciente de iot-device-client mediante la búsqueda de Maven.

  4. Agregue la siguiente dependencia al nodo dependencies. Esta dependencia configura una instrucción NOP para la fachada de registro de Apache SLF4J, que usa el SDK de cliente de dispositivo para implementar el registro. Esta configuración es opcional, pero si la omite, es posible que vea una advertencia en la consola al ejecutar la aplicación. Para más información sobre el registro en el SDK de cliente de dispositivo, consulte Registro en el archivo Léame Ejemplos para el SDK de dispositivo IoT de Azure para Java.

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.7.28</version>
    </dependency>
    
  5. Agregue el nodo build después del nodo dependencies. Esta configuración indica a Maven que use Java 1.8 para compilar la aplicación:

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  6. Guarde y cierre el archivo pom.xml.

  7. Con un editor de texto, abra el archivo simulated-device\src\main\java\com\mycompany\app\App.java.

  8. Agregue las siguientes instrucciones import al archivo:

    import com.microsoft.azure.sdk.iot.device.*;
    import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;
    
    import java.io.IOException;
    import java.net.URISyntaxException;
    import java.util.Scanner;
    
  9. Agregue las siguientes variables de nivel de clase a la clase App . Reemplace {yourdeviceconnectionstring} por la cadena de conexión de dispositivo que vio cuando registró un dispositivo en IoT Hub:

    private static String connString = "{yourdeviceconnectionstring}";
    private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
    private static String deviceId = "myDeviceId";
    

    Esta aplicación de ejemplo usa la variable protocol al crear una instancia de un objeto DeviceClient.

  10. Agregue el método siguiente a la clase App para imprimir información sobre las actualizaciones de dispositivos gemelos:

    protected static class DeviceTwinStatusCallBack implements IotHubEventCallback {
        @Override
        public void execute(IotHubStatusCode status, Object context) {
          System.out.println("IoT Hub responded to device twin operation with status " + status.name());
        }
      }
    
  11. Reemplace el código del método main por el código siguiente:

    • Cree un cliente de dispositivo para comunicarse con IoT Hub.

    • Cree un objeto Device para almacenar las propiedades del dispositivo gemelo.

    DeviceClient client = new DeviceClient(connString, protocol);
    
    // Create a Device object to store the device twin properties
    Device dataCollector = new Device() {
      // Print details when a property value changes
      @Override
      public void PropertyCall(String propertyKey, Object propertyValue, Object context) {
        System.out.println(propertyKey + " changed to " + propertyValue);
      }
    };
    
  12. Agregue el código siguiente al método main para crear una propiedad notificada connectivityType y enviarla a IoT Hub:

    try {
      // Open the DeviceClient and start the device twin services.
      client.open();
      client.startDeviceTwin(new DeviceTwinStatusCallBack(), null, dataCollector, null);
    
      // Create a reported property and send it to your IoT hub.
      dataCollector.setReportedProp(new Property("connectivityType", "cellular"));
      client.sendReportedProperties(dataCollector.getReportedProp());
    }
    catch (Exception e) {
      System.out.println("On exception, shutting down \n" + " Cause: " + e.getCause() + " \n" + e.getMessage());
      dataCollector.clean();
      client.closeNow();
      System.out.println("Shutting down...");
    }
    
  13. Agregue el siguiente código al final del método main. Esperar a la clave Enter da tiempo a IoT Hub a informar del estado de las operaciones del dispositivo gemelo.

    System.out.println("Press any key to exit...");
    
    Scanner scanner = new Scanner(System.in);
    scanner.nextLine();
    
    dataCollector.clean();
    client.close();
    
  14. Modifique la firma del método main para incluir las excepciones de la siguiente manera:

    public static void main(String[] args) throws URISyntaxException, IOException
    
  15. Guarde y cierre el archivo simulated-device\src\main\java\com\mycompany\app\App.java.

  16. Compile la aplicación simulated-device y corrija los errores. En el símbolo del sistema, vaya a la carpeta simulated-device y ejecute el comando siguiente:

    mvn clean package -DskipTests
    

Creación de una aplicación de servicio que actualiza las propiedades deseadas y consulta gemelos

En esta sección, creará una aplicación de Java que agrega metadatos de ubicación como una etiqueta al dispositivo gemelo en IoT Hub asociado con myDeviceId. La aplicación consulta el centro de IoT para los dispositivos que se encuentran en Estados Unidos y, después, consulta los dispositivos que notifican una conexión de red de telefonía móvil.

  1. En el equipo de desarrollo, cree una carpeta vacía denominada iot-java-twin-getstarted.

  2. En la carpeta iot-java-twin-getstarted, cree un proyecto de Maven denominado add-tags-query mediante el siguiente comando en el símbolo del sistema:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=add-tags-query -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  3. En el símbolo del sistema, vaya a la carpeta add-tags-query.

  4. Con un editor de texto, abra el archivo pom.xml en la carpeta add-tags-query y agregue la dependencia siguiente al nodo dependencies. Esta dependencia permite usar el paquete iot-service-client en la aplicación para comunicarse con la instancia de IoT Hub:

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-service-client</artifactId>
      <version>1.17.1</version>
      <type>jar</type>
    </dependency>
    

    Nota

    Puede comprobar la versión más reciente de iot-service-client mediante la búsqueda de Maven.

  5. Agregue el nodo build después del nodo dependencies. Esta configuración indica a Maven que use Java 1.8 para compilar la aplicación.

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  6. Guarde y cierre el archivo pom.xml.

  7. Con un editor de texto, abra el archivo add-tags-query\src\main\java\com\mycompany\app\App.java.

  8. Agregue las siguientes instrucciones import al archivo:

    import com.microsoft.azure.sdk.iot.service.devicetwin.*;
    import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;
    
    import java.io.IOException;
    import java.util.HashSet;
    import java.util.Set;
    
  9. Agregue las siguientes variables de nivel de clase a la clase App . Reemplace {youriothubconnectionstring} por la cadena de conexión de IoT Hub que copió en Obtención de la cadena de conexión de IoT Hub.

    public static final String iotHubConnectionString = "{youriothubconnectionstring}";
    public static final String deviceId = "myDeviceId";
    
    public static final String region = "US";
    public static final String plant = "Redmond43";
    
  10. Actualice la firma del método main para incluir la cláusula throws siguiente:

    public static void main( String[] args ) throws IOException
    
  11. Reemplace el código del método main por el código siguiente para crear los objetos DeviceTwin y DeviceTwinDevice. El objeto DeviceTwin administra la comunicación con el IoT Hub. El objeto DeviceTwinDevice representa el dispositivo gemelo con sus propiedades y etiquetas:

    // Get the DeviceTwin and DeviceTwinDevice objects
    DeviceTwin twinClient = DeviceTwin.createFromConnectionString(iotHubConnectionString);
    DeviceTwinDevice device = new DeviceTwinDevice(deviceId);
    
  12. Agregue el siguiente bloque try/catch al método main:

    try {
      // Code goes here
    } catch (IotHubException e) {
      System.out.println(e.getMessage());
    } catch (IOException e) {
      System.out.println(e.getMessage());
    }
    
  13. Para actualizar las etiquetas de dispositivo gemelo region y plant en el dispositivo gemelo, agregue el código siguiente en el bloque try:

    // Get the device twin from IoT Hub
    System.out.println("Device twin before update:");
    twinClient.getTwin(device);
    System.out.println(device);
    
    // Update device twin tags if they are different
    // from the existing values
    String currentTags = device.tagsToString();
    if ((!currentTags.contains("region=" + region) && !currentTags.contains("plant=" + plant))) {
      // Create the tags and attach them to the DeviceTwinDevice object
      Set<Pair> tags = new HashSet<Pair>();
      tags.add(new Pair("region", region));
      tags.add(new Pair("plant", plant));
      device.setTags(tags);
    
      // Update the device twin in IoT Hub
      System.out.println("Updating device twin");
      twinClient.updateTwin(device);
    }
    
    // Retrieve the device twin with the tag values from IoT Hub
    System.out.println("Device twin after update:");
    twinClient.getTwin(device);
    System.out.println(device);
    
  14. Para consultar los dispositivos gemelos en IoT Hub, agregue el código siguiente al bloque try después del código que agregó en el paso anterior. El código ejecuta dos consultas. Cada consulta devuelve un máximo de 100 dispositivos.

    // Query the device twins in IoT Hub
    System.out.println("Devices in Redmond:");
    
    // Construct the query
    SqlQuery sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, "tags.plant='Redmond43'", null);
    
    // Run the query, returning a maximum of 100 devices
    Query twinQuery = twinClient.queryTwin(sqlQuery.getQuery(), 100);
    while (twinClient.hasNextDeviceTwin(twinQuery)) {
      DeviceTwinDevice d = twinClient.getNextDeviceTwin(twinQuery);
      System.out.println(d.getDeviceId());
    }
    
    System.out.println("Devices in Redmond using a cellular network:");
    
    // Construct the query
    sqlQuery = SqlQuery.createSqlQuery("*", SqlQuery.FromType.DEVICES, "tags.plant='Redmond43' AND properties.reported.connectivityType = 'cellular'", null);
    
    // Run the query, returning a maximum of 100 devices
    twinQuery = twinClient.queryTwin(sqlQuery.getQuery(), 3);
    while (twinClient.hasNextDeviceTwin(twinQuery)) {
      DeviceTwinDevice d = twinClient.getNextDeviceTwin(twinQuery);
      System.out.println(d.getDeviceId());
    }
    
  15. Guarde y cierre el archivo add-tags-query\src\main\java\com\mycompany\app\App.java.

  16. Compile la aplicación add-tags-query y corrija los errores. En el símbolo del sistema, vaya a la carpeta add-tags-query y ejecute el comando siguiente:

    mvn clean package -DskipTests
    

Ejecución de las aplicaciones

Ya está preparado para ejecutar las aplicaciones de consola.

  1. En un símbolo del sistema en la carpeta add-tags-query, ejecute el siguiente comando para ejecutar la aplicación de servicio add-tags-query:

    mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
    

    Captura de pantalla en la que se muestra la salida del comando para ejecutar la aplicación de servicio add-tags-query.

    Puede ver las etiquetas plant y region agregadas al dispositivo gemelo. La primera consulta devuelve el dispositivo, pero la segunda no.

  2. En un símbolo del sistema en la carpeta simulated-device, ejecute el siguiente comando para agregar la propiedad notificada connectivityType al dispositivo gemelo:

    mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
    

    El cliente de dispositivo agrega la propiedad notificada connectivityType.

  3. En un símbolo del sistema en la carpeta add-tags-query, ejecute el siguiente comando para ejecutar la aplicación de servicio add-tags-query una segunda vez:

    mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
    

    Aplicación de servicio de IoT Hub de Java para actualizar valores de etiqueta y ejecutar consultas de dispositivo

    Ahora que el dispositivo ha enviado la propiedad connectivityType a IoT Hub, la segunda consulta devuelve el dispositivo.

En este artículo:

  • Ha agregado metadatos de dispositivo como etiquetas desde una aplicación de back-end.
  • Ha notificado la información de conectividad del dispositivo en el dispositivo gemelo.
  • Ha consultado la información del dispositivo gemelo mediante el lenguaje de consulta de IoT Hub de tipo SQL.

Pasos siguientes

Para saber cómo: