Planen und Übertragen von Aufträgen (Python)

Verwenden Sie Azure IoT Hub zum Planen und Nachverfolgen von Aufträgen, die Millionen von Geräte aktualisieren. Verwenden Sie Aufträge zum:

  • Aktualisieren gewünschter Eigenschaften
  • Aktualisieren von Tags
  • Aufrufen direkter Methoden

Vom Konzept her umschließt ein Auftrag eine dieser Aktionen und verfolgt den Ausführungsfortschritt für eine Gruppe von Geräten nach, die anhand einer Gerätezwillingsabfrage definiert wird. Mit einem Auftrag kann eine Back-End-App beispielsweise eine Neustartmethode auf 10.000 Geräten aufrufen – angegeben durch eine Gerätezwillingsabfrage und geplant für einen späteren Zeitpunkt. Diese Anwendung kann dann den Fortschritt nachverfolgen, da jedes dieser Geräte die Neustartmethode empfängt und ausführt.

Weitere Informationen zu diesen Funktionen finden Sie in den folgenden Artikeln:

Hinweis

Die in diesem Artikel beschriebenen Features stehen nur im Standard-Tarif von IoT Hub zur Verfügung. Weitere Informationen zu den IoT Hub-Tarifen „Basic“ und „Standard/Free“ finden Sie unter Wählen des richtigen IoT Hub-Tarifs für Ihre Lösung.

In diesem Artikel wird gezeigt, wie Sie zwei Python-Apps erstellen:

  • Eine simulierte Python-Geräte-App, simDevice.py, die eine direkte Methode namens lockDoor implementiert, die von der Back-End-App aufgerufen werden kann.

  • Eine Python-Konsolen-App, scheduleJobService.py, die zwei Aufträge erstellt. Ein Auftrag ruft die direkte Methode lockDoor auf, und ein anderer Auftrag sendet die gewünschten Eigenschaftenupdates an mehrere Geräte.

Hinweis

Weitere Informationen zu den SDK-Tools zum Erstellen von Geräten und Back-End-Apps finden Sie unter Azure IoT SDKs.

Voraussetzungen

  • Ein aktives Azure-Konto. (Wenn Sie nicht über ein Konto verfügen, können Sie in nur wenigen Minuten ein kostenloses Konto erstellen.)

  • Ein IoT Hub in Ihrem Azure-Abonnement. Wenn Sie noch keinen Hub haben, können Sie die Schritte unter Erstellen eines IoT-Hubs ausführen.

  • Ein in Ihrem IoT-Hub registriertes Gerät. Wenn Sie nicht über ein Gerät in Ihrem IoT-Hub verfügen, führen Sie die Schritte unter Registrieren eines Geräts aus.

  • Empfohlen wird Python, Version 3.7 oder höher. Stellen Sie je nach Einrichtung sicher, dass die 32-Bit- bzw. die 64-Bit-Installation verwendet wird. Fügen Sie Python Ihrer plattformspezifischen Umgebungsvariablen hinzu, wenn Sie während der Installation dazu aufgefordert werden.

Erstellen einer simulierten Geräte-App

In diesem Abschnitt erstellen Sie eine Python-Konsolen-App, die auf eine von der Cloud aufgerufene direkte Methode antwortet. Dadurch wird eine simulierte lockDoor-Methode ausgelöst.

Wichtig

Dieser Artikel enthält Schritte zum Verbinden eines Geräts mithilfe einer Shared Access Signature, was auch als symmetrische Schlüsselauthentifizierung bezeichnet wird. Diese Authentifizierungsmethode eignet sich für Tests und Auswertungen, aber die Authentifizierung eines Geräts mit X.509-Zertifikaten ist ein sichererer Ansatz. Weitere Informationen finden Sie unter Bewährte Methoden für die Sicherheit von IoT-Lösungen > Verbindungssicherheit.

  1. Führen Sie an der Eingabeaufforderung den folgenden Befehl aus, um das Paket azure-iot-device zu installieren:

    pip install azure-iot-device
    
  2. Erstellen Sie mit einem Text-Editor in Ihrem Arbeitsverzeichnis die Datei simDevice.py.

  3. Fügen Sie am Anfang der Datei simDevice.py die folgenden import-Anweisungen und Variablen hinzu. Ersetzen Sie deviceConnectionString durch die Verbindungszeichenfolge des Geräts, das Sie oben erstellt haben:

    import time
    from azure.iot.device import IoTHubDeviceClient, MethodResponse
    
    CONNECTION_STRING = "{deviceConnectionString}"
    
  4. Definieren Sie die folgende Funktion, die einen Client instanziiert und so konfiguriert, dass er auf die lockDoor-Methode reagiert und Gerätezwillingsupdates empfängt:

    def create_client():
        # Instantiate the client
        client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
    
        # Define behavior for responding to the lockDoor direct method
        def method_request_handler(method_request):
            if method_request.name == "lockDoor":
                print("Locking Door!")
    
                resp_status = 200
                resp_payload = {"Response": "lockDoor called successfully"}
                method_response = MethodResponse.create_from_method_request(
                    method_request=method_request,
                    status=resp_status,
                    payload=resp_payload
                )
                client.send_method_response(method_response)
    
        # Define behavior for receiving a twin patch
        def twin_patch_handler(twin_patch):
            print("")
            print("Twin desired properties patch received:")
            print(twin_patch)
    
        # Set the handlers on the client
        try:
            print("Beginning to listen for 'lockDoor' direct method invocations...")
            client.on_method_request_received = method_request_handler
            print("Beginning to listen for updates to the Twin desired properties...")
            client.on_twin_desired_properties_patch_received = twin_patch_handler
        except:
            # If something goes wrong while setting the handlers, clean up the client
            client.shutdown()
            raise
    
  5. Fügen Sie den folgenden Code hinzu, um das Beispiel auszuführen:

    def main():
        print ("Starting the IoT Hub Python jobs sample...")
        client = create_client()
    
        print ("IoTHubDeviceClient waiting for commands, press Ctrl-C to exit")
        try:
            while True:
                time.sleep(100)
        except KeyboardInterrupt:
            print("IoTHubDeviceClient sample stopped!")
        finally:
            # Graceful exit
            print("Shutting down IoT Hub Client")
            client.shutdown()
    
    
    if __name__ == '__main__':
        main()
    
  6. Speichern und schließen Sie die Datei simDevice.py.

Hinweis

Der Einfachheit halber wird in diesem Artikel keine Wiederholungsrichtlinie implementiert. Im Produktionscode sollten Sie Wiederholungsrichtlinien implementieren (z.B. exponentielles Backoff), wie es im Artikel Behandeln vorübergehender Fehler vorgeschlagen wird.

Abrufen der IoT-Hub-Verbindungszeichenfolge

In diesem Artikel erstellen Sie einen Back-End-Dienst, der eine direkte Methode auf einem Gerät aufruft und den Gerätezwilling aktualisiert. Für den Dienst wird die Berechtigung Dienstverbindung benötigt, um eine direkte Methode auf einem Gerät aufzurufen. Darüber hinaus sind für den Dienst auch die Berechtigungen Lesevorgänge in Registrierung und Schreibvorgänge in Registrierung erforderlich, um Lese- und Schreibvorgänge für die Identitätsregistrierung durchführen zu können. Da keine SAS-Standardrichtlinie ausschließlich mit diesen Berechtigungen zur Verfügung steht, müssen Sie eine erstellen.

Erstellen Sie wie folgt eine SAS-Richtlinie, die die Berechtigungen Dienstverbindung, Lesevorgänge in Registrierung und Schreibvorgänge in Registrierung gewährt, und rufen Sie eine Verbindungszeichenfolge für diese Richtlinie ab:

  1. Öffnen Sie im Azure-Portal Ihren IoT-Hub. Wählen Sie dazu am besten Ressourcengruppen, anschließend die Ressourcengruppe, in der sich Ihr IoT-Hub befindet, und dann in der Ressourcenliste diesen IoT-Hub aus.

  2. Wählen Sie im linken Bereich Ihres IoT-Hubs Freigegebene Zugriffsrichtlinien aus.

  3. Wählen Sie im oberen Menü über der Richtlinienliste die Option SAS-Richtlinie hinzufügen aus.

  4. Geben Sie im Bereich SAS-Richtlinie hinzufügen einen aussagekräftigen Namen für Ihre Richtlinie ein; Beispiel: serviceAndRegistryReadWrite. Wählen Sie unter Berechtigungen die Optionen Schreibvorgänge in Registrierung und Dienstverbindung aus (Lesevorgänge in Registrierung wird bei Auswahl von Schreibvorgänge in Registrierung automatisch ausgewählt). Wählen Sie dann Hinzufügen aus.

    Screenshot, der zeigt, wie im IoT Hub des Azure-Portals eine neue Zugriffsrichtlinie hinzugefügt wird.

  5. Wählen Sie auf der Seite SAS-Richtlinien in der Richtlinienliste Ihre neue Richtlinie aus.

  6. Wählen Sie in dem daraufhin angezeigten neuen Bereich das Kopiersymbol für Primäre Verbindungszeichenfolge aus, und speichern Sie den Wert.

    Screenshot, der zeigt, wie im IoT Hub des Azure-Portals die primäre Verbindungszeichenfolge aus einer Zugriffsrichtlinie abgerufen wird.

Weitere Informationen zu SAS-Richtlinien und Berechtigungen für IoT-Hubs finden Sie unter Access Control und Berechtigungen.

Wichtig

Dieser Artikel enthält Schritte zum Herstellen einer Verbindung mit einem Dienst mithilfe einer Shared Access Signature. Diese Authentifizierungsmethode eignet sich für Tests und Auswertungen, aber die Authentifizierung bei einem Dienst mit Microsoft Entra ID oder verwalteten Identitäten ist ein sichererer Ansatz. Weitere Informationen finden Sie unter Bewährte Methoden für die Sicherheit von IoT-Lösungen > Cloudsicherheit.

Planen von Aufträgen zum Aufrufen einer direkten Methode und Aktualisieren der Eigenschaften eines Gerätezwillings

In diesem Abschnitt erstellen Sie eine Python-Konsolen-App, mit der eine lockDoor-Remotefunktion auf einem Gerät mit einer direkten Methode initiiert wird, und aktualisieren außerdem die gewünschten Eigenschaften des Gerätezwillings.

  1. Führen Sie an der Eingabeaufforderung den folgenden Befehl aus, um das Paket azure-iot-hub zu installieren:

    pip install azure-iot-hub
    
  2. Erstellen Sie mit einem Text-Editor in Ihrem Arbeitsverzeichnis die Datei scheduleJobService.py.

  3. Fügen Sie am Anfang der Datei scheduleJobService.py die folgenden import-Anweisungen und Variablen hinzu. Ersetzen Sie den Platzhalter {IoTHubConnectionString} durch die IoT-Hub-Verbindungszeichenfolge, die Sie zuvor unter Abrufen der IoT-Hub-Verbindungszeichenfolge kopiert haben. Ersetzen Sie den Platzhalter {deviceId} durch die Geräte-ID (den Namen) aus Ihrem registrierten Gerät:

    import os
    import sys
    import datetime
    import time
    import threading
    import uuid
    import msrest
    
    from azure.iot.hub import IoTHubJobManager, IoTHubRegistryManager
    from azure.iot.hub.models import JobProperties, JobRequest, Twin, TwinProperties, CloudToDeviceMethod
    
    CONNECTION_STRING = "{IoTHubConnectionString}"
    DEVICE_ID = "{deviceId}"
    
    METHOD_NAME = "lockDoor"
    METHOD_PAYLOAD = "{\"lockTime\":\"10m\"}"
    UPDATE_PATCH = {"building":43,"floor":3}
    TIMEOUT = 60
    WAIT_COUNT = 5
    
    # Create IoTHubJobManager
    iothub_job_manager = IoTHubJobManager.from_connection_string(CONNECTION_STRING)
    
    
  4. Fügen Sie die folgenden Methoden hinzu, um die Aufträge zum Aufrufen der direkten Methode und des Gerätezwillings auszuführen:

    def device_method_job(job_id, device_id, execution_time):
        print ( "" )
        print ( "Scheduling job: " + str(job_id) )
    
        job_request = JobRequest()
        job_request.job_id = job_id
        job_request.type = "scheduleDeviceMethod"
        job_request.start_time = datetime.datetime.utcnow().isoformat()
        job_request.cloud_to_device_method = CloudToDeviceMethod(method_name=METHOD_NAME, payload=METHOD_PAYLOAD)
        job_request.max_execution_time_in_seconds = execution_time
        job_request.query_condition = "DeviceId in ['{}']".format(device_id)
    
        new_job_response = iothub_job_manager.create_scheduled_job(job_id, job_request)
    
    def device_twin_job(job_id, device_id, execution_time):
        print ( "" )
        print ( "Scheduling job " + str(job_id) )
    
        job_request = JobRequest()
        job_request.job_id = job_id
        job_request.type = "scheduleUpdateTwin"
        job_request.start_time = datetime.datetime.utcnow().isoformat()
        job_request.update_twin = Twin(etag="*", properties=TwinProperties(desired=UPDATE_PATCH))
        job_request.max_execution_time_in_seconds = execution_time
        job_request.query_condition = "DeviceId in ['{}']".format(device_id)
    
        new_job_response = iothub_job_manager.create_scheduled_job(job_id, job_request)
    
    
  5. Fügen Sie den folgenden Code hinzu, um die Aufträge zu planen und den Auftragsstatus zu aktualisieren. Schließen Sie auch die Routine main ein:

    def iothub_jobs_sample_run():
        try:
            method_job_id = uuid.uuid4()
            device_method_job(method_job_id, DEVICE_ID, TIMEOUT)
    
            print ( "" )
            print ( "Direct method called with Job Id: " + str(method_job_id) )
    
            twin_job_id = uuid.uuid4()
            device_twin_job(twin_job_id, DEVICE_ID, TIMEOUT)
    
            print ( "" )
            print ( "Device twin called with Job Id: " + str(twin_job_id) )
    
            while True:
                print ( "" )
    
                method_job_status = iothub_job_manager.get_scheduled_job(method_job_id)
                print ( "...job " + str(method_job_id) + " " + method_job_status.status )
    
                twin_job_status = iothub_job_manager.get_scheduled_job(twin_job_id)
                print ( "...job " + str(twin_job_id) + " " + twin_job_status.status )
    
                print ( "Job status posted, press Ctrl-C to exit" )
                time.sleep(WAIT_COUNT)
    
        except msrest.exceptions.HttpOperationError as ex:
            print ( "" )
            print ( "Http error {}".format(ex.response.text) )
            return
        except Exception as ex:
            print ( "" )
            print ( "Unexpected error {}".format(ex) )
            return
        except KeyboardInterrupt:
            print ( "" )
            print ( "IoTHubService sample stopped" )
    
    if __name__ == '__main__':
        print ( "Starting the IoT Hub jobs Python sample..." )
        print ( "    Connection string = {0}".format(CONNECTION_STRING) )
        print ( "    Device ID         = {0}".format(DEVICE_ID) )
    
        iothub_jobs_sample_run()
    
  6. Speichern und schließen Sie die Datei scheduleJobService.py.

Ausführen der Anwendungen

Sie können nun die Anwendungen ausführen.

  1. Führen Sie an der Eingabeaufforderung in Ihrem Arbeitsverzeichnis den folgenden Befehl aus, um mit dem Lauschen auf die direkte Methode zum Neustarten zu beginnen:

    python simDevice.py
    
  2. Führen Sie an einer weiteren Eingabeaufforderung in Ihrem Arbeitsverzeichnis den folgenden Befehl aus, um die Aufträge zum Absperren der Tür und zum Aktualisieren des Zwillings auszulösen:

    python scheduleJobService.py
    
  3. Die Antworten des Geräts auf die Aktualisierungen der direkten Methode und der Gerätezwillinge wird in der Konsole angezeigt.

    IoT Hub-Auftrag Beispiel 1 – Geräteausgabe

    IoT Hub-Auftrag Beispiel 2 – Geräteausgabe

Nächste Schritte

In diesem Artikel haben Sie Aufträge geplant, um eine direkte Methode auszuführen und die Eigenschaften des Gerätezwillings zu aktualisieren.

Informationen zur weiteren Erkundung von IoT Hub und Geräteverwaltungsmustern, aktualisieren Sie ein Image unter Device Update for Azure IoT Hub unter Verwendung des Raspberry Pi 3 B+-Referenzimages.