Files
egorin/lora/README_v2.md
T

9.0 KiB
Raw Blame History

Энергомониторинг v2: LoRa + LAN, сервер учёта, интерфейс (Егорин / ORBIT)

1. Архитектура

      ┌─ LoRa-узлы (869 МГц) ──→ Шлюз gw1 (ESP32 + RA-01H + W5500, RJ45) ─┐
                                                                          │ Ethernet
      ┌─ LAN-узлы (WT32-ETH01, RJ45) ─────────────────────────────────────┤
                                                                          ▼
                                              Mosquitto (Proxmox srv001, :1883)
                                                          │
                          ┌───────────────────────────────┼──────────────────┐
                          ▼                               ▼                  ▼
                 provisioner.js                    Home Assistant           n8n
             (учёт устройств, API :8090,        (MQTT Discovery —      (алерты в
              Postgres, HA Discovery)            сущности сами)        @Svetdo_bot)
                          ▲
                          │ REST
                    Веб-интерфейс (ui-prototype.html → далее React)

Правило выбора транспорта узла: есть розетка RJ45 в щите → LAN-узел (WT32-ETH01, надёжнее, чаще телеметрия, LWT-статус). Кабеля нет → LoRa-узел через шлюз. Протокол данных у обоих одинаковый.

2. Железо (дополнение к v1)

Позиция Модель Цена Прим.
LAN-узел WT32-ETH01 (ESP32 + LAN8720, RJ45) 700–900 ₽ вместо DevKit+RA-01H
Шлюз v2 ESP32 DevKit + RA-01H + W5500 mini +250 ₽ к v1 Ethernet вместо WiFi
PoE-вариант Olimex ESP32-POE ~2500 ₽ питание по одному кабелю, для мачт/удалённых щитов

Распиновка WT32-ETH01: PZEM на IO5/IO17 (UART2); входы реле IO32/IO33 (внутренний pullup) и IO35/IO36 (только вход — внешний pullup 10к на 3.3V); выходы реле IO2/IO4/IO14/IO15. Шлюз: LoRa и W5500 на общей шине VSPI (SCK18/MISO19/MOSI23), CS: LoRa=5, W5500=4.

3. Единое пространство топиков (v2)

Топик Направление Содержимое
nodes/<id>/info узел → сервер, retained паспорт: {"id","fw","hw":"lan|lora","caps":{"pzem":true,"relays":4,"ctl":true},"ip","mac","gw"}
nodes/<id>/data узел → сервер телеметрия: v, a, w, kwh, pf, hz, r[], seq (+rssi/snr/gw для LoRa)
nodes/<id>/status LAN-узел → сервер online/offline (LWT). LoRa-узлам статус ставит сервер по таймауту last_seen
nodes/<id>/cmd сервер → узел {"cmd":"relay","n":0,"s":1} · {"cmd":"poll"} · {"cmd":"info"}
gateways/<id>/status шлюз online/offline (LWT)

LAN-узлы публикуют напрямую; LoRa-узлы шлют JSON с полем "t":"info"|"d", шлюз раскладывает по тем же топикам и добавляет rssi/snr/gw.

4. Механизм добавления устройств на сервер

Принцип: узел регистрируется сам, человек только подтверждает. Прошивка одинаковая для всех узлов, отличается только NODE_ID — на объекте монтажнику ничего настраивать не нужно.

  1. Выход в эфир. При включении узел публикует nodes/<id>/info (retained). LoRa-узел делает то же через шлюз. Повтор раз в 10 минут.
  2. Регистрация. provisioner.js видит неизвестный node_id → создаёт запись в devices со status='pending'. Паспорт (транспорт, IP/MAC или шлюз+RSSI, прошивка, число реле) сохраняется автоматически.
  3. Интерфейс. На экране «Устройства» появляется янтарная полоса «Обнаружены новые устройства» со списком pending-узлов.
  4. Мастер добавления (3 шага):
    • Паспорт — проверка, что это ожидаемый узел (ID, транспорт, RSSI/IP, реле);
    • Параметры — название, проект (Егорин/ORBIT), объект, имена реле;
    • Подтверждение — POST /api/devices/<id>/approve.
  5. Автопубликация в HA. При approve сервис публикует retained-конфиги MQTT Discovery (homeassistant/sensor|switch/.../config) — датчики V/A/W/кВт·ч и выключатели реле появляются в Home Assistant без правки yaml.
  6. Жизненный цикл. pending → active → disabled. Disabled-узел данные пишет, но скрыт с борда и не публикуется в HA. Повторное включение — снова approve.

Замена узла в поле: новый узел с тем же NODE_ID подхватывает старую карточку (info обновит fw/mac), история сохраняется.

5. REST API (provisioner.js, :8090)

Метод Путь Назначение
GET /api/devices?status=pending|active&project=egorin|orbit список + последняя телеметрия (view v_devices_board)
POST /api/devices/:id/approve {name, project, object, relay_names[]} → active + HA Discovery
POST /api/devices/:id/disable скрыть/отклонить
POST /api/devices/:id/cmd команда узлу, пишется в журнал commands
GET /api/devices/:id/history?hours=24 ряды для графиков
GET /api/devices/:id/relay-events журнал переключений реле

Запуск: npm i mqtt pg express && node provisioner.js (ENV: MQTT_URL, PG_URL, PORT). Схема БД — schema.sql (Postgres).

6. Структура интерфейса (ORBIT design system)

Стиль: фон #070a10, акцент #4ADE80, Unbounded + Onest + JetBrains Mono, glassmorphism-карточки. Desktop ≥1024: левый рейл 80px; mobile: нижний таб-бар (паттерн ORBIT GPS). Рабочий прототип — ui-prototype.html.

├─ Обзор            сводка по проектам: Σ кВт·ч сегодня/месяц, узлы в сети,
│                   последние события реле, состояние шлюзов
├─ Устройства  ★    основной экран (реализован в прототипе):
│   ├─ фильтр-чипы  Все / Егорин / ORBIT
│   ├─ полоса «Обнаружены новые устройства» (pending) → мастер добавления
│   ├─ сетка карточек: статус-точка с пульсацией, бейдж LAN/LoRa+RSSI,
│   │   метрики В·А·Вт·кВт·ч (mono), тумблеры реле с именами, last seen
│   └─ карточка узла (drill-down, след. итерация): графики W/kWh за 24ч/30д,
│       журнал реле, паспорт, кнопки poll / перезапрос info / disable
├─ Шлюзы            gw1..N: online, IP, число узлов, средний RSSI по узлам
├─ Журнал           relay_events + commands: кто переключил, что, когда, источник
└─ Настройки        MQTT-брокер, таймаут offline, частота/SF сети, ретенция БД

7. Порядок внедрения

  1. Postgres: применить schema.sql (LXC на srv001).
  2. Запустить provisioner.js (Docker/LXC, systemd).
  3. Прошить шлюз gateway_lora_eth.ino, воткнуть в свитч щитовой.
  4. Прошить узлы: LAN — node_lan_energy.ino, LoRa — node_lora_energy_v2.ino (уникальные NODE_ID: eg01…, orb01…, eg-lan1…).
  5. Узлы появятся в pending → добавить через мастер → проверить сущности в HA.
  6. n8n: подписка на nodes/+/data, алерты в @Svetdo_bot (узел offline >5 мин, ток выше порога, внеплановое отключение реле).