Progress Log

Pi Rover Agent Stub + Rover Console

April 12, 202618:16Build Log

Pi Rover Agent Stub + Rover Console

Date: 2026-04-12 Type: Build Log

Context

The Convex backend and Next.js control center were fully built out — schema, mutations, queries, dashboard UI — but no actual Python code existed on the Raspberry Pi to call those APIs. This session created the Pi-side rover agent with mock sensors, verified end-to-end comms, then built a Rover Console page in the control center for real-time observability and remote shell access.

What Changed

Part 1: Pi Rover Agent (pi/)

Created a complete Python rover agent that runs on the Pi and communicates with Convex over HTTP. Uses mock sensor data by default so the full pipeline works without hardware.

  • pi/convex_client.py — HTTP wrapper around the Convex REST API. Key discovery: the Convex HTTP API format is POST /api/mutation with {"path": "module:function", "args": {...}} in the body — NOT the function name in the URL (that returns 404).
  • pi/sensors.py — Abstraction layer with MOCK_SENSORS=1 default. GPS does a random walk near 42.18N/-74.53W, battery drains from 8.4V, CPU temp drifts. MOCK_SENSORS=0 stubs exist for real hardware.
  • pi/command_loop.py — Background thread: heartbeat every 3s, command poll every 3s, dispatches to registered handlers.
  • pi/mission_controller.py — Full lifecycle: preflight diagnostics → missions:start → capture loop (15s intervals, 6 max) → missions:complete. Handles abort via stop command.
  • pi/shell_handler.py — Executes shell commands from the console. 30s timeout, 10KB output cap, blocks dangerous commands (rm -rf /, shutdown, dd, etc.).
  • pi/config.py — Convex URL + env overrides.
  • pi/main.py — Entry point wiring everything together.

Part 2: Rover Console (/control-center/console)

Built a terminal-style console page for full observability and control.

  • convex/console.ts — Unified feed query merging rover_commands, diagnostics, and missions tables into a chronological timeline.
  • convex/schema.ts + convex/rover.ts — Added run_shell to the command type union.
  • src/app/control-center/console/page.tsx — The console UI:
    • Live activity feed with timestamps, source-specific rendering (commands with status badges, diagnostics with pass/warn/fail icons, missions with route and battery info)
    • Filter tabs: All / Cmds / Diag / Missions
    • Status bar: online indicator, state, battery%, WiFi dBm, CPU temp
    • Quick command buttons: Start Mission, Stop, Return Home, Photo, Pause, Resume
    • Shell input with $ prompt — type any command, hits Pi via run_shell, output appears in feed
    • Auto-scroll with scroll-to-bottom FAB
  • src/components/app-sidebar.tsx — Added Console link to Control Center nav.

Files Modified

  • pi/convex_client.py — New: Convex HTTP API client
  • pi/sensors.py — New: Mock sensor layer
  • pi/command_loop.py — New: Heartbeat + command loop
  • pi/mission_controller.py — New: Mission lifecycle
  • pi/shell_handler.py — New: Remote shell execution
  • pi/config.py — New: Configuration
  • pi/main.py — New: Entry point
  • convex/schema.ts — Added run_shell to rover_commands command union
  • convex/rover.ts — Added run_shell to sendCommand args
  • convex/console.ts — New: Unified feed query
  • src/app/control-center/console/page.tsx — New: Console page
  • src/components/app-sidebar.tsx — Added Console nav link

Key Takeaways

  • Convex HTTP API: path goes in the JSON body ({"path": "rover:heartbeat", "args": {...}}), not the URL
  • The Pi venv already had requests from adafruit deps — no new packages needed
  • First Convex call from Pi takes ~8-14s (cold start), subsequent calls are fast
  • nohup + background process works fine for keeping the rover agent running; systemd service is the next step
  • Mock sensors drift realistically — battery drains, GPS walks, CPU temp rises — makes dashboard testing feel real
  • The console's shell input goes through the same rover_commands queue as button presses, so all commands are logged and auditable