165 lines
7.1 KiB
Markdown
165 lines
7.1 KiB
Markdown
# NDC XGRIDS K1 Connector
|
|
|
|
Pre-production research project for connecting an owner-controlled
|
|
XGRIDS/LixelKity K1 to a Mac without LixelGO, firmware changes, device opening,
|
|
or speculative writes.
|
|
|
|
Current status: live proof completed on firmware 3.0.2. The Mac provisioned the
|
|
K1 onto an existing LAN without LixelGO, connected to its MQTT broker, captured
|
|
the scan-correlated point-cloud and pose streams, and decoded both successfully.
|
|
The repository also contains a local React control console and a Foxglove live
|
|
bridge for the verified point-cloud and trajectory topics.
|
|
|
|
The repository now contains one narrowly gated state-changing command:
|
|
`ble wifi-configure`. It accepts only the reviewed firmware-3 provisioning
|
|
profile and requires explicit `--confirm-write`; the Wi-Fi password is collected
|
|
through a hidden local macOS dialog. MQTT capture and decoding are read-only.
|
|
Nothing changes router settings, firmware or global Python packages.
|
|
|
|
## Available stand
|
|
|
|
- one XGRIDS/LixelKity K1;
|
|
- one Apple Silicon MacBook running macOS;
|
|
- one ordinary TP-Link Deco/mesh network used by other devices;
|
|
- no LixelGO, phone, Linux host, dedicated AP, OpenWrt, or vendor SDK.
|
|
|
|
The ordinary router is sufficient for the first gates. We first observe the
|
|
existing LAN without changing it. A Guest/IoT SSID is optional and may be
|
|
counterproductive if Deco isolates clients; Mac and K1 must ultimately be able
|
|
to reach each other.
|
|
|
|
## What is actually being proved
|
|
|
|
The project has three independent gates:
|
|
|
|
1. K1 is operational and can record a project autonomously.
|
|
2. Mac can discover and inspect the K1 BLE/GATT surface safely.
|
|
3. Without LixelGO, K1 can be associated with Wi-Fi and a proprietary data
|
|
session can be opened.
|
|
|
|
All three gates are now proven on the tested unit. The external stream is plain
|
|
MQTT 3.1.1 on TCP 1883. Firmware-3 `lio_pcl` is protobuf wrapped in a raw LZ4
|
|
block, and `lio_pose` is an uncompressed protobuf. Raw panoramic camera access is
|
|
still unproven and is not implied by point-cloud success.
|
|
|
|
## Local environment
|
|
|
|
The project uses Python 3.12 in a repository-local `.venv` managed by `uv`.
|
|
This does not install Python packages globally and does not modify neighboring
|
|
repositories.
|
|
|
|
```bash
|
|
cd /Users/dcconstructions/Downloads/mnt/NODEDC/NDC_xgrids-k1-connector
|
|
uv sync --group dev
|
|
uv run k1link doctor
|
|
uv run pytest
|
|
```
|
|
|
|
## Live console and Foxglove
|
|
|
|
Build the browser control surface once, then launch the whole local stand from
|
|
the repository root:
|
|
|
|
```bash
|
|
cd apps/k1-viewer
|
|
npm install
|
|
npm run build
|
|
cd ../..
|
|
uv run k1link serve
|
|
```
|
|
|
|
Open `http://127.0.0.1:8000`. The API, credential form and Foxglove WebSocket
|
|
bind to loopback only. The console supports:
|
|
|
|
- real CoreBluetooth K1 discovery;
|
|
- one operator-triggered reviewed BLE Wi-Fi provisioning write;
|
|
- live read-only MQTT capture with raw-first evidence storage;
|
|
- replay of native `.k1mqtt` evidence and the reviewed four-column TSV capture;
|
|
- `/k1/points`, `/k1/pose`, `/k1/trajectory` and `/k1/metrics` for Foxglove;
|
|
- measured Mac-side MQTT-receive-to-Foxglove-publish latency and bounded
|
|
latest-wins preview dropping.
|
|
|
|
For live mode, start the session in the console and use the verified physical
|
|
double-click on K1 to start or stop scanning. The connector deliberately does
|
|
not publish modeling commands yet. For the recorded proof, replay this ignored
|
|
local file at `1x` with loop enabled:
|
|
|
|
```text
|
|
sessions/20260715T122850Z_live_power_cycle/captures/mqtt_scan_full_payloads_03.tsv
|
|
```
|
|
|
|
Foxglove remains the full 3D workspace rather than being reimplemented in the
|
|
React console. In its 3D panel, select `/k1/points`, color by `intensity` (or
|
|
`z`/`<distance>`) and choose Turbo, Rainbow or a custom gradient. Add
|
|
`/k1/trajectory` for the cyan path and `/k1/pose` for the current pose. See the
|
|
[live viewer runbook](docs/06_K1_LIVE_VIEWER.md) for timing semantics and current
|
|
limitations.
|
|
|
|
`doctor` is intentionally non-invasive. It checks the local Python environment
|
|
and reports external tools; it does not request Bluetooth permission, scan the
|
|
LAN, touch the K1, alter Homebrew, or change capture permissions.
|
|
|
|
The implemented laboratory commands include:
|
|
|
|
```bash
|
|
uv run k1link ble scan --duration 30 --out sessions/<id>/captures/ble.json
|
|
uv run k1link ble gatt-dump --device <corebluetooth-uuid> \
|
|
--out sessions/<id>/captures/gatt.json
|
|
uv run k1link ble wifi-configure --device <corebluetooth-uuid> \
|
|
--profile xgrids-k1-fw3-wifi-v1 --write-mode with_response \
|
|
--confirm-write --out sessions/<id>/captures/wifi.sensitive.json
|
|
uv run k1link net snapshot --out sessions/<id>/captures/network.json
|
|
uv run k1link net mqtt-capture --host <confirmed-private-k1-ip> \
|
|
--confirm-owned-device --duration 180 \
|
|
--out sessions/<id>/captures/mqtt-run
|
|
uv run k1link analyze mqtt-streams \
|
|
--capture sessions/<id>/captures/mqtt-run/mqtt.raw.k1mqtt \
|
|
--out sessions/<id>/analysis/mqtt-streams.summary.json
|
|
```
|
|
|
|
On macOS the BLE scan is active CoreBluetooth discovery, but it does not connect
|
|
to or modify devices. `gatt-dump` connects and performs service discovery only.
|
|
`mqtt-capture` accepts only a literal RFC1918 target, uses a fixed report-topic
|
|
allowlist, never publishes and never reconnects. It writes a length-framed raw
|
|
file, JSONL metadata and an integrity summary with mode `0600`.
|
|
|
|
Session output is sensitive and ignored by Git. It can contain device identity,
|
|
trajectory, mapped interiors and local addressing even when no credentials are
|
|
present.
|
|
|
|
## Documentation
|
|
|
|
- [Technical audit](docs/00_TECHNICAL_AUDIT.md)
|
|
- [Implementation gates](docs/01_IMPLEMENTATION_PLAN.md)
|
|
- [First lab runbook](docs/02_FIRST_LAB_RUNBOOK.md)
|
|
- [Artifact and secret policy](docs/03_ARTIFACT_POLICY.md)
|
|
- [Reviewed BLE Wi-Fi profile](docs/04_K1_WIFI_PROVISIONING_PROFILE.md)
|
|
- [Verified MQTT stream profile](docs/05_K1_MQTT_STREAM_PROFILE.md)
|
|
- [Live console and Foxglove runbook](docs/06_K1_LIVE_VIEWER.md)
|
|
- [Redacted live lab report](docs/lab/001_K1_LIVE_MQTT_20260715.redacted.md)
|
|
- [Session manifest schema](schemas/session-manifest.schema.json)
|
|
- [Reference input provenance](docs/reference/README.md)
|
|
|
|
The two supplied source documents are retained unchanged under
|
|
`docs/reference/`. Corrections and decisions are recorded separately so their
|
|
provenance remains clear.
|
|
|
|
## Safety boundary
|
|
|
|
Allowed initial work is non-mutating discovery, standard device-information reads,
|
|
controlled notification listening, autonomous button operation, targeted
|
|
capture of traffic to or from the confirmed K1 address, and offline analysis of
|
|
owned artifacts.
|
|
|
|
The reviewed provisioning write requires its named profile and explicit operator
|
|
confirmation. Application command publishing remains disabled: physical
|
|
double-click is the verified start/stop mechanism. Any future MQTT publisher,
|
|
router configuration change or new BLE write requires its own evidence and
|
|
reviewed step. Random writes, fuzzing, brute force, firmware operations,
|
|
destructive file access and credential guessing remain out of scope.
|
|
|
|
Real captures, projects, router metadata, serials, credentials, maps, images,
|
|
and logs are ignored by normal Git. Redacted manifests and SHA-256 inventories
|
|
are committed; encrypted artifact storage will be selected only when real data
|
|
exists.
|