Entender e usar módulos gêmeos no Hub IoT
No Hub IoT, em cada identidade do dispositivo, você pode criar até 50 identidades de módulo. Cada identidade de módulo implicitamente gera módulo gêmeo. Semelhante aos gêmeos do dispositivo, os gêmeos do módulo são documentos JSON que armazenam informações de estado do módulo, incluindo metadados, configurações e condições. O Hub IoT do Azure mantém um módulo gêmeo para cada módulo que você conecta ao Hub IoT.
Este artigo pressupõe que você leia Entender e usar dispositivos gêmeos no Hub IoT primeiro.
No lado do dispositivo, os SDKs (kits de desenvolvimento de software) do dispositivo do Hub IoT permitem que você crie módulos em que cada um abre uma conexão independente com o Hub IoT. Essa funcionalidade permite usar namespaces separados para diferentes componentes em seu dispositivo. Por exemplo, você tem uma máquina de vendas com três sensores diferentes. Diferentes departamentos da sua empresa controlam cada sensor. Você pode criar um módulo para cada sensor para que um departamento só possa enviar trabalhos ou direcionar métodos para o sensor que controla, evitando conflitos e erros do usuário.
A identidade do módulo e o módulo gêmeo fornecem os mesmos recursos que a identidade do dispositivo e o dispositivo gêmeo, mas com granularidade mais precisa. Essa granularidade mais fina permite que dispositivos capazes, como dispositivos baseados em sistema operacional ou dispositivos de firmware que gerenciam vários componentes, isolem a configuração e as condições de cada um desses componentes. A identidade do módulo e os módulos gêmeos fornecem uma separação de problemas do gerenciamento ao trabalhar com dispositivos IoT que têm componentes de software modular. Nosso objetivo é dar suporte a toda a funcionalidade de dispositivos gêmeos no nível dos módulos gêmeos por meio da disponibilidade de módulos gêmeos para o público geral.
Observação
Os recursos descritos neste artigo estão disponíveis apenas na camada padrão 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 a sua solução.
Este artigo descreve:
- A estrutura do módulo gêmeo: marcas, propriedades desejadas e relatadas.
- As operações que aplicativos de dispositivo e o back-end da solução podem ser executadas em módulos gêmeos.
Veja as Diretrizes de comunicação do dispositivo para nuvem para obter orientação sobre o uso de propriedades reportadas, mensagens do dispositivo para nuvem ou upload do arquivo.
Veja as Diretrizes de comunicação da nuvem para dispositivo para obter orientação sobre o uso de propriedades desejadas, métodos diretos ou mensagens da nuvem para dispositivo.
Módulos gêmeos
Módulos gêmeos armazenam informações relacionadas ao módulo que:
Os módulos no dispositivo e o Hub IoT podem usar para sincronizar a configuração e as condições do módulo.
A solução que o back-end pode usar para consultar e direcionar operações de execução longa.
O ciclo de vida de um módulo gêmeo está vinculado a correspondente identidade de módulo. Os módulos gêmeos são criados e excluídos implicitamente quando uma identidade de módulo é criada ou excluída no Hub IoT.
Um módulo gêmeo é um documento JSON que inclui:
Marcas. Uma seção do documento JSON na qual os aplicativos de back-end podem ler e gravar. As tags não são visíveis para os módulos no dispositivo. As marcações são definidas para fins de consulta.
Propriedades desejadas. Usado junto com as propriedades relatadas para sincronizar a configuração ou condições de módulo. Os aplicativos de back-end podem definir as propriedades desejadas e o aplicativo de módulo pode lê-las. O aplicativo do módulo também pode receber notificações de alterações nas propriedades desejadas.
Propriedades reportadas. Usado junto com as propriedades desejadas para sincronizar a configuração ou condições de módulo. O aplicativo de módulo pode definir propriedades relatadas e os aplicativos de back-end podem lê-las e consultá-las.
Propriedades de identidade do módulo. A raiz do documento JSON do módulo gêmeo contém as propriedades somente leitura da identidade de módulo correspondente armazenado na registro de identidade.
O seguinte exemplo mostra um documento JSON de módulo gêmeo:
{
"deviceId": "devA",
"moduleId": "moduleA",
"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
}
}
}
No nível superior, um objeto de módulo gêmeo contém as propriedades de identidade do módulo e os objetos de contêiner para tags
e as propriedades reported
e desired
. O contêiner properties
apresenta alguns elementos somente leitura ($metadata
e $version
) descritos nas seções Metadados do módulo gêmeo e Simultaneidade otimista.
Exemplo da propriedade reportada
No exemplo anterior, o módulo gêmeo contém uma propriedade relatada batteryLevel
. Essa propriedade torna possível a consultar e operação em módulos com base no último nível da bateria reportado. Outros exemplos incluem os recursos de módulo de relatórios de aplicativo de módulo ou as opções de conectividade.
Observação
As propriedades relatadas simplificam os cenários em que você está interessado no último valor conhecido de uma propriedade. Use mensagens do dispositivo para a nuvem se quiser processar a telemetria do módulo em sequências de eventos com carimbo de data/hora, como séries temporais.
Exemplo da propriedade desejada
No exemplo anterior, as propriedades desejadas e relatadas do módulo gêmeo telemetryConfig
são usadas pelos aplicativos de back-end e pelo aplicativo de módulo para sincronizar a configuração de telemetria para este módulo. Por exemplo:
Um aplicativo de back-end define a propriedade desejada com o valor de configuração desejado. Aqui está a parte do documento com a propriedade desejada definida:
... "desired": { "telemetryConfig": { "sendFrequency": "5m" }, ... }, ...
O aplicativo de módulo será notificado sobre a alteração imediatamente se o módulo estiver conectado. Se ele não estiver conectado, o aplicativo de módulo seguirá o fluxo de reconexão de módulo ao se conectar. Em seguida, o aplicativo do módulo reporta a configuração atualizada (ou uma condição de erro usando a propriedade
status
). Aqui está a parte das propriedades relatadas:"reported": { "telemetryConfig": { "sendFrequency": "5m", "status": "success" } ... }
Um aplicativo de back-end pode acompanhar os resultados da operação de configuração em vários módulos, consultando módulos gêmeos.
Observação
Os snippets anteriores são exemplos, otimizados para facilitar a leitura, de uma forma de codificar uma configuração de módulo e seu status. O Hub IoT não impõe um esquema específico para as propriedades desejadas e reportadas do módulo gêmeo nos módulos gêmeos.
Importante
A 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 a IoT Plug and Play, você precisa seguir as convenções de Plug and Play ao atualizar propriedades de gêmeo. Para obter mais informações e um exemplo, confira Propriedades graváveis no IoT Plug and Play.
Operações de back-end
Os aplicativos de back-end operam no módulo gêmeo usando as seguintes operações atômicas, expostas por meio de HTTPS:
Recuperar módulo gêmeo por ID. Essa operação retorna o documento do módulo gêmeo, incluindo marcas e propriedades do sistema desejadas e reportadas.
Atualizar parcialmente o módulo gêmeo. Essa operação atualiza parcialmente as marcas ou propriedades desejadas em um módulo gêmeo. A atualização parcial é expressa como um documento JSON que adiciona ou atualiza qualquer propriedade. As propriedades definidas como
null
foram removidas. O exemplo a seguir cria uma nova propriedade desejada com o valor{"newProperty": "newValue"}
, substitui o valor existente deexistingProperty
por"otherNewValue"
e removeotherOldProperty
. Nenhuma outra alteração é feitas nas propriedades desejadas ou marcas existentes:{ "properties": { "desired": { "newProperty": { "nestedProperty": "newValue" }, "existingProperty": "otherNewValue", "otherOldProperty": null } } }
Substituir propriedades desejadas. Essa operação substitui completamente todas as propriedades desejadas existentes e substitui um novo documento JSON por
properties/desired
.Substituir marcas. Essa operação substitui completamente todas as tags existentes e substitui um novo documento JSON por
tags
.Receba notificações gêmeas. Essa operação notifica quando o gêmeo é modificado. Para receber notificações de alteração do módulo gêmeo, 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, e portanto nenhuma notificação gêmea é enviada. Se a taxa de alteração for alta demais ou então por outros motivos como falhas internas, o Hub IoT poderá enviar apenas uma notificação contendo todas as alterações. Portanto, se o aplicativo precisar de auditoria e registro em log confiável de todos os estados intermediários, será necessário 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 no artigo Control Access to IoT Hub.
Além dessas operações, os aplicativos de back-end podem consultar os módulos gêmeos usando a linguagem de consulta do Hub IoT semelhante ao SQL.
Operações de módulo
O aplicativo do módulo opera no módulo gêmeo usando as seguintes operações atômicas:
Recuperar módulo gêmeo. Essa operação retorna o documento do módulo gêmeo (incluindo as propriedades do sistema desejadas e relatadas) para o módulo conectado no momento.
Atualizar parcialmente as propriedades reportadas. Essa operação permite a atualização parcial das propriedades reportadas do módulo conectado no momento.
Observar as propriedades desejadas. O módulo conectado no momento pode optar por ser notificado sobre atualizações para as propriedades desejadas quando elas ocorrem.
Todas as operações anteriores exigem a permissão DeviceConnect, conforme a definição no artigo Controlar o acesso ao Hub IoT.
Os SDKs do dispositivo IoT do Azure facilitam o uso das operações anteriores em várias linguagens e plataformas.
Formato de marcas e propriedades
Marcas, propriedades desejadas e propriedades reportadas 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. Os caracteres permitidos excluem caracteres de controle UNICODE (segmentos C0 e C1) e
.
,$
e SP.Valores: todos os valores em objetos JSON podem ser dos seguintes tipos de JSON: booliano, número, cadeia de caracteres ou objeto. Também há suporte para matrizes.
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 marcas, propriedades desejadas e propriedades relatadas é dez. Por exemplo, o seguinte objeto é válido:
{ ... "tags": { "one": { "two": { "three": { "four": { "five": { "six": { "seven": { "eight": { "nine": { "ten": { "property": "value" } } } } } } } } } } }, ... }
Tamanho do módulo gêmeo
O Hub IoT impõe um limite de tamanho de 8 KB para o valor de tags
, e um limite de tamanho de 32 KB para cada valor de properties/desired
e properties/reported
. Esses totais são exclusivos de elementos somente leitura como $version
e $metadata/$lastUpdated
.
O tamanho do gêmeo é calculado da seguinte maneira:
O Hub IoT calcula e adiciona cumulativamente o comprimento da chave e do valor de cada propriedade.
As chaves de propriedade são consideradas cadeias de caracteres codificadas em UTF-8.
Os valores de propriedades simples são considerados cadeias de caracteres codificadas em UTF-8, valores numéricos (8 bytes) ou valores boolianos (4 bytes).
O tamanho das cadeias de caracteres codificadas em UTF-8 é calculado pela contagem de todos os caracteres, exceto caracteres de controle UNICODE (segmentos C0 e C1).
Os valores de propriedades complexos (objetos aninhados) são calculados com base no tamanho agregado das chaves de propriedades e dos valores de propriedades que eles contêm.
O Hub IoT rejeita com erro todas as operações que podem aumentar o tamanho desses documentos acima do limite.
Metadados do módulo gêmeo
O Hub IoT mantém o carimbo de data e hora da última atualização de cada objeto JSON nas propriedades desejadas e reportadas do módulo gêmeo. Os carimbos de data e hora estão em UTC e são codificados no formato ISO8601YYYY-MM-DDTHH:MM:SS.mmmZ
.
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": "5m",
"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 armazenadas em cada nível (não apenas nas folhas da estrutura JSON) a fim de preservar as atualizações que removem chaves de objeto.
Simultaneidade otimista
As marcas, propriedades desejadas e propriedades reportadas oferecem suporte à simultaneidade otimista. Se você precisar garantir a ordem das atualizações de propriedades gêmeas, implemente 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 módulos gêmeos têm uma ETag (propriedade etag
), de acordo com RFC7232, que corresponde à representação JSON do gêmeo. Você pode usar a propriedade etag
em operações de atualização condicional de aplicativos de back-end para garantir a consistência. Essa opção garante consistência nas operações que envolvem o contêiner tags
.
As propriedades desejadas e reportadas do módulo gêmeo também têm um valor $version
com garantia de ser incremental. Da mesma forma que uma ETag, você pode usar o valor da versão para impor a consistência das atualizações. Por exemplo, um aplicativo de módulo para uma propriedade relatada ou um aplicativo de back-end para uma propriedade desejada.
Versões também são úteis quando um agente observador (por exemplo, o aplicativo do módulo que observa 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 módulo fornece mais informações.
Fluxo de reconexão do módulo
O Hub IoT não preserva as notificações de atualização de propriedades desejadas para módulos desconectados. Um módulo que está se conectando precisa recuperar o documento de propriedades desejadas completo, além de assinar notificações de atualização. Considerando a possibilidade de corridas entre notificações de atualização e recuperação completa, o seguinte fluxo deve ser garantido:
- O aplicativo de módulo se conecta com um hub IoT.
- O aplicativo de módulo assina as notificações de atualização de propriedades desejadas.
- O aplicativo de módulo recupera o documento completo das propriedades desejadas.
O aplicativo de módulo pode ignorar todas as notificações com $version
menor ou igual à versão do documento recuperado completo. Essa abordagem é possível porque o Hub IoT garante que as versões sempre aumentam.
Próximas etapas
Para experimentar alguns dos conceitos descritos neste artigo, consulte os tutoriais do Hub IoT a seguir: