Compreender e usar gêmeos de dispositivo no Hub IoT

Gêmeos de dispositivo são documentos JSON que armazenam informações de estado do dispositivo, incluindo metadados, configurações e condições. O Hub IoT do Azure mantém um dispositivo duplo para cada dispositivo que ligar ao serviço.

Nota

Os recursos descritos neste artigo estão disponíveis somente na camada padrão do Hub IoT. Para obter mais informações sobre as camadas básica e padrão/gratuita do Hub IoT, consulte Escolha a camada certa do Hub IoT para sua solução.

Este artigo descreve:

  • A estrutura do gêmeo do dispositivo: tags, propriedades desejadas e propriedades relatadas.
  • As operações que o dispositivo e os aplicativos back-end podem executar em gêmeos de dispositivo.

Use gêmeos de dispositivo para:

  • Armazene metadados específicos do dispositivo na nuvem. Por exemplo, a localização de uma máquina de venda automática.

  • Relate informações de estado atual, como recursos e condições disponíveis do aplicativo do dispositivo. Por exemplo, se um dispositivo está conectado ao seu hub IoT por celular ou WiFi.

  • Sincronize o estado de fluxos de trabalho de longa execução entre o aplicativo de dispositivo e o aplicativo back-end. Por exemplo, quando o back-end da solução especifica a nova versão de firmware a ser instalada e o aplicativo de dispositivo relata os vários estágios do processo de atualização.

  • Consulte os metadados, a configuração ou o estado do dispositivo.

Para obter mais informações sobre como usar propriedades relatadas, mensagens de dispositivo para nuvem ou upload de arquivos, consulte Diretrizes de comunicação de dispositivo para nuvem.

Para obter mais informações sobre como usar as propriedades desejadas, métodos diretos ou mensagens de nuvem para dispositivo, consulte Diretrizes de comunicação de nuvem para dispositivo.

Para saber como os gêmeos de dispositivo se relacionam com o modelo de dispositivo usado por um dispositivo Azure IoT Plug and Play, consulte Compreender os gêmeos digitais IoT Plug and Play.

Gêmeos de dispositivo

Os gêmeos de dispositivo armazenam informações relacionadas ao dispositivo que:

  • O dispositivo e os back-ends podem ser usados para sincronizar as condições e a configuração do dispositivo.

  • O back-end da solução pode ser usado para consultar e direcionar operações de longa execução.

O ciclo de vida de um dispositivo gêmeo está vinculado à identidade do dispositivo correspondente. Os gêmeos de dispositivo são implicitamente criados e excluídos quando uma identidade de dispositivo é criada ou excluída no Hub IoT.

Um gêmeo de dispositivo é um documento JSON que inclui:

  • Etiquetas. Uma seção do documento JSON que o back-end da solução pode ler e gravar. As etiquetas não são visíveis para as aplicações do dispositivo.

  • Propriedades desejadas. Usado junto com as propriedades relatadas para sincronizar a configuração ou as condições do dispositivo. O back-end da solução pode definir as propriedades desejadas e o aplicativo do dispositivo pode lê-las. O aplicativo do dispositivo também pode receber notificações de alterações nas propriedades desejadas.

  • Propriedades relatadas. Usado junto com as propriedades desejadas para sincronizar a configuração ou as condições do dispositivo. O aplicativo de dispositivo pode definir propriedades relatadas e o back-end da solução pode lê-las e consultá-las.

  • Propriedades de identidade do dispositivo. A raiz do documento JSON gêmeo do dispositivo contém as propriedades somente leitura da identidade do dispositivo correspondente armazenada no registro de identidade. Propriedades connectionStateUpdatedTime e generationId não serão incluídas.

Diagram that shows which applications interact with which device twin properties.

O exemplo a seguir mostra um documento JSON gêmeo de dispositivo:

{
    "deviceId": "devA",
    "etag": "AAAAAAAAAAc=", 
    "status": "enabled",
    "statusReason": "provisioned",
    "statusUpdateTime": "0001-01-01T00:00:00",
    "connectionState": "connected",
    "lastActivityTime": "2015-02-30T16:24:48.789Z",
    "cloudToDeviceMessageCount": 0, 
    "authenticationType": "sas",
    "x509Thumbprint": {     
        "primaryThumbprint": null, 
        "secondaryThumbprint": null 
    }, 
    "version": 2, 
    "tags": {
        "deploymentLocation": {
            "building": "43",
            "floor": "1"
        }
    },
    "properties": {
        "desired": {
            "telemetryConfig": {
                "sendFrequency": "5m"
            },
            "$metadata" : {...},
            "$version": 1
        },
        "reported": {
            "telemetryConfig": {
                "sendFrequency": "5m",
                "status": "success"
            },
            "batteryLevel": 55,
            "$metadata" : {...},
            "$version": 4
        }
    }
}

O objeto raiz contém as propriedades de identidade do dispositivo e objetos de contêiner para tags e ambas reporteddesired as propriedades. O properties contêiner contém alguns elementos somente leitura ($metadata e $version) descritos nas seções Metadados gêmeos do dispositivo e Simultaneidade otimista.

Exemplo de propriedade relatada

No exemplo anterior, o gêmeo do dispositivo contém uma batteryLevel propriedade que é relatada pelo aplicativo do dispositivo. Esta propriedade torna possível consultar e operar em dispositivos com base no último nível de bateria relatado. Outros exemplos incluem o aplicativo de dispositivo, o relatório, os recursos do dispositivo ou as opções de conectividade.

Nota

As propriedades relatadas simplificam os cenários em que o back-end da solução está interessado no último valor conhecido de uma propriedade. Use mensagens de dispositivo para nuvem se o back-end da solução precisar processar a telemetria do dispositivo na forma de sequências de eventos com carimbo de data/hora, como séries temporais.

Exemplo de propriedade desejada

No exemplo anterior, as propriedades desejadas e relatadas telemetryConfig do gêmeo de dispositivo são usadas pelo back-end da solução e pelo aplicativo do dispositivo para sincronizar a configuração de telemetria para esse dispositivo. Por exemplo:

  1. O back-end da solução define a propriedade desejada com o valor de configuração desejado. Aqui está a parte do documento com o conjunto de propriedades desejado:

    "desired": {
        "telemetryConfig": {
            "sendFrequency": "5m"
        },
        ...
    },
    
  2. O aplicativo do dispositivo é notificado da alteração imediatamente se o dispositivo estiver conectado. Se não estiver ligado, a aplicação do dispositivo segue o fluxo de religação do dispositivo quando se liga. Em seguida, o aplicativo de dispositivo relata a configuração atualizada (ou uma condição de erro usando a status propriedade). Aqui está a parte das propriedades relatadas:

    "reported": {
        "telemetryConfig": {
            "sendFrequency": "5m",
            "status": "success"
        }
        ...
    }
    
  3. O back-end da solução pode acompanhar os resultados da operação de configuração em muitos dispositivos consultando gêmeos de dispositivos.

Nota

Os trechos anteriores são exemplos, otimizados para legibilidade, de uma maneira de codificar uma configuração de dispositivo e seu status. O Hub IoT não impõe um esquema específico para as propriedades desejadas e relatadas do gêmeo do dispositivo nos gêmeos do dispositivo.

Importante

O IoT Plug and Play define um esquema que usa várias propriedades adicionais para sincronizar as alterações nas propriedades desejadas e relatadas. Se sua solução usa IoT Plug and Play, você deve seguir as convenções Plug and Play ao atualizar as propriedades gêmeas. Para obter mais informações e um exemplo, consulte Propriedades graváveis no IoT Plug and Play.

Você pode usar gêmeos para sincronizar operações de longa duração, como atualizações de firmware. Para obter mais informações sobre como usar propriedades para sincronizar e rastrear uma operação de longa execução entre dispositivos, consulte Usar propriedades desejadas para configurar dispositivos.

Operações de back-end

O back-end da solução opera no dispositivo twin usando as seguintes operações atômicas, expostas através de HTTPS:

  • Recupere o dispositivo gêmeo por ID. Esta operação retorna o documento gêmeo do dispositivo, incluindo tags e propriedades do sistema desejadas e relatadas.

  • Dispositivo gêmeo de atualização parcial. Essa operação permite que o back-end da solução atualize parcialmente as tags ou as propriedades desejadas em um dispositivo gêmeo. A atualização parcial é expressa como um documento JSON que adiciona ou atualiza qualquer propriedade. As propriedades definidas como null são removidas. O exemplo a seguir cria uma nova propriedade desejada com value {"newProperty": "newValue"}, substitui o valor existente de existingProperty with "otherNewValue"e remove otherOldProperty. Nenhuma outra alteração é feita nas propriedades ou tags desejadas existentes:

    {
         "properties": {
             "desired": {
                 "newProperty": {
                     "nestedProperty": "newValue"
                 },
                 "existingProperty": "otherNewValue",
                 "otherOldProperty": null
             }
         }
    }
    
  • Substitua as propriedades desejadas. Essa operação permite que o back-end da solução substitua completamente todas as propriedades desejadas existentes e substitua um novo documento JSON por properties/desired.

  • Substitua tags. Essa operação permite que o back-end da solução substitua completamente todas as tags existentes e substitua um novo documento JSON por tags.

  • Receba notificações duplas. Esta operação permite que o back-end da solução seja notificado quando o gêmeo é modificado. Para fazer isso, sua solução de IoT precisa criar uma rota e definir a Fonte de Dados igual a twinChangeEvents. Por padrão, essa rota não existe, portanto, nenhuma notificação dupla é enviada. Se a taxa de alteração for muito alta, ou por outros motivos, como falhas internas, o Hub IoT poderá enviar apenas uma notificação que contenha todas as alterações. Portanto, se seu aplicativo precisa de auditoria confiável e registro em log de todos os estados intermediários, você deve usar mensagens de dispositivo para nuvem. Para saber mais sobre as propriedades e o corpo retornados na mensagem de notificação gêmea, consulte Esquemas de eventos não telemétricos.

Todas as operações anteriores suportam simultaneidade otimista e exigem a permissão ServiceConnect , conforme definido em Controlar acesso ao Hub IoT.

Além dessas operações, o back-end da solução pode:

Operações do dispositivo

O aplicativo de dispositivo opera no gêmeo do dispositivo usando as seguintes operações atômicas:

  • Recuperar dispositivo gêmeo. Esta operação retorna o documento gêmeo do dispositivo (incluindo as propriedades do sistema desejadas e relatadas) para o dispositivo conectado no momento. (As etiquetas não são visíveis para as aplicações do dispositivo.)

  • Atualize parcialmente as propriedades relatadas. Esta operação permite a atualização parcial das propriedades relatadas do dispositivo conectado no momento. Esta operação usa o mesmo formato de atualização JSON que o back-end da solução usa para uma atualização parcial das propriedades desejadas.

  • Observe as propriedades desejadas. O dispositivo atualmente conectado pode optar por ser notificado sobre atualizações nas propriedades desejadas quando elas acontecerem. O dispositivo recebe a mesma forma de atualização (substituição parcial ou total) executada pelo back-end da solução.

Todas as operações anteriores exigem a permissão DeviceConnect , conforme definido em Controlar acesso ao Hub IoT.

Os SDKs de dispositivo IoT do Azure facilitam o uso das operações anteriores de muitos idiomas e plataformas. Para obter mais informações sobre os detalhes das primitivas do Hub IoT para a sincronização de propriedades desejadas, consulte Fluxo de reconexão de dispositivo.

Formato de tags e propriedades

Tags, propriedades desejadas e propriedades relatadas são objetos JSON com as seguintes restrições:

  • Chaves: Todas as chaves em objetos JSON são codificadas em UTF-8, diferenciam maiúsculas de minúsculas e têm até 1 KB de comprimento. Os caracteres permitidos excluem caracteres de controle UNICODE (segmentos C0 e C1) e ., $e SP.

    Nota

    As consultas do Hub IoT usadas no Roteamento de Mensagens não suportam espaço em branco ou qualquer um dos seguintes caracteres como parte de um nome de chave: ()<>@,;:\"/?={}.

  • Valores: Todos os valores em objetos JSON podem ser dos seguintes tipos JSON: booleano, número, cadeia de caracteres, objeto. Matrizes também são suportadas.

    • Os inteiros podem ter um valor mínimo de -4503599627370496 e um valor máximo de 4503599627370495.

    • Os valores de cadeia de caracteres são codificados em UTF-8 e podem ter um comprimento máximo de 4 KB.

  • Profundidade: A profundidade máxima de objetos JSON em tags, propriedades desejadas e propriedades relatadas é 10. Por exemplo, o seguinte objeto é válido:

    {
         ...
         "tags": {
             "one": {
                 "two": {
                     "three": {
                         "four": {
                             "five": {
                                 "six": {
                                     "seven": {
                                         "eight": {
                                             "nine": {
                                                 "ten": {
                                                     "property": "value"
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         },
         ...
    }
    

Tamanho duplo do dispositivo

O Hub IoT impõe um limite de tamanho de 8 KB no valor de , e um limite de tamanho de tags32 KB cada no valor de properties/desired e properties/reported. Esses totais são exclusivos de elementos somente leitura como $version e $metadata/$lastUpdated.

O tamanho duplo é calculado da seguinte forma:

  • Para cada propriedade no documento JSON, o Hub IoT calcula cumulativamente e adiciona o comprimento da chave e do valor da propriedade.

  • As chaves de propriedade são consideradas como cadeias de caracteres codificadas em UTF8.

  • Os valores de propriedade simples são considerados como cadeias de caracteres codificadas em UTF8, valores numéricos (8 Bytes) ou valores booleanos (4 Bytes).

  • O tamanho das cadeias de caracteres codificadas em UTF8 é calculado contando todos os caracteres, excluindo caracteres de controle UNICODE (segmentos C0 e C1).

  • Os valores de propriedade complexos (objetos aninhados) são calculados com base no tamanho agregado das chaves de propriedade e dos valores de propriedade que eles contêm.

O Hub IoT rejeita com um erro todas as operações que aumentariam o tamanho do tags, properties/desiredou properties/reported documentos acima do limite.

Metadados gêmeos do dispositivo

O Hub IoT mantém o carimbo de data/hora da última atualização para cada objeto JSON nas propriedades desejadas e relatadas do gêmeo do dispositivo. Os carimbos de data/hora estão em UTC e codificados no formato YYYY-MM-DDTHH:MM:SS.mmmZISO8601.

Por exemplo:

{
    ...
    "properties": {
        "desired": {
            "telemetryConfig": {
                "sendFrequency": "5m"
            },
            "$metadata": {
                "telemetryConfig": {
                    "sendFrequency": {
                        "$lastUpdated": "2016-03-30T16:24:48.789Z"
                    },
                    "$lastUpdated": "2016-03-30T16:24:48.789Z"
                },
                "$lastUpdated": "2016-03-30T16:24:48.789Z"
            },
            "$version": 23
        },
        "reported": {
            "telemetryConfig": {
                "sendFrequency": "5m",
                "status": "success"
            },
            "batteryLevel": "55%",
            "$metadata": {
                "telemetryConfig": {
                    "sendFrequency": {
                        "$lastUpdated": "2016-03-31T16:35:48.789Z"
                    },
                    "status": {
                        "$lastUpdated": "2016-03-31T16:35:48.789Z"
                    },
                    "$lastUpdated": "2016-03-31T16:35:48.789Z"
                },
                "batteryLevel": {
                    "$lastUpdated": "2016-04-01T16:35:48.789Z"
                },
                "$lastUpdated": "2016-04-01T16:24:48.789Z"
            },
            "$version": 123
        }
    }
    ...
}

Essas informações são mantidas em todos os níveis (não apenas nas folhas da estrutura JSON) para preservar as atualizações que removem chaves de objeto.

Simultaneidade otimista

Tags, propriedades desejadas e propriedades relatadas suportam simultaneidade otimista. Se você precisar garantir a ordem das atualizações de propriedades gêmeas, considere implementar a sincronização no nível do aplicativo aguardando o retorno de chamada das propriedades relatadas antes de enviar a próxima atualização.

Os gêmeos de dispositivo têm uma ETag (etag propriedade), conforme RFC7232, que representa a representação JSON do gêmeo. Você pode usar a etag propriedade em operações de atualização condicional do back-end da solução para garantir a consistência. Esta é a única opção para garantir a consistência nas operações que envolvem o tags contêiner.

As propriedades desejadas e relatadas do gêmeo do dispositivo também têm um $version valor que é garantido como incremental. Da mesma forma que um ETag, a versão pode ser usada pela parte de atualização para impor a consistência das atualizações. Por exemplo, um aplicativo de dispositivo para uma propriedade relatada ou o back-end da solução para uma propriedade desejada.

As versões também são úteis quando um agente de observação (como o aplicativo do dispositivo observando as propriedades desejadas) deve reconciliar corridas entre o resultado de uma operação de recuperação e uma notificação de atualização. A seção Fluxo de reconexão do dispositivo fornece mais informações.

Fluxo de reconexão do dispositivo

O Hub IoT não preserva as notificações de atualização de propriedades desejadas para dispositivos desconectados. Segue-se que um dispositivo que está se conectando deve recuperar o documento completo de propriedades desejadas, além de se inscrever para notificações de atualização. Dada a possibilidade de corridas entre as notificações de atualização e a recuperação total, deve ser assegurado o seguinte fluxo:

  1. O aplicativo de dispositivo se conecta a um hub IoT.
  2. O aplicativo de dispositivo se inscreve para receber notificações de atualização de propriedades desejadas.
  3. O aplicativo de dispositivo recupera o documento completo para as propriedades desejadas.

O aplicativo de dispositivo pode ignorar todas as notificações com $version menos ou igual à versão do documento recuperado completo. Essa abordagem é possível porque o Hub IoT garante que as versões sempre sejam incrementadas.

Próximos passos

Agora que você aprendeu sobre gêmeos de dispositivo, pode estar interessado nos seguintes tópicos do guia do desenvolvedor do Hub IoT:

Para experimentar alguns dos conceitos descritos neste artigo, consulte os seguintes tutoriais do Hub IoT: