15.04.2026: Христос Воскрес!

Проснулся от требовательного котомява под дверью. С моей стороны двери. Пытался игнорировать, но тщетно. Пришлось вставать.
Сначала глянул на часы. Ох ё! Спать бы мне ещё и спать… Потом на монитор — как там поживает компилирующаяся прошивка? Готово. Скомпилировалась за ночь. Это хорошо.

Правда, вопрос «А почему так долго-то?» повис в воздухе. Ещё одна загадка, ответ на которую я, скорее всего, не узнаю.

Кота выпустил, зевнул и вернулся к столу.

Дальше по плану: заливаем прошивку. Залил. Итог: устройство MeshCore выдало сакраментальное 0.0.0.0.

То есть всё было зря. Лёг поздно не пользы дела для, а просто потому что.

Полез в логи. И чуть не выматерился вслух.

Обычно, глядя на ПО, представляешь швейцарские часы: каждая шестерёнка на своём месте, каждый камешек отполирован. Но за фасадом красивых окошек (или в кромешной тьме консоли) скрывается хаос, бардак и костыли.

Прямо как в том анекдоте про швабры и остров. Кто знает — пропускайте.

Доверили тебе достроить лабораторию на острове. Приходишь — комната под реактором забита швабрами от пола до потолка, снаружи 120-тонный вентилятор, а к крыше привязан воздушный шар. Ты, как нормальный человек, выкидываешь этот колхоз и делаешь всё по уму.

Приходят учёные, через пять минут выбегают с криком: «УТЕЧКА!»

Звонишь прошлому прорабу Васе.
— Вася, газ потёк! Что делать?
— Что менял?
— Да выкинул эти дурацкие швабры…
— ***! Они пол под реактором держали! Проектировщик накосячил с перекрытием! Включай вентилятор, он сдует газ с острова!
— Я его выкинул. Зачем вентилятор? Хватило бы ящика противогазов.
— Противогазы ещё поискать надо, а вентилятор с прошлого объекта остался!
— Нету больше вентилятора…
— ***! Тогда садитесь на шар и валите с острова!

Скрипт сборки этой прошивки — типичный пример. Всё работает, пока в пароле вашего Wi-Fi (который, блин, зачем-то нужно хардкодить прямо в код) не встретится хоть одна скобка (.

Казалось бы — какая разница, что там за символы? Строка и строка. Но нет. Пароль идёт до места назначения через ж… некий путь.

И путь сей тернист, извилист и вонюч: Windows CMD → Docker → Bash → PlatformIO → Компилятор C++

На каждом этапе у бедной скобки своё особое значение:

  1. CMD: ( — группировка команд. «О, вложенная инструкция!».
  2. Docker: ( — разбивка аргументов.
  3. Bash: ( — запуск subshell (подоболочка).
  4. PlatformIO (sed): ( — группа захвата в регулярке. Тут пароль рвётся в клочья.
  5. C++: А вот тут скобка уже безопасна. Но до этого этапа она не доходит.

Три разных инструмента — три разных трактовки одного символа. Пароль просто не может проскочить эту мясорубку, оставаясь обычным текстом.

Да что ж вы все докопались до бедной скобки!??

Что делать?

  • Вариант 1 (для слабаков): Убрать скобки из пароля. Не мой случай. Менять пароль в двух десятках умных розеток и датчиков, где он зашит намертво — то ещё удовольствие. Так что нет, нет и нет!
  • Вариант 2 (для извращенцев): Написать патч, который при запуске воткнёт пароль прямо в исходный код, в обход этого адского конвейера интерпретаций.
  • Вариант 3 (для умных): Установить мессенджер Макс и забыть про любительские текстовые радиосети как страшный сон.

На счёт варианта 3 я серьёзно. Лучше ложиться вовремя спать и не страдать фигнёй, чем вот это вот всё руко**дие.

Вердикт: MeshCore как сеть на порядки круче Meshtastic, спору нет. Но прошивка у него… как сырое жидкое дерьмо криворукого дегенерата. Это субъективное мнение раздражённого пользователя. В Meshtastic пароль вбивается в приложении человеческим способом — и скобки там никого не волнуют.

Часа через два мне удалось накатить прошивку. Устройство само подключилось к Wi-Fi, а мне осталось зарезервировать этот IP в роутере, чтобы не менялся, и интегрировать в Home Assistant.

Прошивку для Heltec V3 с Wi-Fi оставлю тут, на случай если она мне снова понадобится.

meshcore-heltec-wifi-builder-main

Для её работы нужно:

  1. Принять тот факт, что все дальнейшие пункты вы делаете на свой страх и риск, а я за это не несу вообще никакой ответственности. Если не приняли, то не вздумайте выполнять следующие шаги.
  2. Установить Docker для Windows (и всё что нужно для его работы) и включить его.
  3. Распаковать архив в какую-нибудь папку и войти в эту папку.
  4. Отредактировать build_firmware.bat, заменив там название сети Wi-Fi и пароль к ней на свои. Не забыть сохранить!
  5. Запустить build_firmware.bat и долго-долго ждать когда он выполнится полностью.
  6. При успешном выполнении, зайти в подпапку firmware-output и полюбоваться файлом прошивки.
  7. Перейти во флешер Мешкора https://meshcore.co.uk/flasher.html, перемотать страницу до самого низа и кликнуть кнопку Custom Firmware.
  8. Откроется проводник для поиска файла. Зайдите в папку из пункта 3, перейдите в подпапку firmware-output и кликните по бинарнику (файл с созданной вами прошивкой).
  9. Дальше заливаете эту прошивку как если бы шили обычной стандартной. Там надо выбрать COM-порт (к которому подключен USB и всё такое).
  10. После успешной прошивки на экране Heltec V3 появится IP, по которому теперь доступно это устройство. Желательно зарезервировать этот IP в роутере.
  11. По этому IP можно будет подключиться к устройству через приложение на смартфоне и настроить его так как требуется.
  12. После настройки можно пробовать подключать устройство по TCP к Home Assistant, указав IP из шага 10.

Ну и пару мыслей вдогонку.

  • Время компиляции 3 часа и более — это нормально. Смирись.
  • Если вдруг после всех мучений устройство упорно показывает 0.0.0.0 — проверь частоту WiFi. Heltec v3 на ESP32-S3 видит только 2.4 GHz. Если роутер раздаёт 5 GHz с тем же SSID — подключения не будет. Вторая причина — регион WiFi в прошивке (иногда нужно выставить вручную через веб-интерфейс, но я не хочу об этом думать, так что оставлю как есть).
  • Если пароль содержит » или \ (и прочие спецсимволы) — молись, ибо патч может сломаться.

Теперь  осталось настроить устройство и автоматизации к нему непосредственно в Home Assistant, но это уже совсем другой гемор этап. С этим как-нибудь потом. А сейчас — стартую рабочий день.


Всё! Компиляторно-техногенные страдания закончились, и хватит про них. Прошивка готова, устройство в сети — погнали дальше. Тем более, что руки чешутся попробовать следующую идею.

Делаю бота на HASS под Meshcore

К Home Assistant устройство подключилось буднично, словно и не было тех изнурительных многочасовых танцев с бубном, когда пытался присоединить через Bluetooth или напрямую USB-кабелем. Я даже удивился немного.

Теперь переходим к задумке.

Для начала, добавляю публичный канал #bot в устройство. В HASS делаю это скриптом (в разделе Автоматизации и сцены — Скрипты).

sequence:
  - action: meshcore.execute_command
    metadata: {}
    data:
      command: "channel add #bot"
  - action: meshcore.execute_command
    metadata: {}
    data:
      command: "set_channel 1 #bot"
alias: "Добавим #bot"
description: ""

Думаю тут всё понятно. Сначала добавляем канал, а потом присваиваем ему индекс.

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

alias: "MeshCore - Автоответчик понг"
description: "Отправляет понг в ответ на ping'и"
triggers:
  - trigger: event
    event_type: meshcore_message
conditions:
  - condition: template
    value_template: "{{ trigger.event.data.channel_idx == 1 }}"
  - condition: template
    value_template: |
      {{ 'ping' in trigger.event.data.message | lower or 
         'пинг' in trigger.event.data.message | lower or
         'test' in trigger.event.data.message | lower or
         'тест' in trigger.event.data.message | lower}}
actions:
  # Ответ в MeshCore
  - action: meshcore.send_channel_message
    data:
      channel_idx: 1
      message: >
        {% set rx = trigger.event.data.rx_log_data[0] %}
        {% set path_raw = rx.path if rx.path else '' %}
        {% set path_f = (path_raw[0:2] ~ ',' ~ path_raw[2:4] ~ ',' ~ path_raw[4:6]) | upper if path_raw | length >= 6 else path_raw | upper %}
        {% set hops = rx.path_len if rx.path_len else 0 %}
        
        {% if hops > 1 and path_f %}
          @[{{ trigger.event.data.sender_name }}] хопов {{ hops }} ({{ path_f }})
        {% elif hops > 1 %}
          @[{{ trigger.event.data.sender_name }}] хопов {{ hops }}
        {% elif path_f %}
          @[{{ trigger.event.data.sender_name }}] ({{ path_f }})
        {% else %}
          @[{{ trigger.event.data.sender_name }}] pong 🏓
        {% endif %}

Практической пользы ноль, ибо в канале уже живёт хоть и глуховатый, но работающий бот-старожил.

Стоило мне сунуться туда со своим, и некоторые местные пользователи начали всячески ругаться и обзывать словом на букву М. Токсичные люди со странной логикой. Канал называется #bot и создан для ботов, но второй бот, находящийся за пределами  города им мешает… Танцевать очевидно?

Перенёс своего ботика в канал моей областной локации. О нём знают считанные единицы, а потому глаза никому мозолить не будет, зато мне пригодится для дальнейших тестов.


Выдохнул! Улыбнулся. Бот готов. Бот работает ради моего блага. А сообщество поживёт без моего бота. Не принципиально. Зато, пока писал бота, под хмурящееся небо и дождик за окном, задумался вот над чем.

Персонаж — прекрасное изобретение человечества. Он как робот, только лучше. Он как единорог, но его можно встретить, а иногда даже потрогать. При этом, персонаж остаётся существом полумифическим.

У него есть недостатки, но от людей он отличается вовсе не этим, а некоей неполноценностью.

Персонаж не ходит в туалет, например. А если ходит, то ради ивентов или забавных приключений. У него не умирают коты или родственники, а если и умирают, то лишь для развития сюжета или раскрытия характера. У него не болят мышцы после приседания, а если и болят, то лишь для подчёркивания какой-нибудь особенности организма, полноты образа для.

Люди любят персонажей больше людей. Персонажи просты, понятны и предсказуемы, а значит их запросто  можно встраивать в свою картину мира.

Я — какой-то неправильный персонаж. Буду исправлять.

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

Раз не выспался как следует, то и трудовые подвиги сегодня свершать не стал. Весь день гонялся за изменившимися селекторами, чтобы снова сделать тесты зрячими. При этом, спокойно и не сильно напрягаясь, заактуалил их штук 30.

Благо блок предусловий починил ещё вчера.

По окончании рабочего дня, налил ванну и хорошенько попарился. А затем меня ждали задачи от УЦ. Увы, но ради них придётся отложить собственные проекты. Люди просят починить, допилить, доработать, создать нужное им.

Как тут отказать?

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

Заказчику отписался. Чтобы закрыть задачу нужен тест с его стороны.

Да, днём я AQA, вечерами — разраб, а во время полнолуний превращаюсь в туленеобразного дивановаляку, если меня не пинают швабры, скобки и 0.0.0.0

Заказчик ответил, и тут же навалил мне ещё 5 тасков. Сделал самый срочный и стопнул таймер.

Был бы на мне индикатор эмоционального выгорания, он наверняка бы светил оранжевым. Типа пока как бы нет, но ещё немного и таки-да.

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

Однако, надо тщательнее выбирать место для прогулок, когда появляется возможность.

Так что докачиваю обновления игр и решительно обесточиваю рабочее место. Хватит работать. Пора готовиться ко сну.

Доброй ночи, если тоже собираешься.

Напишите комментарий

Введите имя

Введите адрес электронной почты

Введите адрес вашего сайта

Нажмите эту кнопку, чтобы отправить комментарий.

Введите текст комментария