Commencez avec le SDK pour appareils finaux - Intégrations gérées pour AWS IoT Device Management

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.

Commencez avec le SDK pour appareils finaux

Procédez comme suit pour exécuter le SDK du terminal sur un appareil Linux. Cette section vous guide tout au long de la configuration de l'environnement, de la configuration du réseau, de la mise en œuvre des fonctions matérielles et de la configuration des terminaux.

Important

Les applications de démonstration figurant dans le examples répertoire et leur implémentation de la couche d'abstraction de plate-forme (PAL) ne platform/posix sont fournies qu'à titre de référence. Ne les utilisez pas dans des environnements de production.

Passez en revue attentivement chaque étape de la procédure suivante afin de garantir une intégration correcte des appareils avec les intégrations gérées.

Intégrer le SDK pour appareils finaux
  1. Configuration de l' EC2 instance Amazon

    Connectez-vous à l' EC2 instance Amazon AWS Management Console et lancez-la à l'aide d'une AMI Amazon Linux. Consultez Commencer avec Amazon EC2 dans le guide de l'utilisateur d'Amazon Elastic Container Registry.

  2. Configuration de l'environnement de construction

    Créez le code sur Amazon Linux 2023/x86_64 en tant qu'hôte de développement. Installez les dépendances de build nécessaires :

    dnf install make gcc gcc-c++ cmake
  3. (Facultatif) Configurer le réseau

    Il est préférable d'utiliser le SDK de l'appareil final avec du matériel physique. Si vous utilisez Amazon EC2, ne suivez pas cette étape.

    Si vous n'utilisiez pas Amazon EC2 avant d'utiliser l'exemple d'application, initialisez le réseau et connectez votre appareil à un réseau Wi-Fi disponible. Terminez la configuration du réseau avant le provisionnement des appareils :

    /* Provisioning the device PKCS11 with claim credential. */ status = deviceCredentialProvisioning();
  4. Configuration des paramètres de provisionnement
    Note

    Suivez Provisionee pour obtenir le certificat de réclamation et la clé privée avant de poursuivre.

    Modifiez le fichier de configuration example/project_name/device_config.sh avec les paramètres de provisionnement suivants :

    Paramètres de provisionnement
    Paramètres des macros Description Comment obtenir ces informations
    IOTMI_ROOT_CA_PATH Le fichier de certificat racine de l'autorité de certification. Vous pouvez télécharger ce fichier depuis la section Télécharger le certificat Amazon Root CA du guide du AWS IoT Core développeur.
    IOTMI_CLAIM_CERTIFICATE_PATH Le chemin d'accès au fichier de certificat de réclamation. Pour obtenir le certificat de réclamation et la clé privée, créez un profil de provisionnement à l'aide de l'CreateProvisioningProfileAPI. Pour obtenir des instructions, veuillez consulter Création d'un profil de provisionnement.
    IOTMI_CLAIM_PRIVATE_KEY_PATH Le chemin d'accès au fichier de clé privée réclamé.
    IOTMI_MANAGEDINTEGRATIONS_ENDPOINT URL du point de terminaison pour les intégrations gérées. Pour obtenir le point de terminaison des intégrations gérées, utilisez l'RegisterCustomEndpointAPI. Pour obtenir des instructions, veuillez consulter Enregistrer un point de terminaison personnalisé.
    IOTMI_MANAGEDINTEGRATIONS_ENDPOINT_PORT Le numéro de port du point de terminaison des intégrations gérées Par défaut, le port 8883 est utilisé pour les opérations de publication et d'abonnement MQTT. Le port 443 est défini pour l'extension TLS ALPN (Application Layer Protocol Negotiation) utilisée par les appareils.
  5. Créez et exécutez les applications de démonstration

    Cette section présente deux applications de démonstration Linux : une simple caméra de sécurité et un purificateur d'air, tous deux CMake utilisés comme système de construction.

    1. Application de caméra de sécurité simple

      Pour créer et exécuter l'application, exécutez les commandes suivantes :

      >cd <path-to-code-drop> # If you didn't generate cluster code earlier >(cd codegen && poetry run poetry install --no-root && ./gen-data-model-api.sh) >mkdir build >cd build >cmake .. >cmake —build . >./examples/iotmi_device_sample_camera/iotmi_device_sample_camera

      Cette démonstration implémente des fonctions C de bas niveau pour une caméra simulée avec un contrôleur de session RTC et des clusters d'enregistrement. Complétez le flux mentionné dans Flux de travail Provisionee avant de lancer.

      Exemple de sortie de l'application de démonstration :

      [2406832727][MAIN][INFO] ======= Device initialization and WIFI provisioning ======= [2406832728][MAIN][INFO] fleetProvisioningTemplateName: XXXXXXXXXXX [2406832728][MAIN][INFO] managedintegrationsEndpoint: XXXXXXXXX.account-prefix-ats.iot.region.amazonaws.com [2406832728][MAIN][INFO] pDeviceSerialNumber: XXXXXXXXXXXX [2406832728][MAIN][INFO] universalProductCode: XXXXXXXXXXXX [2406832728][MAIN][INFO] rootCertificatePath: XXXXXXXXX [2406832728][MAIN][INFO] pClaimCertificatePath: XXXXXXXX [2406832728][MAIN][INFO] pClaimKeyPath: XXXXXXXXXXXXXXXXX [2406832728][MAIN][INFO] deviceInfo.serialNumber XXXXXXXXXXXX [2406832728][MAIN][INFO] deviceInfo.universalProductCode XXXXXXXXXXXXXXX [2406832728][PKCS11][INFO] PKCS #11 successfully initialized. [2406832728][MAIN][INFO] ============= Start certificate provisioning ============= [2406832728][PKCS11][INFO] ======== Loading Root CA and claim credentials through PKCS#11 interface ======== [2406832728][PKCS11][INFO] Writing certificate into label "Root Cert". [2406832728][PKCS11][INFO] Creating a 0x1 type object. [2406832728][PKCS11][INFO] Writing certificate into label "Claim Cert". [2406832728][PKCS11][INFO] Creating a 0x1 type object. [2406832728][PKCS11][INFO] Creating a 0x3 type object. [2406832728][MAIN][INFO] ======== Fleet-provisioning-by-Claim ======== [2025-01-02 01:43:11.404995144][iotmi_device_sdkLog][INFO] [2406832728][MQTT_AGENT][INFO] [2025-01-02 01:43:11.405106991][iotmi_device_sdkLog][INFO] Establishing a TLS session to XXXXXXXXXXXXXXX.account-prefix-ats.iot.region.amazonaws.com [2025-01-02 01:43:11.405119166][iotmi_device_sdkLog][INFO] [2025-01-02 01:43:11.844812513][iotmi_device_sdkLog][INFO] [2406833168][MQTT_AGENT][INFO] [2025-01-02 01:43:11.844842576][iotmi_device_sdkLog][INFO] TLS session connected [2025-01-02 01:43:11.844852105][iotmi_device_sdkLog][INFO] [2025-01-02 01:43:12.296421687][iotmi_device_sdkLog][INFO] [2406833620][MQTT_AGENT][INFO] [2025-01-02 01:43:12.296449663][iotmi_device_sdkLog][INFO] Session present: 0. [2025-01-02 01:43:12.296458997][iotmi_device_sdkLog][INFO] [2025-01-02 01:43:12.296467793][iotmi_device_sdkLog][INFO] [2406833620][MQTT_AGENT][INFO] [2025-01-02 01:43:12.296476275][iotmi_device_sdkLog][INFO] MQTT connect with clean session. [2025-01-02 01:43:12.296484350][iotmi_device_sdkLog][INFO] [2025-01-02 01:43:13.171056119][iotmi_device_sdkLog][INFO] [2406834494][FLEET_PROVISIONING][INFO] [2025-01-02 01:43:13.171082442][iotmi_device_sdkLog][INFO] Received accepted response from Fleet Provisioning CreateKeysAndCertificate API. [2025-01-02 01:43:13.171092740][iotmi_device_sdkLog][INFO] [2025-01-02 01:43:13.171122834][iotmi_device_sdkLog][INFO] [2406834494][FLEET_PROVISIONING][INFO] [2025-01-02 01:43:13.171132400][iotmi_device_sdkLog][INFO] Received privatekey and certificate with Id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX [2025-01-02 01:43:13.171141107][iotmi_device_sdkLog][INFO] [2406834494][PKCS11][INFO] Creating a 0x3 type object. [2406834494][PKCS11][INFO] Writing certificate into label "Device Cert". [2406834494][PKCS11][INFO] Creating a 0x1 type object. [2025-01-02 01:43:18.584615126][iotmi_device_sdkLog][INFO] [2406839908][FLEET_PROVISIONING][INFO] [2025-01-02 01:43:18.584662031][iotmi_device_sdkLog][INFO] Received accepted response from Fleet Provisioning RegisterThing API. [2025-01-02 01:43:18.584671912][iotmi_device_sdkLog][INFO] [2025-01-02 01:43:19.100030237][iotmi_device_sdkLog][INFO] [2406840423][FLEET_PROVISIONING][INFO] [2025-01-02 01:43:19.100061720][iotmi_device_sdkLog][INFO] Fleet-provisioning iteration 1 is successful. [2025-01-02 01:43:19.100072401][iotmi_device_sdkLog][INFO] [2406840423][MQTT][ERROR] MQTT Connection Disconnected Successfully [2025-01-02 01:43:19.216938181][iotmi_device_sdkLog][INFO] [2406840540][MQTT_AGENT][INFO] [2025-01-02 01:43:19.216963713][iotmi_device_sdkLog][INFO] MQTT agent thread leaves thread loop for iotmiDev_MQTTAgentStop. [2025-01-02 01:43:19.216973740][iotmi_device_sdkLog][INFO] [2406840540][MAIN][INFO] iotmiDev_MQTTAgentStop is called to break thread loop function. [2406840540][MAIN][INFO] Successfully provision the device. [2406840540][MAIN][INFO] Client ID : XXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXX [2406840540][MAIN][INFO] Managed thing ID : XXXXXXXXXXXXXXXXXXXXXXX [2406840540][MAIN][INFO] ======================== application loop ================= [2025-01-02 01:43:19.217094828][iotmi_device_sdkLog][INFO] [2406840540][MQTT_AGENT][INFO] [2025-01-02 01:43:19.217124600][iotmi_device_sdkLog][INFO] Establishing a TLS session to XXXXXXXXX.account-prefix-ats.iot.region.amazonaws.com:8883 [2025-01-02 01:43:19.217138724][iotmi_device_sdkLog][INFO] [2406840540][Cluster OnOff][INFO] exampleOnOffInitCluster() for endpoint#1 [2406840540][MAIN][INFO] Press Ctrl+C when you finish testing... [2406840540][Cluster ActivatedCarbonFilterMonitoring][INFO] exampleActivatedCarbonFilterMonitoringInitCluster() for endpoint#1 [2406840540][Cluster AirQuality][INFO] exampleAirQualityInitCluster() for endpoint#1 [2406840540][Cluster CarbonDioxideConcentrationMeasurement][INFO] exampleCarbonDioxideConcentrationMeasurementInitCluster() for endpoint#1 [2406840540][Cluster FanControl][INFO] exampleFanControlInitCluster() for endpoint#1 [2406840540][Cluster HepaFilterMonitoring][INFO] exampleHepaFilterMonitoringInitCluster() for endpoint#1 [2406840540][Cluster Pm1ConcentrationMeasurement][INFO] examplePm1ConcentrationMeasurementInitCluster() for endpoint#1 [2406840540][Cluster Pm25ConcentrationMeasurement][INFO] examplePm25ConcentrationMeasurementInitCluster() for endpoint#1 [2406840540][Cluster TotalVolatileOrganicCompoundsConcentrationMeasurement][INFO] exampleTotalVolatileOrganicCompoundsConcentrationMeasurementInitCluster() for endpoint#1 [2025-01-02 01:43:19.648185488][iotmi_device_sdkLog][INFO] [2406840971][MQTT_AGENT][INFO] [2025-01-02 01:43:19.648211988][iotmi_device_sdkLog][INFO] TLS session connected [2025-01-02 01:43:19.648225583][iotmi_device_sdkLog][INFO] [2025-01-02 01:43:19.938281231][iotmi_device_sdkLog][INFO] [2406841261][MQTT_AGENT][INFO] [2025-01-02 01:43:19.938304799][iotmi_device_sdkLog][INFO] Session present: 0. [2025-01-02 01:43:19.938317404][iotmi_device_sdkLog][INFO]
    2. Application simple du purificateur d'air

      Pour créer et exécuter l'application, exécutez les commandes suivantes :

      >cd <path-to-code-drop> # If you didn't generate cluster code earlier >(cd codegen && poetry run poetry install --no-root && ./gen-data-model-api.sh) >mkdir build >cd build >cmake .. >cmake --build . >./examples/iotmi_device_dm_air_purifier/iotmi_device_dm_air_purifier_demo

      Cette démonstration implémente des fonctions C de bas niveau pour un purificateur d'air simulé avec 2 terminaux et les clusters pris en charge suivants :

      Clusters pris en charge pour le terminal du purificateur d'air
      Endpoint Clusters
      Point final #1 : Purificateur d'air OnOff
      Contrôle du ventilateur
      Surveillance des filtres HEPA

      Surveillance du filtre à charbon actif

      Point final #2 : Capteur de qualité de l'air Qualité de l'air
      Mesure de la concentration de dioxyde de carbone
      Mesure de la concentration de formaldéhyde
      Mesure de la concentration de Pm25
      Mesure de la concentration de Pm1
      Mesure de la concentration totale de composés organiques volatils

      Le résultat est similaire à celui de l'application de démonstration de caméra, avec différents clusters pris en charge.

  6. Étapes suivantes :

    Le SDK pour appareils finaux et les applications de démonstration des intégrations gérées s'exécutent désormais sur vos instances Amazon EC2 . Cela vous permet de développer et de tester vos applications sur votre propre matériel physique. Avec cette configuration, vous pouvez tirer parti du service d'intégrations gérées pour contrôler vos AWS IoT appareils.

    1. Développer des fonctions de rappel matérielles

      Avant d'implémenter les fonctions de rappel matériel, comprenez le fonctionnement de l'API. Cet exemple utilise le On/Off cluster et OnOff l'attribut pour contrôler la fonction d'un appareil. Pour plus de détails sur l'API, consultezFonction C de faible niveau APIs.

      struct DeviceState { struct iotmiDev_Agent *agent; struct iotmiDev_Endpoint *endpointLight; /* This simulates the HW state of OnOff */ bool hwState; }; /* This implementation for OnOff getter just reads the state from the DeviceState */ iotmiDev_DMStatus exampleGetOnOff(bool *value, void *user) { struct DeviceState *state = (struct DeviceState *)(user); *value = state->hwState; return iotmiDev_DMStatusOk; }
    2. Configuration des points de terminaison et des fonctions de rappel du matériel

      Après avoir implémenté les fonctions, créez des points de terminaison et enregistrez vos rappels. Réalisez les tâches suivantes :

      1. Créez un agent de périphérique.

        1. Créez un agent de périphérique iotmiDev_Agent_new() avant d'appeler toute autre fonction du SDK.

        2. Au minimum, votre configuration doit inclure les paramètres ThingID et ClientID.

        3. Utilisez cette iotmiDev_Agent_initDefaultConfig() fonction pour définir des valeurs par défaut raisonnables pour des paramètres tels que la taille des files d'attente et le nombre maximal de points de terminaison.

        4. Lorsque vous avez fini d'utiliser les ressources, libérez-les avec la iotmiDev_Agent_free() fonction. Cela permet d'éviter les fuites de mémoire et de garantir une gestion appropriée des ressources de votre application.

      2. Remplissez les pointeurs de la fonction de rappel pour chaque structure de cluster que vous souhaitez prendre en charge.

      3. Configurez les points de terminaison et enregistrez les clusters pris en charge.

        Créez des points de terminaison aveciotmiDev_Agent_addEndpoint(), ce qui nécessite :

        1. Un identifiant de point de terminaison unique.

        2. Un nom de point de terminaison descriptif

        3. Un ou plusieurs types de périphériques conformes aux définitions AWS des modèles de données.

        4. Après avoir créé les points de terminaison, enregistrez les clusters à l'aide des fonctions d'enregistrement spécifiques aux clusters appropriées.

        5. Chaque enregistrement de cluster nécessite des fonctions de rappel pour les attributs et les commandes. Le système transmet votre pointeur de contexte utilisateur aux rappels pour maintenir l'état entre les appels.

      struct DeviceState { struct iotmiDev_Agent * agent; struct iotmiDev_Endpoint *endpoint1; /* OnOff cluster states*/ bool hwState; }; /* This implementation for OnOff getter just reads the state from the DeviceState */ iotmiDev_DMStatus exampleGetOnOff( bool * value, void * user ) { struct DeviceState * state = ( struct DeviceState * ) ( user ); *value = state->hwState; printf( "%s(): state->hwState: %d\n", __func__, state->hwState ); return iotmiDev_DMStatusOk; } iotmiDev_DMStatus exampleGetOnTime( uint16_t * value, void * user ) { *value = 0; printf( "%s(): OnTime is %u\n", __func__, *value ); return iotmiDev_DMStatusOk; } iotmiDev_DMStatus exampleGetStartUpOnOff( iotmiDev_OnOff_StartUpOnOffEnum * value, void * user ) { *value = iotmiDev_OnOff_StartUpOnOffEnum_Off; printf( "%s(): StartUpOnOff is %d\n", __func__, *value ); return iotmiDev_DMStatusOk; } void setupOnOff( struct DeviceState *state ) { struct iotmiDev_clusterOnOff clusterOnOff = { .getOnOff = exampleGetOnOff, .getOnTime = exampleGetOnTime, .getStartUpOnOff = exampleGetStartUpOnOff, }; iotmiDev_OnOffRegisterCluster( state->endpoint1, &clusterOnOff, ( void * ) state); } /* Here is the sample setting up an endpoint 1 with OnOff cluster. Note all error handling code is omitted. */ void setupAgent(struct DeviceState *state) { struct iotmiDev_Agent_Config config = { .thingId = IOTMI_DEVICE_MANAGED_THING_ID, .clientId = IOTMI_DEVICE_CLIENT_ID, }; iotmiDev_Agent_InitDefaultConfig(&config); /* Create a device agent before calling other SDK APIs */ state->agent = iotmiDev_Agent_new(&config); /* Create endpoint#1 */ state->endpoint1 = iotmiDev_Agent_addEndpoint( state->agent, 1, "Data Model Handler Test Device", (const char*[]){ "Camera" }, 1 ); setupOnOff(state); }
    3. Utilisez le gestionnaire de tâches pour obtenir le document de tâche
      1. Lancez un appel vers votre application OTA :

        static iotmi_JobCurrentStatus_t processOTA( iotmi_JobData_t * pJobData ) { iotmi_JobCurrentStatus_t jobCurrentStatus = JobSucceeded; ... // This function should create OTA tasks jobCurrentStatus = YOUR_OTA_FUNCTION(iotmi_JobData_t * pJobData); ... return jobCurrentStatus; }
      2. Appelez iotmi_JobsHandler_start pour initialiser le gestionnaire de tâches.

      3. Appelez iotmi_JobsHandler_getJobDocument pour récupérer le document de travail à partir des intégrations gérées.

      4. Lorsque le document de tâches est obtenu avec succès, écrivez votre opération OTA personnalisée dans la processOTA fonction et renvoyez un JobSucceeded statut.

        static void prvJobsHandlerThread( void * pParam ) { JobsHandlerStatus_t status = JobsHandlerSuccess; iotmi_JobData_t jobDocument; iotmiDev_DeviceRecord_t * pThreadParams = ( iotmiDev_DeviceRecord_t * ) pParam; iotmi_JobsHandler_config_t config = { .pManagedThingID = pThreadParams->pManagedThingID, .jobsQueueSize = 10 }; status = iotmi_JobsHandler_start( &config ); if( status != JobsHandlerSuccess ) { LogError( ( "Failed to start Jobs Handler." ) ); return; } while( !bExit ) { status = iotmi_JobsHandler_getJobDocument( &jobDocument, 30000 ); switch( status ) { case JobsHandlerSuccess: { LogInfo( ( "Job document received." ) ); LogInfo( ( "Job ID: %.*s", ( int ) jobDocument.jobIdLength, jobDocument.pJobId ) ); LogInfo( ( "Job document: %.*s", ( int ) jobDocument.jobDocumentLength, jobDocument.pJobDocument ) ); /* Process the job document */ iotmi_JobCurrentStatus_t jobStatus = processOTA( &jobDocument ); iotmi_JobsHandler_updateJobStatus( jobDocument.pJobId, jobDocument.jobIdLength, jobStatus, NULL, 0 ); iotmiJobsHandler_destroyJobDocument(&jobDocument); break; } case JobsHandlerTimeout: { LogInfo( ( "No job document available. Polling for job document." ) ); iotmi_JobsHandler_pollJobDocument(); break; } default: { LogError( ( "Failed to get job document." ) ); break; } } } while( iotmi_JobsHandler_getJobDocument( &jobDocument, 0 ) == JobsHandlerSuccess ) { /* Before stopping the Jobs Handler, process all the remaining jobs. */ LogInfo( ( "Job document received before stopping." ) ); LogInfo( ( "Job ID: %.*s", ( int ) jobDocument.jobIdLength, jobDocument.pJobId ) ); LogInfo( ( "Job document: %.*s", ( int ) jobDocument.jobDocumentLength, jobDocument.pJobDocument ) ); storeJobs( &jobDocument ); iotmiJobsHandler_destroyJobDocument(&jobDocument); } iotmi_JobsHandler_stop(); LogInfo( ( "Job handler thread end." ) ); }