Підключення модуля ESP8266 з прошивкою NodeMCU / Lua до сервера Home Assistant по HTTP

Підключення модуля ESP8266 з прошивкою NodeMCU / Lua до сервера Home Assistant по HTTP

Сервер Home Assistant прямо “з коробки” пропонує засобами плагіна “ESP Home” простий шлях з підключення модуля ESP8266 / ESP32 а також пристроїв на базі цих модулів. “ESP Home” є потужною системою побудови прошивок у форматі пакетних файлів YAML. – Але слід зауважити, що у такий спосіб можливо побудувати лише таке програмне забезпечення, яке підтримує інтеграція ESP Home.

Наприклад, якщо бібліотека драйверів “ESP Home” не містить драйвера для розширювача портів NXP PCA9538 (а ми, наприклад, хотіли б його застосовувати), то користувач не зможе створити потрібну йому прошивку з підтримкою PCA9538. Також слід звернути увагу, що yaml-скрипти компіляції прошивки, мають свою програмну парадигму, яка може просто не задовольняти тій задачі, яку поставив перед собою користувач.

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

Мова програмування

Оскільки alterstrategy.lab спеціалізується на прошивці NodeMCU для ESP8266 / ESP32, у даній публікації пропонуємо розглянути у якості такої мови – Lua, що входить до складу цієї потужної і популярної прошивки для мікроконтролерів ESP8266 / ESP32 виробництва компанії Espressif – мови яку ми вважаємо гнучкою і функціональною, щоб швидко розробляти будь-яку функціональність у сфері IoT.

В той же час, аналогічних результатів можливо досягти програмуючи будь-якою з мов, що підтримуються ESP8266 / ESP32: Arduino & C++, C & ESP-IDF, MicroPython, та іншими. Механізми інтеграції Home Assistant, що розглядаємо у даній статті, з легкістю підходять не лише для Lua, а і для будь-якої іншої мови програмування.

Опис задачі

Уявимо, що у нас вже є мікроконтролер з прошивкою NodeMCU і написаним прикладним програмним модулем.
Наприклад, це може бути модуль radcounter – лічильник імпульсів з розрахунком еквівалентної потужності іонізуючого випромінювання для трубки Гейгера-Мюллера СБМ-20. 

У апаратній частині задачі, у такому випадку нам також знадобиться сенсор – детектор гамма частинок GGreg20_V1 виробництва IoT-devices.

У якості мікроконтролерної платформи може бути будь-яка плата з ESP8266 на борту. Таких платформ є безліч – зручні і прості плати NodeMCU, або ж більш функціональні модулі на кшталт ESP12.OLED з вбудованим OLED дисплеєм. 

Ми могли б розширювати і ускладнювати задачу для даного пристрою, але обмежимося лише тим, що нам потрібно щохвилини надсилати на сервер Home Assistant одне зі значень, яке нам надає lua-модуль radcounter

  • state, current event status state (Wait/Ok/Warn/Danger/Error);
  • avg_rad_lvl, current moving average radiation level value in uSV/hour; 
  • meas_min, total current minimum level radiation measured in uSV/hour;
  • meas_max, total current maximum level radiation measured in uSV/hour;
  • dose, total cumulative dose measured in uSv;
  • g_count, total current impulses count;
  • minutes_passed, total minutes passed from measuring start / power on.

То ж візьмемо для прикладу значення avg_rad_lvl – ковзне середнє значення (MA5) поточного рівня потужності іонізуючого випромінювання з розмірністю [мікрозіверт на годину].

Прошивка NodeMCU з мовою Lua

Щоб самостійно побудувати прошивку NodeMCU, якщо ви плануєте робити це вперше, ми радимо ознайомитися з розробленою нами докладною інструкцією тут:

ESP8266 з прошивкою NodeMCU / Lua – докладна інструкція з програмування під Windows

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

Сервер Home Assistant

Також для цілей цієї публікації вам знадобиться сервер Home Assistant. Ми розмістили стислу інструкцію з розгортання тут:

Сервер Home Assistant: інструкція з розгортання у віртуальній машині під ОС Windows

Локальна мережа

Оскільки у класичному варіанті розгортання, а також за своїм задумом, сервер Home Assistant є сервером призначеним для роботи у локальній мережі, саме цей варіант надсилання даних контролером ESP8266 до Home Assistant ми і будемо розглядати: контролер і сервер знаходяться у одній локальній мережі.

Наприклад, в одній домашній мережі утвореній роутером WiFi.

Протокол передачі даних

У якості протоколу передачі даних ми могли б обрати будь-який з доступних: MQTT, CoAP, UDP, HTTP, але послуговуватися у даній публікації будемо лише останнім, адже HTTP підтримується сервером Home Assistant без встановлення додаткових доповнень та без виконання спеціальних налаштувань.

Захищений SSL/TLS протокол HTTP також підтримується як Home Assistant, так і NodeMCU, але оскільки він вимагає додаткових налаштувань на стороні сервера, ми не будемо вимагати від читача його вивчати у даній статті.

Серверний інтерфейс інтеграції Home Assistant

Сервер Home Assistant за замовчуванням має необхідний ендпойнт для надсилання даних по HTTP, який не потребує додаткових налаштувань. За це відповідає компонент API сервера HTTP типу Sensor

Відповідно до документації на компонент HTTP/Sensor бачимо, що нам лише потрібно надсилати запити з боку контролера у бік сервера на наступний ендпойнт:

http://IP_ADDRESS:8123/api/states/sensor.DEVICE_NAME

де 

IP_ADDRESS це адреса нашого сервера Home Assistant у локальній мережі.

DEVICE_NAME це унікальна назва (яку ми самі маємо придумати) для нашого контролера.

Важливо. Отримуючи такий запит, Сервер автоматично створює тимчасові структури сутностей, що будуть існувати до наступного перезапуску сервера. 

Тимчасовість цих даних – суттєвий нюанс, про який потрібно пам’ятати. Якщо для таких тимчасових сутностей створити віджети дашборду, чи сценарії автоматизації, сервер не зможе отримати до них доступу після (під час) перезапуску. До яких це може призвести наслідків – потрібно перевіряти у кожному конкретному випадку. Наприклад, на дашборді буде просто віджет з помилкою, як показано на Рис.

Віджет після перезапуску
Рис. Віджет після перезапуску сервера до нової порції даних

Щойно такий зовнішній пристрій надішле чергову порцію своїх даних, вони знову будуть утворені на сервері. Та всі процеси де залучено такі дані, почнуть працювати.

Надсилання та отримання даних 

Для того, щоб розмістити дані контролера на сервері, потрібно на боці контролера виконувати запит типу HTTP POST у бік сервера. 

Для того, щоб отримати дані від сервера, потрібно на боці контролера виконувати запит типу HTTP GET у бік сервера.

Токен довготривалого доступу

Єдине, що нам потрібно зробити на сервері, щоб мати змогу робити запити з локальної мережі – створити довготривалий статичний токен доступу. Цей токен потрібен для автентифікації запитів до API сервера ззовні, які роблять контролери (та інші системи). Кожен пристрій повинен (бажано) мати свій унікальний токен – адже саме завдяки токену, ми маємо змогу ідентифікувати кожен пристрій.

Щоб створити такий токен, а його потрібно створювати вручну, необхідно зайти у аккаунт користувача (з правами admin чи user – різниці немає), під яким створюється токен і у меню Профіль (http://homeassistant.local:8123/profile), 

Токени довготермінового доступу
Рис. Токени довготермінового доступу у меню Профіль

у підрозділі Токени довготермінового доступу, натиснути на СТВОРИТИ ТОКЕН. Процедура дуже проста, як показано на Рис. Токени довготермінового доступу у меню Профіль.

Назва токену довготермінового доступу
Рис. Назва токену довготермінового доступу
Значення токену довготермінового доступу
Рис. Значення токену довготермінового доступу

У результаті буде створено токен доступу, який має наступний вигляд:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIzZDI2NWMyYzBiMDI0Y2RiYmEwNmIwZGEyZDA1ZWE4MSIsImlhdCI6MTYxOTg1OTQ2OCwiZXhwIjoxOTM1MjE5NDY4fQ.y9AVoopELWxSpXhCLBvPrYztGFv5o2_lg8hkQ4EO9M8

Відповідно до документації, під час запиту до API-ендпойнту Home Assistant через HTTP, тип токену, та його значення необхідно включати у заголовки запиту, а саме у заголовок Authorization.

Частина запиту з заголовком Authorization для випадку використання CURL у загальному вигляді така: 

де 

Bearer це тип токену/процедури авторизації

LONG_LIVED_ACCESS_TOKEN це значення створеного нами рініше токену “eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIzZDI2NWMyYzBiMDI0Y2RiYmEwNmIwZGEyZDA1ZWE4MSIsImlhdCI6MTYxOTg1OTQ2OCwiZXhwIjoxOTM1MjE5NDY4fQ.y9AVoopELWxSpXhCLBvPrYztGFv5o2_lg8hkQ4EO9M8”.

Примітка. Як можна бачити, контролер має знати не лише HTTP-адресу (IP-адресу чи hostname у тому числі) ендпойнта сервра та формат запиту, а й значення токену доступу. Це купа інформації, яку якось потрібно вносити користувачеві у налаштування свого контролера до того, як він зможе звертатися із запитом до сервера.

Але на жаль, у сучасному світі інформаційна безпека понад усе і без неї ніяк не можна. 

Найпростіший варіант – це підняти на контролері власну веб-сторінку для таких налаштувань через браузер із збереженням налаштувань на флеш пам’ять (ESP8266 має аж 4 Мб і немає жодних проблем щоб зберігати всі необхідні для роботи параметри). 

Ну, або ж просто зашити хардкодом токени та адреси у Lua-скрипт, що не правильно з багатьох точок зору, але не вимагатиме складного програмування на боці контролера.

Запити контролера до сервера з рівня Lua (NodeMCU)

Для виконання запитів по HTTP в прошивці NodeMCU є одноіменний C-модуль http, який потрібно включити до складу модулів під час побудови прошивки.

Запит до API на HTTP-ендпойнт сервера Home Assistant має наступний вид:

Наведений вище запит HTTP POST, дозволяє надіслати дані з контролера на сервер.

Щоб виконати запит до API на HTTP-ендпойнт сервера Home Assistant і отримати дані з сервера на контролер, потрібно застосовувати метод HTTP GET, який має схожий вигляд:

Тепер ми готові написати повний Lua-код, який завдяки функції post() і таймеру, може надсилати дані на сервер щохвилини, а також за запитом користувача, може отримувати дані з сервера засобами функції get().

Це описано в частині 2 статті.

Бажаємо успіхів!