16 KiB
Пункт управления NODE.DC
Универсальный браузерный пункт управления NODE.DC на React 19, TypeScript и Vite. Приложение задаёт общую операторскую оболочку для аппаратов, сенсоров, наблюдения, миссий и записей. XGRIDS/LixelKity K1 является первым реальным device adapter, но структура интерфейса от него не зависит.
Внутри пространственной рабочей поверхности встроен открытый Rerun Web Viewer.
Это self-hosted frontend-компонент из npm-пакета @rerun-io/web-viewer, а не
переход во внешний облачный интерфейс. Сам браузерный компонент, однако, должен
получить совместимый источник RRD или Rerun gRPC.
Текущее состояние
| Контур | Состояние | Что это означает |
|---|---|---|
| NODE.DC fixed shell | Реализован | Header, навигация по разделам, рабочая поверхность, окна и инспекторы работают в одном приложении. |
| Локальный control plane | Реализован | React получает состояние и выполняет операции через FastAPI REST и WebSocket на loopback. |
| K1 BLE → Wi-Fi | Реализован | Реальный BLE-поиск всех видимых устройств и одна подтверждённая provisioning-запись выбранному устройству. |
| K1 live/replay MQTT | Реализован | Read-only приём, raw-first сохранение, декодирование облака точек и позы, реальные метрики. |
| Legacy Foxglove adapter | Реализован | Текущий Python runtime публикует декодированные K1 данные в локальный Foxglove WebSocket. Это проверенный диагностический backend, а не продуктовый UI. |
| Встроенный Rerun Viewer | Реализован | Открывает назначенный RRD по HTTP(S) или совместимый Rerun gRPC/proxy source внутри Control Station. |
| Автоматический MQTT → Rerun | Не реализован | Запуск K1 live/replay пока не создаёт RRD и не подаёт данные во встроенный Rerun viewport. Нужен отдельный stream adapter. |
| Контролы сцены → Rerun Blueprint | Не реализованы | Размер точек, палитра, накопление, слои, проекция, timeline и компоновка пока являются честным UI-контрактом и состоянием текущего сеанса. |
| Камеры, карты и миссии | Интерфейс готов | Серверная логика и реальные каналы для этих рабочих поверхностей ещё не подключены. |
Приложение не генерирует демонстрационное облако, траекторию, кадры или
метрики. Если реальных данных нет, область сцены остаётся пустой, а числовые поля
показывают —.
Архитектура данных
NODE.DC Control Station в браузере
├── control plane
│ └── REST /api/* + WebSocket /api/events
│ └── FastAPI на 127.0.0.1:8000
│ ├── CoreBluetooth: discovery и reviewed Wi-Fi provisioning
│ └── live/replay session runtime
│
├── текущий K1 preview path — legacy adapter
│ └── K1 MQTT :1883, read-only
│ ├── raw .k1mqtt + metadata + SHA-256 сохраняются первыми
│ └── protobuf/LZ4 decoder
│ └── Foxglove bridge → локальный WebSocket
│
└── продуктовая пространственная сцена
└── встроенный @rerun-io/web-viewer
└── RRD URL или Rerun gRPC/proxy source
Между декодером K1 и Rerun Viewer сейчас нет автоматической стрелки. Поля
foxglove_ws_url и foxglove_viewer_url ещё присутствуют в API только потому,
что Python runtime продолжает поднимать проверенный legacy adapter. Пункт
управления не использует их как основную поверхность визуализации.
Фиксированная оболочка
Shell собран из локальных NODE.DC UI packages и сохраняет одну структуру для всех функциональных модулей:
AppHeader— марка NODE.DC, выбор архитектурного раздела и состояние локального backend.AdminNavigationPanel— контекст аппарата и список рабочих поверхностей выбранного раздела.LandingStage— стартовая ситуационная поверхность и быстрые переходы.ApplicationPanel— единый контейнер активной рабочей поверхности.WindowиInspector— источник, отображение, слои и компоновка без раскрытия внутренних панелей визуального движка.
Встроенный Rerun Viewer работает как canvas внутри этой оболочки. Его верхняя,
blueprint-, selection- и time-панели скрыты, чтобы продуктовые действия жили в
Control Station. Это ещё не означает, что все продуктовые контролы уже связаны
с API Rerun: текущая граница явно показана статусом Интерфейс готов.
Архитектурные разделы
Навигация описана данными в src/productModel.ts, а не зашита в разметку каждой
страницы.
| Раздел | Назначение |
|---|---|
| Центр | Оперативный обзор, состояние контура и активность оператора. |
| Парк | Аппараты, текущее устройство, сенсоры и конфигурации борта. |
| Наблюдение | Пространственная сцена, камеры, карта, объекты, телеметрия и время. |
| Миссии | Планировщик, маршруты, сценарии и исполнение. Командный backend отключён. |
| Данные | Сессии, потоки, сущности, playback и экспорт доказательств. |
| Система | Модули, интеграции, сеть, аудит и настройки платформы. |
Карточки возможностей имеют четыре честных уровня: работает сейчас, готово к источнику, интерфейсный контракт и последующий этап. Каталог не следует читать как утверждение, что для каждой карточки уже существует backend.
Установка, проверка, сборка и запуск
Требуются Node.js 20 или новее, uv и соседний checkout
NODEDC_DESIGN_GUIDELINE: зависимости @nodedc/* подключены к нему через
локальные file: пути. Python устанавливается только в .venv репозитория.
Канонический путь от корня репозитория:
cd /Users/dcconstructions/Downloads/mnt/NODEDC/NDC_xgrids-k1-connector
uv sync --group dev
cd apps/k1-viewer
npm install
npm run typecheck
npm run build
cd ../..
uv run k1link serve
Открыть http://127.0.0.1:8000. Команда serve отдаёт собранный dist/ и
локальный API. Она намеренно привязана только к 127.0.0.1; LAN bind не
предусмотрен, потому что endpoint подключения кратковременно принимает пароль
Wi-Fi.
Для разработки интерфейса после запуска backend:
cd apps/k1-viewer
npm run dev
Vite слушает http://127.0.0.1:5173 и проксирует /api и /api/events на
http://127.0.0.1:8000. Другой локальный backend можно указать переменной
VITE_API_TARGET. Preview production-сборки запускается командой
npm run preview на http://127.0.0.1:4173.
Операторский путь для текущего K1 adapter
- Запустить
uv run k1link serveи открыть Control Station. - Выбрать Парк → Локальное устройство.
- Включить K1, дождаться стабильного индикатора и подтвердить это в форме.
- Нажать Показать все BLE-устройства. Интерфейс показывает полный результат шестисекундного поиска; метка совместимости является подсказкой, выбор делает оператор.
- Ввести SSID и пароль существующей сети и явно запустить подключение. Это одна reviewed provisioning-запись без автоматических повторов.
- Запустить live-приём по определённому адресу K1 либо replay локального
.k1mqtt/проверенного TSV. Физическое сканирование K1 запускается и останавливается подтверждённым двойным нажатием кнопки устройства. - Состояние, частота, число точек, задержка и пропуски preview появятся только после прихода реальных данных.
Этот путь запускает существующий MQTT/Foxglove runtime. Чтобы увидеть тот же живой K1 поток во встроенной пространственной сцене, нужно сначала реализовать и запустить MQTT→Rerun stream adapter; одного запуска live-сессии сейчас недостаточно.
Источники Rerun
В Наблюдение → Пространственная сцена → Источник принимается URL, который
понимает @rerun-io/web-viewer версии, зафиксированной в package.json:
rerun+http://127.0.0.1:9876/proxy
http://127.0.0.1:8080/recording.rrd
https://example.internal/recording.rrd
rerun+http://…/proxy— живой Rerun gRPC source через доступный браузеру proxy;http(s)://…/recording.rrd— RRD-запись по HTTP(S);- версия RRD должна быть совместима с версией Web Viewer;
- URL хранится только в состоянии текущей страницы;
- ошибка запуска показывается в viewport, без подстановки фиктивных данных.
После готовности Viewer выбор Rerun entity возвращает entityPath и имя view в
оболочку. Продуктовые настройки отображения, custom timeline, переключатель
2D/3D/карты и сохранение RBL пока не вызывают Blueprint/playback API. Черновик
компоновки фиксируется только в памяти текущей страницы и не записывается на
диск.
Контракт локального API
| Метод | Route | Тело / назначение |
|---|---|---|
GET |
/api/health |
Проверка локального сервиса. |
GET |
/api/state |
Авторитетный snapshot состояния. |
POST |
/api/ble/scan |
{ "duration_seconds": 6 }. |
POST |
/api/connect |
{ "device_id", "ssid", "password" }. |
POST |
/api/session/live |
Опционально { "host", "duration_seconds" }. |
POST |
/api/session/replay |
{ "path", "speed", "loop" }. |
POST |
/api/session/stop |
Остановка активного источника. |
WS |
/api/events |
Периодические snapshots для live UI. |
/api/state и изменяющие состояние ответы могут вернуть snapshot напрямую или
как { "state": { ... } }. Текущие поля включают phase, message, devices,
selected_device_id, k1_ip, source_mode, metrics и legacy-поля
foxglove_ws_url/foxglove_viewer_url. OpenAPI доступен по /api/docs.
Карта исходников frontend
| Файл | Ответственность |
|---|---|
src/App.tsx |
Fixed shell, выбор разделов и окна source/display/layers/layout. |
src/productModel.ts |
Архитектурные разделы, рабочие поверхности и уровни готовности. |
src/workspaces/DeviceWorkspace.tsx |
Реальный K1 BLE/Wi-Fi/live/replay adapter UI. |
src/workspaces/Workspaces.tsx |
Оперативный обзор, spatial viewport и остальные продуктовые поверхности. |
src/components/RerunViewport.tsx |
Жизненный цикл встроенного Rerun Web Viewer и selection events. |
src/api.ts |
REST/WebSocket контракт с FastAPI. |
src/useK1Console.ts |
Состояние backend, polling, события и действия оператора. |
src/sceneSettings.ts |
Типизированный UI-профиль пространственной сцены. |
src/presentation.ts |
Русские подписи фаз и форматирование реальных метрик. |
src/messages.ts |
Обезличивание и локализация технических сообщений в пользовательском интерфейсе. |
src/styles.css, src/styles/* |
Компоновка shell и рабочих поверхностей. |
Safety и чувствительные данные
- Control Station и credential endpoint доступны только на loopback.
- Пароль Wi-Fi находится только в React memory, передаётся в JSON POST body, очищается после успешного ответа и не сохраняется в URL/local storage.
- BLE-подключение выполняет только отдельно рассмотренную provisioning-запись; случайные GATT writes и автоматические повторы запрещены.
- MQTT live/replay не публикует команды устройству. Запуск и остановка физического сканирования остаются за кнопкой K1.
- Live-сессии сначала сохраняют сырые сообщения, затем формируют preview. При перегрузке preview может быть отброшен, raw evidence сохраняется.
sessions/игнорируется Git и может содержать адреса, идентификаторы, траекторию и карту помещения. В репозиторий попадают только redacted manifests и безопасная документация.