Partager via


Comprendre et utiliser les jumeaux de module dans IoT Hub

Dans IoT Hub, sous chaque identité d’appareil, vous pouvez créer jusqu’à 50 identités de module. Chaque identité de module génère implicitement un jumeau de module. À l’image des jumeaux d’appareil, les jumeaux de module sont des documents JSON qui stockent des informations sur l’état des modules (métadonnées, configurations et conditions). Azure IoT Hub conserve un jumeau de module pour chaque module que vous y connectez.

Cet article suppose que vous lisez Comprendre et utiliser les jumeaux d’appareil dans IoT Hub d’abord.

Côté appareil, les kits de développement logiciel (SDK) IoT Hub vous permettent de créer des modules où chacun ouvre une connexion indépendante à IoT Hub. Cette fonctionnalité vous permet d’utiliser des espaces de noms distincts pour les différents composants de votre appareil. Par exemple, vous disposez d’un distributeur automatique dotés de trois capteurs différents. Différents services de votre entreprise contrôlent chaque capteur. Vous pouvez créer un module pour chaque capteur afin qu’un service puisse uniquement envoyer des travaux ou des méthodes directes au capteur qu’il contrôle, en évitant les conflits et les erreurs utilisateur.

L’identité de module et le jumeau de module fournissent les mêmes fonctionnalités que l’identité d’appareil et le jumeau d’appareil, mais avec une plus grande précision. Ainsi, les appareils compatibles, tels que les appareils basés sur le système d’exploitation ou les appareils avec microprogramme gérant plusieurs composants, peuvent isoler la configuration et les conditions pour chacun de ces composants. L’identité de module et les jumeaux de module vous permettent de gérer les problèmes de façon séparée quand vous utilisez des appareils IoT qui comportent des composants logiciels modulaires. Nous œuvrons pour que toutes les fonctionnalités de jumeau d’appareil soient prises en charge au niveau des jumeaux de module au plus tard quand ces derniers seront en disponibilité générale.

Notes

Les fonctionnalités décrites dans cet article sont uniquement disponibles au niveau Standard d’IoT Hub. Pour plus d’informations sur les niveaux de base et standard/gratuit d’IoT Hub, consultez Choisir le niveau IoT Hub correspondant à votre solution.

Cet article aborde les points suivants :

Pour des conseils sur l’utilisation des propriétés rapportées, des messages appareil-à-cloud ou du chargement de fichiers, consultez Recommandations sur les communications appareil-à-cloud.

Pour des conseils sur l’utilisation des propriétés souhaitées, des méthodes directes ou des messages cloud-à-appareil, consultez Recommandations sur les communications cloud-à-appareil.

Jumeaux de module

Les jumeaux de module stockent des informations relatives aux modules, dont l’utilité est la suivante :

  • Elles permettent aux modules sur l’appareil et IoT Hub de synchroniser les conditions et la configuration des modules.

  • Ils permettent à un back-end de solution d’interroger et de cibler des opérations de longue durée.

Le cycle de vie d’un jumeau de module est lié à l’identité de module correspondante. Des jumeaux de module sont implicitement créés et supprimés au moment de la création ou de la suppression d’une identité de module dans IoT Hub.

Un jumeau de module est un document JSON incluant les éléments suivants :

  • Tags (balises). Une section du document JSON accessible en lecture et en écriture par les applications back-end. Les balises ne sont pas visibles pour les modules sur l’appareil. Les balises sont définies à des fins d’interrogation.

  • Propriétés souhaitées (Desired) . Utilisées en même temps que les propriétés signalées pour synchroniser une configuration ou une condition de module. Les applications principales peuvent définir les propriétés souhaitées et l’application de module peut les lire. L’application de module peut également recevoir des notifications sur les changements des propriétés souhaitées.

  • Propriétés signalées (Reported) . Utilisées en même temps que les propriétés souhaitées pour synchroniser une configuration ou une condition de module. L’application de module peut définir les propriétés signalées, et les applications principales peuvent les lire et les interroger.

  • Propriétés d’identité des modules. La racine du document JSON du jumeau de module contient les propriétés en lecture seule de l’identité de module correspondante stockées dans le registre des identités.

Représentation architecturale du jumeau d’appareil

L’exemple suivant montre un document JSON de jumeau de module :

{
    "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
        }
    }
}

Au niveau supérieur, un objet jumeau de module contient les propriétés d’identité de module et les objets conteneur pour tags et les propriétés reported et desired. Le conteneur properties contient des éléments en lecture seule ($metadata et $version) décrits dans les sections Métadonnées des jumeaux de module et Accès concurrentiel optimiste.

Exemple de propriété signalée (Reported)

Dans l’exemple précédent, le jumeau de module contient une propriété batteryLevel signalée. Cette propriété permet d’interroger des modules et d’agir sur ceux-ci en fonction du dernier niveau signalé de charge de la batterie. D’autres exemples incluent une application de module signalant des capacités de module ou des options de connectivité.

Remarque

Les propriétés signalées simplifient les scénarios où la dernière valeur connue d’une propriété vous intéresse. Utilisez messages appareil-à-cloud si vous souhaitez traiter les données de télémétrie de module dans des séquences d’événements horodatés, tels que des séries chronologiques.

Exemple de propriété souhaitée

Dans l’exemple précédent, les propriétés souhaitées et signalées du jumeau de module telemetryConfig sont utilisées par les applications principales et l’application de module pour synchroniser la configuration de télémétrie pour ce module. Par exemple :

  1. Une application back-end définit la propriété souhaitée avec la valeur de configuration souhaitée. Voici la partie du document contenant la propriété souhaitée définie :

    ...
    "desired": {
        "telemetryConfig": {
            "sendFrequency": "5m"
        },
        ...
    },
    ...
    
  2. L’application de module est informée de la modification immédiatement si le module est connecté. S’il n’est pas connecté, l’application de module suit le flux de reconnexion du module lorsqu’il se connecte. L’application de module signale ensuite la configuration mise à jour (ou une condition d’erreur à l’aide de la propriété status). Voici la partie contenant les propriétés signalées :

    "reported": {
        "telemetryConfig": {
            "sendFrequency": "5m",
            "status": "success"
        }
        ...
    }
    
  3. Une application back-end peut suivre les résultats de l’opération de configuration sur de nombreux modules, en interrogeant jumeaux de module.

Remarque

Les extraits de code précédents sont des exemples, optimisés pour la lisibilité, de manière possible d’encoder la configuration d’un module et son état. IoT Hub n’impose pas de schéma spécifique pour les propriétés souhaitées et signalées de jumeau de module dans les jumeaux de module.

Important

IoT Plug-and-Play définit un schéma qui utilise plusieurs propriétés supplémentaires pour synchroniser les modifications apportées aux propriétés souhaitées et signalées. Si votre solution utilise IoT Plug-and-Play, vous devez respecter les conventions de Plug-and-Play lors de la mise à jour des propriétés des jumeaux. Pour plus d’informations et un exemple, consultez Propriétés accessibles en écriture dans IoT Plug-and-Play.

Opérations principales

Les applications principales fonctionnent sur le jumeau de module à l’aide des opérations atomiques suivantes, exposées via HTTPS :

  • Récupérer le jumeau de module par ID. Cette opération retourne le contenu du document du jumeau de module, à savoir les Tags (balises) et les propriétés système souhaitées (Desired) et signalées (Reported).

  • Mettre à jour partiellement le jumeau de module. Cette opération met partiellement à jour les balises ou les propriétés souhaitées dans un jumeau de module. La mise à jour partielle est exprimée sous la forme d’un document JSON qui ajoute ou met à jour toute propriété. Les propriétés définies sur null sont supprimées. L’exemple suivant crée une propriété souhaitée avec la valeur {"newProperty": "newValue"}, remplace la valeur existante de existingProperty par "otherNewValue" et supprime otherOldProperty. Aucune autre modification n’est apportée aux autres propriétés souhaitées ou Tags existants :

    {
        "properties": {
            "desired": {
                "newProperty": {
                    "nestedProperty": "newValue"
                },
                "existingProperty": "otherNewValue",
                "otherOldProperty": null
            }
        }
    }
    
  • Remplacer des propriétés souhaitées. Cette opération remplace complètement toutes les propriétés souhaitées existantes et substitue properties/desired par un nouveau document JSON.

  • Remplacer des Tags. Cette opération remplace complètement toutes les étiquettes existantes et substitue tags par un nouveau document JSON.

  • Recevoir des notifications jumelles. Cette opération notifie lorsque le jumeau est modifié. Pour recevoir des notifications de modification de jumeau de module, votre solution IoT doit créer un itinéraire et définir la source de données égale à twinChangeEvents. Par défaut, aucune route n’existe, donc aucune notification jumelle n’est envoyée. Si le taux de variation est trop élevé, ou pour d’autres raisons, telles que des défaillances internes, IoT Hub peut envoyer une seule notification qui contient toutes les modifications. Par conséquent, si l’audit et la journalisation fiables de tous les états intermédiaires sont nécessaires pour votre application, vous devez utiliser des messages appareil-à-cloud. Pour en savoir plus sur les propriétés et le corps retournés dans le message de notification jumelle, consultez Schémas d’événements autres que les événements de télémétrie.

Toutes les opérations précédentes prennent en charge l’accès concurrentiel optimiste et nécessitent l’autorisation ServiceConnect définie dans l’article Contrôler l’accès à IoT Hub.

En plus de ces opérations, les applications principales peuvent interroger les jumeaux de module à l’aide du langage de requête langage de requête IoT Hub.

Opérations sur les modules

L’application de module opère sur le jumeau de module en utilisant les opérations atomiques suivantes :

  • Récupérer le jumeau de module. Cette opération retourne le document du jumeau de module (y compris les propriétés système souhaitées et signalées ) pour le module actuellement connecté.

  • Mettre à jour partiellement les propriétés signalées (Reported) . Cette opération permet la mise à jour partielle des propriétés signalées du module connecté.

  • Observer les propriétés souhaitées (Desired) . Le module connecté peut choisir d’être informé des mises à jour des propriétés souhaitées au moment où elles se produisent.

Toutes les opérations précédentes nécessitent l’autorisation DeviceConnect, comme défini dans l’article Contrôler l’accès à IoT Hub.

Les kits Azure IoT device SDK simplifient l’utilisation des opérations précédentes dans un grand nombre de langages et de plateformes.

Format des Tags et propriétés

Les Tags (balises) ainsi que les propriétés souhaitées (Desired) et signalées (Reported) sont des objets JSON soumis aux restrictions suivantes :

  • Clés : Toutes les clés des objets JSON sont encodées en UTF-8, respectent la casse et mesurent jusqu’à 1 Ko. Les caractères autorisés excluent les caractères de contrôle UNICODE (segments C0 et C1), ainsi que ., $ et SP.

  • Valeurs : Toutes les valeurs figurant dans les objets JSON peuvent être des types JSON suivants : booléen, nombre, chaîne, objet. Les tableaux sont également pris en charge.

    • Les entiers peuvent avoir une valeur minimale de 4503599627370496 et une valeur maximale de 4503599627370495.

    • Les valeurs de chaîne sont encodées au format UTF-8 et peuvent avoir une longueur maximale de 4 Ko.

  • Profondeur : La profondeur maximale des objets JSON dans les balises, les propriétés souhaitées et les propriétés signalées est de 10. Par exemple, l’objet suivant est valide :

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

Taille de jumeau de module

IoT Hub applique une limite de taille de 8 Ko à la valeur tags, et une limite de taille de 32 Ko aux valeurs properties/desired et properties/reported. Ces totaux n’incluent pas les éléments en lecture seule, tels que $version et $metadata/$lastUpdated.

La taille du jumeau est calculée comme suit :

  • IoT Hub calcule et ajoute de façon cumulative la longueur de la clé et la valeur de chaque propriété.

  • Les clés de propriété sont considérées comme des chaînes encodées au format UTF8.

  • Les valeurs de propriété simples sont considérées comme des chaînes encodées au format UTF8, des valeurs numériques (huit octets) ou des valeurs booléennes (quatre octets).

  • La taille des chaînes encodées au format UTF8 est calculée en comptant tous les caractères, à l’exception des caractères de contrôle UNICODE (segments C0 et C1).

  • Les valeurs de propriété complexes (objets imbriqués) sont calculées en fonction de la taille agrégée des clés de propriété et des valeurs de propriété qu’elles contiennent.

IoT Hub rejette en générant une erreur toute opération susceptible d’augmenter la taille de ces documents au-delà de la limite.

Métadonnées de jumeau de module

IoT Hub tient à jour l’horodateur de la dernière mise à jour de chaque objet JSON dans les propriétés souhaitées et signalées du jumeau de module. Les horodateurs sont exprimés en UTC et codés au format ISO8601YYYY-MM-DDTHH:MM:SS.mmmZ. Par exemple :

{
    ...
    "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
        }
    }
    ...
}

Ces informations sont conservées à chaque niveau (pas uniquement celui des feuilles de la structure JSON) afin de préserver les mises à jour qui suppriment des clés d’objet.

Accès concurrentiel optimiste

Les Tags ainsi que les propriétés souhaitées (Desired) et signalées (Reported) prennent en charge l’accès concurrentiel optimiste. Si vous devez garantir l’ordre des mises à jour des propriétés de jumeau, envisagez d’implémenter la synchronisation au niveau de l’application en attendant le rappel des propriétés signalées avant d’envoyer la prochaine mise à jour.

Les jumeaux de module possèdent une propriété ETag (etag), conformément à RFC7232, correspondant à la représentation JSON des jumeaux. Vous pouvez utiliser la propriété etag dans les opérations de mise à jour conditionnelle à partir d’applications principales pour garantir la cohérence. Cette option garantit la cohérence dans les opérations qui impliquent le conteneur tags.

Les propriétés souhaitées et signalées des jumeaux de module présentent aussi une valeur $version dont la nature incrémentielle est garantie. Comme pour un ETag, vous pouvez utiliser la valeur de version pour appliquer la cohérence des mises à jour. Par exemple, une application de module pour une propriété signalée ou une application back-end pour une propriété souhaitée.

Les versions sont également utiles quand un agent observateur (par exemple, l’application de module observant les propriétés souhaitées) doit concilier des concurrences entre les résultats d’une opération de récupération et d’une notification de mise à jour. Pour plus d’informations, consultez la section Flux de reconnexion de module.

Flux de reconnexion de module

IoT Hub ne conserve pas les notifications de mise à jour des propriétés souhaitées pour les modules déconnectés. Il en résulte qu’un module qui se connecte doit récupérer le document complet des propriétés souhaitées, en plus de s’abonner aux notifications de mise à jour. Étant donné la possibilité de concurrences entre les notifications de mise à jour et la récupération complète, le flux suivant doit être assuré :

  1. L’application de module se connecte à un hub IoT.
  2. L’application de module s’abonne aux notifications de mise à jour des propriétés souhaitées.
  3. L’application de module récupère le document complet pour les propriétés souhaitées.

L’application de module peut ignorer toutes les notifications dont la $version a une valeur inférieure ou égale à la version du document complet récupéré. Cette approche est possible, car IoT Hub garantit que les numéros de version sont toujours incrémentiels.

Étapes suivantes

Pour tenter de mettre en pratique certains des concepts décrits dans cet article, consultez les didacticiels IoT Hub suivants :