You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
IoT-For-Beginners/translations/uk/2-farm/lessons/5-migrate-application-to-th.../README.md

58 KiB

Перенесення логіки вашого додатку в хмару

Скетчнот огляд цього уроку

Скетчнот від Nitya Narasimhan. Натисніть на зображення для перегляду у більшому розмірі.

Цей урок був проведений у рамках IoT для початківців: Проект 2 - Цифрове сільське господарство від Microsoft Reactor.

Керування вашим IoT-пристроєм за допомогою безсерверного коду

Тест перед лекцією

Тест перед лекцією

Вступ

У попередньому уроці ви дізналися, як підключити моніторинг вологості ґрунту вашої рослини та керування реле до хмарного IoT-сервісу. Наступним кроком є перенесення серверного коду, який контролює таймінг реле, у хмару. У цьому уроці ви навчитеся робити це за допомогою безсерверних функцій.

У цьому уроці ми розглянемо:

Що таке безсерверність?

Безсерверність, або безсерверне обчислення, передбачає створення невеликих блоків коду, які виконуються в хмарі у відповідь на різні типи подій. Коли подія відбувається, ваш код запускається і отримує дані про цю подію. Ці події можуть надходити з різних джерел, включаючи веб-запити, повідомлення в черзі, зміни даних у базі даних або повідомлення, надіслані IoT-пристроями до IoT-сервісу.

Події, що надсилаються з IoT-сервісу до безсерверного сервісу, обробляються одночасно кількома функціями

💁 Якщо ви раніше використовували тригери баз даних, це схоже на них — код запускається у відповідь на подію, наприклад, вставку рядка.

Коли багато подій надсилаються одночасно, безсерверний сервіс масштабується для їх одночасного виконання

Ваш код виконується лише тоді, коли відбувається подія, в інший час він не активний. Подія відбувається, ваш код завантажується і виконується. Це робить безсерверність дуже масштабованою — якщо багато подій відбуваються одночасно, хмарний провайдер може виконувати вашу функцію стільки разів, скільки потрібно, одночасно на доступних серверах. Недоліком цього є те, що якщо вам потрібно ділитися інформацією між подіями, її потрібно зберігати десь, наприклад, у базі даних, а не в пам'яті.

Ваш код пишеться як функція, яка приймає деталі про подію як параметр. Ви можете використовувати широкий спектр мов програмування для написання цих безсерверних функцій.

🎓 Безсерверність також називають функціями як сервіс (FaaS), оскільки кожен тригер події реалізується як функція в коді.

Попри назву, безсерверність насправді використовує сервери. Назва пояснюється тим, що як розробник ви не турбуєтеся про сервери, необхідні для виконання вашого коду, вас цікавить лише те, що ваш код виконується у відповідь на подію. Хмарний провайдер має безсерверний runtime, який управляє виділенням серверів, мережами, зберіганням, процесором, пам'яттю та всім іншим, необхідним для виконання вашого коду. Ця модель означає, що ви не платите за сервер, оскільки його немає. Натомість ви платите за час виконання вашого коду та обсяг використаної пам'яті.

💰 Безсерверність — один із найдешевших способів виконання коду в хмарі. Наприклад, на момент написання, один хмарний провайдер дозволяє всім вашим безсерверним функціям виконуватися загалом 1,000,000 разів на місяць безкоштовно, а після цього стягує $0.20 за кожен 1,000,000 виконань. Коли ваш код не виконується, ви не платите.

Як розробник IoT, модель безсерверності є ідеальною. Ви можете написати функцію, яка викликається у відповідь на повідомлення, надіслані будь-яким IoT-пристроєм, підключеним до вашого хмарного IoT-сервісу. Ваш код оброблятиме всі надіслані повідомлення, але виконуватиметься лише тоді, коли це необхідно.

Згадайте код, який ви написали як серверний код для прослуховування повідомлень через MQTT. Як це може працювати в хмарі за допомогою безсерверності? Як, на вашу думку, код може бути змінений для підтримки безсерверного обчислення?

💁 Модель безсерверності поширюється на інші хмарні сервіси, крім виконання коду. Наприклад, у хмарі доступні безсерверні бази даних із моделлю ціноутворення, де ви платите за кожен запит до бази даних, наприклад, запит або вставку, зазвичай із ціноутворенням, заснованим на обсязі роботи, необхідної для обслуговування запиту. Наприклад, один запит на вибір рядка за первинним ключем коштуватиме менше, ніж складна операція з об'єднанням багатьох таблиць і поверненням тисяч рядків.

Створення безсерверного додатку

Сервіс безсерверного обчислення від Microsoft називається Azure Functions.

Логотип Azure Functions

Коротке відео нижче містить огляд Azure Functions.

Відео огляд Azure Functions

🎥 Натисніть на зображення вище, щоб переглянути відео.

Знайдіть час для дослідження та прочитайте огляд Azure Functions у документації Microsoft Azure Functions.

Щоб написати Azure Functions, ви починаєте з додатку Azure Functions на вибраній вами мові програмування. Azure Functions підтримує Python, JavaScript, TypeScript, C#, F#, Java та Powershell. У цьому уроці ви навчитеся писати додаток Azure Functions на Python.

💁 Azure Functions також підтримує користувацькі обробники, тому ви можете писати функції на будь-якій мові, яка підтримує HTTP-запити, включаючи старі мови, такі як COBOL.

Додатки функцій складаються з одного або кількох тригерів — функцій, які реагують на події. Ви можете мати кілька тригерів у одному додатку функцій, які використовують спільну конфігурацію. Наприклад, у конфігураційному файлі вашого додатку функцій можна вказати дані підключення до вашого IoT Hub, і всі функції в додатку можуть використовувати це для підключення та прослуховування подій.

Завдання - встановлення інструментів Azure Functions

На момент написання, інструменти для роботи з Azure Functions не повністю працюють на Apple Silicon для проєктів Python. Вам потрібно використовувати Mac на базі Intel, ПК з Windows або ПК з Linux.

Однією з чудових функцій Azure Functions є можливість запуску локально. Той самий runtime, який використовується в хмарі, може бути запущений на вашому комп'ютері, дозволяючи писати код, який реагує на IoT-повідомлення, і запускати його локально. Ви навіть можете налагоджувати ваш код під час обробки подій. Коли ви будете задоволені вашим кодом, його можна буде розгорнути в хмарі.

Інструменти Azure Functions доступні як CLI, відомий як Azure Functions Core Tools.

  1. Встановіть Azure Functions Core Tools, дотримуючись інструкцій у документації Azure Functions Core Tools.

  2. Встановіть розширення Azure Functions для VS Code. Це розширення забезпечує підтримку створення, налагодження та розгортання функцій Azure. Ознайомтеся з документацією розширення Azure Functions для інструкцій щодо встановлення цього розширення у VS Code.

Коли ви розгортаєте ваш додаток Azure Functions у хмарі, він потребує невеликого обсягу хмарного сховища для зберігання таких речей, як файли додатку та файли журналів. Коли ви запускаєте ваш додаток функцій локально, вам все одно потрібно підключитися до хмарного сховища, але замість використання реального хмарного сховища ви можете використовувати емулятор сховища під назвою Azurite. Він працює локально, але поводиться як хмарне сховище.

🎓 У Azure сховище, яке використовують Azure Functions, є обліковим записом Azure Storage. Ці облікові записи можуть зберігати файли, блоби, дані в таблицях або дані в чергах. Ви можете використовувати один обліковий запис сховища для багатьох додатків, таких як додаток функцій і веб-додаток.

  1. Azurite — це додаток на Node.js, тому вам потрібно встановити Node.js. Ви можете знайти інструкції з завантаження та встановлення на вебсайті Node.js. Якщо ви використовуєте Mac, ви також можете встановити його через Homebrew.

  2. Встановіть Azurite за допомогою наступної команди (npm — це інструмент, який встановлюється разом із Node.js):

    npm install -g azurite
    
  3. Створіть папку під назвою azurite для використання Azurite для зберігання даних:

    mkdir azurite
    
  4. Запустіть Azurite, передавши йому цю нову папку:

    azurite --location azurite
    

    Емулятор сховища Azurite запуститься і буде готовий до підключення локального runtime функцій.

    ➜  ~ azurite --location azurite  
    Azurite Blob service is starting at http://127.0.0.1:10000
    Azurite Blob service is successfully listening at http://127.0.0.1:10000
    Azurite Queue service is starting at http://127.0.0.1:10001
    Azurite Queue service is successfully listening at http://127.0.0.1:10001
    Azurite Table service is starting at http://127.0.0.1:10002
    Azurite Table service is successfully listening at http://127.0.0.1:10002
    

Завдання - створення проєкту Azure Functions

CLI Azure Functions можна використовувати для створення нового додатку функцій.

  1. Створіть папку для вашого додатку функцій і перейдіть до неї. Назвіть її soil-moisture-trigger.

    mkdir soil-moisture-trigger
    cd soil-moisture-trigger
    
  2. Створіть віртуальне середовище Python всередині цієї папки:

    python3 -m venv .venv
    
  3. Активуйте віртуальне середовище:

    • У Windows:

      • Якщо ви використовуєте Command Prompt або Command Prompt через Windows Terminal, виконайте:

        .venv\Scripts\activate.bat
        
      • Якщо ви використовуєте PowerShell, виконайте:

        .\.venv\Scripts\Activate.ps1
        
    • У macOS або Linux виконайте:

      source ./.venv/bin/activate
      

    💁 Ці команди слід виконувати з того ж місця, де ви виконали команду для створення віртуального середовища. Вам ніколи не потрібно переходити до папки .venv, ви завжди повинні виконувати команду активації та будь-які команди для встановлення пакетів або запуску коду з папки, в якій ви були, коли створювали віртуальне середовище.

  4. Виконайте наступну команду для створення додатку функцій у цій папці:

    func init --worker-runtime python soil-moisture-trigger
    

    Це створить три файли всередині поточної папки:

    • host.json — цей JSON-документ містить налаштування вашого додатку функцій. Вам не потрібно змінювати ці налаштування.
    • local.settings.json — цей JSON-документ містить налаштування, які ваш додаток використовуватиме під час локального запуску, наприклад, рядки підключення до вашого IoT Hub. Ці налаштування є локальними і не повинні додаватися до системи контролю версій. Коли ви розгортаєте додаток у хмарі, ці налаштування не розгортаються, натомість ваші налаштування завантажуються з налаштувань додатку. Це буде розглянуто пізніше в цьому уроці.
    • requirements.txt — це файл вимог Pip, який містить пакети Pip, необхідні для запуску вашого додатку функцій.
  5. Файл local.settings.json має налаштування для облікового запису сховища, який використовуватиме додаток функцій. За замовчуванням це налаштування порожнє, тому його потрібно встановити. Щоб підключитися до локального емулятора сховища Azurite, встановіть це значення на наступне:

    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    
  6. Встановіть необхідні пакети Pip за допомогою файлу вимог:

    pip install -r requirements.txt
    

    💁 Необхідні пакети Pip повинні бути в цьому файлі, щоб коли додаток функцій буде розгорнуто в хмарі, runtime міг переконатися, що він встановлює правильні пакети.

  7. Щоб перевірити, чи все працює правильно, ви можете запустити runtime функцій. Виконайте наступну команду для цього:

    func start
    

    Ви побачите, як runtime запускається і повідомляє, що він не знайшов жодних функцій (тригерів).

    (.venv) ➜  soil-moisture-trigger func start
    Found Python version 3.9.1 (python3).
    
    Azure Functions Core Tools
    Core Tools Version:       3.0.3442 Commit hash: 6bfab24b2743f8421475d996402c398d2fe4a9e0  (64-bit)
    Function Runtime Version: 3.0.15417.0
    
    [2021-05-05T01:24:46.795Z] No job functions found.
    

⚠️ Якщо ви отримали сповіщення про брандмауер, надайте доступ, оскільки додаток func повинен мати можливість читати та записувати у вашу мережу. ⚠️ Якщо ви використовуєте macOS, у вихідних даних можуть з'явитися попередження:

> (.venv) ➜  soil-moisture-trigger func start
> Found Python version 3.9.1 (python3).
>
> Azure Functions Core Tools
> Core Tools Version:       3.0.3442 Commit hash: 6bfab24b2743f8421475d996402c398d2fe4a9e0  (64-bit)
> Function Runtime Version: 3.0.15417.0
>
> [2021-06-16T08:18:28.315Z] Cannot create directory for shared memory usage: /dev/shm/AzureFunctions
> [2021-06-16T08:18:28.316Z] System.IO.FileSystem: Access to the path '/dev/shm/AzureFunctions' is denied. Operation not permitted.
> [2021-06-16T08:18:30.361Z] No job functions found.
> ```

Ви можете їх ігнорувати, якщо програма Functions запускається правильно і показує список працюючих функцій. Як зазначено в цьому питанні на Microsoft Docs Q&A, це можна пропустити.

  1. Зупиніть програму Functions, натиснувши ctrl+c.

  2. Відкрийте поточну папку у VS Code, або запустивши VS Code і відкривши цю папку, або виконавши наступну команду:

    code .
    

    VS Code розпізнає ваш проект Functions і покаже сповіщення:

    Detected an Azure Functions Project in folder "soil-moisture-trigger" that may have been created outside of
    VS Code. Initialize for optimal use with VS Code?
    

    Сповіщення

    Виберіть Yes у цьому сповіщенні.

  3. Переконайтеся, що віртуальне середовище Python запущене у терміналі VS Code. Завершіть його і перезапустіть, якщо необхідно.

Створення тригера подій IoT Hub

Програма Functions є оболонкою вашого безсерверного коду. Щоб реагувати на події IoT Hub, ви можете додати тригер IoT Hub до цієї програми. Цей тригер має підключитися до потоку повідомлень, які надсилаються до IoT Hub, і реагувати на них. Для отримання цього потоку повідомлень ваш тригер має підключитися до event hub compatible endpoint IoT Hub.

IoT Hub базується на іншій службі Azure, яка називається Azure Event Hubs. Event Hubs — це служба, яка дозволяє надсилати та отримувати повідомлення, а IoT Hub розширює її, додаючи функції для IoT-пристроїв. Спосіб підключення для читання повідомлень з IoT Hub такий самий, як і для використання Event Hubs.

Проведіть дослідження: Прочитайте огляд Event Hubs у документації Azure Event Hubs. Як базові функції порівнюються з IoT Hub?

Для підключення IoT-пристрою до IoT Hub необхідно використовувати секретний ключ, який гарантує, що лише дозволені пристрої можуть підключатися. Те ж саме стосується підключення для читання повідомлень — ваш код потребує рядка підключення, який містить секретний ключ разом із деталями IoT Hub.

💁 Рядок підключення за замовчуванням, який ви отримуєте, має дозволи iothubowner, що дає будь-якому коду, який його використовує, повні дозволи на IoT Hub. Ідеально, якщо ви підключаєтеся з найнижчим рівнем необхідних дозволів. Це буде розглянуто в наступному уроці.

Після підключення тригера код всередині функції буде викликатися для кожного повідомлення, надісланого до IoT Hub, незалежно від того, який пристрій його надіслав. Тригер передасть повідомлення як параметр.

Завдання - отримати рядок підключення до event hub compatible endpoint

  1. У терміналі VS Code виконайте наступну команду, щоб отримати рядок підключення до event hub compatible endpoint IoT Hub:

    az iot hub connection-string show --default-eventhub \
                                      --output table \
                                      --hub-name <hub_name>
    

    Замініть <hub_name> на ім'я, яке ви використовували для вашого IoT Hub.

  2. У VS Code відкрийте файл local.settings.json. Додайте наступне значення всередині секції Values:

    "IOT_HUB_CONNECTION_STRING": "<connection string>"
    

    Замініть <connection string> на значення з попереднього кроку. Вам потрібно додати кому після попереднього рядка, щоб зробити це валідним JSON.

Завдання - створити тригер подій

Тепер ви готові створити тригер подій.

  1. У терміналі VS Code виконайте наступну команду з папки soil-moisture-trigger:

    func new --name iot-hub-trigger --template "Azure Event Hub trigger"
    

    Це створить нову функцію під назвою iot-hub-trigger. Тригер підключиться до event hub compatible endpoint IoT Hub, тому ви можете використовувати тригер event hub. Специфічного тригера IoT Hub немає.

Це створить папку всередині папки soil-moisture-trigger під назвою iot-hub-trigger, яка міститиме цю функцію. У цій папці будуть наступні файли:

  • __init__.py - це файл коду Python, який містить тригер, використовуючи стандартну конвенцію іменування файлів Python для перетворення цієї папки на модуль Python.

    Цей файл міститиме наступний код:

    import logging
    
    import azure.functions as func
    
    
    def main(event: func.EventHubEvent):
        logging.info('Python EventHub trigger processed an event: %s',
                    event.get_body().decode('utf-8'))
    

    Основою тригера є функція main. Саме ця функція викликається з подіями з IoT Hub. Ця функція має параметр event, який містить EventHubEvent. Кожного разу, коли повідомлення надсилається до IoT Hub, ця функція викликається, передаючи це повідомлення як event, разом із властивостями, які є такими ж, як і анотації, які ви бачили в попередньому уроці.

    Основою цієї функції є логування події.

  • function.json - цей файл містить конфігурацію для тригера. Основна конфігурація знаходиться в секції bindings. Binding — це термін для з'єднання між Azure Functions та іншими службами Azure. Ця функція має вхідний binding до event hub — вона підключається до event hub і отримує дані.

    💁 Ви також можете мати вихідні bindings, щоб вихід функції надсилався до іншої служби. Наприклад, ви можете додати вихідний binding до бази даних і повернути подію IoT Hub з функції, і вона автоматично буде вставлена в базу даних.

    Проведіть дослідження: Прочитайте про bindings у документації концепцій тригерів та bindings Azure Functions.

    Секція bindings включає конфігурацію для binding. Значення, які вас цікавлять:

    • "type": "eventHubTrigger" - це вказує функції, що вона має слухати події з Event Hub

    • "name": "events" - це ім'я параметра для подій Event Hub. Це відповідає імені параметра у функції main у коді Python.

    • "direction": "in" - це вхідний binding, дані з event hub надходять до функції

    • "connection": "" - це визначає ім'я налаштування для читання рядка підключення. При локальному запуску це налаштування буде читатися з файлу local.settings.json.

      💁 Рядок підключення не може бути збережений у файлі function.json, його потрібно читати з налаштувань. Це зроблено для того, щоб ви випадково не розкрили ваш рядок підключення.

  1. Через помилку в шаблоні Azure Functions, у файлі function.json є некоректне значення для поля cardinality. Оновіть це поле з many на one:

    "cardinality": "one",
    
  2. Оновіть значення "connection" у файлі function.json, щоб вказати на нове значення, яке ви додали до файлу local.settings.json:

    "connection": "IOT_HUB_CONNECTION_STRING",
    

    💁 Пам'ятайте - це має вказувати на налаштування, а не містити фактичний рядок підключення.

  3. Рядок підключення містить значення eventHubName, тому значення для цього у файлі function.json потрібно очистити. Оновіть це значення до порожнього рядка:

    "eventHubName": "",
    

Завдання - запустити тригер подій

  1. Переконайтеся, що ви не запускаєте монітор подій IoT Hub. Якщо він працює одночасно з програмою Functions, програма Functions не зможе підключитися і споживати події.

    💁 До endpoint IoT Hub можуть підключатися кілька програм, використовуючи різні групи споживачів. Це буде розглянуто в наступному уроці.

  2. Щоб запустити програму Functions, виконайте наступну команду з терміналу VS Code:

    func start
    

    Програма Functions запуститься і знайде функцію iot-hub-trigger. Вона обробить будь-які події, які вже були надіслані до IoT Hub за останній день.

    (.venv) ➜  soil-moisture-trigger func start
    Found Python version 3.9.1 (python3).
    
    Azure Functions Core Tools
    Core Tools Version:       3.0.3442 Commit hash: 6bfab24b2743f8421475d996402c398d2fe4a9e0  (64-bit)
    Function Runtime Version: 3.0.15417.0
    
    Functions:
    
            iot-hub-trigger: eventHubTrigger
    
    For detailed output, run func with --verbose flag.
    [2021-05-05T02:44:07.517Z] Worker process started and initialized.
    [2021-05-05T02:44:09.202Z] Executing 'Functions.iot-hub-trigger' (Reason='(null)', Id=802803a5-eae9-4401-a1f4-176631456ce4)
    [2021-05-05T02:44:09.205Z] Trigger Details: PartitionId: 0, Offset: 1011240-1011632, EnqueueTimeUtc: 2021-05-04T19:04:04.2030000Z-2021-05-04T19:04:04.3900000Z, SequenceNumber: 2546-2547, Count: 2
    [2021-05-05T02:44:09.352Z] Python EventHub trigger processed an event: {"soil_moisture":628}
    [2021-05-05T02:44:09.354Z] Python EventHub trigger processed an event: {"soil_moisture":624}
    [2021-05-05T02:44:09.395Z] Executed 'Functions.iot-hub-trigger' (Succeeded, Id=802803a5-eae9-4401-a1f4-176631456ce4, Duration=245ms)
    

    Кожен виклик функції буде оточений блоками Executing 'Functions.iot-hub-trigger'/Executed 'Functions.iot-hub-trigger' у вихідних даних, щоб ви могли побачити, скільки повідомлень було оброблено в кожному виклику функції.

  3. Переконайтеся, що ваш IoT-пристрій працює. Ви побачите нові повідомлення про вологість ґрунту, які з'являються в програмі Functions.

  4. Зупиніть і перезапустіть програму Functions. Ви побачите, що вона більше не обробляє попередні повідомлення, а лише нові.

💁 VS Code також підтримує налагодження ваших функцій. Ви можете встановити точки зупинки, натиснувши на межу біля початку кожного рядка коду, або поставивши курсор на рядок коду і вибравши Run -> Toggle breakpoint, або натиснувши F9. Ви можете запустити налагоджувач, вибравши Run -> Start debugging, натиснувши F5, або вибравши панель Run and debug і натиснувши кнопку Start debugging. Таким чином ви можете побачити деталі оброблюваних подій.

Виправлення помилок

  • Якщо ви отримуєте наступну помилку:

    The listener for function 'Functions.iot-hub-trigger' was unable to start. Microsoft.WindowsAzure.Storage: Connection refused. System.Net.Http: Connection refused. System.Private.CoreLib: Connection refused.
    

    Перевірте, чи запущений Azurite і чи встановлено AzureWebJobsStorage у файлі local.settings.json на UseDevelopmentStorage=true.

  • Якщо ви отримуєте наступну помилку:

    System.Private.CoreLib: Exception while executing function: Functions.iot-hub-trigger. System.Private.CoreLib: Result: Failure Exception: AttributeError: 'list' object has no attribute 'get_body'
    

    Перевірте, чи встановлено cardinality у файлі function.json на one.

  • Якщо ви отримуєте наступну помилку:

    Azure.Messaging.EventHubs: The path to an Event Hub may be specified as part of the connection string or as a separate value, but not both.  Please verify that your connection string does not have the `EntityPath` token if you are passing an explicit Event Hub name. (Parameter 'connectionString').
    

    Перевірте, чи встановлено eventHubName у файлі function.json на порожній рядок.

Надсилання запитів на прямі методи з безсерверного коду

Досі ваша програма Functions слухала повідомлення з IoT Hub, використовуючи endpoint, сумісний з Event Hub. Тепер вам потрібно надсилати команди до IoT-пристрою. Це робиться через інше підключення до IoT Hub через Registry Manager. Registry Manager — це інструмент, який дозволяє бачити, які пристрої зареєстровані в IoT Hub, і спілкуватися з цими пристроями, надсилаючи повідомлення з хмари до пристрою, запити на прямі методи або оновлюючи device twin. Ви також можете використовувати його для реєстрації, оновлення або видалення IoT-пристроїв з IoT Hub.

Щоб підключитися до Registry Manager, вам потрібен рядок підключення.

Завдання - отримати рядок підключення до Registry Manager

  1. Щоб отримати рядок підключення, виконайте наступну команду:

    az iot hub connection-string show --policy-name service \
                                      --output table \
                                      --hub-name <hub_name>
    

    Замініть <hub_name> на ім'я, яке ви використовували для вашого IoT Hub.

    Рядок підключення запитується для політики ServiceConnect за допомогою параметра --policy-name service. Коли ви запитуєте рядок підключення, ви можете вказати, які дозволи цей рядок підключення дозволить. Політика ServiceConnect дозволяє вашому коду підключатися і надсилати повідомлення до IoT-пристроїв.

    Проведіть дослідження: Прочитайте про різні політики у документації про дозволи IoT Hub

  2. У VS Code відкрийте файл local.settings.json. Додайте наступне значення всередині секції Values:

    "REGISTRY_MANAGER_CONNECTION_STRING": "<connection string>"
    

    Замініть <connection string> на значення з попереднього кроку. Вам потрібно додати кому після попереднього рядка, щоб зробити це валідним JSON.

Завдання - надіслати запит на прямий метод до пристрою

  1. SDK для Registry Manager доступний через пакет Pip. Додайте наступний рядок до файлу requirements.txt, щоб додати залежність від цього пакета:

    azure-iot-hub
    
  2. Переконайтеся, що термінал VS Code має активоване віртуальне середовище, і виконайте наступну команду для встановлення пакетів Pip:

    pip install -r requirements.txt
    
  3. Додайте наступні імпорти до файлу __init__.py:

    import json
    import os
    from azure.iot.hub import IoTHubRegistryManager
    from azure.iot.hub.models import CloudToDeviceMethod
    

    Це імпортує деякі системні бібліотеки, а також бібліотеки для взаємодії з Registry Manager і надсилання запитів на прямі методи.

  4. Видаліть код з функції main, але залиште саму функцію.

  5. У функції main додайте наступний код:

    body = json.loads(event.get_body().decode('utf-8'))
    device_id = event.iothub_metadata['connection-device-id']
    
    logging.info(f'Received message: {body} from {device_id}')
    

    Цей код витягує тіло події, яке містить JSON-повідомлення, надіслане IoT-пристроєм.

    Потім він отримує ID пристрою з анотацій, переданих разом із повідомленням. Тіло події містить повідомлення, надіслане як телеметрія, а словник iothub_metadata містить властивості, встановлені IoT Hub, такі як ID пристрою відправника і час, коли повідомлення було надіслано.

    Ця інформація потім логується. Ви побачите це логування в терміналі, коли запустите програму Functions локально.

  6. Нижче цього додайте наступний код:

    soil_moisture = body['soil_moisture']
    
    if soil_moisture > 450:
        direct_method = CloudToDeviceMethod(method_name='relay_on', payload='{}')
    else:
        direct_method = CloudToDeviceMethod(method_name='relay_off', payload='{}')
    

    Цей код отримує вологість ґрунту з повідомлення. Потім він перевіряє вологість ґрунту і, залежно від значення, створює допоміжний клас для запиту на прямий метод relay_on або relay_off. Запит методу не потребує корисного навантаження, тому надсилається порожній JSON-документ.

  7. Нижче цього додайте наступний код:

    logging.info(f'Sending direct method request for {direct_method.method_name} for device {device_id}')
    
    registry_manager_connection_string = os.environ['REGISTRY_MANAGER_CONNECTION_STRING']
    registry_manager = IoTHubRegistryManager(registry_manager_connection_string)
    

Цей код завантажує REGISTRY_MANAGER_CONNECTION_STRING із файлу local.settings.json. Значення з цього файлу доступні як змінні середовища, які можна прочитати за допомогою функції os.environ, що повертає словник усіх змінних середовища.

💁 Коли цей код розгортається в хмарі, значення з файлу local.settings.json будуть встановлені як Application Settings, і їх можна буде прочитати зі змінних середовища.

Потім код створює екземпляр допоміжного класу Registry Manager, використовуючи рядок підключення.

  1. Додайте наступний код:

    registry_manager.invoke_device_method(device_id, direct_method)
    
    logging.info('Direct method request sent!')
    

    Цей код вказує менеджеру реєстру надіслати запит прямого методу до пристрою, який надіслав телеметрію.

    💁 У версіях програми, створених у попередніх уроках за допомогою MQTT, команди керування реле надсилалися всім пристроям. Код припускав, що у вас буде лише один пристрій. Ця версія коду надсилає запит методу до одного пристрою, тому буде працювати, якщо у вас є кілька наборів датчиків вологості ґрунту та реле, надсилаючи правильний запит прямого методу до правильного пристрою.

  2. Запустіть програму Functions і переконайтеся, що ваш IoT-пристрій надсилає дані. Ви побачите, як повідомлення обробляються, а запити прямого методу надсилаються. Переміщуйте датчик вологості ґрунту в ґрунт і з нього, щоб побачити зміну значень і ввімкнення/вимкнення реле.

💁 Ви можете знайти цей код у папці code/functions.

Розгорніть свій безсерверний код у хмарі

Ваш код тепер працює локально, тому наступним кроком буде розгортання Functions App у хмарі.

Завдання - створення хмарних ресурсів

Вашу програму Functions потрібно розгорнути в ресурсі Functions App в Azure, який знаходиться всередині групи ресурсів, створеної для вашого IoT Hub. Вам також знадобиться обліковий запис сховища, створений в Azure, щоб замінити емулятор, який працює локально.

  1. Запустіть наступну команду для створення облікового запису сховища:

    az storage account create --resource-group soil-moisture-sensor \
                              --sku Standard_LRS \
                              --name <storage_name> 
    

    Замініть <storage_name> на назву для вашого облікового запису сховища. Ця назва має бути глобально унікальною, оскільки вона є частиною URL-адреси, яка використовується для доступу до облікового запису сховища. Ви можете використовувати лише малі літери та цифри для цієї назви, без інших символів, і вона обмежена 24 символами. Використовуйте щось на кшталт sms і додайте унікальний ідентифікатор, наприклад, кілька випадкових слів або ваше ім'я.

    Параметр --sku Standard_LRS вибирає рівень ціноутворення, обираючи найдешевший загальний обліковий запис. Безкоштовного рівня сховища немає, і ви платите за те, що використовуєте. Витрати відносно низькі, з найвищою ціною сховища менш ніж $0.05 за місяць за гігабайт збережених даних.

    Ознайомтеся з ціноутворенням на сторінці Azure Storage Account pricing page

  2. Запустіть наступну команду для створення Function App:

    az functionapp create --resource-group soil-moisture-sensor \
                          --runtime python \
                          --functions-version 3 \
                          --os-type Linux \
                          --consumption-plan-location <location> \
                          --storage-account <storage_name> \
                          --name <functions_app_name>
    

    Замініть <location> на місце, яке ви використовували під час створення групи ресурсів у попередньому уроці.

    Замініть <storage_name> на назву облікового запису сховища, створеного на попередньому кроці.

    Замініть <functions_app_name> на унікальну назву для вашого Functions App. Ця назва має бути глобально унікальною, оскільки вона є частиною URL-адреси, яка може бути використана для доступу до Functions App. Використовуйте щось на кшталт soil-moisture-sensor- і додайте унікальний ідентифікатор, наприклад, кілька випадкових слів або ваше ім'я.

    Параметр --functions-version 3 встановлює версію Azure Functions для використання. Версія 3 є останньою версією.

    Параметр --os-type Linux вказує середовищу Functions використовувати Linux як операційну систему для хостингу цих функцій. Functions можуть бути розміщені на Linux або Windows залежно від використовуваної мови програмування. Програми на Python підтримуються лише на Linux.

Завдання - завантаження налаштувань програми

Під час розробки вашого Functions App ви зберігали деякі налаштування у файлі local.settings.json для рядків підключення до вашого IoT Hub. Ці налаштування потрібно записати в Application Settings у вашому Function App в Azure, щоб їх можна було використовувати у вашому коді.

🎓 Файл local.settings.json призначений лише для локальних налаштувань розробки, і його не слід додавати до системи контролю версій, такої як GitHub. Під час розгортання в хмарі використовуються Application Settings. Application Settings — це пари ключ/значення, розміщені в хмарі, які читаються зі змінних середовища або у вашому коді, або середовищем виконання під час підключення вашого коду до IoT Hub.

  1. Запустіть наступну команду для встановлення налаштування IOT_HUB_CONNECTION_STRING у Application Settings вашого Functions App:

    az functionapp config appsettings set --resource-group soil-moisture-sensor \
                                          --name <functions_app_name> \
                                          --settings "IOT_HUB_CONNECTION_STRING=<connection string>"
    

    Замініть <functions_app_name> на назву, яку ви використовували для вашого Functions App.

    Замініть <connection string> на значення IOT_HUB_CONNECTION_STRING з вашого файлу local.settings.json.

  2. Повторіть попередній крок, але встановіть значення REGISTRY_MANAGER_CONNECTION_STRING на відповідне значення з вашого файлу local.settings.json.

Коли ви виконаєте ці команди, вони також виведуть список усіх Application Settings для функціонального додатка. Ви можете використовувати це, щоб перевірити, чи ваші значення встановлені правильно.

💁 Ви побачите значення, вже встановлене для AzureWebJobsStorage. У вашому файлі local.settings.json це значення було встановлено для використання локального емулятора сховища. Коли ви створюєте Functions App, ви передаєте обліковий запис сховища як параметр, і це значення встановлюється автоматично.

Завдання - розгортання вашого Functions App у хмарі

Тепер, коли Functions App готовий, ваш код можна розгорнути.

  1. Запустіть наступну команду з терміналу VS Code для публікації вашого Functions App:

    func azure functionapp publish <functions_app_name>
    

    Замініть <functions_app_name> на назву, яку ви використовували для вашого Functions App.

Код буде упакований і відправлений до Functions App, де він буде розгорнутий і запущений. Буде багато виводу в консолі, що закінчиться підтвердженням розгортання та списком розгорнутих функцій. У цьому випадку список міститиме лише тригер.

Deployment successful.
Remote build succeeded!
Syncing triggers...
Functions in soil-moisture-sensor:
    iot-hub-trigger - [eventHubTrigger]

Переконайтеся, що ваш IoT-пристрій працює. Змініть рівень вологості, регулюючи вологість ґрунту або переміщуючи датчик у ґрунт і з нього. Ви побачите, як реле вмикається і вимикається залежно від змін вологості ґрунту.


🚀 Виклик

У попередньому уроці ви керували часом роботи реле, відписуючись від MQTT-повідомлень, поки реле було увімкнене, і протягом короткого часу після його вимкнення. Ви не можете використовувати цей метод тут — ви не можете відписатися від тригера IoT Hub.

Подумайте про різні способи, якими ви могли б обробляти це у вашому Functions App.

Післялекційний тест

Післялекційний тест

Огляд і самостійне навчання

Завдання

Додайте ручне керування реле


Відмова від відповідальності:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу Co-op Translator. Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.