adacam/BEE-ACCESS-PLAN.md

6.7 KiB

Truck Bee Access Plan

Updated 2026-03-22 — read this before touching the Bee


Network Topology (important)

Cobb's phone ──── Bee AP (wlp1s0f0, 192.168.0.10) ──── phone gets 192.168.0.x
                                                         ROUTING CONFLICT on phone
                                                         (both AP and zerocool are 192.168.0.0/24)

Bee WiFi client (wlp1s0f1) ──── zerocool ──── Lucy (192.168.0.5) ──── OpenClaw

Key facts:

  • sshd on Bee binds ONLY to 192.168.0.10 (AP interface) — confirmed from recon
  • The reverse tunnel OUTBOUND uses wlp1s0f1 (zerocool) — do NOT kill this interface
  • Routing conflict is on Cobb's PHONE (both AP and zerocool are 192.168.0.0/24)
  • Killing wlp1s0f1 kills zerocool → kills the tunnel path → wrong

Step 1 — Get Clean Access

1a. Phone connects to Bee AP

Connect to dashcam-4A928016A02C1046, SSH to root@192.168.0.10

1b. Start reverse tunnel FROM THE BEE immediately

Run this on the Bee before the routing conflict kicks you off:

ssh -R 2222:192.168.0.10:22 -N -o StrictHostKeyChecking=no root@192.168.0.5 &
  • Goes OUTBOUND via wlp1s0f1 (zerocool) to Lucy
  • AP interface not involved in this path
  • Even if your phone SSH session dies, tunnel stays alive
  • Lucy will show 127.0.0.1:2222 listening

Auth requirement: Bee needs a key that Lucy's root authorized_keys accepts.

  • Check what's in /root/.ssh/ on the Bee
  • If nothing: during the phone session, generate a key on Bee and add pubkey to Lucy's authorized_keys

1c. Verify from OpenClaw

ssh lucy "ss -tlnp | grep 2222"
# Should show: LISTEN 0 128 127.0.0.1:2222

Step 2 — Read-Only Recon (NO WRITES)

2a. Storage inventory

df -h
du -sh /data/recording/*/
sqlite3 /data/odc-api.db ".tables"
sqlite3 /data/odc-api.db ".schema framekms"
sqlite3 /data/odc-api.db "SELECT COUNT(*) FROM framekms;"
ls /data/recording/ml_metadata/ | head -20
cat $(ls /data/recording/ml_metadata/ | head -1) 2>/dev/null

2b. Redis — find detection keys

redis-cli keys "*"
# Look specifically for detection/landmark keys:
redis-cli keys "*landmark*"
redis-cli keys "*detection*"
redis-cli keys "*sign*"
redis-cli keys "*ai*"
# Check GNSSFusion30Hz (may not appear until Bee has been running a while):
redis-cli type GNSSFusion30Hz 2>/dev/null
redis-cli zrevrange GNSSFusion30Hz 0 2 2>/dev/null

2c. Find detection key in odc-api source

grep -in "redis\|landmark\|detection\|zadd\|rpush\|publish" /opt/odc-api/odc-api-bee.js | head -40

2d. Find detection key in map-ai source

ls /opt/map-ai/
grep -in "redis\|landmark\|detection\|zadd\|rpush\|publish" /opt/map-ai/map-ai.py 2>/dev/null | head -40

2e. Frame storage format

ls /tmp/recording/pics/ | head -5
ls /tmp/recording/pics/ | wc -l

2f. SSH keys on Bee

ls -la /root/.ssh/ 2>/dev/null
cat /root/.ssh/authorized_keys 2>/dev/null
ls /root/.ssh/id_* 2>/dev/null

2g. map-ai service file

systemctl cat map-ai.service

Step 3 — Decisions Based on Recon

Finding Decision
Detection Redis key found Forwarder polls Redis directly
No detection Redis key Use ml_metadata files or poll odc-api at low frequency
ml_metadata has detection files Primary source, tail by mtime
Large stored framekm backlog Plan backfill to ADAMaps before liberation

Step 4 — Liberation (v0.6)

Kill list

hivemapper-data-logger    ← MUST — the uploader
mitmproxy                 ← MUST — Hivemapper proxy
beekeeper-plugin          ← kill — Hivemapper telemetry
here-plugin               ← kill — HERE Maps
mender-client             ← kill — OTA updates (USB recovery still works)
odc-api                   ← kill — Node.js bloat (we read Redis/files directly)

Keep list

redis                     ← IPC backbone
depthai_gate              ← Camera hardware init
map-ai                    ← ML inference — THIS IS THE VALUE
jpeg-recorder             ← Frame storage
video-processor           ← Frame pipeline
RedisHandler              ← Sensor fusion
datalogger                ← GPS/IMU logging to SQLite
hostapd / dnsmasq         ← AP + DHCP

New service: adacam-forwarder (rewritten)

  • Polls detection Redis key for new entries
  • Grabs JPEG from /tmp/recording/pics/ by timestamp
  • POSTs to ADAMaps /api/ingest + /api/images
  • Tracks state in /data/adacam/forwarder-state.json
  • Runs every 30s, pure Python, minimal CPU

systemd drop-in (removes odc-api dep from map-ai)

# /etc/systemd/system/map-ai.service.d/no-odc-api.conf
[Unit]
Requires=redis.service
# Overrides Requires=odc-api.service from base unit

SSH keys

Drop to /root/.ssh/authorized_keys:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQxwJU91TCxds34P18D3xRbu7rxlrgTUoml/H8nxeDK kayos@openclaw

Domain blocks (/etc/hosts)

0.0.0.0 data.api.hivemapper.com
0.0.0.0 api.hivemapper.com
0.0.0.0 edge.hereapi.com
0.0.0.0 direct.data.api.platform.here.com
0.0.0.0 account.api.here.com
0.0.0.0 mender.io
0.0.0.0 s3.amazonaws.com

Do NOT touch

  • /etc/ssh/sshd_config
  • AP config / SSID / IP
  • Firewall (no rules yet)

Step 5 — Test

  1. redis-cli get MAP_AI_READY → should be "True"
  2. Check forwarder log → detections posting to ADAMaps
  3. Verify no Hivemapper traffic (nmap or check /etc/hosts working)
  4. Check /data/adacam/forwarder-state.json updating

Step 6 — bee-tunnel.service (permanent remote access)

[Unit]
Description=AdaCam Reverse Tunnel to Lucy
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/ssh -N \
  -R 2222:192.168.0.10:22 \
  -o StrictHostKeyChecking=no \
  -o ServerAliveInterval=30 \
  -o ServerAliveCountMax=3 \
  -o ExitOnForwardFailure=yes \
  root@192.168.0.5
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target

Goes outbound via wlp1s0f1 (zerocool) — AP interface not involved.


Known Issues

Issue Notes
sshd binds to 192.168.0.10 only Reverse tunnel must use 192.168.0.10:22 not localhost:22
Routing conflict on phone AP + zerocool both 192.168.0.0/24 — start tunnel BEFORE conflict kicks you
wlp1s0f1 must stay UP It's the zerocool path — tunnel dies without it
depthai-device-kb at 98% CPU Normal — VPU running ML inference
rngd at 20% CPU Investigate — may be killable
Redis localhost:6379 only Must be on Bee or tunneled in to query
GNSSFusion30Hz absent at boot Appears after GNSS warms up (~5-10 min)
Bee has stored framekm backlog Plan backfill to ADAMaps
Bee-to-Lucy auth key unknown Resolve during first phone session