#полоумныйдом ESP8266 OTA, обновление без регистрации и смс ;)

Краткое (не очень) описание похода на поводу у собственной лени и желания чего-нибудь автоматизировать прямо вот сейчас и здесь, дома, с помощью esp8266, nodemcu и нескольких часов свободного времени.

Для начала, вводные:

  • в квартире есть несколько разных типов сенсоров (в розетке или с автономным питанием на базе LiFePo4, с датчиками bme280, am230x и/или ds18b20), которые в итоге делают совершенно одинаковые вещи: подключаются по Wi-Fi к домашней сети, получают адрес по DHCP, собирают информацию с сенсоров, передают информацию на MQTT-брокер, есть радикально другой тип датчиков, никакого MQTT, суровый UDP с самодельным гейтом в MQTT-брокер – этот подвид в данной статье не рассматривается, там нет Lua и nodemcu
  • на все датчики установлена прошивка Nodemcu-firmware, с нужным набором модулей (для всех одна, вне зависимости от набора датчиков)
  • вся инфрастуктура или уже есть, или же находится в процессе инсталляции по мере поступления дензнаков и наличия свободного времени (SCADA-система, подобие HMI, элементы управления на импульсных реле, PLC, прочие штуки, которые мне хотелось попробовать, но все никак не доходили руки)
  • написана условная “прошивка”, пускай это будет называться нашим микрокодом, на Lua, который успешно “раскатан” по всем устройствам (в той или иной итерации)
  • ключевым недостатком решений-поделок для “умного” дома на базе ESP8266 (ну и ESP32, я помаленьку поглядываю и в эту сторону), на мой взгляд, является отсутствие какого-либо централизованного управления микрокодом
  • замена ESP8266 на что-либо не предполагается и суть не рассматривается, ибо цена и доступность являются решающими факторами в выборе поделок для сенсоров, которые не учавствуют в управляющих цепях, то есть не имеют прямой обратной связи с освещением, кондиционированием, приточно-вытяжными устройствами и прочими устройствами, которые способны нарушить мой комфорт буквально физически
  • OTA, в рассматриваемом контексте, я лично называю процесс замены всех *.lua файлов на устройстве с некоторым набором дополнительных проверок
  • я не программист, выбор Lua и nodemcu по сути случаен, оптимальный код – не мой конек, увы

В очередной раз, глянув в пол-глаза на чудовищную поделку под названием “это-написал-я-два-месяца-назад-и-этот-ужас-нужно-срочно-исправить”, ощютил небывалый прилив сил и сподобился-таки починить то, что и так (неплохо) работало. Внезапно понял, что лезть в кладовку за датчиком, цеплять к нему клемы, выкатывать т.н. обновление вот прямо сейчас и еще в течении месяца мне мешает лень, причем дикая. А таких датчиков, как оказалось, уже десяток. Опасаясь очередного озарения, решил действовать проактивно и накатал подобие OTA-обновления, используя костыли вкупе с ранее полученными познаниями в процессе самостоятельного хождения по грабелькам и подчерпнутой из интернетов информацией. Вышло, в общем-то, неплохо, для моих целей. Странно, что удобоваримых чужих наработок с наскоку не нашел, да и ладно (видимо, это слишком очевидная задача).

Собственно, для самых нетерпеливых весь код сложен в одном месте.

Итого, имеем следующий набор кое-как склеенного в единообразную кучку кода. Рассматривать предлагаю только по существу, в рамках предложенной темы обновления микрокода “по воздуху”, без использования чего-то материального (ну за исключением ноутбука на столе, мы-то обсуждаем лень и рациональность использования).

Микрокод состоит из нескольких функциональных частей, нарезан на “кусочки” (с чисто практической пользой, прошу заметить, ниже по тексту будет одна маленькая деталь).

init.lua вызывает user.lua после заданного тайм-аута, данный атавизмъ взят из примера, суть не требуется для нормальной работы. user.lua, в свою очередь, последовательно исполняет набор файлов, из которых нам интересны не только лишь все.

credentials.lua (загружен для примера credentials.lua.example, его надо переименовать и прописать свои настройки)

Адресок web-сервера, где лежат наши файлы для обновления

variables.lua

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

wifi.lua

ota.lua

web_server_url = “http://”..web_server..”/ota/”..sensor_client_id..”/” – меняем на свой вариант, где, собственно, у нас лежат подкаталоги с обновлениями для каждого устройства.

Функция ota() запускает таймер, который раз в 400 мс. (подобрано эмпирическим путем “тычком-пальцем-в-небо”) запускает процедуру опроса ota_loop(), которая, в свою очередь, циклично проверяет, а чем мы, собственно, сейчас заняты, и продвигается дальше по мере необходимости:

ota_success применит нашу прошивку и безоговорочно перезагрузит датчик, ota_error просто вернет систему к искомому состоянию до начала обновления.

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

function ota_get_version() получаем version.txt и сверяем версии, локальную и удаленную, запускаем дальнейший рок-н-ролл по мере необходимости:

function ota_get_filelist() получаем filelist.txt, искомый список файлов для обновления, файл генерируется автоматически для каждого устройства скриптом esp_scripts/send_ota_fw.sh, содержит два поля – собственно имя файла и контрольную сумму sha1.

После получения файла файлов со списком файлов настало время легкого (не так – мутного) порожняка, из-за которого и появился таймер 😉

function ota_get_file() получает требуемый файл обновления, кладет его на файловую систему, сверяет контрольную сумму и делает это столько раз, сколько там мы вычитали из filelist.txt. Теоретически, недоступность файла, сервера обновления и-или иные причины приведут лишь к тому, что мы продолжим работать со старой прошивкой в течении нескольких секунд.

В целом – все просто, за исключение одного важного нюанса – больше 4 килобайт в GET-запрос впихнуть не получается. Невелика беда, не лень и нарезать на кусочки, но имейте в виду.

Далее все становится еще проще – запускается скриптик на bash, esp_scripts/send_ota_fw.sh , который генерирует три файла: version.txt, filelist.txt и device_settings.lua, по scp все это “щастье” переправляется в искомую папку на сервере обновлений. Это можно делать и руками, и приблудой с web-мордой на flask – как угодно, не имеет значения. Его надо малость допилить и использовать по назначению, а в целом сейчас стоит задача получения набора данных с MQTT-сервера – где будет лежать и тип сенсоров, подключенных к датчику, то есть первое подключение к брокеру всегда однозначно будет определять, с чем имеем дело, и в этом случае можно попросту отказаться от выделенных папок для каждого отдельно взятого устройства. В ближайших планах (это вынужденная мера, да) – надо “допилить” нотификацию о необходимости обновления.

Leave a Reply

Your email address will not be published. Required fields are marked *