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. Tale applicazione può quindi tenere traccia dello stato di avanzamento in quanto ognuno di questi 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 di hub IoT di base e standard/gratuiti, vedere Scegliere il livello di hub IoT appropriato per la soluzione.

Questo articolo illustra come creare due app Python:

  • Un'app per dispositivi simulata 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

Per altre informazioni sugli strumenti SDK disponibili per creare app back-end e dispositivo, vedere Azure IoT SDK .

Prerequisiti

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

  • Un hub IoT. Crearne uno con l'interfaccia della riga di comando o il portale di Azure.

  • Dispositivo registrato. Registrare una nella portale di Azure.

  • È 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.

  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 , nonché ricevere gli aggiornamenti del dispositivo gemello:

    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 mantenere semplici le operazioni, questo articolo non implementa criteri 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 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 del servizio per chiamare un metodo diretto in un dispositivo. Il servizio necessita anche delle autorizzazioni di lettura e scrittura del Registro di sistema per leggere e scrivere il Registro di sistema 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 concede autorizzazioni di lettura, lettura del Registro di sistema e scrittura del Registro di sistema e per ottenere una stringa di connessione per questo criterio, seguire questa procedura:

  1. Aprire l'hub IoT nell'portale di Azure. 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 in alto sopra l'elenco dei 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 Write and Service Connect (Registro di sistema Lettura viene selezionato automaticamente quando si seleziona Scrittura registro) e quindi selezionare Aggiungi.

    Screenshot di come aggiungere un nuovo criterio di accesso nella hub IoT dell'portale di Azure.

  5. Nella pagina Criteri di accesso condiviso selezionare i nuovi criteri dall'elenco dei criteri.

  6. Nel nuovo riquadro visualizzato selezionare l'icona di copia per la stringa di connessione primaria e salvare il valore.

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

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

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

In questa sezione viene creata un'app console Python che avvia un blocco remoto in un dispositivo usando un metodo diretto e aggiorna 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 istruzioni e le variabili seguenti import all'inizio del file di scheduleJobService.py . Sostituire il {IoTHubConnectionString} segnaposto con la stringa di connessione dell'hub IoT copiata in precedenza in Recupera la stringa di connessione dell'hub IoT. Sostituire il {deviceId} segnaposto con l'ID dispositivo (il nome) dal 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 hub IoT 1 - output del dispositivo

    hub IoT Esempio di processo 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 hub IoT e modelli di gestione dei dispositivi, aggiornare un'immagine in Aggiornamento dei dispositivi per hub IoT di Azure esercitazione usando l'immagine di riferimento Raspberry Pi 3 B+ .