Condividi tramite


Pianificare e trasmettere processi (Python)

Usare l'hub IoT per pianificare e tenere traccia dei processi che aggiornano milioni di dispositivi. Usare i processi per:

  • Aggiornare le proprietà desiderate
  • Aggiornare i tag
  • Richiamare metodi diretti

Concettualmente, un processo esegue il wrapping di una di queste azioni e tiene traccia dell'avanzamento dell'esecuzione rispetto a un set di dispositivi, definito da una query di dispositivi gemelli. Grazie a un processo, ad esempio, un'app back-end può richiamare un metodo di riavvio in 10.000 dispositivi, specificato da una query di dispositivi gemelli e pianificato in un secondo momento. L'applicazione può quindi tenere traccia dell'avanzamento mentre ognuno dei dispositivi riceve ed esegue il metodo di riavvio.

Altre informazioni su queste funzionalità sono disponibili in questi articoli:

Nota

Le funzionalità descritte in questo articolo sono disponibili solo nel livello Standard dell'hub IoT. Per altre informazioni sui livelli Basic e Standard/Gratuito dell'hub IoT, vedere Scegliere il livello appropriato dell'hub IoT per la soluzione.

Questo articolo illustra come creare due app Python:

  • Un'app dispositivo simulato Python, simDevice.py, che implementa un metodo diretto denominato lockDoor, che può essere chiamato dall'app back-end.

  • Un'app console Python, scheduleJobService.py, che crea due processi. Un processo chiama il metodo diretto lockDoor e un altro processo invia gli aggiornamenti delle proprietà desiderati a più dispositivi.

Nota

Vedere Azure IoT SDK per altre informazioni sugli strumenti SDK disponibili per creare app sia per dispositivi che back-end.

Prerequisiti

  • Un account Azure attivo. Se non si dispone di un account, è possibile crearne uno gratuito in pochi minuti.

  • Un hub IoT nella sottoscrizione di Azure. Se non si ha ancora un hub, è possibile seguire la procedura descritta in Creare un hub IoT.

  • Un dispositivo registrato nell'hub IoT. Se non si ha un dispositivo nell'hub IoT, seguire la procedura descritta in Registrare un dispositivo.

  • È consigliabile usare Python versione 3.7 o successive. Assicurarsi di usare le installazioni a 32 bit o 64 bit, come richiesto dalla configurazione. Quando richiesto durante l'installazione, assicurarsi di aggiungere Python alla variabile di ambiente specifica per la piattaforma.

Creare un'app di dispositivo simulato

In questa sezione viene creata un'applicazione console Python che risponde a un metodo chiamato dal cloud, che attiva un metodo lockDoor simulato.

Importante

Questo articolo include la procedura per connettere un dispositivo usando una firma di accesso condiviso, altrimenti chiamata autenticazione con chiave simmetrica. Questo metodo di autenticazione è comodo per i test e le valutazioni, ma l'autenticazione tramite certificati X.509 rappresenta un approccio più sicuro. Per scoprire di più, vedere Procedure consigliate per la sicurezza > Sicurezza della connessione.

  1. Al prompt dei comandi eseguire il comando seguente per installare il pacchetto azure-iot-device:

    pip install azure-iot-device
    
  2. Usando un editor di testo, creare un nuovo file simDevice.py nella directory di lavoro.

  3. Aggiungere le variabili e le istruzioni import seguenti all'inizio del file simDevice.py. Sostituire deviceConnectionString con la stringa di connessione del dispositivo creato in precedenza:

    import time
    from azure.iot.device import IoTHubDeviceClient, MethodResponse
    
    CONNECTION_STRING = "{deviceConnectionString}"
    
  4. Definire la funzione seguente, che creerà un'istanza di un client e la configurerà per rispondere al metodo lockDoor, oltre a ricevere gli aggiornamenti dei dispositivi gemelli:

    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. Aggiungere il codice seguente per eseguire l'esempio:

    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. Salvare e chiudere il file simDevice.py.

Nota

Per semplicità, in questo articolo non si implementa alcun criterio di ripetizione dei tentativi. Nel codice di produzione è consigliabile implementare criteri di ripetizione dei tentativi, ad esempio un backoff esponenziale, come suggerito nell'articolo Gestione degli errori temporanei.

Ottenere la stringa di connessione dell'hub IoT

In questo articolo viene creato un servizio back-end che richiama un metodo diretto in un dispositivo e aggiorna il dispositivo gemello. Il servizio richiede l'autorizzazione di connessione al servizio per chiamare un metodo diretto in un dispositivo. Il servizio necessita anche delle autorizzazioni di lettura del registro e scrittura del registro per leggere e scrivere nel registro delle identità. Non esistono criteri di accesso condiviso predefiniti che contengono solo queste autorizzazioni, quindi è necessario crearne uno.

Per creare criteri di accesso condiviso che concedono le autorizzazioni di connessione al servizio, lettura del registro e scrittura del registro e per ottenere una stringa di connessione per questo criterio, attenersi alla seguente procedura:

  1. Nel portale di Azure aprire l'hub IoT. Il modo più semplice per accedere all'hub IoT consiste nel selezionare Gruppi di risorse, selezionare il gruppo di risorse in cui si trova l'hub IoT e quindi selezionare l'hub IoT dall'elenco delle risorse.

  2. Nel riquadro sinistro dell'hub IoT selezionare Criteri di accesso condiviso.

  3. Dal menu superiore sopra l'elenco di criteri selezionare Aggiungi criteri di accesso condiviso.

  4. Nel riquadro Aggiungi criteri di accesso condiviso immettere un nome descrittivo per il criterio; ad esempio: serviceAndRegistryReadWrite. In Autorizzazioni selezionare Scrittura del registro e Connessione al servizio (Lettura del registro viene selezionata automaticamente quando si seleziona Scrittura del registro) e quindi selezionare Aggiungi.

    Screenshot di come aggiungere un nuovo criterio di accesso nell'hub IoT del portale di Azure.

  5. Tornare alla pagina Criteri di accesso condiviso e selezionare i nuovi criteri dall'elenco.

  6. Nel nuovo pannello visualizzato, selezionare l'icona di copia per Stringa di connessione primaria e salvare il valore.

    Screenshot di come ottenere la stringa di connessione primaria da un criterio di accesso nell'hub IoT del portale di Azure.

Per altre informazioni sui criteri di accesso condiviso e sulle autorizzazioni dell'hub IoT, vedere Controllo dell'accesso e autorizzazioni.

Importante

Questo articolo include la procedura per connettersi a un servizio usando una firma di accesso condiviso. Questo metodo di autenticazione è comodo per i test e le valutazioni, ma l'autenticazione a un servizio con Microsoft Entra ID o identità gestite rappresenta un approccio più sicuro. Per altre informazioni, vedere Procedure consigliate per la sicurezza > Sicurezza cloud.

Pianificare i processi per chiamare un metodo diretto e aggiornare le proprietà dei dispositivi gemelli

In questa sezione si creerà un'app console Python che avvia un lockDoor remoto su un dispositivo usando un metodo diretto e verranno aggiornate anche le proprietà desiderate del dispositivo gemello.

  1. Al prompt dei comandi eseguire il comando seguente per installare il pacchetto azure-iot-hub:

    pip install azure-iot-hub
    
  2. Usando un editor di testo, creare un nuovo file scheduleJobService.py nella directory di lavoro.

  3. Aggiungere le variabili e le istruzioni import seguenti all'inizio del file scheduleJobService.py. Sostituire il segnaposto {IoTHubConnectionString} con la stringa di connessione dell'hub IoT copiata in precedenza in Ottenere la stringa di connessione dell'hub IoT. Sostituire il segnaposto {deviceId} con l'ID dispositivo (il nome) del dispositivo registrato:

    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. Aggiungere i seguenti metodi per eseguire i processi che chiamano il metodo diretto e il dispositivo gemello:

    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. Aggiungere il codice seguente per pianificare i processi e aggiornare lo stato del dispositivo. Includere anche la routine main:

    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. Salvare e chiudere il file scheduleJobService.py.

Eseguire le applicazioni

A questo punto è possibile eseguire le applicazioni.

  1. Al prompt dei comandi, eseguire il comando riportato di seguito nella directory di lavoro per iniziare l'ascolto del metodo diretto di riavvio:

    python simDevice.py
    
  2. Al prompt dei comandi successivo, eseguire il comando riportato di seguito nella directory di lavoro per attivare i processi per bloccare la porta e aggiornare il dispositivo gemello:

    python scheduleJobService.py
    
  3. Nella console vengono visualizzate le risposte del dispositivo al metodo diretto e l'aggiornamento dei dispositivi gemelli.

    Esempio di processo dell'hub IoT 1: output del dispositivo

    Esempio di processo dell'hub IoT 2: output del dispositivo

Passaggi successivi

In questo articolo sono stati pianificati processi per eseguire un metodo diretto e aggiornare le proprietà del dispositivo gemello.

Per continuare a esplorare i modelli di gestione dell'hub IoT e dei dispositivi, aggiornare un'immagine nell'esercitazione sull'aggiornamento dei dispositivi per l'hub IoT di Azure usando l'immagine di riferimento Raspberry Pi 3 B+.