Обычно Meshtastic используют как мессенджер. Я применил его как резервный канал связи с удаленным объектом.
Задача простая: есть дача с регулярно отключаемым мобильным интернетом. При этом нужно получать алармы от автоматики дачи. И иметь возможность минимального управления оборудованием, например, проверить состояние бойлера, выключить свет или посмотреть температуру в помещении.
И я сделал это. Как – читайте ниже.

Что такое Meshtastic
Meshtastic — это открытый проект, который строит децентрализованную mesh-сеть для обмена сообщениями по радиоканалу LoRa, без использования сотовой связи и интернета.
Узлы сети — это недорогие устройства на базе ESP32 с LoRa-модулем. Они обмениваются короткими сообщениями как напрямую, так и ретранслируют их друг через друга.
Основные свойства:
работает в нелицензируемых диапазонах LoRa (433/868/915 МГц — зависит от региона);
передает небольшие пакеты данных;
поддерживает сквозное шифрование;
маршрутизация сообщений производится автоматически;
радиомодули LoRA подключаются к телефону или ПК по Bluetooth, Wi-Fi или USB.
Итого: Meshtastic — это такая «народная» сеть для передачи данных. Главный недостаток — очень низкая пропускная способность. Сеть подходит только для редких коротких сообщений и простой телеметрии.

С чего всё началось
В Казани уже работает сеть Meshtastic, именно ее я и решил использовать.
Стенд собрал на Wiren Board 8.5 с Meshtastic-узлом, состоящим из Pro Micro на базе nRF52840 и LoRa-модулем SX1262. Все это размещено на даче.
На контроллере поднял отдельный сервис, который общается с Meshtastic-узлом через serial/API и сохраняет сообщения в локальную базу данных SQLite.
В моей конфигурации сообщения проходили примерно 50 км. При маршруте в три хопа команда доходила до объекта за 10–15 секунд.
Сначала я просто переключал реле, управляющие освещением и бойлером. Затем добавил чтение температуры воздуха. Обмен данными происходил стабильно.
Но у такого канала есть серьезные ограничения. Задержки непредсказуемы: они зависят от рельефа, размещения нод и загрузки сети. Иногда пакет не доходит вовсе, поэтому каждую команду нужно подтверждать.
Ну и не обойтись без защиты: контроллер принимает команды только от доверенной ноды.
Для задач, требующих гарантированного времени реакции, такой канал не подходит. Но как резерв для управления дачей — вполне рабочий вариант.
Как это работает
Путь команды выглядит так:
Телефон, через подключенный по Bluetooth Meshtastic-узел, отправляет сообщение в mesh-сеть;
сервис на Wiren Board принимает сообщение через CLI или API (по serial) и разбирает его как текстовую команду, если источник доверенный;
сообщение сохраняется в SQLite;
команда публикуется в MQTT и обрабатывается правилами на Wiren Board;
после выполнения команды контроллер отправляет подтверждение отправителю.
Я создал набор текстовых команд, которые сервис умеет обрабатывать:
включи бойлер;
выключи бойлер;
включи свет;
выключи свет;
включи режим охраны;
статус.
Сервис сравнивает текст входящего сообщения с этим списком и при совпадении выполняет необходимые действия (собирает необходимые данные, пакует в пакет и т.д.).
Дополнительные фото


Спойлер: конфигурационные файлы
Сам проект описан подробно на https://github.com/VolkMicro/WB-Meshtastic-control
Основными файлами конфигурации являются controls.yaml и rules.yaml :
controls.yaml
controls.yaml описывает сущности объекта: бойлер, свет, температуру и другие параметры. Это человекочитаемый слой поверх MQTT-топиков Wiren Board.
controls: boiler: title: "Бойлер" type: switch command_topic: "/devices/<device>/controls/<control>/on" state_topic: "/devices/<device>/controls/<control>" payload_on: "1" payload_off: "0" light: title: "Свет" type: switch command_topic: "/devices/<device>/controls/<control>/on" state_topic: "/devices/<device>/controls/<control>" payload_on: "1" payload_off: "0" room_temperature: title: "Температура помещения" type: sensor state_topic: "/devices/<device>/controls/<control>" unit: "°C"
Здесь <device> и <control> — это идентификаторы устройств и контролов в MQTT.
Такой слой убирает жесткую привязку к длинным топикам. В правилах я использую короткие имена (boiler, light, room_temperature), а не строки вида /devices/....
rules.yaml
rules.yaml описывает, как сервис реагирует на входящие сообщения.
trusted_sources: - "<meshtastic_node_id>" rules: - name: "Включить бойлер" match: text: - "включи бойлер" action: type: set_control control: boiler value: true - name: "Выключить бойлер" match: text: - "выключи бойлер" action: type: set_control control: boiler value: false - name: "Запрос статуса" match: text: - "статус" action: type: send_status
Сервис проверяет источник сообщения (по ID ноды Meshtastic), ищет совпадение по тексту и выполняет соответствующее действие.
Заключение
При таком мобильном интернете, как сейчас, приходится искать резервные каналы связи. Один из вариантов — mesh-сеть Meshtastic, которую можно использовать не только для общения.
Если на объекте стоит ПЛК на Linux (например, Wiren Board), то предложенный проект решает эту задачу.
Такой подход не заменяет основной канал связи, но как резерв для простых команд и получения статуса он работает.
