Comunicar-se com o Hub IoT usando o protocolo MQTT

Este artigo descreve como os dispositivos podem usar comportamentos do MQTT compatíveis para se comunicar com o Hub IoT do Azure. O Hub IoT permite que os dispositivos comuniquem-se com os pontos de extremidade do dispositivo de Hub IoT usando:

  • MQTT v3.1.1 na porta TCP 8883
  • MQTT v3.1.1 por WebSocket na porta TCP 443.

Observação

Alguns dos recursos mencionados neste artigo, como mensagens de nuvem para dispositivo, dispositivos gêmeos e gerenciamento de dispositivo estão disponíveis somente na camada Standard do Hub IoT. Para obter mais informações sobre as camadas básica e padrão/gratuita do Hub IoT, confira Escolher a camada certa do Hub IoT para sua solução.

Todas as comunicações de dispositivo com o Hub IoT devem ser protegidas usando TLS/SSL. Portanto, o Hub IoT não suporta conexões não seguras pela porta TCP 1883.

Comparar o suporte ao MQTT no Hub IoT e na Grade de Eventos

O Hub IoT não é um agente MQTT completo e não dá suporte a todos os comportamentos especificados no padrão MQTT v3.1.1. Se a sua solução precisar de MQTT, recomendamos o suporte ao MQTT na Grade de Eventos do Azure. A Grade de Eventos permite a comunicação bidirecional entre clientes MQTT em tópicos hierárquicos flexíveis usando um modelo de mensagens de publicação e assinatura. Ele também permite rotear mensagens MQTT para serviços do Azure ou pontos de extremidade personalizados para processamento adicional.

A tabela a seguir explica as diferenças no suporte ao MQTT entre os dois serviços:

Hub IoT Grade de Eventos
Modelo cliente-servidor com acoplamento apertado entre dispositivos e aplicativos de nuvem. Modelo de publicação e assinatura que separa editores e assinantes.
Suporte limitado a recursos para MQTT v3.1.1 e suporte limitado a recursos para MQTT v5 em versão prévia. Mais suporte a recursos não está planejado. Suporte ao protocolo MQTT v3.1.1 e v5, com mais suporte de recursos e conformidade do setor planejadas.
Tópicos estáticos e predefinidos. Tópicos hierárquicos personalizados com suporte curinga.
Não há suporte para transmissões de nuvem para dispositivo e comunicação entre dispositivos. Dá suporte a transmissões de dispositivo para nuvem, altas transmissões de nuvem para dispositivo e padrões de comunicação de dispositivo para dispositivo.
Tamanho máximo da mensagem de 256 KB. Tamanho máximo da mensagem de 512 KB.

Conectando-se ao Hub IoT

Um dispositivo pode usar o protocolo MQTT para se conectar a um hub IoT usando uma das seguintes opções:

A porta MQTT (porta TCP 8883) está bloqueada em muitos ambientes de rede corporativos e educacionais. Se você não pode abrir a porta 8883 em seu firewall, recomendamos o uso do MQTT por Web Sockets. O MQTT por WebSockets se comunica pela porta 443, que quase sempre está aberta em ambientes de rede. Para saber como especificar os protocolos MQTT e MQTT por WebSockets ao usar os SDKs de Internet das Coisas do Azure, confira Usando os SDKs do dispositivo.

Usando os SDKs de dispositivo

Os SDKs do cliente do dispositivo que dão suporte ao protocolo MQTT estão disponíveis para Java, Node.js, C, C# e Python. Os SDKs do dispositivo usam o mecanismo de autenticação escolhido para estabelecer uma conexão com um hub IoT. Para usar o protocolo MQTT, o parâmetro do protocolo do cliente deve ser definido como MQTT. Você também pode especificar MQTT por WebSockets no parâmetro de protocolo do cliente. Por padrão, os SDKs do dispositivo se conectam a um Hub IoT com o sinalizador CleanSession definido como 0 e usam QoS 1 para troca de mensagens com o Hub IoT. Embora seja possível configurar o QoS 0 para a troca de mensagens mais rápida, você deve observar que a entrega não é garantida nem confirmada. Por esse motivo, o QoS 0 é geralmente chamado de "fire and forget".

Quando um dispositivo está conectado a um Hub IoT, os SDKs do dispositivo fornecem métodos que permitem que o dispositivo troque mensagens com um Hub IoT.

A tabela a seguir contém links para exemplos de código de cada linguagem com suporte e especifica o parâmetro a ser usado para estabelecer uma conexão com o Hub IoT usando o protocolo MQTT ou MQTT por WebSockets.

Linguagem Parâmetro do protocolo MQTT Parâmetro do protocolo MQTT por 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 fará o fallback para o MQTT por WebSockets se o MQTT falhar. Para especificar apenas o MQTT por WebSockets, use TransportType.Mqtt_WebSocket_Only
Python Dá suporte a MQTT por padrão Adicionar websockets=True na chamada para criar o cliente

O fragmento a seguir mostra como especificar o protocolo MQTT por WebSockets ao usar o SDK do Node.js da Internet das Coisas do Azure:

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

O fragmento a seguir mostra como especificar o protocolo MQTT por WebSockets ao usar o SDK de Python da Internet das Coisas do Azure:

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

Tempo limite de Keep Alive padrão

Para garantir que uma conexão de cliente/Hub IoT permaneça ativa, o serviço e o cliente enviam regularmente um ping de Keep Alive entre si. O cliente que usa o SDK de IoT envia um keep-alive no intervalo definido na seguinte tabela:

Linguagem Intervalo de Keep Alive padrão Configurável
Node.js 180 segundos Não
Java 230 segundos Sim
C 240 segundos Sim
C# 300 segundos* Sim
Python 60 segundos Sim

*O SDK de C# define o valor padrão da propriedade KeepAliveInSeconds do MQTT como 300 segundos. Na verdade, o SDK envia uma solicitação de ping quatro vezes por conjunto de duração de keep-alive. Em outras palavras, o SDK envia um ping keep-alive uma vez a cada 75 segundos.

Seguindo a especificação MQTT v3.1.1, o intervalo de ping de keep-alive do Hub IoT é 1,5 vezes o valor do keep-alive do cliente. No entanto, o Hub IoT limita o tempo limite máximo do lado do servidor a 29,45 minutos (1.767 segundos). Esse limite existe porque todos os serviços do Azure são vinculados ao tempo limite ocioso de TCP do balanceador de carga do Azure, que é 29,45 minutos.

Por exemplo, um dispositivo que usa o SDK do Java envia o ping de keep alive e perde a conectividade de rede. Depois de 230 segundos, o dispositivo perde o ping de Keep Alive porque está offline. No entanto, o Hub IoT não fecha a conexão imediatamente. Ele aguarda mais (230 * 1.5) - 230 = 115 segundos antes de desconectar o dispositivo com o erro 404104 DeviceConnectionClosedRemotely.

O valor máximo de Keep Alive do cliente que você pode definir é 1767 / 1.5 = 1177 segundos. Qualquer tráfego redefine o keep-alive. Por exemplo, uma atualização bem-sucedida do token SAS (assinatura de acesso compartilhado) redefine o keep-alive.

Migrando um aplicativo de dispositivo de AMQP para MQTT

Se você estiver usando os SDKs de dispositivo, a mudança do uso de AMQP para MQTT exigirá alteração do parâmetro de protocolo na inicialização do cliente, conforme mencionado anteriormente.

Ao fazer isso, verifique os seguintes itens:

  • AMQP retorna erros para várias condições, enquanto MQTT encerra a conexão. Como resultado, sua lógica de manipulação de exceções pode exigir algumas alterações.

  • MQTT não dá suporte a operações de rejeição quando recebe mensagens de nuvem para dispositivo. Se seu aplicativo de back-end precisar receber uma resposta do aplicativo do dispositivo, considere usar métodos diretos.

  • Não há suporte para AMQP no SDK do Python.

Usando o protocolo MQTT diretamente (como um dispositivo)

Se um dispositivo não puder usar os SDKs do dispositivo, ainda poderá se conectar com os pontos de extremidade públicos do dispositivo usando o protocolo MQTT na porta 8883.

No pacote CONNECT, o dispositivo deve usar os seguintes valores:

  • No campo ClientId, use o deviceId.

  • Para o campo Nome de usuário, use {iotHub-hostname}/{device-id}/?api-version=2021-04-12, em que {iotHub-hostname} é o CName completo do hub IoT.

    Por exemplo, se o nome de seu Hub IoT for contoso.azure-devices.net e se o nome do dispositivo for MyDevice01, o campo Username completo deverá conter:

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

    É recomendável incluir a versão da API no campo. Caso contrário, isso pode causar comportamentos inesperados.

  • No campo Senha use um token SAS. O formato do token SAS é o mesmo, conforme descrito para os protocolos HTTPS e AMQP:

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

    Observação

    Se você usa a autenticação de certificado X.509, as senhas de token SAS não são necessárias. Para obter mais informações, confira Tutorial: Criar e carregar certificados para testar e siga instruções de código na seção de configuração do TLS/SSL.

    Para saber mais sobre como gerar tokens SAS, consulte a seção Usar tokens SAS como um dispositivo de Controlar o acesso ao Hub IoT usando Assinaturas de Acesso Compartilhado.

    Você também pode usar a extensão Hub IoT do Azure para Visual Studio Code multiplataforma ou o comando da extensão CLI az iot hub generate-sas-token para gerar rapidamente um token SAS. Em seguida, você pode copiar e colar o token SAS em seu código para fins de teste.

Para obter um tutorial sobre como usar o MQTT diretamente, confira Usar MQTT para desenvolver um cliente de dispositivo IoT sem usar um SDK do dispositivo.

Usando a extensão Hub IoT do Azure para Visual Studio Code

  1. Na barra lateral, expanda o nó Dispositivos na seção Hub IoT do Azure.

  2. Clique com o botão direito do mouse em seu dispositivo de IoT e selecione Gerar token SAS para o Dispositivo no menu de contexto.

  3. Insira o tempo de expiração, em horas, para o token SAS na caixa de entrada e, em seguida, selecione a tecla Enter.

  4. O token SAS é criado e copiado para a área de transferência.

    O token de SAS gerado tem a seguinte estrutura:

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

    A parte desse token para usar como o campo Senha para conectar usando MQTT é:

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

O aplicativo de dispositivo pode especificar uma mensagem Will no pacote CONNECT. O aplicativo do dispositivo devem usar devices/{device-id}/messages/events/ ou devices/{device-id}/messages/events/{property-bag}como o nome do tópico Will para definir mensagens Will a serem encaminhadas como uma mensagem de telemetria. Nesse caso, se a conexão de rede for fechada, mas um pacote DISCONNECT não tiver sido recebido anteriormente do dispositivo, o Hub IoT enviará a mensagem Will fornecida no pacote CONNECT para o canal de telemetria. O canal de telemetria pode ser o ponto de extremidade padrão Eventos, ou um ponto de extremidade personalizado definido pelo roteamento do Hub IoT. A mensagem tem a propriedade iothub-MessageType com um valor de Will atribuído a ele.

Usando o protocolo MQTT diretamente (como um módulo)

Você pode se conectar ao Hub IoT via MQTT usando uma identidade de módulo, semelhante à conexão ao Hub IoT como um dispositivo. Para obter mais informações sobre como se conectar ao Hub IoT via MQTT como um dispositivo, consulte Usando o protocolo MQTT diretamente (como um dispositivo). No entanto, você precisa usar os seguintes valores:

  • Defina a ID do cliente como {device-id}/{module-id}.

  • Se autenticando com o nome de usuário e senha, defina o nome de usuário como <hubname>.azure-devices.net/{device_id}/{module_id}/?api-version=2021-04-12 e use o token SAS associado à identidade de módulo como sua senha.

  • Use devices/{device-id}/modules/{module-id}/messages/events/ como tópico para a publicação de telemetria.

  • Use devices/{device-id}/modules/{module-id}/messages/events/ como o tópico WILL.

  • Use devices/{device-id}/modules/{module-id}/# como um tópico para o recebimento de mensagens.

  • Os tópicos gêmeos GET e PATCH são idênticos para módulos e dispositivos.

  • Os tópicos de status gêmeos são idênticos para módulos e dispositivos.

Para obter mais informações sobre como usar o MQTT com módulos, confira Publicar e assinar com o IoT Edge e saiba mais sobre o Ponto de extremidade MQTT do hub do IoT Edge.

Amostras usando MQTT sem um SDK da Internet das Coisas do Azure

O repositório de exemplo do IoT MQTT contém exemplos de C/C++, Python e CLI que mostram como enviar mensagens de telemetria, receber mensagens de nuvem para dispositivo e usar dispositivos gêmeos sem usar os SDKs do dispositivo do Azure.

Os exemplos de C/C++ usam a biblioteca Eclipse Mosquitto, o exemplo do Python usa a Eclipse Paho e os exemplos da CLI usam mosquitto_pub.

Para saber mais, confira Tutorial – Usar o MQTT para desenvolver um cliente de dispositivo IoT.

Configuração de TLS/SSL

Para usar o protocolo MQTT diretamente, o cliente deve se conectar por TLS/SSL. Tentativas de ignorar essa etapa falham com erros de conexão.

Para estabelecer uma conexão TLS, talvez seja necessário baixar e referenciar o certificado raiz DigiCert que o Azure usa. Entre 15 de fevereiro e 15 de outubro de 2023, o Hub IoT do Azure está migrando seu certificado raiz TLS do Certificado Raiz DigiCert Baltimore para o DigiCert Global Root G2. Durante o período de migração, você deve ter ambos os certificados em seus dispositivos para garantir a conectividade. Para obter mais informações sobre a migração, confira Migrar recursos de IoT para uma nova raiz de certificado TLS Para obter mais informações sobre esses certificados, confira o site do DigiCert.

O exemplo a seguir demonstra como implementar essa configuração usando a versão do Python da biblioteca Paho MQTT pelo Eclipse Foundation.

Primeiro, instale a biblioteca Paho do seu ambiente de linha de comando:

pip install paho-mqtt

Em seguida, implemente o cliente em um script Python. Substitua estes espaços reservados no seguinte snippet de código:

  • <local path to digicert.cer> é o caminho para um arquivo local que contém o certificado raiz DigiCert. Você pode criar esse arquivo, copiando as informações sobre o certificado do certs.c no SDK de IoT do Azure para C. Inclua as linhas -----BEGIN CERTIFICATE----- e -----END CERTIFICATE-----, remova as marcas " no início e no final de cada linha, e remova os caracteres \r\n no final de cada linha.

  • <device id from device registry> é a ID de um dispositivo que você adicionou ao seu Hub IoT.

  • <generated SAS token> é um token de SAS para o dispositivo criado, conforme descrito anteriormente neste artigo.

  • <iot hub name> o nome do seu Hub IoT.

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 autenticar usando um certificado de dispositivo, atualize o snippet de código anterior com as alterações especificadas no snippet de código a seguir. Para obter mais informações sobre como se preparar para a autenticação baseada em certificado, consulte a seção Obter um certificado de AC X.509 de Autenticar dispositivos usando certificados de AC 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)

Enviando mensagens de dispositivo para nuvem

Depois de uma conexão bem-sucedida, um dispositivo pode enviar mensagens ao Hub IoT usando devices/{device-id}/messages/events/ ou devices/{device-id}/messages/events/{property-bag} como um nome de tópico. O elemento {property-bag} habilita o dispositivo a enviar mensagens com outras propriedades em um formato codificado de URL. Por exemplo:

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

Observação

Esse elemento {property_bag} usa a mesma codificação de cadeias de caracteres de consulta do protocolo HTTPS.

Observação

Se você estiver roteando mensagens D2C para uma conta de Armazenamento do Azure e quiser aproveitar a codificação JSON, precisará especificar informações de Codificação de Conteúdo e Tipo de Conteúdo, incluindo $.ct=application%2Fjson&$.ce=utf-8 como parte do {property_bag} mencionado na nota acima.

O formato desses atributos é específico do protocolo. O Hub IoT converte esses atributos nas propriedades de sistema correspondentes. Para saber mais, consulte a seção Propriedades do sistema de Sintaxe de consulta de roteamento de mensagens do Hub IoT.

A seguinte lista descreve comportamentos específicos à implementação do Hub IoT:

  • O Hub IoT não dá suporte a mensagens de QoS 2. Se um aplicativo de dispositivo publicar uma mensagem com o QoS 2, o Hub IoT fechará a conexão de rede.

  • O Hub IoT não persiste mensagens de Retenção. Se um dispositivo envia uma mensagem com o sinalizador RETAIN definido como 1, o Hub IoT adiciona a propriedade de aplicativo mqtt-retain à mensagem. Nesse caso, em vez de persistir a mensagem de retenção, o Hub IoT a transmite ao aplicativo de back-end.

  • O Hub IoT oferece suporte apenas a uma conexão MQTT ativa por dispositivo. Qualquer nova conexão MQTT em nome da mesma ID do dispositivo faz com que o Hub IoT interrompa a conexão existente e 400027 ConnectionForcefullyClosedOnNewConnection seja conectado aos Logs do Hub IoT

  • Para rotear mensagens com base no corpo da mensagem, primeiro você precisa adicionar a propriedade 'contentType' (ct) ao final do tópico MQTT e definir o valor como application/json;charset=utf-8, conforme mostrado no exemplo a seguir. Para obter mais informações sobre o roteamento de mensagens com base nas propriedades ou no corpo da mensagem, confira a documentação da sintaxe de consulta de roteamento de mensagens do Hub IoT.

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

Para obter mais informações, consulte Enviar mensagens de dispositivo para nuvem e da nuvem para dispositivo com o Hub IoT.

Recebendo mensagens da nuvem para o dispositivo

Para receber mensagens do Hub IoT, um dispositivo deve fazer uma assinatura usando devices/{device-id}/messages/devicebound/# como um Filtro do Tópico. O curinga de vários níveis # no Filtro de Tópico é usado apenas para permitir que o dispositivo receba mais propriedades no nome do tópico. O Hub IoT não permite o uso dos caracteres curinga # ou ? para filtragem de subtópicos. Como o Hub IoT não é um agente de mensagens pub-sub de uso geral, dá suporte somente a nomes de tópicos e filtros de tópicos documentados. Um dispositivo só pode assinar cinco tópicos por vez.

O dispositivo só receberá mensagens do Hub IoT depois de assinar com êxito o ponto de extremidade específico ao dispositivo, representado pelo filtro de tópico devices/{device-id}/messages/devicebound/#. Depois que uma assinatura é estabelecida, o dispositivo receberá mensagens de nuvem para dispositivo que foram enviadas após o horário da assinatura. Se o dispositivo se conectar com o sinalizador CleanSession definido como 0, a assinatura será persistida entre as diferentes sessões. Neste caso, a próxima vez que o dispositivo conectar-se com CleanSession 0, ele receberá todas as mensagens pendentes enviadas a ele enquanto estava desconectado. Se o dispositivo usar o sinalizador CleanSession definido como 1, ele não receberá mensagens do Hub IoT até que assine o ponto de extremidade do dispositivo.

O Hub IoT entrega mensagens com o Nome do Tópicodevices/{device-id}/messages/devicebound/ ou devices/{device-id}/messages/devicebound/{property-bag} quando há propriedades de mensagens. {property-bag} contém pares de chave/valor codificados de URL das propriedades da mensagem. Somente propriedades de aplicativo e propriedades do sistema definível pelo usuário (como messageId ou correlationId) estão incluídas no recipiente de propriedades. Os nomes de propriedade do sistema têm o prefixo $ ; as propriedades de aplicativo usam o nome da propriedade original sem prefixo. Para obter mais informações sobre o formato do recipiente de propriedades, confira Enviando mensagens do dispositivo para nuvem.

Em mensagens da nuvem para dispositivo, os valores no recipiente de propriedades são representados como na seguinte tabela:

Valor da propriedade Representação Descrição
null key Somente a chave aparece no recipiente de propriedades
cadeia de caracteres vazia key= A chave seguida por um sinal de igual sem valor
valor não nulo, não vazio key=value A chave seguida por um sinal de igual e o valor

O seguinte exemplo mostra um recipiente de propriedades que contém três propriedades de aplicativo: prop1 com o valor null; prop2, uma cadeia de caracteres vazia (""); e prop3 com o valor "uma cadeia de caracteres".

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

Quando um aplicativo do dispositivo assina um tópico com o QoS 2, o Hub IoT concede, no máximo, o nível 1 do QoS no pacote SUBACK. Depois disso, o Hub IoT entrega mensagens ao dispositivo usando QoS 1.

Recuperando as propriedades de um dispositivo gêmeo

Primeiro, um dispositivo assina $iothub/twin/res/# para receber respostas da operação. Em seguida, ele envia uma mensagem vazia ao tópico $iothub/twin/GET/?$rid={request id}, com um valor preenchido como a ID da solicitação. O serviço então envia uma mensagem de resposta que contém os dados do dispositivo gêmeo no tópico $iothub/twin/res/{status}/?$rid={request-id}, usando a mesma ID de solicitação da solicitação.

A ID da solicitação pode ser qualquer valor válido para um valor de propriedade de mensagem, e o status é validado como um inteiro. Para obter mais informações, consulte Enviar mensagens de dispositivo para nuvem e da nuvem para dispositivo com o Hub IoT.

O corpo de resposta contém a seção de propriedades do dispositivo gêmeo, como no seguinte exemplo de resposta:

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

Os códigos de status possíveis são:

Status Descrição
200 Sucesso
429 Muitas solicitações (limitadas). Para obter mais informações, confira Limitação do Hub IoT
5** Erros do servidor

Para saber mais, veja Noções básicas e uso de dispositivos gêmeos no Hub IoT.

Atualizar as propriedades relatadas do dispositivo gêmeo

Para atualizar as propriedades relatadas, o dispositivo emite uma solicitação para o Hub IoT por meio de uma publicação ao longo de um tópico MQTT designado. Depois de processar a solicitação, o Hub IoT responde com o status de êxito ou falha da operação de atualização por meio de uma publicação para outro tópico. O dispositivo pode assinar este tópico para notificá-lo sobre o resultado da sua solicitação de atualização gêmea. Para implementar esse tipo de interação de solicitação/resposta em MQTT, utilizamos a noção de ID de solicitação ($rid) fornecida inicialmente pelo dispositivo na respectiva solicitação de atualização. Essa ID de solicitação também está incluído na resposta do Hub IoT para permitir que o dispositivo correlacionar a resposta à sua solicitação anterior específica.

A sequência a seguir descreve como um dispositivo atualiza as propriedades relatadas no dispositivo gêmeo no Hub IoT:

  1. Primeiro, um dispositivo deve assinar o tópico $iothub/twin/res/# para receber respostas da operação do Hub IoT.

  2. Um dispositivo envia uma mensagem que contém a atualização do dispositivo gêmeo para o tópico $iothub/twin/PATCH/properties/reported/?$rid={request-id}. Essa mensagem inclui um valor de id da solicitação.

  3. Em seguida, o serviço envia uma mensagem de resposta que contém o novo valor de ETag para a coleção de propriedades relatadas no tópico $iothub/twin/res/{status}/?$rid={request-id}. Essa mensagem de resposta usa a mesma id de solicitação da solicitação.

O corpo da mensagem de solicitação contém um documento JSON que contém novos valores para propriedades relatadas. Cada membro no documento JSON atualiza ou adiciona o membro correspondente no documento do dispositivo gêmeo. Um membro definido como null exclui o membro do objeto que o contém. Por exemplo:

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

Os códigos de status possíveis são:

Status Descrição
204 Êxito (nenhum conteúdo retorna)
400 Solicitação inválida. JSON malformado
429 Número excessivo de solicitações (limitado), de acordo com a Limitação do Hub IoT
5** Erros do servidor

O seguinte snippet de código Python demonstra o processo de atualização das propriedades gêmeas relatadas por MQTT usando o cliente Paho MQTT:

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)

Após o sucesso do processo de atualização das propriedades gêmeas relatadas no trecho do código anterior, a mensagem de publicação do Hub de IoT tem o seguinte tópico: $iothub/twin/res/204/?$rid=1&$version=6, em que 204 é o código de status que indica êxito, $rid=1 corresponde à ID da solicitação fornecida pelo dispositivo no código e $version corresponde à versão da seção de propriedades relatadas dos dispositivos gêmeos após a atualização.

Para saber mais, veja Noções básicas e uso de dispositivos gêmeos no Hub IoT.

Recebendo notificações de atualização de propriedades desejadas

Quando um dispositivo é conectado, o Hub IoT envia notificações para o tópico $iothub/twin/PATCH/properties/desired/?$version={new-version}, que contêm o conteúdo da atualização executada pelo back-end da solução. Por exemplo:

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

Em relação às atualizações de propriedade, valores null significam que o membro do objeto JSON está sendo excluído. Além disso, $version indica a nova versão da seção de propriedades desejada do gêmeo.

Importante

O Hub IoT gera notificações de alteração somente quando os dispositivos estão conectados. Lembre-se de implementar o fluxo de reconexão do dispositivo para manter as propriedades desejadas sincronizadas entre o Hub IoT e o aplicativo do dispositivo.

Para saber mais, veja Noções básicas e uso de dispositivos gêmeos no Hub IoT.

Responder a um método direto

Primeiro, um dispositivo precisa assinar $iothub/methods/POST/#. O Hub IoT envia solicitações de método para o tópico $iothub/methods/POST/{method-name}/?$rid={request-id} com um corpo vazio ou JSON válido.

Para responder, o dispositivo envia uma mensagem com um JSON válido ou um corpo vazio para o tópico $iothub/methods/res/{status}/?$rid={request-id}. Nessa mensagem, a ID da Solicitação deve corresponder com o da mensagem de solicitação e o status deve ser um número inteiro.

Para obter mais informações, consulte Entender e invocar métodos diretos do Hub IoT.

Próximas etapas

Para saber mais sobre como usar o MQTT, confira:

Para saber mais sobre como usar SDKS do dispositivo IoT, confira:

Para saber mais sobre como planejar sua implantação do Hub IoT, consulte: