feat: prove and decode K1 realtime MQTT streams

This commit is contained in:
DCCONSTRUCTIONS
2026-07-15 19:10:41 +03:00
parent faa442eefc
commit 6b22e5a1d2
30 changed files with 4375 additions and 41 deletions
@@ -0,0 +1,114 @@
{
"schema_version": 1,
"session_id": "20260715T122850Z_live_power_cycle",
"experiment": "BLE provisioning and physical-button MQTT stream capture",
"tool": {
"version": "0.1.0",
"git_commit": "faa442e+working-tree-lab-tooling"
},
"host": {
"macos_version": "26.5.1",
"machine": "arm64",
"python_version": "3.12.13",
"wifi_interface": "en0",
"vpn_active": true
},
"device": {
"model": "XGRIDS/LixelKity K1",
"serial_suffix": null,
"activation_state": "active",
"firmware": "3.0.2"
},
"network": {
"topology": "current_lan",
"k1_address_redacted": "RFC1918 private IPv4"
},
"timeline": [
{
"event": "MQTT standby baseline begins",
"monotonic_seconds": 0.0,
"utc": "2026-07-15T14:05:15.186Z",
"note": "heartbeat and device_status only"
},
{
"event": "first live pose report",
"monotonic_seconds": 57.778,
"utc": "2026-07-15T14:06:12.964Z",
"note": "physical double-click scan start"
},
{
"event": "first live point-cloud report",
"monotonic_seconds": 57.795,
"utc": "2026-07-15T14:06:12.981Z",
"note": "firmware-3 lio_pcl topic"
},
{
"event": "full-payload capture window ends",
"monotonic_seconds": 179.166,
"utc": "2026-07-15T14:08:14.352Z",
"note": "180-second subscriber timeout"
},
{
"event": "post-stop negative control begins",
"monotonic_seconds": 369.254,
"utc": "2026-07-15T14:11:24.440Z",
"note": "solid-green standby; no lio_pcl/lio_pose/modeling reports"
},
{
"event": "repository-native standby smoke capture",
"monotonic_seconds": 2443.564,
"utc": "2026-07-15T14:45:58.750Z",
"note": "5-second fixed-topic subscriber; 11 heartbeat/status frames"
}
],
"artifacts": [
{
"path": "reference/LG_i18n_125_20250820.apk",
"size_bytes": 118234630,
"sha256": "c83736f782981282b933cd4737c4f9fa46cbd7f651660c1a9057580f7312361f",
"classification": "sensitive"
},
{
"path": "captures/wifi_provisioning_attempt_01.json",
"size_bytes": 1258,
"sha256": "cc73705c185315286f4009b6619f82a7953b38528a919f7fd2b18ecd788c7637",
"classification": "sensitive"
},
{
"path": "captures/wifi_provisioning_attempt_02.json",
"size_bytes": 1247,
"sha256": "4acf432dd8797802a0033efb7c89f3c11827f681bbf152249c02cccb41d9f873",
"classification": "sensitive"
},
{
"path": "captures/mqtt_scan_full_payloads_03.tsv",
"size_bytes": 79937918,
"sha256": "6b2a4a66d24a89ac048a2be11c5ab45923ee60d4ef07ad3ed3fa3cc508bf8500",
"classification": "sensitive"
},
{
"path": "captures/mqtt_post_stop_metadata_04.tsv",
"size_bytes": 1488,
"sha256": "677835db8175ab6001bec6ecc703413c07795062bb9b4e86c187c77c3e6c73eb",
"classification": "sensitive"
},
{
"path": "captures/native_mqtt_standby_05/mqtt.raw.k1mqtt",
"size_bytes": 1924,
"sha256": "1ff2984d7f305e41f80c13b820405b9b18c8c79c15efe698d51a02fffa22ca82",
"classification": "sensitive"
},
{
"path": "analysis/native_mqtt_standby_05.summary.json",
"size_bytes": 1481,
"sha256": "da72847c9454bd69915c65d49101cb93261d034ec1c1db329ead0b20a6dcbb0e",
"classification": "sensitive"
}
],
"decision": {
"status": "GO",
"gate": "Stage 5 point-cloud and pose decoding",
"reason": "All captured firmware-3 point-cloud and pose frames decoded and correlated with controlled physical motion.",
"next_smallest_experiment": "Longer repository-native capture on verified power bank; keep camera discovery separate."
}
}
@@ -0,0 +1,117 @@
# K1 Lab Report 001 — redacted
Date: 2026-07-15
Decision: **GO** for BLE provisioning, LAN association, MQTT capture, firmware-3
point-cloud decoding and live pose decoding. Camera stream remains unproven.
## Stand
- owner-controlled XGRIDS/LixelKity K1;
- observed firmware 3.0.2;
- Apple Silicon MacBook;
- existing TP-Link mesh LAN;
- no LixelGO, phone, SDK, router reconfiguration or firmware change;
- device identity, SSID, password, IP and MAC retained only in ignored artifacts.
## Physical result
- power-on: slow blue to solid green standby;
- autonomous scan start: physical double-click from standby;
- start transition: fast green, LiDAR rotation, then scanning green;
- initialization: device held still for at least 20 seconds;
- controlled movement: approximately one metre plus a turn;
- stop: physical double-click, fast green while saving, LiDAR stopped, solid green;
- single-click is not the scan-start action;
- a depleted battery caused one clean power loss; the battery was replaced before
the successful run;
- later transfer from battery/USB connection to a verified power bank did not
reset the device or change the standby LED.
## BLE and Wi-Fi result
The reviewed 99-byte firmware-3 provisioning frame was tested twice:
1. write without response, mirroring the Android application: transport
completed but K1 remained in AP mode;
2. write with response, matching the live CoreBluetooth property: immediate
success, status code 1 and a LAN IPv4 address.
There was no automatic retry and no third provisioning write. The password was
entered in a hidden local macOS dialog and never appeared in arguments, logs,
artifacts or Git.
## MQTT result
Targeted connection to the confirmed K1 address accepted plain MQTT 3.1.1 on
TCP 1883 with no username/password. A subscribe-only client received standby
heartbeat and status at approximately 1 Hz.
The 180-second scan capture contained 2,836 valid records and no framing/declared
length errors:
| Topic | Messages | MQTT payload bytes |
| --- | ---: | ---: |
| `device_status` | 180 | 31,830 |
| `heartbeat` | 180 | 17,997 |
| `lio_pcl` | 1,140 | 39,617,777 |
| `lio_pose` | 1,215 | 204,370 |
| `modeling` | 121 | 10,867 |
After physical stop, a separate 12-second negative-control subscription received
only 12 heartbeat and 12 status messages. It received no `lio_pcl`, `lio_pose` or
`modeling` reports.
After implementation, the repository-native `k1link net mqtt-capture` command
was smoke-tested for 5 seconds in standby. It completed a fixed allowlisted
subscription, saved 11 messages in the length-framed `.k1mqtt` format and exited
on duration. `k1link analyze mqtt-streams` then verified the raw capture hash and
all frame boundaries; as expected for standby, it found no PCL or pose frames.
## Decoder result
All 1,140 point-cloud MQTT payloads decoded successfully:
- compression: raw LZ4 block, enum 0 in every frame;
- decoded protobuf size: 37,083 through 55,111 bytes per frame;
- scaler: 1000 in every frame;
- 2,703 through 4,065 points per frame;
- total decoded points: 4,165,862;
- decode failures: 0.
All 1,215 pose payloads decoded successfully:
- protobuf position and quaternion values were finite;
- first-to-last pose displacement was approximately 1.566 m, consistent with
the operator's controlled movement;
- reported pose accuracy was approximately 0.001 throughout;
- decode failures: 0.
Scene bounds, trajectory coordinates and raw payloads remain private and ignored.
## Artifact integrity
The raw files are under the ignored session
`20260715T122850Z_live_power_cycle`. Only redacted facts and hashes are committed.
| Artifact | SHA-256 |
| --- | --- |
| owned reference APK | `c83736f782981282b933cd4737c4f9fa46cbd7f651660c1a9057580f7312361f` |
| provisioning attempt 01 | `cc73705c185315286f4009b6619f82a7953b38528a919f7fd2b18ecd788c7637` |
| provisioning attempt 02 | `4acf432dd8797802a0033efb7c89f3c11827f681bbf152249c02cccb41d9f873` |
| full MQTT scan capture | `6b2a4a66d24a89ac048a2be11c5ab45923ee60d4ef07ad3ed3fa3cc508bf8500` |
| post-stop metadata control | `677835db8175ab6001bec6ecc703413c07795062bb9b4e86c187c77c3e6c73eb` |
| native standby `.k1mqtt` smoke capture | `1ff2984d7f305e41f80c13b820405b9b18c8c79c15efe698d51a02fffa22ca82` |
| native aggregate analysis | `da72847c9454bd69915c65d49101cb93261d034ec1c1db329ead0b20a6dcbb0e` |
## Remaining gates
1. Integrate the bounded stream decoder with the repository-native binary MQTT
capture format.
2. Run a longer power-bank capture and measure packet loss, CPU, disk and thermal
behavior.
3. Establish K1-to-vehicle/airframe extrinsics and time synchronization before
using pose on a robot or UAV.
4. Determine whether usable RGB is packed into `rgbi` or delivered elsewhere.
5. Treat raw panoramic camera access as unproven until a scan-correlated stream
or endpoint is observed.