Прошивка для ESP8266 на ESP-01/ESP-01s, Wemos/LOLIN D1 mini и ESP-07S с web-порталом и интеграцией в HomeAssistant.
Одна кодовая база, три типа устройств: одноканальное реле, банк из восьми реле и датчик температуры DS18B20. Конкретный образ выбирает и плату, и тип устройства; ядро — портал, Wi-Fi, MQTT, настройки и OTA — у всех общее.
| Окружение | Плата | Устройство | Версия | Пин |
|---|---|---|---|---|
esp01_relay |
ESP-01 | Реле | 4.5.0 | GPIO0 |
d1_mini_relay |
D1 mini | Реле | 4.5.0 | D1 (GPIO5) |
esp07s_relay8 |
ESP-07S | 8 реле | 4.5.0 | 16,14,12,13,15,0,4,5 |
esp01_ds18b20 |
ESP-01 | Датчик температуры | 4.5.0 | GPIO2 (OneWire) |
d1_mini_ds18b20 |
D1 mini | Датчик температуры | 4.5.0 | D2 (GPIO4, OneWire) |
Все пять образов проверены на живом железе: портал, MQTT и обновление по воздуху работают на каждом.
Номер версии общий для всех устройств — ядро одно, и правка в нём выходит сразу для всех. Подробнее об этом и обо всех изменениях — в разделе История версий.
-
Web-портал для управления и настройки, без приложений и облаков.
-
MQTT и интеграция с HomeAssistant через автообнаружение: discovery, состояние и доступность публикуются retained, а завещание (Last Will) переводит пропавшее устройство в
offline. Одно физическое устройство может публиковать несколько сущностей — так работает банк из восьми реле. -
Обновление по воздуху тремя путями: кнопкой прямо в портале из свежего релиза на GitHub, файлом через страницу портала и через
espotaиз PlatformIO. -
Точка доступа при недоступном Wi-Fi. Устройство поднимает свою сеть, чтобы его можно было перенастроить, и само возвращается в режим клиента, как только сеть появится — без перезагрузки. Короткое моргание связи ничего не запускает: сначала выжидается 10 секунд.
-
Поиск сетей на странице Wi-Fi. Показываются три самые сильные сети, повторяющиеся SSID убираются, уровень сигнала виден столбиками, а нажатие переносит имя сети в форму. Сканирование асинхронное, поэтому портал и остальные задачи не замирают.
-
Опциональная авторизация портала. Логин и пароль закрывают и портал, и страницу обновления прошивки. Сохранённый пароль обратно в форму не выводится.
-
Часы по NTP с выбором часового пояса. Запрос и ответ разнесены во времени, поэтому неотвечающий сервер не останавливает устройство.
-
Настройки переживают обновление прошивки: новый параметр получает значение по умолчанию, остальные не трогаются.
-
Лог с уровнями — в Serial и на страницу
/logпортала, читается и глазами, и грепом:[ 0.043] I boot start Relay v4.5.0 built=10.08.2026 [ 0.044] I boot chip=a1b2c3 heap=31240 flash=DOUT reset=External System [ 2.117] I wifi connected ip=10.0.1.22 rssi=-61 [ 4.980] I ntp synced time=12:04:33 [ 1204.551] W dev sensor read failed value=-127.0Отметка времени — аптайм: часы появляются только после NTP, а самое интересное происходит до него. Загрузочный баннер называет версию, дату сборки, chip ID, свободную кучу, режим флеша и причину сброса, а каждая перезагрузка объясняет свою причину. Паролей в логе нет — печатается только факт смены. Уровень отсекается при сборке: по умолчанию
INFO,-D LOG_LEVEL=4добавляет отладочные строки,-D LOG_LEVEL=2оставляет предупреждения и ошибки и освобождает около 4,8 КБ флеша. Разбор формата — в ARCHITECTURE.md и ADR 0009. -
Ничего не блокирует главный цикл. MQTT подключается асинхронно, и недоступный брокер не останавливает портал на время TCP-таймаута. Опрос датчика, синхронизация времени и попытки Wi-Fi разнесены во времени. Страницы, после сохранения которых устройство перезагружается, сначала отвечают браузеру и только потом уходят в перезагрузку.
- Управление как высоким, так и низким уровнем сигнала —
Relay invert mode. - Импульсный
Button mode: командаONнажимает реле на 500 мс и отпускает само, без блокировки портала и MQTT. ПовторнаяONначинает отсчёт заново,OFFотпускает досрочно. На главной странице портала в этом режиме вместо переключателя показывается кнопкаPush— защёлкивать нечего. - Сохранение состояния реле при потере питания. В
Button modeнастройка скрыта: полусекундный импульс во флеш не пишется. - Пять суточных таймеров на странице
Timersс действиями «включить», «выключить», «переключить». ВButton modeвыборActionскрыт — таймер всегда даёт импульсOn, а ранее выбранные действия сохраняются и возвращаются вместе с обычным режимом.
Те же режимы отдельно для каждого канала: своя подпись, инверсия, Button mode
и восстановление состояния. Home Assistant получает восемь независимых
switch-сущностей со стабильными идентификаторами relay_1 … relay_8, общими
state и availability и отдельными command/discovery-топиками.
Пять таймеров общие для платы, и каждый содержит выбор целевого канала либо
пункт All relays — действие сразу для всех восьми.
- Один датчик на шине OneWire.
- Настраиваемый период опроса.
- Медианный фильтр показаний. Ошибки чтения и значения вне диапазона
−55…125 °C отбрасываются и в HomeAssistant не попадают: пока достоверного
значения нет, HA показывает
unknownвместо выдуманного числа.
- Подключиться к точке доступа устройства. Она называется по имени устройства
плюс «AP»:
ESP Relay APу реле,ESP Temperature APу датчика; - Откроется портал; если не открылся — перейти по адресу 192.168.4.1;
- Нажать
Configuration, затемWiFi configuration; - Выбрать найденную сеть (SSID подставится в форму) и указать пароль. Скрытую сеть можно ввести вручную;
- Нажать
Save.
Устройство попробует подключиться секундой позже, перезагрузка не нужна. Секунда нужна, чтобы страница успела ответить: подключение переключает радио, и без паузы ответ на сохранение терялся. При успехе статус Wi-Fi станет зелёным, появятся уровень сигнала и IP-адрес, а точка доступа отключится, как только вы от неё отключитесь. Если данные не подошли, точка доступа останется поднятой и их можно сразу исправить на той же странице.
Дальше подключитесь к своей сети и откройте портал по этому IP-адресу.
Повторные попытки подключения идут с нарастающими паузами: через 30 секунд, минуту, дальше каждые три минуты. Отсчёт до следующей попытки виден на главной странице портала. Пока на портале открыта страница, радио не переключается.
Если Wi-Fi пропадёт у уже настроенного устройства, оно выждет 10 секунд — короткое моргание связи ничего не запускает — и попробует подключиться заново. Точка доступа поднимется, только если и эта попытка не удалась; тогда устройство снова можно перенастроить.
В Configuration → Preferences включается Authorization с логином и
паролем. Поля появляются только при включённом чекбоксе; после сохранения
устройство перезагрузится, и портал вместе со страницей обновления прошивки
начнёт запрашивать эти данные.
Сохранённый пароль обратно в форму не выводится: пустое поле оставляет его без изменений, пока логин не менялся. При смене логина нужно задать новый пароль — иначе новый пользователь незаметно получил бы секрет прежнего.
Устройство показывает, что вышло в релизах, и умеет обновиться само. Компьютера с репозиторием не нужно: достаточно открыть портал с телефона или ноутбука, у которого есть интернет.
- главная страница добавляет строку
New version X.Y.Z available, если релиз свежее установленной прошивки, и молчит, если обновляться не на что; Configuration→Firmware upgradeпоказывает результат проверки всегда:Up to date, номер новой версии илиGitHub unreachable;- кнопка
Installскачивает нужный образ и отправляет его на устройство, показывая ход загрузки и прошивки. Дальше устройство перезагружается само.
Свой образ среди пяти прошивка находит по имени: Relay, Relay_D1_mini,
Relay_ESP07S_8ch, DS18B20, DS18B20_D1_mini. Если в релизе нужного образа
нет или он не помещается в оставшийся флеш, страница скажет об этом до
скачивания.
Вместе с файлом на устройство уходят размер и md5 из манифеста, и устройство
сверяет принятые байты само. Это единственная сквозная проверка образа на пути
зеркало — браузер — устройство: посчитать хэш в браузере нельзя, портал
работает по http, а crypto.subtle доступен только в защищённом контексте. Не
сошёлся хэш — прошивка не применяется, устройство остаётся на прежней.
В интернет ходит браузер, а не устройство: HTTPS на ESP8266 стоит больше флеша, чем осталось у ESP-01 и ESP-07S. Поэтому при подключении к точке доступа самого устройства проверка честно сообщит, что GitHub недоступен, а ручная заливка файлом продолжит работать. Разбор — в ADR 0012 и ADR 0013.
Путь для отката, непубликованных сборок и случая, когда у браузера нет доступа в интернет.
- Скачать последний опубликованный релиз
либо собрать образ самостоятельно. Выбрать файл строго для своей платы и
устройства:
ESP_Relay_...bin,ESP_Relay_D1_mini_...bin,ESP_Relay_ESP07S_8ch_...bin,ESP_DS18B20_...binилиESP_DS18B20_D1_mini_...bin. Образы разных плат взаимозаменять нельзя. - Открыть
Configuration→Firmware upgrade. - Нажать
OTA firmwareи выбрать.bin. - Дождаться
Update success, после чего подождать не менее 25 секунд. - Вернуться на главную страницу и проверить версию в
Information.
Опубликованный релиз может отставать от release_version в рабочей ветке.
Непубликованный образ при необходимости собирается из исходников нужного
коммита; для штатного обновления следует использовать файл из release.
У ESP-01 нет USB, поэтому обычный способ обновления — espota на адрес устройства:
pio run -e esp01_relay -t uploadАдреса устройств в конфигурации сборки репозитория не хранятся, поэтому команда выше сработает только если адрес задан локально. Разово его можно передать ключом:
pio run -e esp01_ds18b20 -t upload --upload-port 192.168.1.50Чтобы не писать каждый раз, заведите рядом с platformio.ini файл
platformio_override.ini — он подключён через extra_configs и лежит
в .gitignore:
[env:esp01_relay]
upload_port = 192.168.1.40
[env:d1_mini_relay]
upload_protocol = espota
upload_port = 192.168.1.41
[env:esp07s_relay8]
upload_protocol = espota
upload_port = 192.168.1.42
[env:esp01_ds18b20]
upload_port = 192.168.1.50
[env:d1_mini_ds18b20]
upload_protocol = espota
upload_port = 192.168.1.51Файл необязательный: без него всё собирается, ругаться будет только -t upload.
Для D1 mini и ESP-07S по умолчанию выбран esptool: первую прошивку можно
залить по UART командой соответствующего окружения. У D1 mini UART встроен:
pio run -e d1_mini_relay -t uploadПоказанные выше upload_protocol = espota и upload_port переводят это
окружение на обновление по сети.
Так залить нельзя ни один из способов выше: espota работает только с
устройством, где эта прошивка уже стоит. Чистый ESP-01 прошивается через
USB-UART переходник, GPIO0 на землю в момент подачи питания. Протокол задаётся
только в конфигурации — ключа командной строки для него нет, поэтому опишите
провод в том же platformio_override.ini, поверх espota:
[env:esp01_relay]
upload_protocol = esptool
upload_port = /dev/cu.usbserial-XXXX
upload_speed = 115200и запускайте обычное pio run -e esp01_relay -t upload. После первой прошивки
строки можно убрать и вернуться к обновлению по воздуху.
D1на плате D1 mini подключить к управляющему входуINреле.GNDD1 mini иGNDмодуля реле должны быть общими.- Питание модуля подаётся по его спецификации; катушку на 5 В нельзя питать от
вывода
3V3. - Управляющий вход модуля должен корректно распознавать логический уровень 3,3 В.
D1 — это маркировка D1 mini для GPIO5. Это не GPIO1: переносить номер с
шёлкографии платы в RELAY_PIN как обычное число нельзя. Если реле активно
низким уровнем, после первого запуска включите Relay invert mode в
Configuration → Preferences.
- вывод данных DS18B20 подключить к
D2(GPIO4); - между
D2и3V3установить подтягивающий резистор 4,7 кОм; - питание датчика подключить к
3V3, землю — кGND.
Окружение d1_mini_ds18b20 задаёт этот пин явно как ONE_WIRE_PIN=D2.
До 4.4.0 шина была на D4/GPIO2 — это загрузочный пин ESP8266, и внешней шине
на нём делать нечего.
Нужен PlatformIO — расширение для VSCode либо pio
в командной строке. Зависимости он поставит сам при первой сборке.
pio run -e esp01_relay # реле
pio run -e d1_mini_relay # реле на D1 mini, пин D1
pio run -e esp07s_relay8 # восемь реле на ESP-07S
pio run -e esp01_ds18b20 # датчик температуры
pio run -e d1_mini_ds18b20 # датчик температуры на D1 mini, пин D2Без -e собирается реле для ESP-01: именно esp01_relay указано в
default_envs. Готовые файлы ложатся в .pio/build/<окружение>/:
.pio/build/esp01_relay/ESP_Relay_v4.5.0.bin
.pio/build/d1_mini_relay/ESP_Relay_D1_mini_v4.5.0.bin
.pio/build/esp07s_relay8/ESP_Relay_ESP07S_8ch_v4.5.0.bin
.pio/build/esp01_ds18b20/ESP_DS18B20_v4.5.0.bin
.pio/build/d1_mini_ds18b20/ESP_DS18B20_D1_mini_v4.5.0.bin
В конце сборки печатается строка вида
OTA headroom: 477216 of 481280 bytes used (99.2%), 4064 left
Это остаток до предела, за которым прошивка перестанет обновляться по воздуху. Предел задаётся профилем платы: 481280 байт для ESP-01 и релейной платы ESP-07S с 1 МБ флеша, 1044464 байта для D1 mini с 4 МБ. При превышении сборка падает.
Версия платформы прикреплена (espressif8266@4.2.1). Без этого образы из CI
выходили на 3,3 КБ больше локальных при том же исходном коде, а на однометровых
платах такая разница — это разница между «влезает» и «нет». Обновлять её нужно
осознанно, вместе с пересчётом всех строк OTA headroom.
Образы ESP-01 собираются в режиме флеша dout, хотя манифест платы предлагает
qio. Под этим профилем в парке оказался не только настоящий ESP-01 с внешней
флеш-памятью, но и ESP8285 со встроенной, которой qio не подходит: прежний
SDK это терпел, а новый перестал, и устройство замерло на инициализации радио.
dout работает на обоих видах чипов ценой чуть более медленного чтения флеша.
Режим устройства виден в загрузочном баннере полем flash=; по воздуху он не
меняется никогда — Updater сохраняет режим работающей прошивки, поэтому
исправить его можно только заливкой по UART.
То же самое повторяется на GitHub Actions при каждом push в main/dev и на
каждый pull request: юнит-тесты плюс сборка шести окружений, включая
диагностическое esp01_relay_metrics. Строка OTA headroom каждого окружения
попадает в сводку прогона, а bin и elf — в артефакты, где лежат 30 дней.
Тег вида version_4.5.0 дополнительно собирает прошивки заново и публикует их
в GitHub Release. В релиз идут обычные образы реле для всех трёх плат и датчика
для ESP-01/D1 mini; диагностическая сборка туда не попадает. Если версия в теге
не совпадает с release_version из platformio.ini, публикация падает, не
создав релиз.
Те же образы вместе с manifest.json уезжают на GitHub Pages — это зеркало для
страницы обновления в портале. Ассеты релиза ей не годятся: они отдаются без
заголовка Access-Control-Allow-Origin, и браузер запрещает их читать со
страницы устройства. Шаги публикации стоят в workflow после создания релиза,
поэтому сломанное зеркало не ломает выпуск прошивок.
Зеркало требует двух настроек репозитория, которых нет в коде:
- Settings → Pages → Source =
GitHub Actions. Сайт, заведённый из ветки, остаётся в режимеlegacy, иdeploy-pagesотказывается разворачивать в него артефакт. В workflow стоитenablement: true, который переводит режим сам, но право на это у токена должно быть. - Settings → Environments →
github-pages→ Deployment branches and tags: добавить правило для теговversion_*. По умолчанию окружение разрешает деплой только с ветки по умолчанию, а релиз идёт с тега, и публикация падает сTag "version_X.Y.Z" is not allowed to deploy to github-pages due to environment protection rules.
Логика, не зависящая от железа, гоняется на хосте:
pio test -e native160 тестов. Покрыты слой настроек, автоматы подключения к Wi-Fi и MQTT, расписание таймеров, таблица часовых поясов, имена MQTT-топиков, разбор команд MQTT, часы NTP, отложенная перезагрузка, управление реле и медианный фильтр датчика. Требуют железа и тестами не покрываются портал, сетевой транспорт Wi-Fi/MQTT и файловая система; для них есть runbook проверки.
Для того, что тестами не покрыть, рядом лежит наблюдатель MQTT — он показывает
флаг retain, которого не печатают обычные утилиты:
cp tools/broker.ini.example tools/broker.ini # вписать адрес и пароль
python3 tools/mqtt_watch.py 'homeassistant/switch/ESP_Relay/#' 30Зависимостей у него нет, протокол разобран вручную. tools/broker.ini
в .gitignore — в нём пароль от брокера.
Окружение задаёт плату, а также -D DEVICE_RELAY, -D DEVICE_RELAY_BANK либо
-D DEVICE_DS18B20. Для одноканального реле оно дополнительно задаёт
RELAY_PIN: на ESP-01 это 0, на D1 mini — символьное D1, которое Arduino
core платы преобразует в GPIO5. Для датчика окружение задаёт ONE_WIRE_PIN:
GPIO2 на ESP-01 и символьное D2 (то есть GPIO4) на D1 mini. Банк явно требует все
RELAY1_PIN … RELAY8_PIN. src/main.cpp по этому флагу подключает нужный
каталог lib/device_*. Сборка без флага падает с понятной ошибкой: молча
собранная не тем устройством прошивка уехала бы на железку и щёлкнула чем
попало.
lib/core/ портал, WiFi, MQTT, загрузка — общее для всех устройств
lib/settings/ слой хранения настроек поверх GyverDB
lib/device_relay/ реле: пин, инверсия, таймеры
lib/device_relay_bank/ восемь реле и таймеры с целевым каналом
lib/device_ds18b20/ датчик: опрос шины, фильтрация
lib/median_filter/ медианный фильтр, чистая логика
lib/ntp_clock/ часы и автомат синхронизации, чистая логика
lib/mqtt_client/ асинхронный MQTT-адаптер и автомат переподключения
lib/mqtt_topics/ имена топиков и санация имени устройства
lib/timezone_table/ часовые пояса: подписи для портала и смещения
test/ тесты для pio test -e native, там же фейк Arduino
tools/ наблюдатель MQTT для проверок на живом брокере
Новое устройство — это новый каталог lib/device_*, реализующий контракт из
lib/core/core_contract.h, и новое окружение в platformio.ini. Ядро при этом
не меняется.
- ARCHITECTURE.md — устройство системы, границы модулей и инварианты совместимости;
- журнал ADR — почему приняты ключевые архитектурные решения;
- runbook проверки — сборки, метрики и smoke-тесты на железе;
- SECURITY.md — модель безопасности и известные ограничения.
Номер версии описывает кодовую базу, а не устройство: ядро одно, и любая правка в нём выходит сразу для всех прошивок. До 3.5.0 номера были свои — реле вело линию 3.x, датчик считался от 0.1.0 — но шли они всё равно в ногу. У датчика номер поэтому прыгнул с 0.1.7 сразу на 3.5.0: это не признак большой переделки, а переход на общую нумерацию.
У датчика температуры убрано поле Temperature label. Подпись показания на
главном экране портала теперь берётся из общего Device name — там же, откуда
её брали реле и откуда всегда бралось имя сущности Home Assistant. Отдельная
подпись означала два имени одного устройства: в HomeAssistant она не попадала
никогда, а в портале расходилась с именем в заголовке страницы и в MQTT.
Сохранённое значение старого поля остаётся в базе неиспользованной ячейкой:
удалить один параметр слой настроек не умеет, а сбрасывать ради неё все
настройки миграцией нельзя.
Страница обновления перестала ложно отказывать в установке. Устройство
сообщало браузеру свободное место по формуле обработчика GyverPortal, от
которого прошивка отказалась ещё в 4.3.1: на сектор меньше, чем принимает
собственный приёмник образа. Из-за этого ESP-07S показывал новую версию и не
давал её поставить, промахиваясь мимо предела на 48 байт, хотя образ помещался.
Теперь сравнивается округлённый до сектора размер с настоящим
getFreeSketchSpace(). Заливка через espota этой ошибкой затронута не была.
Шина DS18B20 на D1 mini перенесена с D4/GPIO2 на D2/GPIO4. Перед обновлением такой платы нужно переставить провод данных датчика и подтягивающий резистор. GPIO2 — загрузочный пин ESP8266: он обязан быть высоким в момент сброса, и держать на нём внешнюю шину незачем, когда рядом есть обычный GPIO. У ESP-01 такого выбора нет, там шина остаётся на GPIO2.
Образы ESP-01 теперь собираются в режиме флеша dout вместо qio. Под этим
профилем в парке оказался не только настоящий ESP-01 с внешней флеш-памятью, но
и ESP8285 со встроенной, которой qio не подходит: прежний SDK это терпел, а
пришедший с 4.3.1 перестал, и устройство замерло на инициализации радио. По
воздуху режим не меняется — Updater сохраняет режим работающей прошивки, —
поэтому исправляется он только заливкой по UART.
Загрузочный баннер теперь называет режим флеша полем flash=. Иначе узнать
его можно было, только сняв устройство и подключив UART.
Приём образа перешёл от CustomOTA GyverPortal к своему обработчику. Тот
объявлял приёмнику весь свободный флеш вместо настоящего размера файла и тем
терял 4 КБ у предельного образа: релиз 4.3.0 не вставал на ESP-01 через портал,
промахиваясь мимо предела на 48 байт. Заодно устройство теперь сверяет md5
принятого образа с манифестом, а отказ от чужого модуля освободил 2 КБ. Разбор
— в ADR 0013.
В этой же версии прикреплена версия платформы сборки. Прежде она не была задана, и образы из CI выходили на 3,3 КБ больше локальных.
Портал сам показывает, что вышел новый релиз, и умеет обновиться по кнопке — компьютер с репозиторием больше не нужен. В интернет при этом ходит браузер, а не устройство: HTTPS на ESP8266 стоит больше флеша, чем осталось у ESP-01 и ESP-07S. Разбор — в ADR 0012.
Добавлен образ DS18B20 для D1 mini с шиной OneWire на D4/GPIO2. Пин датчика теперь задаётся окружением явно и больше не зашит в модуль устройства.
Выход одноканального реле D1 mini перенесён с D2/GPIO4 на D1/GPIO5. Перед обновлением такой платы нужно соответственно переставить управляющий провод релейного модуля.
У таймеров банка появился девятый вариант цели All relays. Он выполняет
выбранное действие сразу для восьми каналов; каналы в Button mode по-прежнему
получают импульс On. Сохранённые цели реле 1–8 не изменились.
Профиль ESP-07S исправлен под фактические 1 МБ Flash на релейной плате. Образ
4.0.0 был ошибочно размечен под 4 МБ и отклонялся OTA-проверкой устройства с
сообщением new Flash config wrong real: 1048576.
Добавлена восьмиканальная плата ESP-07S. Каждый канал имеет свою подпись,
инверсию, Button mode и сохранение состояния. Home Assistant получает восемь
независимых switch-сущностей со стабильными ID relay_1 … relay_8, общими
state/availability и отдельными command/discovery-топиками. Пять общих суточных
таймеров дополнены выбором целевого реле.
Добавлена D1 mini для реле, а пин и OTA-предел теперь задаются профилем платы.
Главная страница реле в Button mode показывает кнопку Push вместо
переключателя. Переключатель обещал защёлку, которой в этом режиме нет: импульс
живёт полсекунды и отпускается сам, поэтому switch почти всё время показывал
OFF и просил вернуть себя вручную.
Переделан лог: у строки появились уровень, время от загрузки и тег подсистемы,
а событие записывается полями key=value. Заодно закрыты пробелы в том, что
вообще попадало в лог — раньше об успешном подключении к Wi-Fi не было ни
строки, загрузка не называла ни версию, ни причину сброса, а изменения настроек
и ошибки обновления не отмечались вовсе. Формат описан в разделе
«Возможности».
Настройка Save relay status скрывается при включённом Button mode: для
полусекундного импульса сохранение состояния не имеет смысла. На странице
таймеров в этом режиме также скрыт выбор Action. Уровень Wi-Fi на главной
странице теперь использует ту же шкалу, шрифт и четыре столбика сигнала, что
сети в Available networks.
Страница настройки Wi-Fi автоматически сканирует эфир по образцу Tasmota: показывает сначала три самые сильные сети, убирает повторяющиеся SSID, показывает уровень сигнала и по нажатию переносит выбранное имя в форму.
У реле появился Button mode: вместо защёлкивания команда включения держит
выход активным 500 мс и автоматически отпускает его. Режим работает одинаково
для web-портала, MQTT и суточных таймеров.
Добавлена опциональная авторизация портала: без credentials и с неверным
паролем основной портал и web-OTA отвечают 401, с правильными — 200.
MQTT подключается асинхронно. Недоступный брокер больше не останавливает
loop() и web-портал на время TCP-таймаута. MQTT только читает состояние
Wi-Fi; режимами STA/AP и повторными попытками по-прежнему управляет отдельный
Wi-Fi-автомат.
Страницы, после сохранения которых устройство перезагружается — MQTT configuration и смена имени устройства в Preferences, — сначала отвечают браузеру и только через секунду уходят в перезагрузку. Прежде ответ терялся вместе с соединением и страница просто висела.
Обновление заводит сущность в HomeAssistant заново. Устройство сообщает о себе иначе:
uniq_idстал уникальным на сущность,object_idперестал тащить в себе MAC, а топик доступности переименован изavaibleвavailable. HA такие изменения на живую сущность не переносит, поэтому прошивка сама снимает прежнюю и объявляет новую — от вас ничего не требуется, ноentity_idизменится, а с ним отвяжется история и сломаются ссылки на сущность в автоматизациях и карточках.Прежний
entity_idвидаswitch.esp_esp_relay_dc_4f_22_4d_21_97станетswitch.esp_relay. Хотите сохранить историю — переименуйте старую сущность в HomeAssistant в будущее имя до обновления: HA переносит историю на новыйentity_idсам, и новая сущность подхватит его же.
Прошивки перешли на общую нумерацию версий: до этого реле вело линию 3.x, а датчик считался от 0.1.0.
Обновление сбрасывает настройки один раз. Хранилище переехало на слой с новыми именами параметров, поэтому после прошивки устройство поднимет точку доступа, и Wi-Fi с MQTT нужно указать заново (см. «Первоначальная настройка»). Дальше настройки переживают обновления: новый параметр получает значение по умолчанию, остальные не трогаются.
Заодно убран выбор темы портала — осталась тёмная. Это освободило около 10 КБ флеша, которых на ESP-01 не хватало для обновления по воздуху.




