Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Vous pouvez suivre ce didacticiel pour configurer un appareil principal afin qu'il interagisse avec des appareils IoT locaux, appelés appareils clients, qui se connectent au périphérique principalMQTT. Dans ce didacticiel, vous allez configurer AWS IoT des éléments pour utiliser la découverte du cloud pour se connecter au périphérique principal en tant qu'appareils clients. Lorsque vous configurez la découverte du cloud, un appareil client peut envoyer une demande au service AWS IoT Greengrass cloud pour découvrir les appareils principaux. La réponse AWS IoT Greengrass inclut des informations de connectivité et des certificats pour les appareils principaux que vous configurez pour que le périphérique client découvre. Le dispositif client peut ensuite utiliser ces informations pour se connecter à un dispositif central disponible sur lequel il peut communiquerMQTT.
Dans ce didacticiel, vous effectuez les opérations suivantes :
-
Vérifiez et mettez à jour les autorisations de l'appareil principal, si nécessaire.
-
Associez les appareils clients au périphérique principal afin qu'ils puissent découvrir le périphérique principal à l'aide de la découverte du cloud.
-
Déployez les composants Greengrass sur l'appareil principal pour permettre la prise en charge des appareils clients.
-
Connectez les appareils clients à l'appareil principal et testez la communication avec le service AWS IoT Core cloud.
-
Développez un composant Greengrass personnalisé qui communique avec les appareils clients.
-
Développez un composant personnalisé qui interagit avec les ombres des AWS IoT appareils clients.
Ce didacticiel utilise un seul périphérique central et un seul appareil client. Vous pouvez également suivre le didacticiel pour connecter et tester plusieurs appareils clients.
Vous pouvez vous attendre à consacrer 30 à 60 minutes à ce didacticiel.
Prérequis
Pour suivre ce didacticiel, vous aurez besoin des éléments suivants :
-
Un Compte AWS. Si vous n'en avez pas, veuillez consulter Configurez un Compte AWS.
-
Un AWS Identity and Access Management (IAM) utilisateur doté d'autorisations d'administrateur.
-
Un appareil Greengrass Core. Pour plus d'informations sur la configuration d'un périphérique principal, consultezConfiguration des appareils AWS IoT Greengrass principaux.
-
Le périphérique principal doit exécuter Greengrass nucleus v2.6.0 ou version ultérieure. Cette version inclut la prise en charge des caractères génériques dans les communications locales de publication/d'abonnement et la prise en charge des ombres sur les appareils clients.
Note
La prise en charge des appareils clients nécessite Greengrass nucleus v2.2.0 ou version ultérieure. Cependant, ce didacticiel explore les nouvelles fonctionnalités, telles que la prise en charge des MQTT caractères génériques dans les publications et les abonnements locaux et la prise en charge des ombres sur les appareils clients. Ces fonctionnalités nécessitent Greengrass nucleus v2.6.0 ou version ultérieure.
-
Le périphérique principal doit se trouver sur le même réseau que les appareils clients pour se connecter.
-
(Facultatif) Pour terminer les modules dans lesquels vous développez des composants Greengrass personnalisés, le périphérique principal doit exécuter le Greengrass. CLI Pour de plus amples informations, veuillez consulter Installez le Greengrass CLI.
-
-
Un AWS IoT objet à connecter en tant qu'appareil client dans ce didacticiel. Pour plus d'informations, consultez la section Création de AWS IoT ressources dans le guide du AWS IoT Core développeur.
-
La AWS IoT politique de l'appareil client doit autoriser l'
greengrass:Discover
autorisation. Pour de plus amples informations, veuillez consulter AWS IoTPolitique minimale pour les appareils clients. -
L'appareil client doit se trouver sur le même réseau que le périphérique principal.
-
L'appareil client doit exécuter Python 3
. -
L'appareil client doit exécuter Git
.
-
Étape 1 : révision et mise à jour de la AWS IoT politique de base relative aux appareils
Pour prendre en charge les appareils clients, la AWS IoT politique d'un appareil principal doit autoriser les autorisations suivantes :
-
greengrass:PutCertificateAuthorities
-
greengrass:VerifyClientDeviceIdentity
-
greengrass:VerifyClientDeviceIoTCertificateAssociation
-
greengrass:GetConnectivityInfo
-
greengrass:UpdateConnectivityInfo
— (Facultatif) Cette autorisation est requise pour utiliser le composant de détection IP, qui transmet les informations de connectivité réseau de l'appareil principal au service AWS IoT Greengrass cloud.
Pour plus d'informations sur ces autorisations et AWS IoT politiques pour les appareils principaux, consultez Stratégies AWS IoT pour les opérations de plan de données etAWS IoTPolitique minimale de prise en charge des appareils clients.
Dans cette section, vous passez en revue les AWS IoT politiques de votre appareil principal et ajoutez les autorisations requises manquantes. Si vous avez utilisé le programme d'installation du logiciel AWS IoT Greengrass Core pour provisionner des ressources, votre appareil principal dispose d'une AWS IoT politique qui autorise l'accès à toutes les AWS IoT Greengrass actions (greengrass:*
). Dans ce cas, vous devez mettre à jour la AWS IoT politique uniquement si vous prévoyez de configurer le composant Shadow Manager avec lequel synchroniser les ombres du périphérique AWS IoT Core. Sinon, vous pouvez ignorer cette section.
Pour consulter et mettre à jour la AWS IoT politique d'un appareil principal
-
Dans le menu de navigation de la AWS IoT Greengrass console
, choisissez Core devices. -
Sur la page des appareils principaux, choisissez le périphérique principal à mettre à jour.
-
Sur la page de détails de l'appareil principal, choisissez le lien vers l'objet de l'appareil principal. Ce lien ouvre la page des détails de l'objet dans la AWS IoT console.
-
Sur la page des détails de l'objet, sélectionnez Certificats.
-
Dans l'onglet Certificats, choisissez le certificat actif de l'objet.
-
Sur la page des détails du certificat, sélectionnez Policies.
-
Dans l'onglet Politiques, choisissez la AWS IoT politique à revoir et à mettre à jour. Vous pouvez ajouter les autorisations requises à n'importe quelle politique associée au certificat actif de l'appareil principal.
Note
Si vous avez utilisé le programme d'installation du logiciel AWS IoT Greengrass Core pour provisionner des ressources, vous avez deux AWS IoT règles. Nous vous recommandons de choisir la politique nommée GreengrassV2IoTThingPolicy, s'il existe. Les appareils principaux que vous créez avec le programme d'installation rapide utilisent ce nom de politique par défaut. Si vous ajoutez des autorisations à cette politique, vous les accordez également aux autres appareils principaux qui utilisent cette politique.
-
Dans l'aperçu des politiques, choisissez Modifier la version active.
-
Passez en revue la politique relative aux autorisations requises et ajoutez les autorisations requises manquantes.
-
Pour définir une nouvelle version de politique comme version active, sous État de la version de politique, sélectionnez Définir la version modifiée comme version active pour cette politique.
-
Choisissez Enregistrer en tant que nouvelle version.
Étape 2 : activer la prise en charge des appareils clients
Pour qu'un appareil client utilise la découverte du cloud pour se connecter à un appareil principal, vous devez associer les appareils. Lorsque vous associez un appareil client à un appareil principal, vous permettez à ce dernier de récupérer les adresses IP et les certificats du périphérique principal à utiliser pour se connecter.
Pour permettre aux appareils clients de se connecter en toute sécurité à un appareil principal et de communiquer avec les composants de Greengrass AWS IoT Core, vous déployez les composants Greengrass suivants sur le périphérique principal :
-
Authentification de l'appareil client (
aws.greengrass.clientdevices.Auth
)Déployez le composant d'authentification des appareils clients pour authentifier les appareils clients et autoriser les actions des appareils clients. Ce composant permet à vos AWS IoT objets de se connecter à un appareil principal.
Ce composant nécessite une certaine configuration pour pouvoir être utilisé. Vous devez spécifier les groupes d'appareils clients et les opérations que chaque groupe est autorisé à effectuer, telles que la connexion et la communicationMQTT. Pour plus d'informations, consultez la section Configuration du composant d'authentification de l'appareil client.
-
Courtier MQTT 3.1.1 (Moquette) (
aws.greengrass.clientdevices.mqtt.Moquette
)Déployez le composant Moquette MQTT broker pour exécuter un MQTT broker léger. Le MQTT broker Moquette est conforme à la MQTT version 3.1.1 et inclut un support local pour QoS 0, QoS 1, QoS 2, les messages conservés, les messages de dernier testament et les abonnements permanents.
Vous n'êtes pas obligé de configurer ce composant pour l'utiliser. Toutefois, vous pouvez configurer le port sur lequel ce composant fait fonctionner le MQTT broker. Par défaut, il utilise le port 8883.
-
Pont MQTT (
aws.greengrass.clientdevices.mqtt.Bridge
)(Facultatif) Déployez le composant MQTT pont pour relayer les messages entre les appareils clients (localMQTT), publier/souscrire localement et. AWS IoT Core MQTT Configurez ce composant pour synchroniser les appareils clients avec les appareils clients AWS IoT Core et interagir avec eux à partir des composants Greengrass.
Ce composant nécessite une configuration pour être utilisé. Vous devez spécifier les mappages de rubriques dans lesquels ce composant relaie les messages. Pour plus d'informations, consultez la section Configuration des composants du MQTT pont.
-
Détecteur IP (
aws.greengrass.clientdevices.IPDetector
)(Facultatif) Déployez le composant de détection IP pour signaler automatiquement les points de terminaison du MQTT broker du périphérique principal au service AWS IoT Greengrass cloud. Vous ne pouvez pas utiliser ce composant si votre configuration réseau est complexe, par exemple si un routeur transmet le port du MQTT broker au périphérique principal.
Vous n'êtes pas obligé de configurer ce composant pour l'utiliser.
Dans cette section, vous allez utiliser la AWS IoT Greengrass console pour associer des appareils clients et déployer des composants de périphériques clients sur un périphérique principal.
Pour activer la prise en charge des appareils clients
-
Dans le menu de navigation de gauche, choisissez Core devices.
-
Sur la page des appareils principaux, choisissez le périphérique principal sur lequel vous souhaitez activer la prise en charge des appareils clients.
-
Sur la page des détails de l'appareil principal, choisissez l'onglet Appareils clients.
-
Dans l'onglet Appareils clients, choisissez Configurer la découverte du cloud.
La page Configurer la découverte du périphérique principal s'ouvre. Sur cette page, vous pouvez associer des appareils clients à un appareil principal et déployer des composants de périphériques clients. Cette page sélectionne l'appareil principal pour vous à l'étape 1 : Sélectionnez les appareils principaux cibles.
Note
Vous pouvez également utiliser cette page pour configurer la découverte des périphériques principaux pour un groupe d'objets. Si vous choisissez cette option, vous pouvez déployer les composants de l'appareil client sur tous les appareils principaux d'un groupe d'objets. Toutefois, si vous choisissez cette option, vous devrez associer manuellement les appareils clients à chaque périphérique principal ultérieurement après avoir créé le déploiement. Dans ce didacticiel, vous allez configurer un périphérique monocœur.
-
À l'étape 2 : Associer les appareils clients, associez l' AWS IoT objet de l'appareil client au périphérique principal. Cela permet à l'appareil client d'utiliser la découverte du cloud pour récupérer les informations de connectivité et les certificats du périphérique principal. Procédez comme suit :
-
Choisissez Associer les appareils clients.
-
Dans le mode Associer les appareils clients aux appareils principaux, entrez le nom de l' AWS IoT objet à associer.
-
Choisissez Ajouter.
-
Choisissez Associer.
-
-
À l'étape 3 : Configuration et déploiement des composants Greengrass, déployez des composants pour permettre la prise en charge des appareils clients. Si le périphérique principal cible a déjà été déployé, cette page révise ce déploiement. Dans le cas contraire, cette page crée un nouveau déploiement pour le périphérique principal. Procédez comme suit pour configurer et déployer les composants de l'appareil client :
-
Le périphérique principal doit exécuter Greengrass nucleus v2.6.0 ou version ultérieure pour terminer ce didacticiel. Si le périphérique principal exécute une version antérieure, procédez comme suit :
-
Cochez la case pour déployer aws.greengrass.Nucleuscomposant.
-
Pour le aws.greengrass.Nucleuscomposant, choisissez Modifier la configuration.
-
Pour la version du composant, choisissez la version 2.6.0 ou ultérieure.
-
Choisissez Confirmer.
Note
Si vous mettez à niveau le noyau Greengrass à partir d'une version mineure antérieure et que le périphérique principal exécute des composants AWS fournis qui dépendent du noyau, vous devez également mettre à jour les composants AWS fournis vers des versions plus récentes. Vous pouvez configurer la version de ces composants lorsque vous examinerez le déploiement ultérieurement dans ce didacticiel. Pour de plus amples informations, veuillez consulter Mettre à jour le logiciel AWS IoT Greengrass principal (OTA).
-
-
Pour le aws.greengrass.clientdevices.Authcomposant, choisissez Modifier la configuration.
-
Dans le mode Modifier la configuration pour le composant d'authentification du périphérique client, configurez une politique d'autorisation qui permet aux appareils clients de publier et de s'abonner au MQTT courtier sur le périphérique principal. Procédez comme suit :
-
Sous Configuration, dans le bloc de code Configuration pour fusionner, entrez la configuration suivante, qui contient une politique d'autorisation de l'appareil client. Chaque politique d'autorisation de groupe d'appareils spécifie un ensemble d'actions et les ressources sur lesquelles un appareil client peut effectuer ces actions.
-
Cette politique permet aux appareils clients dont le nom commence par
MyClientDevice
de se connecter et de communiquer sur tous les MQTT sujets. RemplacezMyClientDevice*
par le nom de l' AWS IoT objet à connecter en tant qu'appareil client. Vous pouvez également spécifier un nom avec le*
caractère générique correspondant au nom de l'appareil client. Le*
joker doit se trouver à la fin du nom.Si vous devez vous connecter à un deuxième appareil client, remplacez-le
MyOtherClientDevice*
par le nom de cet appareil client ou par un modèle générique correspondant au nom de cet appareil client. Sinon, vous pouvez supprimer ou conserver cette section de la règle de sélection qui permet aux appareils clients dont les noms correspondent de seMyOtherClientDevice*
connecter et de communiquer. -
Cette politique utilise un
OR
opérateur pour autoriser également les appareils clients dont le nom commence parMyOtherClientDevice
à se connecter et à communiquer sur tous les MQTT sujets. Vous pouvez supprimer cette clause dans la règle de sélection ou la modifier pour qu'elle corresponde aux appareils clients à connecter. -
Cette politique permet aux appareils clients de publier et de s'abonner sur tous les MQTT sujets. Pour suivre les meilleures pratiques de sécurité, limitez les
mqtt:subscribe
opérationsmqtt:publish
et à l'ensemble minimal de sujets utilisés par les appareils clients pour communiquer.
{ "deviceGroups": { "formatVersion": "2021-03-05", "definitions": { "MyDeviceGroup": { "selectionRule": "thingName:
MyClientDevice*
OR thingName:MyOtherClientDevice*
", "policyName": "MyClientDevicePolicy" } }, "policies": { "MyClientDevicePolicy": { "AllowConnect": { "statementDescription": "Allow client devices to connect.", "operations": [ "mqtt:connect" ], "resources": [ "*" ] }, "AllowPublish": { "statementDescription": "Allow client devices to publish to all topics.", "operations": [ "mqtt:publish" ], "resources": [ "*" ] }, "AllowSubscribe": { "statementDescription": "Allow client devices to subscribe to all topics.", "operations": [ "mqtt:subscribe" ], "resources": [ "*" ] } } } } }Pour plus d'informations, consultez la section Configuration du composant d'authentification de l'appareil client.
-
-
Choisissez Confirmer.
-
-
Pour le aws.greengrass.clientdevices.mqtt.Bridgecomposant, choisissez Modifier la configuration.
-
Dans le mode Modifier la configuration du composant MQTT pont, configurez un mappage de rubriques qui relaie les MQTT messages des appareils clients vers AWS IoT Core. Procédez comme suit :
-
Sous Configuration, dans le bloc de code Configuration pour fusionner, entrez la configuration suivante. Cette configuration indique de relayer MQTT les messages sur le filtre
clients/+/hello/world
thématique des appareils clients vers le service AWS IoT Core cloud. Par exemple, ce filtre de rubrique correspond à laclients/MyClientDevice1/hello/world
rubrique.{ "mqttTopicMapping": { "HelloWorldIotCoreMapping": { "topic": "clients/+/hello/world", "source": "LocalMqtt", "target": "IotCore" } } }
Pour plus d'informations, consultez la section Configuration des composants du MQTT pont.
-
Choisissez Confirmer.
-
-
-
Choisissez Vérifier et déployer pour passer en revue le déploiement que cette page crée pour vous.
-
Si vous n'avez pas encore configuré le rôle de service Greengrass dans cette région, la console ouvre un modal pour configurer le rôle de service pour vous. Le composant d'authentification du périphérique client utilise ce rôle de service pour vérifier l'identité des appareils clients, et le composant du détecteur d'adresses IP utilise ce rôle de service pour gérer les informations de connectivité du périphérique principal. Choisissez Grant permissions (Accorder des autorisations).
-
Sur la page Révision, choisissez Déployer pour démarrer le déploiement sur le périphérique principal.
-
Pour vérifier que le déploiement est réussi, vérifiez l'état du déploiement et consultez les journaux sur le périphérique principal. Pour vérifier l'état du déploiement sur le périphérique principal, vous pouvez choisir Target dans l'aperçu du déploiement. Pour plus d’informations, consultez les ressources suivantes :
Étape 3 : Connecter les appareils clients
Les appareils clients peuvent utiliser le Kit SDK des appareils AWS IoT pour découvrir, se connecter et communiquer avec un appareil principal. L'appareil client doit être un AWS IoT objet. Pour plus d'informations, consultez la section Création d'un objet dans le Guide du AWS IoT Core développeur.
Dans cette section, vous allez installer la Kit SDK des appareils AWS IoT version 2 pour Python
Note
Kit SDK des appareils AWS IoT Il est également disponible dans d'autres langages de programmation. Ce didacticiel utilise la Kit SDK des appareils AWS IoT version 2 pour Python, mais vous pouvez explorer l'autre version SDKs pour votre cas d'utilisation. Pour plus d'informations, consultez la section AWS IoT Appareil SDKs dans le guide du AWS IoT Core développeur.
Pour connecter un appareil client à un appareil principal
-
Téléchargez et installez la Kit SDK des appareils AWS IoT version 2 pour Python
sur l' AWS IoT appareil à connecter en tant que périphérique client. Sur l'appareil client, effectuez les opérations suivantes :
-
Clonez le dépôt Kit SDK des appareils AWS IoT v2 pour Python pour le télécharger.
git clone https://github.com/aws/aws-iot-device-sdk-python-v2.git
-
Installez la Kit SDK des appareils AWS IoT version 2 pour Python.
python3 -m pip install --user ./aws-iot-device-sdk-python-v2
-
-
Accédez au dossier d'échantillons dans la Kit SDK des appareils AWS IoT version 2 pour Python.
cd aws-iot-device-sdk-python-v2/samples
-
Exécutez l'exemple d'application de découverte Greengrass. Cette application attend des arguments qui spécifient le nom de l'objet de l'appareil client, le MQTT sujet et le message à utiliser, ainsi que les certificats qui authentifient et sécurisent la connexion. L'exemple suivant envoie un message Hello World à la
clients/
rubrique.MyClientDevice1
/hello/worldNote
Cette rubrique correspond à la rubrique dans laquelle vous avez configuré le MQTT pont pour relayer les messages AWS IoT Core précédemment.
-
MyClientDevice1
Remplacez-le par le nom de l'objet de l'appareil client. -
~/certs/AmazonRootCA1.pem
Remplacez-le par le chemin d'accès au certificat racine de l'autorité de certification Amazon sur l'appareil client. -
Remplacez
~/certs/device.pem.crt
par le chemin d'accès au certificat de l'appareil sur l'appareil client. -
Remplacez
~/certs/private.pem.key
par le chemin d'accès au fichier de clé privée sur l'appareil client. -
Remplacez
us-east-1
par la AWS région dans laquelle fonctionnent votre appareil client et votre appareil principal.
python3 basic_discovery.py \\ --thing_name
MyClientDevice1
\\ --topic 'clients/MyClientDevice1
/hello/world' \\ --message 'Hello World!' \\ --ca_file~/certs/AmazonRootCA1.pem
\\ --cert~/certs/device.pem.crt
\\ --key~/certs/private.pem.key
\\ --regionus-east-1
\\ --verbosity WarnL'exemple d'application de découverte envoie le message 10 fois et se déconnecte. Il s'abonne également au même sujet où il publie des messages. Si le résultat indique que l'application a reçu MQTT des messages sur le sujet, le dispositif client peut communiquer avec succès avec le dispositif principal.
Performing greengrass discovery... awsiot.greengrass_discovery.DiscoverResponse(gg_groups=[awsiot.greengrass_discovery.GGGroup(gg_group_id='greengrassV2-coreDevice-MyGreengrassCore', cores=[awsiot.greengrass_discovery.GGCore(thing_arn='arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore', connectivity=[awsiot.greengrass_discovery.ConnectivityInfo(id='203.0.113.0', host_address='203.0.113.0', metadata='', port=8883)])], certificate_authorities=['-----BEGIN CERTIFICATE-----\
MIICiT...EXAMPLE=
\ -----END CERTIFICATE-----\ '])]) Trying core arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore at host 203.0.113.0 port 8883 Connected! Published topic clients/MyClientDevice1/hello/world: {"message": "Hello World!", "sequence": 0} Publish received on topic clients/MyClientDevice1/hello/world b'{"message": "Hello World!", "sequence": 0}' Published topic clients/MyClientDevice1/hello/world: {"message": "Hello World!", "sequence": 1} Publish received on topic clients/MyClientDevice1/hello/world b'{"message": "Hello World!", "sequence": 1}'...
Published topic clients/MyClientDevice1/hello/world: {"message": "Hello World!", "sequence": 9} Publish received on topic clients/MyClientDevice1/hello/world b'{"message": "Hello World!", "sequence": 9}'Si l'application génère plutôt une erreur, reportez-vous à la section Résolution des problèmes liés à la découverte de Greengrass.
Vous pouvez également consulter les journaux Greengrass sur l'appareil principal pour vérifier si le périphérique client se connecte et envoie des messages avec succès. Pour de plus amples informations, veuillez consulter AWS IoT GreengrassJournaux de surveillance.
-
-
Vérifiez que le MQTT pont relaie les messages de l'appareil client vers AWS IoT Core. Vous pouvez utiliser le client de MQTT test de la AWS IoT Core console pour vous abonner à un filtre de MQTT rubrique. Procédez comme suit :
-
Accédez à la console AWS IoT
. -
Dans le menu de navigation de gauche, sous Test, choisissez le client de MQTT test.
-
Dans l'onglet S'abonner à un sujet, dans le champ Filtre de sujet, entrez pour vous abonner
clients/+/hello/world
aux messages de l'appareil client à partir de l'appareil principal. -
Choisissez Souscrire.
-
Exécutez à nouveau l'application de publication/d'abonnement sur l'appareil client.
Le client de MQTT test affiche les messages que vous envoyez depuis l'appareil client sur les sujets qui correspondent à ce filtre de sujets.
-
Étape 4 : développer un composant qui communique avec les appareils clients
Vous pouvez développer des composants Greengrass qui communiquent avec les appareils clients. Les composants utilisent la communication interprocessus (IPC) et l'interface de publication/d'abonnement locale pour communiquer sur un périphérique principal. Pour interagir avec les appareils clients, configurez le composant MQTT pont pour relayer les messages entre les appareils clients et l'interface de publication/d'abonnement locale.
Dans cette section, vous allez mettre à jour le composant MQTT pont pour relayer les messages des appareils clients vers l'interface de publication/d'abonnement locale. Ensuite, vous développez un composant qui s'abonne à ces messages et les imprime lorsqu'il les reçoit.
Pour développer un composant qui communique avec les appareils clients
-
Révisez le déploiement sur le périphérique principal et configurez le composant MQTT pont pour relayer les messages des appareils clients vers la publication/l'abonnement locaux. Procédez comme suit :
-
Dans le menu de navigation de gauche, choisissez Core devices.
-
Sur la page des appareils principaux, choisissez le périphérique principal que vous utilisez pour ce didacticiel.
-
Sur la page des détails de l'appareil principal, choisissez l'onglet Appareils clients.
-
Dans l'onglet Appareils clients, choisissez Configurer la découverte du cloud.
La page Configurer la découverte du périphérique principal s'ouvre. Sur cette page, vous pouvez modifier ou configurer les composants de l'appareil client déployés sur le périphérique principal.
-
À l'étape 3, pour aws.greengrass.clientdevices.mqtt.Bridgecomposant, choisissez Modifier la configuration.
-
Dans le mode Modifier la configuration du composant MQTT pont, configurez un mappage de rubriques qui relaie les MQTT messages des appareils clients vers l'interface de publication/d'abonnement locale. Procédez comme suit :
-
Sous Configuration, dans le bloc de code Configuration pour fusionner, entrez la configuration suivante. Cette configuration permet de relayer MQTT les messages sur des sujets correspondant au filtre de
clients/+/hello/world
sujets depuis les appareils clients vers le service AWS IoT Core cloud et le courtier de publication/d'abonnement Greengrass local.{ "mqttTopicMapping": { "HelloWorldIotCoreMapping": { "topic": "clients/+/hello/world", "source": "LocalMqtt", "target": "IotCore" }, "HelloWorldPubsubMapping": { "topic": "clients/+/hello/world", "source": "LocalMqtt", "target": "Pubsub" } } }
Pour plus d'informations, consultez la section Configuration des composants du MQTT pont.
-
Choisissez Confirmer.
-
-
Choisissez Vérifier et déployer pour passer en revue le déploiement que cette page crée pour vous.
-
Sur la page Révision, choisissez Déployer pour démarrer le déploiement sur le périphérique principal.
-
Pour vérifier que le déploiement est réussi, vérifiez l'état du déploiement et consultez les journaux sur le périphérique principal. Pour vérifier l'état du déploiement sur le périphérique principal, vous pouvez choisir Target dans l'aperçu du déploiement. Pour plus d’informations, consultez les ressources suivantes :
-
-
Développez et déployez un composant Greengrass qui s'abonne aux messages Hello World depuis les appareils clients. Procédez comme suit :
-
Créez des dossiers pour les recettes et les artefacts sur l'appareil principal.
mkdir recipes mkdir -p artifacts/com.example.clientdevices.MyHelloWorldSubscriber/1.0.0
Important
Vous devez utiliser le format suivant pour le chemin du dossier d'artefacts. Incluez le nom et la version du composant que vous spécifiez dans la recette.
artifacts/
componentName
/componentVersion
/ -
Utilisez un éditeur de texte pour créer une recette de composant avec le contenu suivant. Cette recette indique d'installer la Kit SDK des appareils AWS IoT version 2 pour Python et d'exécuter un script qui s'abonne au sujet et imprime des messages.
Par exemple, sur un système basé sur Linux, vous pouvez exécuter la commande suivante pour utiliser GNU nano pour créer le fichier.
nano recipes/com.example.clientdevices.MyHelloWorldSubscriber-1.0.0.json
Copiez la recette suivante dans le fichier.
{ "RecipeFormatVersion": "2020-01-25", "ComponentName": "com.example.clientdevices.MyHelloWorldSubscriber", "ComponentVersion": "1.0.0", "ComponentDescription": "A component that subscribes to Hello World messages from client devices.", "ComponentPublisher": "Amazon", "ComponentConfiguration": { "DefaultConfiguration": { "accessControl": { "aws.greengrass.ipc.pubsub": { "com.example.clientdevices.MyHelloWorldSubscriber:pubsub:1": { "policyDescription": "Allows access to subscribe to all topics.", "operations": [ "aws.greengrass#SubscribeToTopic" ], "resources": [ "*" ] } } } } }, "Manifests": [ { "Platform": { "os": "linux" }, "Lifecycle": { "install": "python3 -m pip install --user awsiotsdk", "Run": "python3 -u {artifacts:path}/hello_world_subscriber.py" } }, { "Platform": { "os": "windows" }, "Lifecycle": { "install": "py -3 -m pip install --user awsiotsdk", "Run": "py -3 -u {artifacts:path}/hello_world_subscriber.py" } } ] }
-
Utilisez un éditeur de texte pour créer un artefact de script Python
hello_world_subscriber.py
dont le nom est le suivant. Cette application utilise le IPC service de publication/d'abonnement pour s'abonner auclients/+/hello/world
sujet et imprimer les messages qu'elle reçoit.Par exemple, sur un système basé sur Linux, vous pouvez exécuter la commande suivante pour utiliser GNU nano pour créer le fichier.
nano artifacts/com.example.clientdevices.MyHelloWorldSubscriber/1.0.0/hello_world_subscriber.py
Copiez le code Python suivant dans le fichier.
import sys import time import traceback from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2 CLIENT_DEVICE_HELLO_WORLD_TOPIC = 'clients/+/hello/world' TIMEOUT = 10 def on_hello_world_message(event): try: message = str(event.binary_message.message, 'utf-8') print('Received new message: %s' % message) except: traceback.print_exc() try: ipc_client = GreengrassCoreIPCClientV2() # SubscribeToTopic returns a tuple with the response and the operation. _, operation = ipc_client.subscribe_to_topic( topic=CLIENT_DEVICE_HELLO_WORLD_TOPIC, on_stream_event=on_hello_world_message) print('Successfully subscribed to topic: %s' % CLIENT_DEVICE_HELLO_WORLD_TOPIC) # Keep the main thread alive, or the process will exit. try: while True: time.sleep(10) except InterruptedError: print('Subscribe interrupted.') operation.close() except Exception: print('Exception occurred when using IPC.', file=sys.stderr) traceback.print_exc() exit(1)
Note
Ce composant utilise le IPC client V2 dans le Kit SDK des appareils AWS IoT v2 pour que Python
communique avec le logiciel AWS IoT Greengrass Core. Par rapport au IPC client d'origine, le IPC client V2 réduit la quantité de code que vous devez écrire pour l'utiliser IPC dans des composants personnalisés. -
Utilisez le Greengrass CLI pour déployer le composant.
sudo
/bin/greengrass-cli deployment create \ --recipeDir recipes \ --artifactDir artifacts \ --merge "com.example.clientdevices.MyHelloWorldSubscriber=1.0.0"/greengrass/v2
-
-
Consultez les journaux des composants pour vérifier que le composant s'installe correctement et s'abonne à la rubrique.
sudo tail -f
/logs/com.example.clientdevices.MyHelloWorldSubscriber.log/greengrass/v2
Vous pouvez laisser le flux du journal ouvert pour vérifier que le périphérique principal reçoit les messages.
-
Sur l'appareil client, exécutez à nouveau l'exemple d'application de découverte Greengrass pour envoyer des messages au périphérique principal.
python3 basic_discovery.py \\ --thing_name
MyClientDevice1
\\ --topic 'clients/MyClientDevice1
/hello/world' \\ --message 'Hello World!' \\ --ca_file~/certs/AmazonRootCA1.pem
\\ --cert~/certs/device.pem.crt
\\ --key~/certs/private.pem.key
\\ --regionus-east-1
\\ --verbosity Warn -
Consultez à nouveau les journaux du composant pour vérifier que le composant reçoit et imprime les messages provenant de l'appareil client.
sudo tail -f
/logs/com.example.clientdevices.MyHelloWorldSubscriber.log/greengrass/v2
Étape 5 : développer un composant qui interagit avec les ombres du périphérique client
Vous pouvez développer des composants Greengrass qui interagissent avec les ombres de l'AWS IoT appareil client. Une ombre est un JSON document qui stocke les informations d'état actuelles ou souhaitées pour un AWS IoT objet, tel qu'un appareil client. Les composants personnalisés peuvent accéder aux ombres des appareils clients pour gérer leur état, même lorsque le périphérique client n'est pas connecté à AWS IoT. Chaque AWS IoT objet possède une ombre sans nom, et vous pouvez également créer plusieurs ombres nommées pour chaque élément.
Dans cette section, vous déployez le composant Shadow Manager pour gérer les ombres sur le périphérique principal. Vous mettez également à jour le composant MQTT pont pour relayer les messages instantanés entre les appareils clients et le composant Shadow Manager. Ensuite, vous développez un composant qui met à jour les ombres des appareils clients, et vous exécutez un exemple d'application sur les appareils clients qui répond aux mises à jour instantanées du composant. Ce composant représente une application de gestion intelligente de l'éclairage, dans laquelle le périphérique principal gère l'état des couleurs des lampes intelligentes qui s'y connectent en tant que périphériques clients.
Pour développer un composant qui interagit avec les ombres de l'appareil client
-
Révisez le déploiement sur le périphérique principal pour déployer le composant Shadow Manager et configurez le composant MQTT bridge pour relayer les messages instantanés entre les appareils clients et les services de publication/d'abonnement locaux, où le Shadow Manager communique. Procédez comme suit :
-
Dans le menu de navigation de gauche, choisissez Core devices.
-
Sur la page des appareils principaux, choisissez le périphérique principal que vous utilisez pour ce didacticiel.
-
Sur la page des détails de l'appareil principal, choisissez l'onglet Appareils clients.
-
Dans l'onglet Appareils clients, choisissez Configurer la découverte du cloud.
La page Configurer la découverte du périphérique principal s'ouvre. Sur cette page, vous pouvez modifier ou configurer les composants de l'appareil client déployés sur le périphérique principal.
-
À l'étape 3, pour aws.greengrass.clientdevices.mqtt.Bridgecomposant, choisissez Modifier la configuration.
-
Dans le mode Modifier la configuration pour le composant MQTT pont, configurez un mappage de sujets qui relaie les MQTT messages sur les sujets cachés entre les appareils clients et l'interface de publication/d'abonnement locale. Vous confirmez également que le déploiement spécifie une version de MQTT pont compatible. La prise en charge parallèle du périphérique client nécessite MQTT le bridge v2.2.0 ou une version ultérieure. Procédez comme suit :
-
Pour la version du composant, choisissez la version 2.2.0 ou ultérieure.
-
Sous Configuration, dans le bloc de code Configuration pour fusionner, entrez la configuration suivante. Cette configuration indique de relayer les MQTT messages sur des sujets fictifs.
{ "mqttTopicMapping": { "HelloWorldIotCoreMapping": { "topic": "clients/+/hello/world", "source": "LocalMqtt", "target": "IotCore" }, "HelloWorldPubsubMapping": { "topic": "clients/+/hello/world", "source": "LocalMqtt", "target": "Pubsub" }, "ShadowsLocalMqttToPubsub": { "topic": "$aws/things/+/shadow/#", "source": "LocalMqtt", "target": "Pubsub" }, "ShadowsPubsubToLocalMqtt": { "topic": "$aws/things/+/shadow/#", "source": "Pubsub", "target": "LocalMqtt" } } }
Pour plus d'informations, consultez la section Configuration des composants du MQTT pont.
-
Choisissez Confirmer.
-
-
À l'étape 3, sélectionnez aws.greengrass.ShadowManagercomposant pour le déployer.
-
Choisissez Vérifier et déployer pour passer en revue le déploiement que cette page crée pour vous.
-
Sur la page Révision, choisissez Déployer pour démarrer le déploiement sur le périphérique principal.
-
Pour vérifier que le déploiement est réussi, vérifiez l'état du déploiement et consultez les journaux sur le périphérique principal. Pour vérifier l'état du déploiement sur le périphérique principal, vous pouvez choisir Target dans l'aperçu du déploiement. Pour plus d’informations, consultez les ressources suivantes :
-
-
Développez et déployez un composant Greengrass qui gère les appareils clients Smart Light. Procédez comme suit :
-
Créez un dossier contenant les artefacts du composant sur le périphérique principal.
mkdir -p artifacts/com.example.clientdevices.MySmartLightManager/1.0.0
Important
Vous devez utiliser le format suivant pour le chemin du dossier d'artefacts. Incluez le nom et la version du composant que vous spécifiez dans la recette.
artifacts/
componentName
/componentVersion
/ -
Utilisez un éditeur de texte pour créer une recette de composant avec le contenu suivant. Cette recette indique d'installer la Kit SDK des appareils AWS IoT version 2 pour Python et d'exécuter un script qui interagit avec les ombres des appareils clients Smart Light pour gérer leurs couleurs.
Par exemple, sur un système basé sur Linux, vous pouvez exécuter la commande suivante pour utiliser GNU nano pour créer le fichier.
nano recipes/com.example.clientdevices.MySmartLightManager-1.0.0.json
Copiez la recette suivante dans le fichier.
{ "RecipeFormatVersion": "2020-01-25", "ComponentName": "com.example.clientdevices.MySmartLightManager", "ComponentVersion": "1.0.0", "ComponentDescription": "A component that interacts with smart light client devices.", "ComponentPublisher": "Amazon", "ComponentDependencies": { "aws.greengrass.Nucleus": { "VersionRequirement": "^2.6.0" }, "aws.greengrass.ShadowManager": { "VersionRequirement": "^2.2.0" }, "aws.greengrass.clientdevices.mqtt.Bridge": { "VersionRequirement": "^2.2.0" } }, "ComponentConfiguration": { "DefaultConfiguration": { "smartLightDeviceNames": [], "accessControl": { "aws.greengrass.ShadowManager": { "com.example.clientdevices.MySmartLightManager:shadow:1": { "policyDescription": "Allows access to client devices' unnamed shadows", "operations": [ "aws.greengrass#GetThingShadow", "aws.greengrass#UpdateThingShadow" ], "resources": [ "$aws/things/MyClientDevice*/shadow" ] } }, "aws.greengrass.ipc.pubsub": { "com.example.clientdevices.MySmartLightManager:pubsub:1": { "policyDescription": "Allows access to client devices' unnamed shadow updates", "operations": [ "aws.greengrass#SubscribeToTopic" ], "resources": [ "$aws/things/+/shadow/update/accepted" ] } } } } }, "Manifests": [ { "Platform": { "os": "linux" }, "Lifecycle": { "install": "python3 -m pip install --user awsiotsdk", "Run": "python3 -u {artifacts:path}/smart_light_manager.py" } }, { "Platform": { "os": "windows" }, "Lifecycle": { "install": "py -3 -m pip install --user awsiotsdk", "Run": "py -3 -u {artifacts:path}/smart_light_manager.py" } } ] }
-
Utilisez un éditeur de texte pour créer un artefact de script Python
smart_light_manager.py
dont le nom est le suivant. Cette application utilise le IPC service fantôme pour obtenir et mettre à jour les ombres du périphérique client et le IPC service de publication/d'abonnement local pour recevoir les mises à jour fictives signalées.Par exemple, sur un système basé sur Linux, vous pouvez exécuter la commande suivante pour utiliser GNU nano pour créer le fichier.
nano artifacts/com.example.clientdevices.MySmartLightManager/1.0.0/smart_light_manager.py
Copiez le code Python suivant dans le fichier.
import json import random import sys import time import traceback from uuid import uuid4 from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2 from awsiot.greengrasscoreipc.model import ResourceNotFoundError SHADOW_COLOR_PROPERTY = 'color' CONFIGURATION_CLIENT_DEVICE_NAMES = 'smartLightDeviceNames' COLORS = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'] SHADOW_UPDATE_TOPIC = '$aws/things/+/shadow/update/accepted' SET_COLOR_INTERVAL = 15 class SmartLightDevice(): def __init__(self, client_device_name: str, reported_color: str = None): self.name = client_device_name self.reported_color = reported_color self.desired_color = None class SmartLightDeviceManager(): def __init__(self, ipc_client: GreengrassCoreIPCClientV2): self.ipc_client = ipc_client self.devices = {} self.client_tokens = set() self.shadow_update_accepted_subscription_operation = None self.client_device_names_configuration_subscription_operation = None self.update_smart_light_device_list() def update_smart_light_device_list(self): # Update the device list from the component configuration. response = self.ipc_client.get_configuration( key_path=[CONFIGURATION_CLIENT_DEVICE_NAMES]) # Identify the difference between the configuration and the currently tracked devices. current_device_names = self.devices.keys() updated_device_names = response.value[CONFIGURATION_CLIENT_DEVICE_NAMES] added_device_names = set(updated_device_names) - set(current_device_names) removed_device_names = set(current_device_names) - set(updated_device_names) # Stop tracking any smart light devices that are no longer in the configuration. for name in removed_device_names: print('Removing %s from smart light device manager' % name) self.devices.pop(name) # Start tracking any new smart light devices that are in the configuration. for name in added_device_names: print('Adding %s to smart light device manager' % name) device = SmartLightDevice(name) device.reported_color = self.get_device_reported_color(device) self.devices[name] = device print('Current color for %s is %s' % (name, device.reported_color)) def get_device_reported_color(self, smart_light_device): try: response = self.ipc_client.get_thing_shadow( thing_name=smart_light_device.name, shadow_name='') shadow = json.loads(str(response.payload, 'utf-8')) if 'reported' in shadow['state']: return shadow['state']['reported'].get(SHADOW_COLOR_PROPERTY) return None except ResourceNotFoundError: return None def request_device_color_change(self, smart_light_device, color): # Generate and track a client token for the request. client_token = str(uuid4()) self.client_tokens.add(client_token) # Create a shadow payload, which must be a blob. payload_json = { 'state': { 'desired': { SHADOW_COLOR_PROPERTY: color } }, 'clientToken': client_token } payload = bytes(json.dumps(payload_json), 'utf-8') self.ipc_client.update_thing_shadow( thing_name=smart_light_device.name, shadow_name='', payload=payload) smart_light_device.desired_color = color def subscribe_to_shadow_update_accepted_events(self): if self.shadow_update_accepted_subscription_operation == None: # SubscribeToTopic returns a tuple with the response and the operation. _, self.shadow_update_accepted_subscription_operation = self.ipc_client.subscribe_to_topic( topic=SHADOW_UPDATE_TOPIC, on_stream_event=self.on_shadow_update_accepted_event) print('Successfully subscribed to shadow update accepted topic') def close_shadow_update_accepted_subscription(self): if self.shadow_update_accepted_subscription_operation is not None: self.shadow_update_accepted_subscription_operation.close() def on_shadow_update_accepted_event(self, event): try: message = str(event.binary_message.message, 'utf-8') accepted_payload = json.loads(message) # Check for reported states from smart light devices and ignore desired states from components. if 'reported' in accepted_payload['state']: # Process this update only if it uses a client token created by this component. client_token = accepted_payload.get('clientToken') if client_token is not None and client_token in self.client_tokens: self.client_tokens.remove(client_token) shadow_state = accepted_payload['state']['reported'] if SHADOW_COLOR_PROPERTY in shadow_state: reported_color = shadow_state[SHADOW_COLOR_PROPERTY] topic = event.binary_message.context.topic client_device_name = topic.split('/')[2] if client_device_name in self.devices: # Set the reported color for the smart light device. self.devices[client_device_name].reported_color = reported_color print( 'Received shadow update confirmation from client device: %s' % client_device_name) else: print("Shadow update doesn't specify color") except: traceback.print_exc() def subscribe_to_client_device_name_configuration_updates(self): if self.client_device_names_configuration_subscription_operation == None: # SubscribeToConfigurationUpdate returns a tuple with the response and the operation. _, self.client_device_names_configuration_subscription_operation = self.ipc_client.subscribe_to_configuration_update( key_path=[CONFIGURATION_CLIENT_DEVICE_NAMES], on_stream_event=self.on_client_device_names_configuration_update_event) print( 'Successfully subscribed to configuration updates for smart light device names') def close_client_device_names_configuration_subscription(self): if self.client_device_names_configuration_subscription_operation is not None: self.client_device_names_configuration_subscription_operation.close() def on_client_device_names_configuration_update_event(self, event): try: if CONFIGURATION_CLIENT_DEVICE_NAMES in event.configuration_update_event.key_path: print('Received configuration update for list of client devices') self.update_smart_light_device_list() except: traceback.print_exc() def choose_random_color(): return random.choice(COLORS) def main(): try: # Create an IPC client and a smart light device manager. ipc_client = GreengrassCoreIPCClientV2() smart_light_manager = SmartLightDeviceManager(ipc_client) smart_light_manager.subscribe_to_shadow_update_accepted_events() smart_light_manager.subscribe_to_client_device_name_configuration_updates() try: # Keep the main thread alive, or the process will exit. while True: # Set each smart light device to a random color at a regular interval. for device_name in smart_light_manager.devices: device = smart_light_manager.devices[device_name] desired_color = choose_random_color() print('Chose random color (%s) for %s' % (desired_color, device_name)) if desired_color == device.desired_color: print('Desired color for %s is already %s' % (device_name, desired_color)) elif desired_color == device.reported_color: print('Reported color for %s is already %s' % (device_name, desired_color)) else: smart_light_manager.request_device_color_change( device, desired_color) print('Requested color change for %s to %s' % (device_name, desired_color)) time.sleep(SET_COLOR_INTERVAL) except InterruptedError: print('Application interrupted') smart_light_manager.close_shadow_update_accepted_subscription() smart_light_manager.close_client_device_names_configuration_subscription() except Exception: print('Exception occurred', file=sys.stderr) traceback.print_exc() exit(1) if __name__ == '__main__': main()
Cette application Python effectue les opérations suivantes :
-
Lit la configuration du composant pour obtenir la liste des appareils clients Smart Light à gérer.
-
S'abonne aux notifications de mise à jour de configuration à l'aide de l'SubscribeToConfigurationUpdateIPCopération. Le logiciel AWS IoT Greengrass Core envoie des notifications chaque fois que la configuration du composant change. Lorsque le composant reçoit une notification de mise à jour de configuration, il met à jour la liste des appareils clients Smart Light qu'il gère.
-
Obtient l'ombre de chaque appareil client Smart Light pour obtenir son état de couleur initial.
-
Règle la couleur de chaque appareil client Smart Light sur une couleur aléatoire toutes les 15 secondes. Le composant met à jour l'ombre de l'objet de l'appareil client pour en changer la couleur. Cette opération envoie un événement Shadow Delta à l'appareil clientMQTT.
-
S'abonne à la mise à jour instantanée des messages acceptés sur l'interface de publication/d'abonnement locale à l'aide de l'opération. SubscribeToTopic IPC Ce composant reçoit ces messages pour suivre la couleur de chaque dispositif client Smart Light. Lorsqu'un appareil client Smart Light reçoit une mise à jour parallèle, il envoie un MQTT message pour confirmer qu'il a bien reçu la mise à jour. Le MQTT pont transmet ce message à l'interface de publication/d'abonnement locale.
-
-
Utilisez le Greengrass CLI pour déployer le composant. Lorsque vous déployez ce composant, vous spécifiez la liste des appareils clients
smartLightDeviceNames
dont il gère les ombres.MyClientDevice1
Remplacez-le par le nom de l'objet de l'appareil client.sudo
/bin/greengrass-cli deployment create \ --recipeDir recipes \ --artifactDir artifacts \ --merge "com.example.clientdevices.MySmartLightManager=1.0.0" \ --update-config '{ "com.example.clientdevices.MySmartLightManager": { "MERGE": { "smartLightDeviceNames": [ "/greengrass/v2
MyClientDevice1
" ] } } }'
-
-
Consultez les journaux des composants pour vérifier que le composant s'installe et s'exécute correctement.
sudo tail -f
/logs/com.example.clientdevices.MySmartLightManager.log/greengrass/v2
Le composant envoie des demandes pour changer la couleur du dispositif client Smart Light. Le gestionnaire d'ombres reçoit la demande et définit l'
desired
état de l'ombre. Cependant, le périphérique client Smart Light ne fonctionne pas encore, donc l'reported
état de l'ombre ne change pas. Les journaux du composant incluent les messages suivants.2022-07-07T03:49:24.908Z [INFO] (Copier) com.example.clientdevices.MySmartLightManager: stdout. Chose random color (blue) for MyClientDevice1. {scriptName=services.com.example.clientdevices.MySmartLightManager.lifecycle.Run, serviceName=com.example.clientdevices.MySmartLightManager, currentState=RUNNING} 2022-07-07T03:49:24.912Z [INFO] (Copier) com.example.clientdevices.MySmartLightManager: stdout. Requested color change for MyClientDevice1 to blue. {scriptName=services.com.example.clientdevices.MySmartLightManager.lifecycle.Run, serviceName=com.example.clientdevices.MySmartLightManager, currentState=RUNNING}
Vous pouvez laisser le flux du journal ouvert pour voir quand le composant imprime des messages.
-
Téléchargez et exécutez un exemple d'application qui utilise Greengrass Discovery et qui s'abonne aux mises à jour instantanées de l'appareil. Sur l'appareil client, effectuez les opérations suivantes :
-
Accédez au dossier d'échantillons dans la Kit SDK des appareils AWS IoT version 2 pour Python. Cet exemple d'application utilise un module d'analyse en ligne de commande situé dans le dossier des exemples.
cd aws-iot-device-sdk-python-v2/samples
-
Utilisez un éditeur de texte pour créer un script Python
basic_discovery_shadow.py
dont le nom est le suivant. Cette application utilise Greengrass Discovery et les ombres pour synchroniser une propriété entre le périphérique client et le périphérique principal.Par exemple, sur un système basé sur Linux, vous pouvez exécuter la commande suivante pour utiliser GNU nano pour créer le fichier.
nano basic_discovery_shadow.py
Copiez le code Python suivant dans le fichier.
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0. from awscrt import io from awscrt import mqtt from awsiot import iotshadow from awsiot.greengrass_discovery import DiscoveryClient from awsiot import mqtt_connection_builder from concurrent.futures import Future import sys import threading import traceback from uuid import uuid4 # Parse arguments import utils.command_line_utils; cmdUtils = utils.command_line_utils.CommandLineUtils("Basic Discovery - Greengrass discovery example with device shadows.") cmdUtils.add_common_mqtt_commands() cmdUtils.add_common_topic_message_commands() cmdUtils.add_common_logging_commands() cmdUtils.register_command("key", "<path>", "Path to your key in PEM format.", True, str) cmdUtils.register_command("cert", "<path>", "Path to your client certificate in PEM format.", True, str) cmdUtils.remove_command("endpoint") cmdUtils.register_command("thing_name", "<str>", "The name assigned to your IoT Thing", required=True) cmdUtils.register_command("region", "<str>", "The region to connect through.", required=True) cmdUtils.register_command("shadow_property", "<str>", "The name of the shadow property you want to change (optional, default='color'", default="color") # Needs to be called so the command utils parse the commands cmdUtils.get_args() # Using globals to simplify sample code is_sample_done = threading.Event() mqtt_connection = None shadow_thing_name = cmdUtils.get_command_required("thing_name") shadow_property = cmdUtils.get_command("shadow_property") SHADOW_VALUE_DEFAULT = "off" class LockedData: def __init__(self): self.lock = threading.Lock() self.shadow_value = None self.disconnect_called = False self.request_tokens = set() locked_data = LockedData() def on_connection_interupted(connection, error, **kwargs): print('connection interrupted with error {}'.format(error)) def on_connection_resumed(connection, return_code, session_present, **kwargs): print('connection resumed with return code {}, session present {}'.format(return_code, session_present)) # Try IoT endpoints until we find one that works def try_iot_endpoints(): for gg_group in discover_response.gg_groups: for gg_core in gg_group.cores: for connectivity_info in gg_core.connectivity: try: print('Trying core {} at host {} port {}'.format(gg_core.thing_arn, connectivity_info.host_address, connectivity_info.port)) mqtt_connection = mqtt_connection_builder.mtls_from_path( endpoint=connectivity_info.host_address, port=connectivity_info.port, cert_filepath=cmdUtils.get_command_required("cert"), pri_key_filepath=cmdUtils.get_command_required("key"), ca_bytes=gg_group.certificate_authorities[0].encode('utf-8'), on_connection_interrupted=on_connection_interupted, on_connection_resumed=on_connection_resumed, client_id=cmdUtils.get_command_required("thing_name"), clean_session=False, keep_alive_secs=30) connect_future = mqtt_connection.connect() connect_future.result() print('Connected!') return mqtt_connection except Exception as e: print('Connection failed with exception {}'.format(e)) continue exit('All connection attempts failed') # Function for gracefully quitting this sample def exit(msg_or_exception): if isinstance(msg_or_exception, Exception): print("Exiting sample due to exception.") traceback.print_exception(msg_or_exception.__class__, msg_or_exception, sys.exc_info()[2]) else: print("Exiting sample:", msg_or_exception) with locked_data.lock: if not locked_data.disconnect_called: print("Disconnecting...") locked_data.disconnect_called = True future = mqtt_connection.disconnect() future.add_done_callback(on_disconnected) def on_disconnected(disconnect_future): # type: (Future) -> None print("Disconnected.") # Signal that sample is finished is_sample_done.set() def on_get_shadow_accepted(response): # type: (iotshadow.GetShadowResponse) -> None try: with locked_data.lock: # check that this is a response to a request from this session try: locked_data.request_tokens.remove(response.client_token) except KeyError: return print("Finished getting initial shadow state.") if locked_data.shadow_value is not None: print(" Ignoring initial query because a delta event has already been received.") return if response.state: if response.state.delta: value = response.state.delta.get(shadow_property) if value: print(" Shadow contains delta value '{}'.".format(value)) change_shadow_value(value) return if response.state.reported: value = response.state.reported.get(shadow_property) if value: print(" Shadow contains reported value '{}'.".format(value)) set_local_value_due_to_initial_query(response.state.reported[shadow_property]) return print(" Shadow document lacks '{}' property. Setting defaults...".format(shadow_property)) change_shadow_value(SHADOW_VALUE_DEFAULT) return except Exception as e: exit(e) def on_get_shadow_rejected(error): # type: (iotshadow.ErrorResponse) -> None try: # check that this is a response to a request from this session with locked_data.lock: try: locked_data.request_tokens.remove(error.client_token) except KeyError: return if error.code == 404: print("Thing has no shadow document. Creating with defaults...") change_shadow_value(SHADOW_VALUE_DEFAULT) else: exit("Get request was rejected. code:{} message:'{}'".format( error.code, error.message)) except Exception as e: exit(e) def on_shadow_delta_updated(delta): # type: (iotshadow.ShadowDeltaUpdatedEvent) -> None try: print("Received shadow delta event.") if delta.state and (shadow_property in delta.state): value = delta.state[shadow_property] if value is None: print(" Delta reports that '{}' was deleted. Resetting defaults...".format(shadow_property)) change_shadow_value(SHADOW_VALUE_DEFAULT) return else: print(" Delta reports that desired value is '{}'. Changing local value...".format(value)) if (delta.client_token is not None): print (" ClientToken is: " + delta.client_token) change_shadow_value(value, delta.client_token) else: print(" Delta did not report a change in '{}'".format(shadow_property)) except Exception as e: exit(e) def on_publish_update_shadow(future): #type: (Future) -> None try: future.result() print("Update request published.") except Exception as e: print("Failed to publish update request.") exit(e) def on_update_shadow_accepted(response): # type: (iotshadow.UpdateShadowResponse) -> None try: # check that this is a response to a request from this session with locked_data.lock: try: locked_data.request_tokens.remove(response.client_token) except KeyError: return try: if response.state.reported != None: if shadow_property in response.state.reported: print("Finished updating reported shadow value to '{}'.".format(response.state.reported[shadow_property])) # type: ignore else: print ("Could not find shadow property with name: '{}'.".format(shadow_property)) # type: ignore else: print("Shadow states cleared.") # when the shadow states are cleared, reported and desired are set to None except: exit("Updated shadow is missing the target property") except Exception as e: exit(e) def on_update_shadow_rejected(error): # type: (iotshadow.ErrorResponse) -> None try: # check that this is a response to a request from this session with locked_data.lock: try: locked_data.request_tokens.remove(error.client_token) except KeyError: return exit("Update request was rejected. code:{} message:'{}'".format( error.code, error.message)) except Exception as e: exit(e) def set_local_value_due_to_initial_query(reported_value): with locked_data.lock: locked_data.shadow_value = reported_value def change_shadow_value(value, token=None): with locked_data.lock: if locked_data.shadow_value == value: print("Local value is already '{}'.".format(value)) return print("Changed local shadow value to '{}'.".format(value)) locked_data.shadow_value = value print("Updating reported shadow value to '{}'...".format(value)) reuse_token = token is not None # use a unique token so we can correlate this "request" message to # any "response" messages received on the /accepted and /rejected topics if not reuse_token: token = str(uuid4()) # if the value is "clear shadow" then send a UpdateShadowRequest with None # for both reported and desired to clear the shadow document completely. if value == "clear_shadow": tmp_state = iotshadow.ShadowState(reported=None, desired=None, reported_is_nullable=True, desired_is_nullable=True) request = iotshadow.UpdateShadowRequest( thing_name=shadow_thing_name, state=tmp_state, client_token=token, ) # Otherwise, send a normal update request else: # if the value is "none" then set it to a Python none object to # clear the individual shadow property if value == "none": value = None request = iotshadow.UpdateShadowRequest( thing_name=shadow_thing_name, state=iotshadow.ShadowState( reported={ shadow_property: value } ), client_token=token, ) future = shadow_client.publish_update_shadow(request, mqtt.QoS.AT_LEAST_ONCE) if not reuse_token: locked_data.request_tokens.add(token) future.add_done_callback(on_publish_update_shadow) if __name__ == '__main__': tls_options = io.TlsContextOptions.create_client_with_mtls_from_path(cmdUtils.get_command_required("cert"), cmdUtils.get_command_required("key")) if cmdUtils.get_command(cmdUtils.m_cmd_ca_file): tls_options.override_default_trust_store_from_path(None, cmdUtils.get_command(cmdUtils.m_cmd_ca_file)) tls_context = io.ClientTlsContext(tls_options) socket_options = io.SocketOptions() print('Performing greengrass discovery...') discovery_client = DiscoveryClient(io.ClientBootstrap.get_or_create_static_default(), socket_options, tls_context, cmdUtils.get_command_required("region")) resp_future = discovery_client.discover(cmdUtils.get_command_required("thing_name")) discover_response = resp_future.result() print(discover_response) if cmdUtils.get_command("print_discover_resp_only"): exit(0) mqtt_connection = try_iot_endpoints() shadow_client = iotshadow.IotShadowClient(mqtt_connection) try: # Subscribe to necessary topics. # Note that is **is** important to wait for "accepted/rejected" subscriptions # to succeed before publishing the corresponding "request". print("Subscribing to Update responses...") update_accepted_subscribed_future, _ = shadow_client.subscribe_to_update_shadow_accepted( request=iotshadow.UpdateShadowSubscriptionRequest(thing_name=shadow_thing_name), qos=mqtt.QoS.AT_LEAST_ONCE, callback=on_update_shadow_accepted) update_rejected_subscribed_future, _ = shadow_client.subscribe_to_update_shadow_rejected( request=iotshadow.UpdateShadowSubscriptionRequest(thing_name=shadow_thing_name), qos=mqtt.QoS.AT_LEAST_ONCE, callback=on_update_shadow_rejected) # Wait for subscriptions to succeed update_accepted_subscribed_future.result() update_rejected_subscribed_future.result() print("Subscribing to Get responses...") get_accepted_subscribed_future, _ = shadow_client.subscribe_to_get_shadow_accepted( request=iotshadow.GetShadowSubscriptionRequest(thing_name=shadow_thing_name), qos=mqtt.QoS.AT_LEAST_ONCE, callback=on_get_shadow_accepted) get_rejected_subscribed_future, _ = shadow_client.subscribe_to_get_shadow_rejected( request=iotshadow.GetShadowSubscriptionRequest(thing_name=shadow_thing_name), qos=mqtt.QoS.AT_LEAST_ONCE, callback=on_get_shadow_rejected) # Wait for subscriptions to succeed get_accepted_subscribed_future.result() get_rejected_subscribed_future.result() print("Subscribing to Delta events...") delta_subscribed_future, _ = shadow_client.subscribe_to_shadow_delta_updated_events( request=iotshadow.ShadowDeltaUpdatedSubscriptionRequest(thing_name=shadow_thing_name), qos=mqtt.QoS.AT_LEAST_ONCE, callback=on_shadow_delta_updated) # Wait for subscription to succeed delta_subscribed_future.result() # The rest of the sample runs asynchronously. # Issue request for shadow's current state. # The response will be received by the on_get_accepted() callback print("Requesting current shadow state...") with locked_data.lock: # use a unique token so we can correlate this "request" message to # any "response" messages received on the /accepted and /rejected topics token = str(uuid4()) publish_get_future = shadow_client.publish_get_shadow( request=iotshadow.GetShadowRequest(thing_name=shadow_thing_name, client_token=token), qos=mqtt.QoS.AT_LEAST_ONCE) locked_data.request_tokens.add(token) # Ensure that publish succeeds publish_get_future.result() except Exception as e: exit(e) # Wait for the sample to finish (user types 'quit', or an error occurs) is_sample_done.wait()
Cette application Python effectue les opérations suivantes :
-
Utilise Greengrass Discovery pour découvrir l'appareil principal et s'y connecter.
-
Demande le document fantôme à l'appareil principal pour obtenir l'état initial de la propriété.
-
S'abonne aux événements Shadow Delta, que le périphérique principal envoie lorsque la
desired
valeur de la propriété diffère de sareported
valeur. Lorsque l'application reçoit un événement Shadow Delta, elle modifie la valeur de la propriété et envoie une mise à jour au périphérique principal pour définir la nouvelle valeur comme sareported
valeur.
Cette application combine la découverte de Greengrass et des échantillons d'ombres de la Kit SDK des appareils AWS IoT v2.
-
-
Exécutez l'exemple d'application. Cette application attend des arguments qui spécifient le nom de l'objet du périphérique client, la propriété fantôme à utiliser et les certificats qui authentifient et sécurisent la connexion.
-
MyClientDevice1
Remplacez-le par le nom de l'objet de l'appareil client. -
~/certs/AmazonRootCA1.pem
Remplacez-le par le chemin d'accès au certificat racine de l'autorité de certification Amazon sur l'appareil client. -
Remplacez
~/certs/device.pem.crt
par le chemin d'accès au certificat de l'appareil sur l'appareil client. -
Remplacez
~/certs/private.pem.key
par le chemin d'accès au fichier de clé privée sur l'appareil client. -
Remplacez
us-east-1
par la AWS région dans laquelle fonctionnent votre appareil client et votre appareil principal.
python3 basic_discovery_shadow.py \ --thing_name
MyClientDevice1
\ --shadow_property color \ --ca_file~/certs/AmazonRootCA1.pem
\ --cert~/certs/device.pem.crt
\ --key~/certs/private.pem.key
\ --regionus-east-1
\ --verbosity WarnL'exemple d'application s'abonne aux sujets cachés et attend de recevoir les événements Shadow Delta de l'appareil principal. Si le résultat indique que l'application reçoit des événements Shadow Delta et y répond, le dispositif client peut interagir avec succès avec son ombre sur le dispositif principal.
Performing greengrass discovery... awsiot.greengrass_discovery.DiscoverResponse(gg_groups=[awsiot.greengrass_discovery.GGGroup(gg_group_id='greengrassV2-coreDevice-MyGreengrassCore', cores=[awsiot.greengrass_discovery.GGCore(thing_arn='arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore', connectivity=[awsiot.greengrass_discovery.ConnectivityInfo(id='203.0.113.0', host_address='203.0.113.0', metadata='', port=8883)])], certificate_authorities=['-----BEGIN CERTIFICATE-----\n
MIICiT...EXAMPLE=
\n-----END CERTIFICATE-----\n'])]) Trying core arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore at host 203.0.113.0 port 8883 Connected! Subscribing to Update responses... Subscribing to Get responses... Subscribing to Delta events... Requesting current shadow state... Received shadow delta event. Delta reports that desired value is 'purple'. Changing local value... ClientToken is: 3dce4d3f-e336-41ac-aa4f-7882725f0033 Changed local shadow value to 'purple'. Updating reported shadow value to 'purple'... Update request published.Si l'application génère plutôt une erreur, reportez-vous à la section Résolution des problèmes liés à la découverte de Greengrass.
Vous pouvez également consulter les journaux Greengrass sur l'appareil principal pour vérifier si le périphérique client se connecte et envoie des messages avec succès. Pour de plus amples informations, veuillez consulter AWS IoT GreengrassJournaux de surveillance.
-
-
-
Consultez à nouveau les journaux des composants pour vérifier que le composant reçoit des confirmations de mise à jour parallèle de la part du périphérique client Smart Light.
sudo tail -f
/logs/com.example.clientdevices.MySmartLightManager.log/greengrass/v2
Le composant enregistre des messages pour confirmer que le périphérique client Smart Light a changé de couleur.
2022-07-07T03:49:24.908Z [INFO] (Copier) com.example.clientdevices.MySmartLightManager: stdout. Chose random color (blue) for MyClientDevice1. {scriptName=services.com.example.clientdevices.MySmartLightManager.lifecycle.Run, serviceName=com.example.clientdevices.MySmartLightManager, currentState=RUNNING} 2022-07-07T03:49:24.912Z [INFO] (Copier) com.example.clientdevices.MySmartLightManager: stdout. Requested color change for MyClientDevice1 to blue. {scriptName=services.com.example.clientdevices.MySmartLightManager.lifecycle.Run, serviceName=com.example.clientdevices.MySmartLightManager, currentState=RUNNING} 2022-07-07T03:49:24.959Z [INFO] (Copier) com.example.clientdevices.MySmartLightManager: stdout. Received shadow update confirmation from client device: MyClientDevice1. {scriptName=services.com.example.clientdevices.MySmartLightManager.lifecycle.Run, serviceName=com.example.clientdevices.MySmartLightManager, currentState=RUNNING}
Note
L'ombre du dispositif client est synchronisée entre le dispositif principal et le dispositif client. Cependant, le périphérique principal ne synchronise pas l'ombre de l'appareil client avec AWS IoT Core. Vous pouvez synchroniser une ombre avec AWS IoT Core pour afficher ou modifier l'état de tous les appareils de votre parc, par exemple. Pour plus d'informations sur la façon de configurer le composant Shadow Manager avec lequel synchroniser les ombres AWS IoT Core, consultezSynchronisez les ombres de l'appareil local avec AWS IoT Core.
Vous avez terminé ce didacticiel. L'appareil client se connecte au périphérique principal, envoie MQTT des messages aux composants de Greengrass AWS IoT Core et reçoit des mises à jour instantanées du périphérique principal. Pour plus d'informations sur les sujets abordés dans ce didacticiel, consultez les rubriques suivantes :