Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Beginnen Sie mit dem End Device SDK
Gehen Sie wie folgt vor, um das Endgeräte-SDK auf einem Linux-Gerät auszuführen. Dieser Abschnitt führt Sie durch die Einrichtung der Umgebung, die Netzwerkkonfiguration, die Implementierung der Hardwarefunktionen und die Endpunktkonfiguration.
Wichtig
Die Demonstrationsanwendungen im examples Verzeichnis und ihre PAL-Implementierung (Platform Abstraction Layer) platform/posix dienen nur als Referenz. Verwenden Sie diese nicht in Produktionsumgebungen.
Überprüfen Sie jeden Schritt des folgenden Verfahrens sorgfältig, um eine ordnungsgemäße Geräteintegration mit verwalteten Integrationen sicherzustellen.
Integrieren Sie das Endgeräte-SDK
-
EC2 Amazon-Instanz einrichten
Melden Sie sich bei der an AWS-Managementkonsole und starten Sie eine EC2 Amazon-Instance mit einem Amazon Linux AMI. Weitere Informationen finden Sie unter Erste Schritte mit Amazon EC2 im Amazon Elastic Container Registry-Benutzerhandbuch.
-
Richten Sie die Build-Umgebung ein
Erstellen Sie den Code auf Amazon Linux 2023/x86_64 als Entwicklungshost. Installieren Sie die erforderlichen Build-Abhängigkeiten:
dnf install make gcc gcc-c++ cmake -
(Optional) Richten Sie das Netzwerk ein
Das Endgeräte-SDK wird am besten mit physischer Hardware verwendet. Wenn Sie Amazon verwenden EC2, folgen Sie diesem Schritt nicht.
Wenn Sie Amazon EC2 vor der Verwendung der Beispielanwendung nicht verwenden, initialisieren Sie das Netzwerk und verbinden Sie Ihr Gerät mit einem verfügbaren Wi-Fi-Netzwerk. Schließen Sie das Netzwerk-Setup ab, bevor Sie das Gerät bereitstellen:
/* Provisioning the device PKCS11 with claim credential. */ status = deviceCredentialProvisioning(); -
Konfigurieren Sie die Bereitstellungsparameter
Anmerkung
Folgen Sie Provisionee, um das Antragszertifikat und den privaten Schlüssel zu erhalten, bevor Sie fortfahren.
Ändern Sie die Konfigurationsdatei
example/project_name/device_config.shmit den folgenden Bereitstellungsparametern:Bereitstellungsparameter Makro-Parameter Description Wie erhalte ich diese Informationen IOTMI_ROOT_CA_PATHDie Root-CA-Zertifikatsdatei. Sie können diese Datei im Abschnitt Amazon Root CA-Zertifikat herunterladen im AWS IoT Core Entwicklerhandbuch herunterladen. IOTMI_CLAIM_CERTIFICATE_PATHDer Pfad zur Datei mit dem Anspruchszertifikat. Um das Anspruchszertifikat und den privaten Schlüssel zu erhalten, erstellen Sie mithilfe der CreateProvisioningProfileAPI ein Bereitstellungsprofil. Detaillierte Anweisungen finden Sie unter Erstellen Sie ein Provisioning-Profil. IOTMI_CLAIM_PRIVATE_KEY_PATHDer Pfad zur Datei mit dem privaten Claim-Schlüssel. IOTMI_MANAGEDINTEGRATIONS_ENDPOINTEndpunkt-URL für verwaltete Integrationen. Verwenden Sie die API, um den Endpunkt für verwaltete Integrationen abzurufen. RegisterCustomEndpoint Detaillierte Anweisungen finden Sie unter Registrieren Sie einen benutzerdefinierten Endpunkt. IOTMI_MANAGEDINTEGRATIONS_ENDPOINT_PORT Die Portnummer für den Endpunkt der verwalteten Integrationen Standardmäßig wird der Port 8883 für MQTT-Veröffentlichungs- und Abonnementvorgänge verwendet. Port 443 ist für die TLS-Erweiterung Application Layer Protocol Negotiation (ALPN) festgelegt, die Geräte verwenden. -
Erstellen Sie die Demo-Anwendungen und führen Sie sie aus
In diesem Abschnitt werden zwei Linux-Demoanwendungen vorgestellt: eine einfache Sicherheitskamera und ein Luftreiniger, die beide CMake als Build-System verwendet werden.
-
Einfache Sicherheitskamera-Anwendung
Führen Sie die folgenden Befehle aus, um die Anwendung zu erstellen und auszuführen:
>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_cameraIn dieser Demo werden einfache C-Funktionen für eine simulierte Kamera mit RTC Session Controller und Recording Clustern implementiert. Schließen Sie den unter beschriebenen Ablauf ab, bevor Sie ihn ausführen. Arbeitsablauf für den Provisionsnehmer
Beispielausgabe der Demo-Anwendung:
[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] -
Einfache Luftreiniger-Anwendung
Führen Sie die folgenden Befehle aus, um die Anwendung zu erstellen und auszuführen:
>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_demoIn dieser Demo werden grundlegende C-Funktionen für einen simulierten Luftreiniger mit 2 Endpunkten und den folgenden unterstützten Clustern implementiert:
Unterstützte Cluster für den Luftreiniger-Endpunkt Endpoint Cluster Endpunkt #1: Luftreiniger OnOff Steuerung des Lüfters Überwachung von HEPA-Filtern Überwachung von Aktivkohlefiltern
Endpunkt #2: Luftqualitätssensor Luftqualität Messung der Kohlendioxidkonzentration Messung der Formaldehydkonzentration Messung der Pm25-Konzentration Pm1-Konzentrationsmessung Messung der Gesamtkonzentration flüchtiger organischer Verbindungen Die Ausgabe ähnelt der der Kamera-Demo-Anwendung, es werden jedoch verschiedene Cluster unterstützt.
-
-
Nächste Schritte:
Das Managed Integrations End Device SDK und die Demoanwendungen werden jetzt auf Ihren EC2 Amazon-Instances ausgeführt. Auf diese Weise können Sie Ihre Anwendungen auf Ihrer eigenen physischen Hardware entwickeln und testen. Mit diesem Setup können Sie den Managed Integrations Service nutzen, um Ihre AWS IoT Geräte zu steuern.
-
Entwickeln Sie Hardware-Callback-Funktionen
Bevor Sie die Hardware-Callback-Funktionen implementieren, sollten Sie sich mit der Funktionsweise der API vertraut machen. In diesem Beispiel werden der On/Off Cluster und das OnOff Attribut verwendet, um eine Gerätefunktion zu steuern. Einzelheiten zur API finden Sie unterC-Funktion auf niedriger Ebene 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; } -
Richten Sie Endpunkte ein und binden Sie Hardware-Callback-Funktionen ein
Nachdem Sie die Funktionen implementiert haben, erstellen Sie Endpunkte und registrieren Sie Ihre Callbacks. Führen Sie die folgenden Schritte aus:
-
Erstellen Sie einen Geräteagenten.
-
Erstellen Sie einen Geräteagenten,
iotmiDev_Agent_new()bevor Sie andere SDK-Funktionen aufrufen. -
Ihre Konfiguration muss mindestens die Parameter thingId und clientId enthalten.
-
Verwenden Sie die
iotmiDev_Agent_initDefaultConfig()Funktion, um angemessene Standardwerte für Parameter wie Warteschlangengrößen und maximale Endpunkte festzulegen. -
Wenn Sie die Ressourcen nicht mehr verwenden, geben Sie sie mit der
iotmiDev_Agent_free()Funktion wieder frei. Dies verhindert Speicherlecks und gewährleistet eine ordnungsgemäße Ressourcenverwaltung in Ihrer Anwendung.
-
-
Füllen Sie die Callback-Funktionszeiger für jede Clusterstruktur aus, die Sie unterstützen möchten.
-
Richten Sie Endpunkte ein und registrieren Sie Ihre unterstützten Cluster.
Erstellen Sie Endgeräte mit
iotmiDev_Agent_addEndpoint(), was Folgendes erfordert:Eine eindeutige Endpunkt-ID.
Ein beschreibender Endpunktname
Ein oder mehrere Gerätetypen, die den AWS Datenmodelldefinitionen entsprechen.
Nachdem Sie Endpoints erstellt haben, registrieren Sie Cluster mithilfe der entsprechenden clusterspezifischen Registrierungsfunktionen.
Jede Clusterregistrierung erfordert Rückruffunktionen für Attribute und Befehle. Das System übergibt Ihren Benutzerkontextzeiger an Callbacks, um den Status zwischen Aufrufen aufrechtzuerhalten.
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); } -
-
Verwenden Sie den Job-Handler, um das Job-Dokument abzurufen
-
Initiieren Sie einen Anruf an Ihre OTA-Anwendung:
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; } -
Rufen Sie
iotmi_JobsHandler_startauf, um den Job-Handler zu initialisieren. -
Rufen Sie
iotmi_JobsHandler_getJobDocumentauf, um das Jobdokument aus verwalteten Integrationen abzurufen. -
Wenn das Jobs-Dokument erfolgreich abgerufen wurde, schreiben Sie Ihre benutzerdefinierte OTA-Operation in die
processOTAFunktion und geben Sie einenJobSucceededStatus zurück.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." ) ); }
-
-