Skip to content

Веб-панель та HTTP API

Waybeam включає вбудовану веб-панель та повний HTTP API для керування параметрами в реальному часі. Веб-панель доступна за адресою http://<ip-камери>/ (порт за замовчуванням — 80) або просто http://waybeam.local — камера анонсує себе через mDNS. Довідник звірено з версією v0.40.1 (липень 2026).


Веб-панель

Вкладка Settings (Налаштування)

Поля конфігурації згруповані за 14 секціями:

СекціяОпис
SystemПорт, розгін, логування
SensorВибір сенсора (index / mode)
ISPЕкспозиція, AWB, AE-движок (aeEngine діє лише на Star6E; на Maruko завжди рідні AE+AWB з пейсером)
ImageДзеркало, фліп, поворот
VideoКодек, бітрейт, FPS, GOP, framing, resilience
OutgoingСтрімінг, адреса, режим
DiscoverymDNS-анонс у мережі (waybeam.local)
AudioКодек, частота, гучність
FPVROI-кодування + 3DNR
IMUГіроскоп BMI270
AttitudeШтучний горизонт: roll/pitch/yaw з IMU, кути монтажу, трими рівня
RecordingЗапис на SD-картку
Adaptive Encoder ControlДетекція сцен
DebugOSD

Елементи інтерфейсу:

  • 🟢 Live — параметр змінюється миттєво без перезапуску
  • 🟠 Restart — потребує reinit пайплайну (автоматично)
  • 🔴 Reboot — потребує повного перезавантаження камери (лише video0.resilience)
  • Apply Changes — застосувати всі змінені поля
  • Save & Restart — застосувати та перезапустити пайплайн
  • Restore Defaults — повернути конфігурацію з диска
Для версій до v0.8 — секція EIS (GyroGlide)

У старих версіях була окрема секція eis (гіроскопна стабілізація GyroGlide). Її видалено у v0.8.0. Стабілізація тепер живе у секції Video — поле video0.framing (див. нижче).

Для версій до v0.40 — 13 секцій, без Attitude

Секція Attitude (живі roll/pitch/yaw і кнопка «Capture level trims») з'явилась у WebUI у v0.40. У версіях 0.24–0.39 секцій було 13, а гіроскоп BMI270 значився у WebUI як POC без споживача.

Власний дашборд

У поточних збірках (липень 2026) вбудований веб-інтерфейс можна замінити, поклавши власні файли в /usr/share/www — вони мають пріоритет над вбудованим дашбордом.

Вкладка API Reference

Документація всіх HTTP-ендпоінтів з прикладами відповідей. Категорії: Configuration, Encoder Control, ISP & Image Quality, Recording, Dual-Stream.

Вкладка Image Quality (ISP)

Прямий доступ до 62 параметрів ISP SigmaStar:

  • Параметри — розгортувані секції з чіпами параметрів
  • Мульти-поля — вбудований редактор для складних параметрів (colortrans, OBC, demosaic тощо)
  • Export / Import — збереження та відновлення ISP-профілів у JSON

HTTP API — довідник

Всі ендпоінти використовують HTTP GET (сумісно з BusyBox wget). Відповіді — JSON у форматі {"ok": true/false, ...}.

Три рівні мутабельності

  • live — застосовується миттєво без переривання потоку
  • restart_required — ініціює автоматичний reinit пайплайну
  • reboot — потребує повного перезавантаження камери (лише video0.resilience)

/api/v1/capabilities показує рівень мутабельності та підтримку кожного поля бекендом.


GET /api/v1/version

Повертає інформацію про версію.

bash
curl http://<ip>/api/v1/version

Відповідь:

json
{
  "ok": true,
  "data": {
    "app_version": "0.40.1",
    "backend": "star6e",
    "contract_version": "0.12.0",
    "config_schema_version": "0.12.0"
  }
}

Значення contract_version / config_schema_version зростають з релізами (наприклад, у v0.19 контракт піднято до 0.11.0 через видалення video0.frameLost, а у v0.40 — до 0.12.0 з появою attitude-API).


GET /api/v1/config — повна активна конфігурація.

GET /api/v1/capabilities — мутабельність кожного поля (live / restart_required) та підтримка бекендом.

bash
curl http://<ip>/api/v1/config
curl http://<ip>/api/v1/capabilities

Перевірка підтримки

Підтримка полів залежить від бекенда. Наприклад, Star6E повертає video0.scene_threshold як підтримуване, а Maruko — ні. Використовуйте capabilities перед записом.

GET /api/v1/modes

Перелік режимів сенсора (pad + роздільність) — поточний вибір і всі режими, які перелічує SDK. Заповнює випадайку в WebUI.

bash
curl http://<ip>/api/v1/modes

Індекси sensor.mode перенумеровано (v0.21–v0.34)

Лінійки режимів перебудовано на обох платформах: Maruko — у v0.21/v0.23, Star6E — у v0.25–v0.34 (власні in-tree драйвери IMX335/IMX415). Star6E-лінійки тепер: IMX335 — 2560×1920@30/60, 2560×1440@90, 2176×1224@100, 1920×1080@120, 1600×900@144; IMX415 — 5 видимих режимів від 4K@~33 до 1728×816@120. Індекси sensor.mode при цьому перенумеровано кілька разів, а режимів стало менше, ніж у стокового драйвера: збережений у конфізі індекс поза новим діапазоном не дає waybeam стартувати. Після оновлення звіряйте старі конфіги зі списком /api/v1/modes або ставте -1 (автовизначення).

Деталі перенумерації v0.21/v0.23 (Maruko)

Лінійки режимів на Maruko перероблено: IMX415 отримав non-binned 16:9 режими на 1485 Mbps (аж до 1920×1080@100), IMX335 — лінійку «найкращий на кожен fps» (30/50/60/90/100) та ультранизьколатентний 1536×864@144 (v0.24).


Читання та запис полів

GET /api/v1/get?field_name

bash
curl "http://<ip>/api/v1/get?video0.bitrate"
json
{"ok": true, "data": {"field": "video0.bitrate", "value": 8192}}

GET /api/v1/set?field_name=value

Записати поле. Live-поля застосовуються миттєво. Restart-поля ініціюють reinit.

bash
# Миттєва зміна бітрейту (live)
curl "http://<ip>/api/v1/set?video0.bitrate=4096"

# Мульти-зміна (тільки для live-полів)
curl "http://<ip>/api/v1/set?video0.bitrate=4096&system.verbose=true"

# Зміна роздільної здатності (restart — reinit пайплайну)
curl "http://<ip>/api/v1/set?video0.size=1280x720"

Відповіді:

json
// Одне поле
{"ok": true, "data": {"field": "video0.bitrate", "value": 4096}}

// Мульти-зміна
{"ok": true, "data": {"applied": [
  {"field": "video0.bitrate", "value": 4096},
  {"field": "system.verbose", "value": true}
]}}

// Restart-поле
{"ok": true, "data": {"field": "video0.size", "value": "1280x720", "reinit_pending": true}}

Обмеження мульти-set

Мульти-set підтримується тільки для live-полів. Якщо хоча б одне restart-поле присутнє — весь запит відхиляється. Restart-зміни відправляйте по одній (демон перезапускається між ними — чекайте, поки відновиться).

HTTP 409 — помилка валідації

Якщо значення невалідне (наприклад, неіснуючий режим AWB або неіснуюче поле), API поверне HTTP 409 Conflict замість 200.

GET /api/v1/restart

Повний reinit пайплайну. Перезавантажує /etc/waybeam.json та перезапускає камеру без завершення процесу.

bash
curl http://<ip>/api/v1/restart

Контроль енкодера

GET /request/idr

Запит IDR-кейфрейму від енкодера:

bash
curl http://<ip>/request/idr

Коли запитувати IDR

  • Після підключення нового глядача
  • Після втрати пакетів у радіоканалі
  • При появі артефактів відео

GET /api/v1/idr/stats

Лічильники rate-limit IDR за каналом: скільки запитів виконано, а скільки злито (coalesced).

GET /api/v1/awb

Стан автобалансу білого від ISP.

bash
curl http://<ip>/api/v1/idr/stats
curl http://<ip>/api/v1/awb

Спостереження за потоком

GET /api/v1/transport/status

Стан активного відеотранспорту (UDP / Unix / SHM): відсоток заповнення буфера, прапор backpressure, лічильники втрат за весь час роботи.

GET /api/v1/audio/status

Знімок аудіо-пайплайну: чи завантажена бібліотека, стан захоплення, кодек, частота, канали, ініціалізація Opus.

bash
curl http://<ip>/api/v1/transport/status
curl http://<ip>/api/v1/audio/status

Attitude: штучний горизонт з IMU

З v0.39–v0.40 Waybeam оцінює орієнтацію камери (roll/pitch/yaw) за даними гіроскопа BMI270 — для штучного горизонту в HUD наземної станції. Потрібно imu.enabled=true та attitude.enabled=true (обидва — restart).

GET /api/v1/attitude — живий знімок кутів (у системі координат камери, з урахуванням монтажних тримів):

bash
curl http://<ip>/api/v1/attitude

GET /api/v1/attitude/calibrate_level — калібрування рівня однією командою: тримайте камеру нерухомо і рівно ~1.5 с — сервіс усереднить акселерометр, точно обчислить трими (attitude.trimRollDeg / trimPitchDeg), збереже їх у конфіг і перезапустить пайплайн:

bash
curl http://<ip>/api/v1/attitude/calibrate_level

Можливі помилки: 409 — IMU вимкнений або камера рухається; 501 — на Maruko (оцінювач ще не підключений до IMU-шляху цього бекенда).

Поля секції attitude (усі — restart):

ПолеОпис
enabledУвімкнути оцінку горизонту
mountDegКут монтажу камери навколо осі об'єктива: 0 / 90 / 180 / 270
invertRoll / invertPitchІнверсія знаків кутів
axisFwd / axisDownПерестановка осей сенсора для плат у нестандартній орієнтації (будь-яка з 24 осьових); за замовчуванням +x / +z
trimRollDeg / trimPitchDegТрими рівня — їх записує калібрування

ATTITUDE у RTP-sidecar

За увімкненого sidecar (outgoing.sidecarPort) до покадрової телеметрії додається 12-байтовий трейлер ATTITUDE (roll/pitch/yaw у кроках 0.1°, статус, вік IMU-семплу) — для HUD. Сам sidecar з v0.39 мультипідписний: до 4 одержувачів одночасно (TTL 5 с на слот), тож підписка HUD більше не «викрадає» телеметрію у wfb-контролера. Трейлер — тільки Star6E. З v0.40.1 оцінювач відкидає биті IMU-семпли (NaN/Inf) і не публікує «застиглий» горизонт.

У WebUI секція Attitude показує кути наживо (опитування 1 Гц) і має кнопку Capture level trims — калібрує, оновлює поля та перезапускає пайплайн.


Discovery (mDNS)

Камера анонсує себе в локальній мережі як сервіс _waybeam-venc._tcp.local: унікальне ім'я waybeam-<суфікс>.local (суфікс — хвіст die ID чипа SigmaStar) та, за замовчуванням, коротке waybeam.local. Поля секції discovery доступні через API та WebUI (секція Discovery):

bash
# Стан анонсу
curl "http://<ip>/api/v1/get?discovery.enabled"

# Власне ім'я замість waybeam-<суфікс>
curl "http://<ip>/api/v1/set?discovery.name=my-drone"

# Вимкнути коротке ім'я waybeam.local (корисно, якщо камер у мережі кілька)
curl "http://<ip>/api/v1/set?discovery.bareAlias=false"

Повний 12-значний серійник (die ID) — у GET /api/v1/configdata.device.serial (тільки читання). Конфлікт короткого імені між кількома камерами вирішується автоматично за RFC 6762 (IP-tiebreak).


Snapshot (JPEG)

GET /api/v1/snapshot.jpg

Один JPEG-кадр з окремого MJPEG-каналу VENC (відгалуження від того ж порту, що й основний H.265-потік). Без параметрів; якість за замовчуванням 80, роздільність — як в основному потоці.

bash
curl -o snapshot.jpg http://<ip>/api/v1/snapshot.jpg

Відповідь — Content-Type: image/jpeg. Можливі помилки: 503 snapshot_disabled (пайплайн ще не піднявся), 504 snapshot_timeout (немає кадру за 1500 мс), 500 snapshot_failed.

Налаштування snapshot

snapshot.qualitylive (миттєво, без reinit). Поля snapshot.channel, snapshot.width, snapshot.height — restart (зашиваються при MI_VENC_CreateChn). width=0/height=0 означає «як в основному потоці».


Запис на SD-картку

GET /api/v1/record/start

Почати запис. Використовує сконфігурований record.dir, або вкажіть каталог параметром:

bash
curl "http://<ip>/api/v1/record/start"
curl "http://<ip>/api/v1/record/start?dir=/mnt/mmcblk0p1"

GET /api/v1/record/stop — зупинити запис.

GET /api/v1/record/status — статус запису:

bash
curl "http://<ip>/api/v1/record/status"
json
{
  "ok": true,
  "data": {
    "active": true,
    "format": "ts",
    "path": "/mnt/mmcblk0p1/rec_01h23m45s_abcd.ts",
    "frames": 1500,
    "bytes": 12345678,
    "segments": 1,
    "stop_reason": "none"
  }
}

Запис на Maruko

HTTP-керування записом (start/stop) працює лише на Star6E. На Maruko запис тільки через конфіг (record.enabled=true + record.mode=... у /etc/waybeam.json), а /api/v1/record/start|stop повертає 501 not_implemented.


Dual-Stream (Gemini-режим)

GET /api/v1/dual/status

Статус другого VENC-каналу (лише режими dual / dual-stream):

bash
curl "http://<ip>/api/v1/dual/status"
json
{"ok": true, "data": {"active": true, "channel": 1, "bitrate": 20000, "fps": 120, "gop": 240}}

Dual VENC не активний

Якщо режим запису не "dual" або "dual-stream", цей ендпоінт поверне HTTP 404.

GET /api/v1/dual/set?param=value

bash
# Змінити бітрейт запису
curl "http://<ip>/api/v1/dual/set?bitrate=10000"

# Змінити GOP (у секундах)
curl "http://<ip>/api/v1/dual/set?gop=1.0"

GET /api/v1/dual/idr — IDR-кейфрейм для другого каналу.


Framing: стабілізація та цифровий зум

video0.framing — це єдиний користувацький перемикач обрізки VPE. Це іменований пресет (restart-required); коефіцієнт обрізки виводиться з пресету (окремого поля zoomPct немає).

framingЕфектРоздільність @1080pЧіпи
offПовний кадр1920×1080обидва
stabСтабілізація (центрована обрізка 80%)1536×864обидва (Maruko — з v0.35)
stab-fillСтабілізація (плаваюче зображення на чорній рамці)1920×1080обидва (Maruko — з v0.37)
zoom-1.25xЦифровий зум 1.25×1536×864обидва
zoom-1.50xЦифровий зум 1.50×1280×720обидва
zoom-1.75xЦифровий зум 1.75×1088×608обидва
zoom-2xЦифровий зум 2×960×528обидва
zoom-3xЦифровий зум 3×640×352обидва
zoom-4xЦифровий зум 4×480×256обидва

Цифровий зум зменшує і вікно обрізки, і вихідну роздільність — без апскейлу, без додаткового навантаження на канал. Панорамування всередині зуму — live, через video0.zoomX / video0.zoomY (∈ [0,1], центр 0.5/0.5):

bash
# Увімкнути 3× зум (restart)
curl "http://<ip>/api/v1/set?video0.framing=zoom-3x"

# Панорамування (live) — лівий верхній кут / центр
curl "http://<ip>/api/v1/set?video0.zoomX=0.0&video0.zoomY=0.0"
curl "http://<ip>/api/v1/set?video0.zoomX=0.5&video0.zoomY=0.5"

Стабілізація (stab / stab-fill) використовує Kalman-фільтр траєкторії і з v0.35/v0.37 працює на обох чіпах. Тонке налаштування (всі restart; повторний вибір пресету скидає їх до дефолтів, тому спочатку задавайте framing, потім переоприділення):

ПолеЗа замовч.Опис
video0.stabAccuracyautoРівень детектора руху: high / medium / low (якість ↔ CPU). auto = high на Star6E, low на одноядерному Maruko (v0.36)
video0.stabCropPct80Запас на стабілізацію (менше = більший «мертвий» бордер, більше поглинання руху)
video0.stabKalmanQ0.03Реакція на панорамування (0.001..1.0; вище = швидше слідує за повільними панорамами)
video0.stabKalmanR2.0Головний параметр відчуття. Плавність (0.1..50.0; вище = плавніше, але із затримкою)
video0.pauseStablive пауза: плавно повертає вікно/зображення в центр (тільки stab/stab-fill)

Стабілізація на Maruko — ціна CPU

Детектор руху — програмна NEON-бібліотека SigmaStar, не апаратний блок. На одноядерному Maruko це помітна частка CPU (у stab-fill ≈29% ядра на 50 fps при stabAccuracy=low). Також на Maruko stab-fill несумісний з record.mode: "dual" — такий запит відхиляється.

Для версій до v0.35/v0.37 — стабілізація лише на Star6E

До v0.35 stab, а до v0.37 і stab-fill працювали тільки на Star6E: на Maruko детектор MI_IVE не ініціалізувався через несумісну vendor-бібліотеку, тож WebUI показував контролі стабілізації неактивними, а /set відхиляв відповідні поля. З v0.35 тарбол Maruko постачає сумісну libmi_ive.so, і обидва пресети доступні на обох чіпах.

bash
# Увімкнути стабілізацію (restart)
curl "http://<ip>/api/v1/set?video0.framing=stab"

# Пауза стабілізації на льоту (live)
curl "http://<ip>/api/v1/set?video0.pauseStab=1"   # заморозити (плавно в центр)
curl "http://<ip>/api/v1/set?video0.pauseStab=0"   # відновити

Стабілізація не використовує гіроскоп

Стабілізація працює на основі аналізу руху в кадрі (Kalman) і не використовує IMU. Колишня EIS на BMI270 (gyroglide) видалена у 0.8.0. Сам гіроскоп з v0.39 живить іншу функцію — оцінку горизонту (attitude).


Resilience: стійкість до втрат пакетів

video0.resilience обирає профіль стійкості — intra-refresh (rolling GDR-смуга), SVC-T пірамида посилань та довжина GOP виводяться з пресету.

Зміна resilience потребує REBOOT

Запис video0.resilience зберігає значення у /etc/waybeam.json і повертає {"reboot_required": true}. Активний пайплайн продовжує працювати зі старим пресетом до наступного запуску камери — kernel-модуль SigmaStar MI не переживає live-переконфігурацію цих полів (на Star6E це призводить до kernel panic, на Maruko — до зависання демона). Тому застосовується модель «cold-boot».

Пресетintra-refreshrefPredGOPOSD-safe?
offвимк.вимк.користувацькийтак
rescueвимк.вимк.0.25 с (IDR-спам)так
qualityвимк.вимк.4.0 стак
sprintшвидкий (150 мс)вимк.0.5 стак
racingшвидкий (150 мс)вимк.2.0 стак
enduranceзбалансований (500 мс)вимк.2.0 стак
patrolзбалансований (500 мс)вимк.4.0 стак
rallyшвидкий (150 мс)base=1, enhance=12.0 сні — «зелений шлейф»
rangeзбалансований (500 мс)base=1, enhance=42.0 сні — «зелений шлейф»
fpvстійкий (1000 мс)base=1, enhance=42.0 сні — «зелений шлейф»
bash
# FPV з OSD-оверлеєм — швидке відновлення смугами, без SVC-T
curl "http://<ip>/api/v1/set?video0.resilience=racing"
# далі перезавантажте камеру, щоб застосувати

OSD та SVC-T

Пресети з refPred (rally, range, fpv) можуть лишати стійкий «зелений шлейф» на статичному OSD до наступного IDR. Для польотів з OSD-оверлеєм використовуйте OSD-safe пресети (racing, endurance, patrol). Бюджетуйте +20–30% бітрейту для пресетів з intra-refresh.


ISP Image Quality

GET /api/v1/iq — експорт усіх ISP-параметрів:

bash
curl http://<ip>/api/v1/iq > my_tuning.json

POST /api/v1/iq/import — імпорт (повний або частковий):

bash
# Повний імпорт
curl -X POST -H "Content-Type: application/json" \
  -d @my_tuning.json http://<ip>/api/v1/iq/import

# Частковий імпорт — тільки конкретні параметри
echo '{"lightness":{"value":75},"demosaic":{"fields":{"dir_thrd":30}}}' | \
  curl -X POST -H "Content-Type: application/json" -d @- http://<ip>/api/v1/iq/import

GET /api/v1/iq/set?param=value — зміна окремого ISP-параметра (dot-notation):

bash
# Встановити одне поле
curl "http://<ip>/api/v1/iq/set?colortrans.y_ofst=200"

# Встановити масив (через кому)
curl "http://<ip>/api/v1/iq/set?colortrans.matrix=23,45,9,1005,987,56,56,977,1015"

Приклади типових сценаріїв

Швидке перемикання на 720p 90fps

bash
curl "http://<ip>/api/v1/set?video0.size=1280x720"
# Чекаємо reinit...
curl "http://<ip>/api/v1/set?video0.fps=90"
curl "http://<ip>/api/v1/set?video0.bitrate=4096"

Ручний баланс білого (6500K)

bash
curl "http://<ip>/api/v1/set?isp.awbMode=ct_manual"
curl "http://<ip>/api/v1/set?isp.awbCt=6500"

Увімкнення ROI-кодування для FPV

bash
curl "http://<ip>/api/v1/set?fpv.roiEnabled=true"
curl "http://<ip>/api/v1/set?fpv.roiQp=-18"
curl "http://<ip>/api/v1/set?fpv.roiSteps=2"

Увімкнення стабілізації

bash
# framing — restart-поле; задавайте першим, потім тонке налаштування
curl "http://<ip>/api/v1/set?video0.framing=stab"
curl "http://<ip>/api/v1/set?video0.stabKalmanR=6"

Рекомендовані налаштування за сценарієм

FPV-рейсінг (мінімальна затримка)

json
{
  "video0": {"rcMode":"cbr", "fps":90, "size":"1280x720", "bitrate":6144, "gopSize":0.5, "resilience":"racing"},
  "fpv": {"roiEnabled":true, "roiQp":-12, "roiSteps":2, "roiCenter":0.35},
  "outgoing": {"streamMode":"rtp", "server":"unix://wfb_tx"}
}

FPV-фрістайл (якість + запис)

json
{
  "video0": {"rcMode":"cbr", "fps":60, "size":"1920x1080", "bitrate":8192, "gopSize":1.0},
  "fpv": {"roiEnabled":true, "roiQp":-18, "roiSteps":3, "roiCenter":0.4},
  "record": {"enabled":true, "mode":"dual", "bitrate":20000, "fps":120},
  "outgoing": {"streamMode":"rtp", "server":"unix://wfb_tx"}
}

Далекий зв'язок (long range)

json
{
  "video0": {"rcMode":"cbr", "fps":30, "size":"1280x720", "bitrate":3072, "gopSize":2.0, "resilience":"range"},
  "fpv": {"roiEnabled":false},
  "outgoing": {"streamMode":"rtp", "server":"unix://wfb_tx"}
}

resilience у конфізі

resilience застосовується при холодному старті, тому в конфізі він спрацьовує одразу. Через API він потребує перезавантаження камери.


Наступні кроки

Чи була ця сторінка корисною?