Files
LoraMapTester/server
2026-06-11 09:09:28 +03:00
..
2026-06-11 09:09:28 +03:00
2026-06-11 08:46:49 +03:00
2026-06-11 09:09:28 +03:00
2026-06-11 08:38:08 +03:00
2026-06-11 08:38:08 +03:00
2026-06-11 08:38:08 +03:00
2026-06-11 09:09:28 +03:00
2026-06-11 09:09:28 +03:00
2026-06-11 09:09:28 +03:00

LoraTester Server

Единый HTTP-сервер для телеметрии LoRa, GPS устройств, истории статистики, треков и чата.

Быстрый старт

cd server
python -m venv .venv
.venv\Scripts\activate   # Windows
pip install -r requirements.txt
python flask_app.py

Откройте http://localhost:7634

Переменные окружения

Переменная По умолчанию
LORATESTER_HOST 0.0.0.0
LORATESTER_PORT 7634
LORATESTER_DB ./loratester.db
LORATESTER_TELEMETRY_LIMIT 5000 (записей истории на устройство)
LORATESTER_TRACK_POINTS_LIMIT 10000 (точек на один трек)
LORATESTER_ELEVATION_URL http://192.168.1.109:8085/v1/elevation
LORATESTER_ELEVATION_PROBE_TTL 60 (сек, кэш проверки доступности)
LORATESTER_ELEVATION_TIMEOUT 8 (сек, таймаут HTTP к сервису высот)

Docker Compose

cd server
docker compose up -d --build

Проверка:

curl http://127.0.0.1:7634/api/health | jq

Ожидается "elevation_ok": true если локальный Open-Meteo доступен с хоста/контейнера.

Переопределить URL высот (.env рядом с docker-compose.yml):

LORATESTER_ELEVATION_URL=http://192.168.1.109:8085/v1/elevation

БД хранится в volume loratester-data (/data/loratester.db внутри контейнера).

Деплой (grigowashere.ru:7634)

cd /srv/storage/disk2/services/LoraTester/server
docker compose up -d --build

Или без Docker:

cd /srv/storage/disk2/services/LoraTester/server
pip install -r requirements.txt
export LORATESTER_DB=/srv/storage/disk2/services/LoraTester/loratester.db
export LORATESTER_ELEVATION_URL=http://192.168.1.109:8085/v1/elevation
uvicorn fastapi_app:app --host 0.0.0.0 --port 7634

После обновления кода обязательно перезапустите сервис. При старте выполняются миграции SQLite (devices, telemetry.meta, таблицы tracks).

Проверка:

curl http://127.0.0.1:7634/api/health

Ожидается "db_ok": true, "schema_version": 4, "elevation_ok": true.

Если БД создана вручную и схема битая (no such table: devices / no such column: t.meta):

  1. Остановить сервис
  2. cp loratester.db loratester.db.bak
  3. Удалить loratester.db (или оставить бэкап и дать миграциям дописать колонки после рестарта с новым кодом)
  4. Запустить снова — init_db() создаст полную схему

API

Телеметрия (только Android, заголовок X-Lora-Client: android)

  • POST /api/telemetry{device_id, lat?, lon?, rssi?, meta?, fields?, role?, ts?}
  • GET /api/devices — последнее состояние устройств
  • GET /api/telemetry?device_id=&limit=&since=&until=&role= — история (без raw_frame)
  • GET /api/stats/history?device_id= — то же, alias

Треки (запись с Android)

  • POST /api/tracks/start{device_id}{track_id}
  • POST /api/tracks/{id}/points{points: [{ts, lat, lon, altitude_gps?, rssi?, role?, meta?}]}
  • POST /api/tracks/{id}/finish
  • GET /api/tracks?device_id=
  • GET /api/tracks/{id} — метаданные + точки (высота terrain через локальный Open-Meteo)

Команды (очередь на устройство)

  • POST /api/commands{from_device_id, to_device_id, kind, payload?}
    kind: at (payload.line — одна строка, или payload.lines — массив макроса), mode (payload.role: TX/RX), stats_push (снимок meta/rssi/role/sf/bw)
    from_device_id: web или android-xxxxxxxx
    Макрос обычно: S (стоп TX/RX), затем AT+FQ=, AT+PW=, AT+SF=, AT+BW=, AT+CR=, AT+PL=, AT+TM=, при необходимости AT+TX / AT+RX.

Профиль высот (веб, треки)

  • POST /api/elevation/profile{points: [{lat, lon}], step_m?: 10} → срез рельефа (локальный Open-Meteo)
  • GET /api/tracks/{id}/elevation-profile?step_m=10 — то же по сохранённому треку
  • GET /api/elevation/nearest-hill?lat=&lon=&radius_m=5000 — ближайшая возвышенность (прокси Open-Meteo)
  • GET /api/commands/pending?device_id= — Android, доставка + delivered_at
  • GET /api/commands?to_device_id=&limit= — история (веб)

Синхронный трек (два устройства)

  • POST /api/paired-tracks/start{device_ids?: [a,b], initiator?, device_id?} → сессия armed, start_at = now+3s
  • GET /api/paired-tracks/active{active, session?}
  • POST /api/paired-tracks/ack — Android: {session_id, device_id, track_id}
  • POST /api/paired-tracks/cancel{session_id?}

Прочее

  • POST /api/chat{device_id, text}
  • GET /api/chat?since=0
  • GET /api/health{ok, db_ok, schema_version, database_path, elevation_ok, elevation_url, elevation_error}

FastAPI (прод)

uvicorn fastapi_app:app --host 0.0.0.0 --port 7634

Flask (flask_app.py) — тот же API для локальной разработки.

Тесты

cd server
pip install httpx pytest
python -m pytest tests/ -v

Android

URL: http://grigowashere.ru:7634. На карте: Начать/Остановить трекинг пути — точки с GPS, статистикой приёма и высотой (локальный Open-Meteo на сервере). Вкладка Статистика — история с сервера.

Telnet: 127.0.0.1:2727 — мост COM→telnet на устройстве.