Планирование и трансляция заданий (Python)

Центр Интернета вещей Azure позволяет планировать и отслеживать задания по обновлению для миллионов устройств. Что можно сделать с помощью заданий?

  • Обновление требуемых свойств
  • Обновление тегов
  • Вызов прямых методов

По сути, задание включает одно из этих действий, отслеживая ход его выполнения на наборе устройств (определяется запросом двойника устройства). Например, с помощью задания внутреннее приложение может вызывать метод перезагрузки на 10 000 устройств, определенных запросом двойника устройства и запланированных в будущем. Затем это приложение может отследить ход выполнения задания по мере получения и выполнения метода перезагрузки на каждом из этих устройств.

Дополнительные сведения о каждой из этих возможностей см. в следующих статьях:

Примечание

Функции, описанные в этой статье, доступны только на стандартном уровне Центра Интернета вещей. Дополнительные сведения о базовых и стандартных и бесплатных уровнях Центр Интернета вещей см. в статье Выбор подходящего уровня Центр Интернета вещей для решения.

В этой статье показано, как создать два приложения Python:

  • Приложение имитированного устройства Python (simDevice.py), которое реализует прямой метод lockDoor, вызываемый внутренним приложением.

  • Консольное приложение Pythons scheduleJobService.py, которое создает два задания. Одно задание вызывает прямой метод lockDoor, а другое задание отправляет нужные обновления свойств на несколько устройств.

Примечание

Дополнительные сведения о средствах SDK, доступных для создания приложения устройства и внутреннего приложения, см. в статье Пакеты SDK для Интернета вещей Azure.

Предварительные требования

  • Активная учетная запись Azure. Если ее нет, можно создать бесплатную учетную запись всего за несколько минут.

  • Центр Интернета вещей. Создайте его с помощью CLI или портал Azure.

  • Зарегистрированное устройство. Зарегистрируйте его на портале Azure.

  • Рекомендуется использовать Python 3.7 или более поздней версии. Обязательно используйте 32-разрядную или 64-разрядную версию установки согласно требованиям программы настройки. При появлении запроса во время установки обязательно добавьте Python в переменную среды соответствующей платформы.

Создание приложения виртуального устройства

В этом разделе вы создадите консольное приложение Python, отвечающее на прямой метод, вызванный из облака, который активирует имитированный метод lockDoor.

  1. В командной строке выполните следующую команду, чтобы установить пакет azure-iot-device:

    pip install azure-iot-device
    
  2. В текстовом редакторе создайте файл simDevice.py в рабочей папке.

  3. Добавьте следующие инструкции и переменные import в начало файла simDevice.py. Замените deviceConnectionString строкой подключения созданного ранее устройства.

    import time
    from azure.iot.device import IoTHubDeviceClient, MethodResponse
    
    CONNECTION_STRING = "{deviceConnectionString}"
    
  4. Определите приведенную ниже функцию, которая создаст экземпляр клиента и настроит его для реагирования на метод lockDoor, а также получения обновлений для двойника устройства:

    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. Добавьте следующий код, чтобы запустить пример:

    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. Сохраните и закройте файл simDevice.py.

Примечание

Для простоты в этой статье не реализуется политика повтора. В рабочем коде следует реализовать политики повторных попыток (например, с экспоненциальной задержкой), как указано в статье Обработка временных сбоев.

Получение строки подключения Центра Интернета вещей

В этой статье вы научитесь создавать серверную службу, которая вызывает прямой метод на устройстве и обновляет двойник устройства. Службе требуется разрешение подключения служб для вызова прямого метода на устройстве. Службе также требуются разрешения на чтение реестра и запись в реестр для чтения и записи реестра удостоверений. Не существует политик общего доступа по умолчанию, содержащих только эти два разрешения, поэтому данную политику необходимо будет создать.

Чтобы создать политику общего доступа, которая предоставляет разрешения подключения служб, чтения реестра, и записи реестра и получить строку подключения для этой политики, выполните следующие действия.

  1. Откройте центр Интернета вещей на портале Azure. Самый простой способ добраться до центра Интернета вещей — выбрать Группы ресурсов на панели ресурсов, выбрать группу ресурсов, а затем выбрать центр Интернета вещей из списка ресурсов.

  2. В левой части центра Интернета вещей выберите Политики общего доступа.

  3. В верхнем меню над списком политик выберите Добавить политику общего доступа.

  4. В области Добавить политику общего доступа введите описательное имя политики, например: serviceAndRegistryReadWrite. В разделе Разрешения выберите Запись в реестр и Подключение к службе (Чтение реестра будет автоматически выбрано при выборе Запись в реестр), а затем выберите Добавить.

    Снимок экрана: добавление политики доступа в Центр Интернета вещей на портале Azure.

  5. Вернитесь на страницу Политики общего доступа и выберите в списке политик новую политику.

  6. В новой панели выберите значок копирования рядом с пунктом Первичная строка подключения и сохраните значение.

    Снимок экрана: получение первичной строки подключения из политики доступа в Центре Интернета вещей на портале Azure.

Дополнительные сведения о политиках и разрешениях общего доступа Центра Интернета вещей см. в разделе Управления доступом и разрешения.

Планирование заданий для вызова прямого метода и обновления свойств двойника устройства

В этом разделе вы научитесь создавать консольное приложение Python, которое инициирует удаленное действие lockDoor на устройстве с помощью прямого метода и обновляет свойства двойника устройства.

  1. В командной строке выполните следующую команду, чтобы установить пакет azure-iot-hub:

    pip install azure-iot-hub
    
  2. В текстовом редакторе создайте файл scheduleJobService.py в рабочей папке.

  3. Добавьте следующие инструкции и переменные import в начало файла scheduleJobService.py. Замените заполнитель {IoTHubConnectionString} строкой подключения центра Интернета вещей, скопированной в разделе Получение строки подключения центра Интернета вещей. Замените заполнитель {deviceId} удостоверением устройства (именем) с зарегистрированного устройства:

    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. Добавьте следующие методы для выполнения заданий, вызывающих прямой метод и двойник устройств.

    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. Добавьте следующий код, чтобы запланировать задания и обновить их состояние. Добавьте также подпрограмму 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. Сохраните и закройте файл scheduleJobService.py.

Запуск приложений

Теперь все готово к запуску приложений.

  1. В командной строке в рабочей папке выполните следующую команду, чтобы начать прослушивание прямого метода перезагрузки.

    python simDevice.py
    
  2. В командной строке в рабочей папке выполните следующую команду, чтобы активировать задачи для блокировки дверей и обновления двойника.

    python scheduleJobService.py
    
  3. В консоли отобразятся ответы устройства на прямой метод и двойники устройства.

    Пример задания центра Интернета вещей 1 — выходные данные устройства

    Пример задания центра Интернета вещей 2 — выходные данные устройства

Дальнейшие действия

По материалам этой статьи вы запланировали задания для запуска прямого метода и обновления свойств двойника устройства.

Для продолжения работы с Центром Интернета вещей и шаблонами управления устройствами обновите образ в соответствии с инструкциями из руководства по обновлению устройств для Центра Интернета вещей Azure: использование эталонного образа для Raspberry Pi 3 B +.