Comunicación con una instancia de IoT Hub mediante el protocolo MQTT

En este artículo se describe la manera en que los dispositivos pueden utilizar comportamientos admitidos de MQTT para comunicarse con Azure IoT Hub. IoT Hub permite a los dispositivos comunicarse con los puntos de conexión de dispositivos de IoT Hub mediante:

  • MQTT v3.1.1 en el puerto TCP 8883
  • MQTT v3.1.1 sobre WebSocket en el puerto TCP 443.

Nota:

Algunas de las características que se mencionan en este artículo, como la mensajería de la nube al dispositivo, los dispositivos gemelos y la administración de dispositivos, 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.

Toda comunicación de los dispositivos con IoT Hub se debe proteger mediante TLS/SSL. Por lo tanto, IoT Hub no admite conexiones no seguras a través del puerto TCP 1883.

Comparación de la compatibilidad con MQTT en IoT Hub y Event Grid

IoT Hub no es un agente MQTT completo, así que no se admite su uso con todos los comportamientos que se especifican en la norma MQTT v3.1.1. Si la solución necesita compatibilidad con MQTT, se recomienda la compatibilidad con MQTT en Azure Event Grid. Event Grid permite la comunicación bidireccional entre clientes MQTT en temas jerárquicos flexibles mediante un modelo de mensajería publicación/suscripción. También le permite enrutar mensajes MQTT a servicios de Azure o puntos de conexión personalizados para su posterior procesamiento.

En la tabla siguiente se explican las diferencias en la compatibilidad con MQTT entre los dos servicios:

IoT Hub Event Grid
Modelo de servidor cliente con acoplamiento estricto entre dispositivos y aplicaciones en la nube. Modelo de publicación y suscripción que desacopla publicadores y suscriptores.
Compatibilidad limitada con características para MQTT v3.1.1 y compatibilidad limitada con características para MQTT v5 en versión preliminar. No se ha planeado más compatibilidad con características. Compatibilidad con el protocolo MQTT v3.1.1 y v5, con más compatibilidad con características y cumplimiento del sector planeado.
Temas estáticos y predefinidos. Temas jerárquicos personalizados con compatibilidad con caracteres comodín.
No se admiten las difusiones de la nube al dispositivo ni la comunicación entre dispositivos. Admite difusión del dispositivo a la nube, de la nube a dispositivo, de alta distribución y patrones de comunicación de dispositivo a dispositivo.
Tamaño máximo de mensaje: 256 KB. Tamaño máximo de mensaje: 512 KB.

Conexión a IoT Hub

Un dispositivo puede usar el protocolo MQTT para conectarse a un centro de IoT mediante una de las opciones siguientes:

El puerto MQTT (puerto TCP 8883) está bloqueado en muchos entornos de red corporativos y educativos. Si no puede abrir el puerto 8883 en el firewall, se recomienda usar MQTT sobre WebSockets. MQTT sobre WebSockets se comunica a través del puerto 443, que casi siempre está abierto en entornos de red. Para obtener información sobre cómo especificar los protocolos MQTT y MQTT sobre WebSockets cuando use los SDK de IoT de Azure, consulte Uso de los SDK de dispositivo.

Uso de los SDK de dispositivo

Los SDK de dispositivo compatibles con el protocolo MQTT están disponibles para Java, Node.js, C, C# y Python. En los SDK de dispositivo, las conexiones a los centros de IoT se establecen mediante el mecanismo de autenticación que se establezca. Para utilizar el protocolo MQTT, el parámetro de protocolo de cliente debe establecerse en MQTT. También puede especificar MQTT sobre WebSockets en el parámetro de protocolo de cliente. De forma predeterminada, los SDK de dispositivo se conectan a un centro de IoT con la marca CleanSession establecida en 0 y usan QoS 1 para el intercambio de mensajes con el centro de IoT. Aunque es posible configurar QoS 0 para un intercambio de mensajes más rápido, debe tener en cuenta que la entrega no está garantizada ni confirmada. Por esta razón, QoS 0 a menudo se denomina "dispare y olvídese".

Cuando un dispositivo se conecta a un centro de IoT, los SDK de dispositivo proporcionan métodos que permiten al dispositivo intercambiar mensajes desde un centro de IoT.

La tabla siguiente contiene vínculos a ejemplos de código para cada idioma admitido y especifica el parámetro que se debe utilizar para establecer una conexión con Azure IoT Hub mediante el protocolo MQTT o MQTT sobre WebSockets.

Idioma Parámetro de protocolo MQTT Parámetro de protocolo MQTT sobre WebSockets
Node.js azure-iot-device-mqtt.Mqtt azure-iot-device-mqtt.MqttWs
Java IotHubClientProtocol.MQTT IotHubClientProtocol.MQTT_WS
C MQTT_Protocol MQTT_WebSocket_Protocol
C# TransportType.Mqtt TransportType.Mqtt recurre a MQTT sobre WebSockets si se produce un error en MQTT. Para especificar solo MQTT sobre WebSockets, use TransportType.Mqtt_WebSocket_Only.
Python Compatible con MQTT de forma predeterminada Agregue websockets=True en la llamada para crear el cliente.

En el siguiente fragmento se muestra cómo especificar el protocolo MQTT sobre WebSockets al usar el SDK de Node.js para IoT de Azure:

var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-mqtt').MqttWs;
var client = Client.fromConnectionString(deviceConnectionString, Protocol);

En el siguiente fragmento se muestra cómo especificar el protocolo MQTT sobre WebSockets al usar el SDK de Python para IoT de Azure:

from azure.iot.device.aio import IoTHubDeviceClient
device_client = IoTHubDeviceClient.create_from_connection_string(deviceConnectionString, websockets=True)

Tiempo de espera de Keep-Alive predeterminado

Para asegurarse de que una conexión cliente/IoT Hub permanece activa, tanto el servicio como el cliente se envían regularmente un ping Keep-Alive entre sí. El cliente que usa el SDK de IoT envía un mensaje de Keep-Alive en el intervalo definido en la tabla siguiente:

Idioma Intervalo de mantenimiento de conexión predeterminado Configurable
Node.js 180 Segundos No
Java 230 Segundos
C 240 segundos
C# 300 segundos*
Python 60 segundos

*El SDK de C# define el valor predeterminado de la propiedad KeepAliveInSeconds de MQTT como 300 segundos. En realidad, el SDK envía una solicitud de ping cuatro veces por duración de mantenimiento activo establecida. En otras palabras, el SDK envía un ping de conexión una vez cada 75 segundos.

Después de la especificación MQTT v3.1.1, el intervalo de ping de mantenimiento activo de IoT Hub es 1,5 veces el valor de mantenimiento activo del cliente; sin embargo, IoT Hub limita el tiempo de espera máximo del servidor a 29,45 minutos (1767 segundos). Este límite existe porque todos los servicios de Azure están vinculados al tiempo de espera de inactividad TCP del equilibrador de carga de Azure, que es de 29,45 minutos.

Por ejemplo, un dispositivo que usa el SDK de Java envía el ping de Keep-Alive y después pierde la conectividad de red. 230 segundos más tarde, el dispositivo pierde el ping de Keep-Alive porque está sin conexión. Sin embargo, IoT Hub no cierra la conexión de inmediato, espera otros (230 * 1.5) - 230 = 115 segundos antes de desconectar el dispositivo con el error 404104 DeviceConnectionClosedRemotely.

El valor de Keep-Alive máximo del cliente que puede establecer es 1767 / 1.5 = 1177 segundos. Cualquier tráfico restablece el valor de keep-alive. Por ejemplo, una actualización correcta del token de firma de acceso compartido (SAS) restablece el mantenimiento activo.

Migración de una aplicación de dispositivo de AMQP a MQTT

Si usa los SDK de dispositivo, deberá modificar el parámetro de protocolo de la inicialización del cliente para cambiar de AMQP a MQTT, tal como se indicó anteriormente.

Al hacerlo, asegúrese de comprobar los elementos siguientes:

  • AMQP devuelve errores para muchas condiciones, mientras que MQTT finaliza la conexión. Como resultado, la lógica de control de excepciones puede requerir algunos cambios.

  • Con MQTT, no se admiten las operaciones de rechazo cuando se reciben mensajes de la nube al dispositivo. Si la aplicación de back-end tiene que recibir una respuesta de la aplicación del dispositivo, considere el uso de métodos directos.

  • No se admite el uso de AMQP en el SDK de Python.

Uso del protocolo MQTT directamente (como un dispositivo)

Si los SDK de dispositivo no pueden usarse en un dispositivo concreto, seguirá siendo posible conectarse a los puntos de conexión públicos del dispositivo mediante el protocolo MQTT y desde el puerto 8883.

En el paquete CONNECT el dispositivo debe usar los siguientes valores:

  • Para el campo ClientId, use deviceId.

  • Para el campo Nombre de usuario use {iotHub-hostname}/{device-id}/?api-version=2021-04-12, donde {iotHub-hostname} es el CName completo del centro de IoT.

    Por ejemplo, si el nombre de su centro de IoT es contoso.azure-devices.net y si el nombre del dispositivo es MyDevice01, el campo Nombre de usuario completo debe contener:

    contoso.azure-devices.net/MyDevice01/?api-version=2021-04-12

    El mejor procedimiento consiste en incluir la versión de la API en el campo. De lo contrario, podrían producirse comportamientos inesperados.

  • Para el campo Contraseña , use un token SAS. El formato del token de SAS es el mismo que para los protocolos HTTPS y AMQP:

    SharedAccessSignature sig={signature-string}&se={expiry}&sr={URL-encoded-resourceURI}

    Nota

    Las contraseñas de token de SAS no son necesarias si utiliza la autenticación de certificados X.509. Para obtener más información, consulte Tutorial: Creación y carga de certificados para pruebas y siga las instrucciones de código de la sección Configuración de TLS/SSL.

    Para obtener más información sobre cómo generar tokens de SAS, consulte la sección Uso de tokens de SAS como dispositivo de Control del acceso a IoT Hub mediante firmas de acceso compartido.

    También puede utilizar la extensión de Azure IoT Hub para Visual Studio Code multiplataforma o el comando de extensión CLI az iot hub generate-sas-token para generar rápidamente un token de SAS. Después, puede copiar y pegar el token de SAS en su propio código con fines de prueba.

Para ver un tutorial sobre el uso de MQTT directamente, consulte Uso de MQTT para desarrollar un cliente de dispositivo IoT sin usar un SDK de dispositivo.

Usar la extensión de Azure IoT Hub para Visual Studio Code

  1. En la barra lateral, expanda el nodo Dispositivos en la sección Azure IoT Hub.

  2. Haga clic con el botón derecho en el dispositivo IoT y seleccione Generar token de SAS para el dispositivo en el menú contextual.

  3. Introduzca el tiempo de expiración, en horas, para el token de SAS en el cuadro de entrada y, a continuación, seleccione la tecla Entrar.

  4. El token de SAS se crea y se copia en el Portapapeles.

    El token de SAS que ha generado tiene la siguiente estructura:

    HostName={iotHub-hostname};DeviceId=javadevice;SharedAccessSignature=SharedAccessSignature sr={iotHub-hostname}%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802

    La parte de este token que se debe usar como el campo Password para conectarse con MQTT es:

    SharedAccessSignature sr={iotHub-hostname}%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802

La aplicación para dispositivo puede especificar un mensajeWill en el paquete CONNECT. La aplicación para dispositivo debe usar devices/{device-id}/messages/events/ o devices/{device-id}/messages/events/{property-bag} como el nombre del tema Will para definir los mensajes Will que se reenviarán como un mensaje de telemetría. En este caso, si la conexión de red se cierra, pero no se recibió anteriormente un paquete DISCONNECT desde el dispositivo, se enviará el mensaje Will, que se suministra en el paquete CONNECT, al canal de telemetría desde IoT Hub. El canal de telemetría puede ser el punto de conexión Eventos predeterminado o un punto de conexión personalizado que se define por el enrutamiento de IoT Hub. El mensaje tiene la propiedad iothub-MessageType con un valor de Will asignado.

Uso del protocolo MQTT directamente (como un módulo)

Puede conectarse a IoT Hub a través de MQTT mediante una identidad de módulo, similar a la conexión a IoT Hub como dispositivo. Para obtener más información sobre cómo conectarse a IoT Hub a través de MQTT como dispositivo, consulte Uso del protocolo MQTT directamente (como dispositivo). Sin embargo, debe utilizar los siguientes valores:

  • Establezca el identificador de cliente en {device-id}/{module-id}.

  • Si la autenticación es mediante el nombre de usuario y la contraseña, establezca el nombre de usuario en <hubname>.azure-devices.net/{device_id}/{module_id}/?api-version=2021-04-12 y use el token de SAS asociado con la identidad del módulo como contraseña.

  • Use devices/{device-id}/modules/{module-id}/messages/events/ como tema para publicar los datos de telemetría.

  • Use devices/{device-id}/modules/{module-id}/messages/events/ como tema de WILL.

  • Use devices/{device-id}/modules/{module-id}/# como tema para recibir mensajes.

  • Los temas de GET y PATCH gemelos son idénticos para los dispositivos y los módulos.

  • El tema de estado gemelo es idéntico para los módulos y los dispositivos.

Para obtener más información sobre el uso de MQTT con módulos, consulte Publicación y suscripción con IoT Edge y obtenga más información sobre el punto de conexión MQTT del centro de IoT Edge.

Ejemplos de uso de MQTT sin un SDK de Azure IoT

El Repositorio de ejemplo de MQTT para IoT contiene ejemplos de C/C++, Python y la CLI que muestran cómo enviar mensajes de telemetría, recibir mensajes de la nube al dispositivo y usar dispositivos gemelos sin usar los SDK de dispositivo de Azure.

Los ejemplos de C/C++ usan la biblioteca de Eclipse Mosquitto, el ejemplo de Python usa Eclipse Paho y los ejemplos de la CLI usan mosquitto_pub.

Para más información, consulte Tutorial: Uso de MQTT para desarrollar un cliente de dispositivo IoT.

Configuración de TLS/SSL

Para usar el protocolo MQTT directamente, el cliente debe conectarse mediante TLS/SSL. Si intenta omitir este paso, se producirá un error con errores de conexión.

Para establecer una conexión TLS, es posible que deba descargar el certificado raíz de DigiCert que usa Azure. Entre el 15 de febrero y el 15 de octubre de 2023, Azure IoT Hub está migrando su certificado raíz TLS desde el certificado raíz DigiCert Baltimore al DigiCert Global Root G2. Durante el período de migración, debe tener ambos certificados en los dispositivos para garantizar la conectividad. Para más información sobre la migración, consulte Migración de recursos de IoT a una nueva raíz de certificado TLS Para obtener más información sobre estos certificados, consulte el sitio web de Digicert.

El siguiente ejemplo muestra cómo implementar esta configuración, utilizando la versión Python de la biblioteca Paho MQTT de la Fundación Eclipse.

En primer lugar, instale la biblioteca Paho desde el entorno de línea de comandos:

pip install paho-mqtt

A continuación, implemente el cliente en un script de Python. Reemplace estos marcadores de posición en el siguiente fragmento de código:

  • <local path to digicert.cer> es la ruta de acceso a un archivo local que contiene el certificado raíz de DigiCert. Puede crear este archivo copiando la información de certificado de certs.c en el SDK de Azure IoT para C. Incluya las líneas -----BEGIN CERTIFICATE----- y -----END CERTIFICATE-----, quite las marcas " al principio y al final de cada línea, y quite los caracteres \r\n al final de cada línea.

  • <device id from device registry> es la identidad de un dispositivo que agregó a IoT Hub.

  • <generated SAS token> es un token de SAS para el dispositivo que se creó como se describió anteriormente en este artículo.

  • <iot hub name> el nombre de IoT Hub.

from paho.mqtt import client as mqtt
import ssl

path_to_root_cert = "<local path to digicert.cer file>"
device_id = "<device id from device registry>"
sas_token = "<generated SAS token>"
iot_hub_name = "<iot hub name>"


def on_connect(client, userdata, flags, rc):
    print("Device connected with result code: " + str(rc))


def on_disconnect(client, userdata, rc):
    print("Device disconnected with result code: " + str(rc))


def on_publish(client, userdata, mid):
    print("Device sent message")


client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311)

client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish

client.username_pw_set(username=iot_hub_name+".azure-devices.net/" +
                       device_id + "/?api-version=2021-04-12", password=sas_token)

client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None,
               cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
client.tls_insecure_set(False)

client.connect(iot_hub_name+".azure-devices.net", port=8883)

client.publish("devices/" + device_id + "/messages/events/", '{"id":123}', qos=1)
client.loop_forever()

Para autenticarse mediante un certificado de dispositivo, actualice el fragmento de código anterior con los cambios especificados en el siguiente fragmento de código. Para obtener más información sobre cómo prepararse para la autenticación basada en certificados, consulte la sección Obtención de un certificado de entidad de certificación X.509 de Autenticación de dispositivos mediante certificados de entidad de certificación X.509.

# Create the client as before
# ...

# Set the username but not the password on your client
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" +
                       device_id + "/?api-version=2021-04-12", password=None)

# Set the certificate and key paths on your client
cert_file = "<local path to your certificate file>"
key_file = "<local path to your device key file>"
client.tls_set(ca_certs=path_to_root_cert, certfile=cert_file, keyfile=key_file,
               cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)

# Connect as before
client.connect(iot_hub_name+".azure-devices.net", port=8883)

Envío de mensajes de dispositivo a nube

Una vez que un dispositivo se ha conectado, puede enviar mensajes a IoT Hub con devices/{device-id}/messages/events/ o devices/{device-id}/messages/events/{property-bag} como Nombre de tema. El elemento {property-bag} permite al dispositivo enviar mensajes con otras propiedades en un formato con codificación URL. Por ejemplo:

RFC 2396-encoded(<PropertyName1>)=RFC 2396-encoded(<PropertyValue1>)&RFC 2396-encoded(<PropertyName2>)=RFC 2396-encoded(<PropertyValue2>)…

Nota

Este elemento {property_bag} usa la misma codificación que se usa para las cadenas de consulta en el protocolo HTTPS.

Nota:

Si está enrutando mensajes D2C a una cuenta Azure Storage y desea aprovechar la codificación JSON, debe especificar la información de Tipo de contenido y Codificación de contenido, incluida $.ct=application%2Fjson&$.ce=utf-8, como parte del elemento {property_bag} mencionado en la nota anterior.

El formato de estos atributos es específico del protocolo. IoT Hub convierte estos atributos en sus propiedades del sistema correspondientes. Para obtener más información, consulte la sección Propiedades del sistema de IoT Hub sintaxis de consulta de enrutamiento de mensajes.

La siguiente lista describe los comportamientos específicos de la implementación de IoT Hub:

  • El uso de mensajes QoS 2 no se admite en IoT Hub. Si una aplicación de dispositivo publica un mensaje con QoS 2, el IoT Hub cierra la conexión de red.

  • Los mensajes de conservación no se retienen en IoT Hub. Si un dispositivo envía un mensaje con la marca RETAIN establecida en 1, IoT Hub agrega la propiedad de aplicación mqtt-retain al mensaje. En este caso, en lugar de retener el mensaje de conservación, IoT Hub lo pasa a la aplicación de back-end.

  • IoT Hub solo admite una conexión MQTT activa por dispositivo. Cualquier nueva conexión MQTT en nombre del mismo identificador de dispositivo hace que IoT Hub elimine la conexión existente y se registre un error 400027 ConnectionForcefullyClosedOnNewConnection en los registros de IoT Hub

  • Para enrutar los mensajes en función del cuerpo del mensaje, primero debe agregar la propiedad "contentType" (ct) al final del tema MQTT y establecer su valor en application/json;charset=utf-8 como se muestra en el siguiente ejemplo. Para obtener más información sobre el enrutamiento de mensajes en función de las propiedades del mensaje o el cuerpo del mensaje, consulte la documentación de Sintaxis de las consultas de enrutamiento de mensajes de IoT Hub.

    devices/{device-id}/messages/events/$.ct=application%2Fjson%3Bcharset%3Dutf-8

Para obtener más información, consulte Envío de mensajes de dispositivo a nube y de nube a dispositivo con IoT Hub.

Recepción de mensajes de nube a dispositivo

Para recibir mensajes de IoT Hub, un dispositivo debe suscribirse usando devices/{device-id}/messages/devicebound/# como un filtro de tema. El comodín de varios niveles # en el filtro de tema solo se utiliza para permitir que el dispositivo reciba propiedades adicionales en el nombre del tema. El uso de los caracteres comodín # o ? para filtrar subtemas no se admite en IoT Hub. Debido a que IoT Hub no es un agente de mensajería de publicación-suscripción de propósito general, solo se admite el uso de los filtros de tema y los nombres de tema que estén documentados. Un dispositivo solo puede suscribirse a cinco temas a la vez.

El dispositivo no recibe ningún mensaje de IoT Hub hasta que se suscribe correctamente al punto de conexión específico del dispositivo, representado por el filtro del tema devices/{device-id}/messages/devicebound/#. Después de que se haya establecido una suscripción, el dispositivo recibe solo los mensajes de la nube al dispositivo que se enviaron a este después de la hora de la suscripción. Si el dispositivo se conecta con la marca CleanSession establecida en 0, la suscripción se conserva entre distintas sesiones. En este caso, la próxima vez que el dispositivo se conecte con CleanSession 0, este recibirá los mensajes pendientes que se le han enviado mientras estaba desconectado. Si el dispositivo usa la marca CleanSession establecida en 1, no recibe los mensajes de IoT Hub hasta que se suscribe al punto de conexión del dispositivo.

IoT Hub entrega los mensajes con el Nombre del temadevices/{device-id}/messages/devicebound/ o devices/{device-id}/messages/devicebound/{property-bag} si hay propiedades de mensaje. {property-bag} contiene pares clave-valor con codificación URL de propiedades del mensaje. Las propiedades de la aplicación y del sistema configuradas por el usuario (como messageId o correlationId) son las únicas que se incluyen en el paquete de propiedades. Los nombres de propiedad del sistema tienen el prefijo $ ; las propiedades de aplicaciones utilizan el nombre de propiedad original sin prefijo. Para obtener más información sobre el formato del contenedor de propiedades, consulte Envío de mensajes de dispositivo a nube.

En los mensajes de la nube al dispositivo, los valores del contenedor de propiedades se representan como en la tabla siguiente:

Valor de propiedad Representación Descripción
null key Solo aparece la clave en el contenedor de propiedades
cadena vacía key= Clave seguida de un signo igual sin valor
valor que no es nulo ni está vacío key=value Clave seguida de un signo igual y un valor

En el ejemplo siguiente se muestra un contenedor de propiedades que contiene tres propiedades de la aplicación: prop1 con un valor de null; prop2, que es una cadena vacía (""); y prop3 que tiene como valor "a string".

/?prop1&prop2=&prop3=a%20string

Cuando una aplicación de dispositivo se suscribe a un tema con QoS 2, IoT Hub concede el QoS de nivel 1 (el máximo) en el paquete SUBACK. Después de eso, IoT Hub envía mensajes al dispositivo con QoS 1.

Recuperación de propiedades del dispositivo gemelo

En primer lugar, un dispositivo se suscribe a $iothub/twin/res/# para recibir las respuestas de la operación. A continuación, envía un mensaje en blanco al tema $iothub/twin/GET/?$rid={request id}, con un valor en Id. de solicitud. El servicio envía entonces un mensaje de respuesta que contiene los datos del dispositivo gemelo del tema $iothub/twin/res/{status}/?$rid={request-id}, con el mismo identificador de solicitud que la solicitud.

El ID de la solicitud puede ser cualquier valor válido para un valor de propiedad de mensaje, y el estado se valida como un número entero. Para obtener más información, consulte Envío de mensajes de dispositivo a nube y de nube a dispositivo con IoT Hub.

El cuerpo de la respuesta contiene la sección de propiedades del dispositivo gemelo, como se muestra en la siguiente respuesta de ejemplo:

{
    "desired": {
        "telemetrySendFrequency": "5m",
        "$version": 12
    },
    "reported": {
        "telemetrySendFrequency": "5m",
        "batteryLevel": 55,
        "$version": 123
    }
}

Los códigos de estado posibles son:

Status Descripción
200 Correcto
429 Demasiadas solicitudes (limitadas). Para obtener más información, consulte Límite de ancho de banda de IoT Hub
5** Errores del servidor

Para más información, consulte Información y uso de dispositivos gemelos en IoT Hub.

Actualización de las propiedades notificadas del dispositivo gemelo

Para actualizar las propiedades notificadas, el dispositivo emite una solicitud a IoT Hub a través de una publicación en un tema designado de MQTT. Una vez que IoT Hub ha procesado la solicitud, responde con el estado de éxito o fracaso de la operación de actualización mediante una publicación en otro tema. El dispositivo puede suscribirse a este tema para que se le notifique el resultado de su solicitud de actualización gemela. Para implementar este tipo de interacción entre las solicitudes y las respuestas en MQTT, se usa la noción de id. de solicitud ($rid) que se proporciona inicialmente desde el dispositivo, durante la solicitud de actualización de este. Este identificador de solicitud también se incluye en la respuesta de IoT Hub para permitir que el dispositivo correlacione la respuesta a su solicitud previa específica.

La secuencia siguiente describe cómo un dispositivo actualiza las propiedades notificadas en el dispositivo gemelo de IoT Hub:

  1. En primer lugar, un dispositivo debe suscribirse al tema $iothub/twin/res/# para recibir las respuestas de la operación de IoT Hub.

  2. Un dispositivo envía un mensaje que contiene la actualización del dispositivo gemelo al tema $iothub/twin/PATCH/properties/reported/?$rid={request-id}. Este mensaje incluye un valor de identificador de solicitud.

  3. Después, el servicio envía un mensaje de respuesta que contiene el nuevo valor de ETag de la colección de propiedades notificadas del tema $iothub/twin/res/{status}/?$rid={request-id}. Este mensaje de respuesta usa el mismo identificador de solicitud que la solicitud.

En el cuerpo del mensaje de solicitud, se incluye un documento JSON donde, a su vez, se incluyen los nuevos valores para las propiedades de las que se informa. En el documento JSON, cada miembro actualiza o agrega al miembro correspondiente en el documento del dispositivo gemelo. La configuración de un miembro en null elimina el miembro del objeto contenedor. Por ejemplo:

{
    "telemetrySendFrequency": "35m",
    "batteryLevel": 60
}

Los códigos de estado posibles son:

Status Descripción
204 Correcto (sin contenido)
400 Solicitud incorrecta. JSON con formato incorrecto
429 Demasiadas solicitudes (limitadas), según el artículo sobre limitaciones de IoT Hub
5** Errores del servidor

El siguiente fragmento de código Python demuestra el proceso de actualización de las propiedades de los informes gemelos a través de MQTT utilizando el cliente MQTT Paho:

from paho.mqtt import client as mqtt

# authenticate the client with IoT Hub (not shown here)

client.subscribe("$iothub/twin/res/#")
rid = "1"
twin_reported_property_patch = "{\"firmware_version\": \"v1.1\"}"
client.publish("$iothub/twin/PATCH/properties/reported/?$rid=" +
               rid, twin_reported_property_patch, qos=0)

Tras el éxito del proceso de actualización de las propiedades notificadas de los gemelos en el fragmento de código anterior, el mensaje de publicación de IoT Hub tiene el siguiente asunto: $iothub/twin/res/204/?$rid=1&$version=6, donde 204 es el código de estado que indica el éxito, $rid=1 corresponde al ID de solicitud proporcionado por el dispositivo en el código, y $version corresponde a la versión de la sección de propiedades notificadas de los gemelos del dispositivo tras la actualización.

Para más información, consulte Información y uso de dispositivos gemelos en IoT Hub.

Recepción de notificaciones de actualización de las propiedades deseadas

Cuando se conecta un dispositivo, IoT Hub envía notificaciones al tema $iothub/twin/PATCH/properties/desired/?$version={new-version}, que contiene la actualización realizada por la solución de back-end. Por ejemplo:

{
    "telemetrySendFrequency": "5m",
    "route": null,
    "$version": 8
}

Para las actualizaciones de propiedad, los valores null significan que se elimina el miembro del objeto JSON. Además, el elemento $version se usa para indicar la nueva versión de la sección de propiedades deseadas del gemelo.

Importante

IoT Hub genera notificaciones de cambio solo si los dispositivos están conectados. Asegúrese de implementar el flujo de reconexión de dispositivos para mantener las propiedades que quiera sincronizadas entre IoT Hub y la aplicación del dispositivo.

Para más información, consulte Información y uso de dispositivos gemelos en IoT Hub.

Respuesta a un método directo

En primer lugar, tiene que suscribirse un dispositivo a $iothub/methods/POST/#. IoT Hub envía solicitudes de método al tema $iothub/methods/POST/{method-name}/?$rid={request-id}, con un valor JSON válido o un cuerpo vacío.

Para responder, el dispositivo envía un mensaje con un valor JSON válido o un cuerpo vacío al tema $iothub/methods/res/{status}/?$rid={request-id}. En este mensaje, el identificador de solicitud debe coincidir con el del mensaje de solicitud y el estado debe ser un número entero.

Para obtener más información, vea el artículo Conocimiento e invocación de los métodos directos de IoT Hub.

Pasos siguientes

Para más información sobre el uso de MQTT, consulte:

Para más información sobre el uso de los SDK de dispositivos IoT, consulte:

Para más información acerca de planificación de la implementación de IoT Hub, consulte: