Progress Log

Rover Console + Real Sensor Reads

April 12, 202618:50Build Log

Rover Console + Real Sensor Reads

Date: 2026-04-12 Type: Build Log

Context

Follow-up to the Pi rover agent stub session. After getting basic comms working, we built a Rover Console page for full observability and remote shell access, then switched WiFi/CPU/disk from mock to real sensor reads since they're just OS-level data that doesn't need hardware.

What Changed

Rover Console (/control-center/console)

New terminal-style page for interacting with the Pi:

  • convex/console.ts — Unified feed query merging rover_commands, diagnostics, and missions into a single chronological timeline.
  • convex/schema.ts + convex/rover.ts — Added run_shell command type to the union.
  • src/app/control-center/console/page.tsx — Full console UI:
    • Live activity feed with timestamps and source-specific rendering
    • Filter tabs (All / Cmds / Diag / Missions)
    • Quick command buttons (Start Mission, Stop, Return Home, Photo, Pause, Resume)
    • Shell input ($ prompt) — executes on Pi, output returns via command queue
    • Auto-scroll with scroll-to-bottom FAB
    • Status bar with online indicator, state, battery, WiFi, CPU temp
  • src/components/app-sidebar.tsx — Added Console to Control Center nav.
  • pi/shell_handler.py — Executes shell commands with 30s timeout, 10KB output cap, and blocked dangerous commands (rm -rf /, shutdown, dd, etc.).

Real Sensor Reads

Switched three sensors from mock to real OS reads in pi/sensors.py:

  • WiFi signal — reads from /proc/net/wireless (not iwconfig which isn't installed on Pi OS Lite). Real value: -24 dBm vs mock -40 to -65.
  • CPU temperature — reads from /sys/class/thermal/thermal_zone0/temp. Real value: 41.9°C.
  • Disk free — reads from shutil.disk_usage("/"). Real value: 50.3 GB.

Each falls back to mock only if the OS read fails. GPS and battery still require hardware (ADC, UART).

WiFi Quality Labels

Added wifiQuality() helper to both dashboard and console that translates dBm to human-readable: Excellent (>-30) / Great / Good / Fair / Weak / Poor (<-80). Display shows both: "Excellent (-24 dBm)".

Blog Post

Created "First Contact: Getting the Pi Talking to the Cloud" at /blog/first-contact-pi-to-cloud via the blog:create mutation.

Files Modified

  • 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/app/control-center/page.tsx — Added wifiQuality() helper, updated WiFi display
  • src/components/app-sidebar.tsx — Added Console nav link
  • pi/sensors.py — WiFi, CPU, disk now read real OS values; mock is fallback only
  • pi/shell_handler.py — New: remote shell command handler
  • pi/main.py — Registered run_shell handler
  • docs/progress/2026-04-12_1741--pi-rover-agent-first-comms.md — Progress log for Pi agent stub

Key Takeaways

  • iwconfig is not installed on Pi OS Lite; use /proc/net/wireless for WiFi signal
  • The Pi reports -24 dBm WiFi which is "Excellent" — sitting close to the router during dev
  • CPU temp at idle is ~42°C; worth monitoring in summer outdoor use (throttles at 80°C)
  • Real disk shows 50.3 GB free vs the 20-28 GB mock range — good to have accurate numbers
  • Shell commands go through the same rover_commands queue as button presses, so everything is logged and auditable