Compartilhar via


Agendar e difundir trabalhos (Python)

Use o Hub IoT do Azure para agendar e controlar os trabalhos que atualizam milhões de dispositivos. Use trabalhos para:

  • Atualizar as propriedades desejadas
  • Marcas de atualização
  • Chamar métodos diretos

Conceitualmente, um trabalho encapsula uma dessas ações e rastreia o progresso da execução com relação a um conjunto de dispositivos, definido por uma consulta do dispositivo gêmeo. Por exemplo, um aplicativo de back-end pode usar um trabalho para invocar um método de reinicialização em 10.000 dispositivos, especificado por uma consulta do dispositivo gêmeo e agendado no futuro. Esse aplicativo pode acompanhar o progresso à medida que cada um desses dispositivos recebe e executa o método de reinicialização.

Saiba mais sobre cada um desses recursos nestes artigos:

Observação

Os recursos descritos neste artigo estão disponíveis apenas na camada padrão do Hub IoT. Para saber mais sobre as camadas Básico e Standard/Gratuita do Hub IoT, confira Escolher a camada ideal do Hub IoT para sua solução.

Este artigo mostra como criar dois aplicativos Python:

  • Um aplicativo de dispositivo simulado Python, simDevice.py que implementa um método direto chamado lockDoor que pode ser chamado pelo aplicativo de back-end.

  • Um aplicativo de console Python, scheduleJobService.py, que cria dois trabalhos. Um trabalho chama o método direto lockDoor e outro envia atualizações de propriedade desejadas para vários dispositivos.

Observação

Consulte os SDKs da IoT do Azure para obter mais informações sobre as ferramentas do SDK disponíveis para compilar aplicativos de dispositivo e back-end.

Pré-requisitos

  • Uma conta ativa do Azure. (Se você não tiver uma conta, poderá criar uma conta gratuita em apenas alguns minutos.)

  • Um Hub IoT na assinatura do Azure. Caso você ainda não tenha um hub, poderá seguir as etapas em Criar um hub IoT.

  • Um dispositivo registrado em seu hub IoT. Se você não tiver um dispositivo no hub IoT, siga as etapas em Registrar um dispositivo.

  • O Python versão 3.7 ou posterior é recomendado. Certifique-se de usar a instalação de 32 bits ou 64 bits conforme exigido pelo seu programa de instalação. Quando solicitado durante a instalação, certifique-se de adicionar Python à variável de ambiente específica da plataforma.

Criar um aplicativo de dispositivo simulado

Nesta seção, você cria um aplicativo de console do Python que responde a um método direto chamado pela nuvem, que aciona um método lockDoor simulado.

  1. No seu prompt de comando, execute o seguinte comando para instalar o pacote azure-iot-device:

    pip install azure-iot-device
    
  2. Usando um editor de texto, crie um novo arquivo simDevice.py no diretório de trabalho.

  3. Adicione as instruções import e variáveis a seguir ao início do arquivo simDevice.py. Substitua deviceConnectionString pela cadeia de conexão do dispositivo criada acima:

    import time
    from azure.iot.device import IoTHubDeviceClient, MethodResponse
    
    CONNECTION_STRING = "{deviceConnectionString}"
    
  4. Defina a seguinte função, que cria uma instância em um cliente, configura-o para responder ao método lockDoor e recebe atualizações do dispositivo gêmeo:

    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. Adicione o seguinte código para executar a amostra:

    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. Salve e feche o arquivo simDevice.py.

Observação

Para simplificar, este artigo não implementa nenhuma política de repetição. No código de produção, implemente políticas de repetição (como uma retirada exponencial), conforme sugerido no artigo Tratamento de falhas transitórias.

Obter a cadeia de conexão do Hub IoT

Neste artigo, você cria um serviço de back-end que invoca um método direto em um dispositivo e atualiza o dispositivo gêmeo. O serviço precisa da permissão de conexão de serviço para chamar um método direto em um dispositivo. O serviço também precisa das permissões de leitura do registro e de gravação do registro para ler e gravar o registro de identidade. Não há nenhuma política padrão de acesso compartilhado que contenha apenas essas duas permissões, portanto, você precisa criar uma.

Para criar uma política de acesso compartilhado que conceda permissões de conexão de serviço, leitura de registro e gravação de registro e para obter uma cadeia de conexão para esta política, siga estas etapas:

  1. Abra o hub IoT no portal do Azure. A maneira mais fácil de acessar o hub IoT é selecionar Grupos de recursos, selecionar o grupo de recurso onde o hub IoT está localizado e, em seguida, selecionar seu hub IoT na lista de recursos.

  2. No painel do lado esquerdo do hub IoT, selecione Políticas de acesso compartilhado.

  3. No menu superior, acima da lista de políticas, selecione Adicionar política de acesso compartilhado.

  4. No painel Adicionar política de acesso compartilhado, insira um nome descritivo para sua política, por exemplo, serviceAndRegistryReadWrite. Em Permissões, selecione Gravação de Registro e Conexão de Serviço (Leitura do registro é selecionada automaticamente quando você seleciona Gravação de registro) e selecione Adicionar.

    Captura de tela de como adicionar uma nova política de acesso no Hub IoT do portal do Azure.

  5. De volta ao painel Políticas de acesso compartilhado, selecione sua nova política na lista de políticas.

  6. No novo painel que aparece, selecione o ícone de cópia da Cadeia de conexão primária e salve o valor.

    Captura de tela de como obter a cadeia de conexão primária de uma política de acesso no Hub IoT do portal do Azure.

Para obter mais informações sobre permissões e políticas de acesso compartilhado do Hub IoT, consulte Controle de acesso e permissões.

Agendar trabalhos para chamar um método direto e atualizar as propriedades do dispositivo gêmeo

Nesta seção, é possível criar um aplicativo de console do Python que inicia um lockDoor remoto em um dispositivo usando um método direto, bem como atualiza as propriedades desejadas do dispositivo gêmeo.

  1. No prompt de comando, execute o seguinte comando para instalar o pacote azure-iot-hub:

    pip install azure-iot-hub
    
  2. Usando um editor de texto, crie um novo arquivo scheduleJobService.py no diretório de trabalho.

  3. Adicione as seguintes instruções e variáveis import no início do arquivo scheduleJobService.py. Substitua o espaço reservado {IoTHubConnectionString} pela cadeia de conexão do hub IoT que você copiou anteriormente em Obter a cadeia de conexão do hub IoT. Substitua o espaço reservado {deviceId} pela identificação do dispositivo registrado (o nome):

    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. Adicione os seguintes métodos para executar os trabalhos que chamam o método direto e dispositivo gêmeo:

    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. Adicione o código a seguir para agendar os trabalhos e atualizar o status do trabalho. Também inclua a rotina 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. Salve e feche o arquivo scheduleJobService.py.

Executar os aplicativos

Agora você está pronto para executar os aplicativos.

  1. No prompt de comando do seu diretório de trabalho, execute o seguinte comando para começar a escutar o método direto de reinicialização:

    python simDevice.py
    
  2. Em outro prompt de comando no seu diretório de trabalho, execute o seguinte comando para disparar os trabalhos para bloquear a porta e atualizar o gêmeo:

    python scheduleJobService.py
    
  3. Veja as respostas de dispositivo para o método direto e dispositivos gêmeos na atualização no console.

    Exemplo de trabalho do Hub IoT 1 – saída do dispositivo

    Exemplo de trabalho do Hub IoT 2 – saída do dispositivo

Próximas etapas

Neste artigo, você agendou trabalhos para executar um método direto e atualizar as propriedades do dispositivo gêmeo.

Para continuar explorando os padrões de Hub IoT e de gerenciamento de dispositivo, atualize uma imagem no tutorial Atualização de dispositivo para o Hub IoT do Azure usando a imagem de referência do Raspberry Pi 3 B +.