Progress Log

Control Center V2: Weather Integration, Mission UX, Post-Mission Logging

April 12, 202610:38Build Log

Control Center V2: Weather Integration, Mission UX, Post-Mission Logging

Date: 2026-04-12 Type: Build Log

Context

The Control Center dashboard was functional but raw. This session focused on making it operationally useful: adding pre-flight checks before missions, integrating live weather data into mission planning and records, improving how captures and battery data are displayed, and simplifying post-mission logging so weather doesn't need to be entered manually.

What Changed

New Mission Page (/control-center/new-mission)

  • Pre-flight checks page that evaluates rover telemetry: connection, battery %, GPS lock, camera, storage, WiFi, CPU temp
  • Weather check based on precipitation probability over next 3 hours from Open-Meteo (advisory only, never blocks launch)
    • =80% precip = fail (advisory), 40-79% = warning, <40% = pass

  • Re-check button to re-evaluate after fixing issues
  • Launch button with confirmation dialog
  • Added to sidebar nav

Weather Auto-Snapshot on Mission Start

  • New convex/weather.ts with snapWeatherForMission internal action
  • missions.start() triggers weather fetch via scheduler.runAfter(0, ...)
  • Structured weatherSnapshot field on missions: temp, humidity, wind, precipitation, WMO code, condition label, 4-hour forecast
  • Zero manual weather logging needed
  • Added precipitationProbability to hourly forecast data in src/lib/weather.ts

Confirmation Dialogs on All Commands

  • Stop, Return Home, Take Photo, Pause, Resume all require confirmation
  • Single shared Dialog component with dynamic title/description/variant
  • Applied to both dashboard and mission detail pages

Captures Gallery + Browsing

  • Mission detail shows a horizontal teaser strip (first 5 thumbnails + "+N more")
  • Links to dedicated /control-center/missions/[id]/captures page
  • Grid/list view toggle
  • Lightbox viewer with prev/next navigation, counter badge, and metadata panel (time, GPS, battery %)

GPS Route Map

  • SVG-based relative route visualization on mission detail
  • Normalizes GPS coords to viewbox with grid lines
  • Start (green) / end (red) markers, waypoint dots along path

Battery as Percentage

  • voltageToPercent() helper using 2S LiPo range (6.0V=0%, 8.4V=100%)
  • Applied across dashboard telemetry, missions list, mission detail, live panel, timeline, capture cards

Missions Named by Date/Time

  • Removed route-based naming throughout
  • Missions identified by formatted startedAt timestamp (e.g. "Apr 12, 2026, 9:34 AM")
  • Removed Route column from missions table

Battery Drain Chart Moved + Collapsed

  • Moved below activity timeline (was directly after stats)
  • Wrapped in Collapsible, defaults to closed

Post-Mission Log (was "Log Tick Count")

  • Renamed to "Post-Mission Log" across UI and sidebar
  • Simplified form: tick count, notes, optional photo uploads
  • Removed temperature, humidity, time of day, cloth condition fields (weather is auto-logged, cloth condition goes in notes if needed)
  • Photo upload: file picker with previews, uploads to Convex storage, displays as thumbnails on log entries
  • Photos clickable to open full-size

Documentation Updates

  • docs/articles/system-overview.md — Rewrote Operation Flow with pre-flight, weather, confirmations, gallery
  • docs/articles/full-spec.md — Expanded "How the System Operates" with full mission lifecycle
  • docs/articles/build-09-pi-api-integration.md — Added weatherSnapshot schema, auto-snapshot note, updated data flow diagram
  • docs/articles/weather-api.md — Documented auto-capture flow, pre-flight check logic, all implementation files

Files Modified

  • convex/schema.ts — Added weatherSnapshot object to missions, photos array to tick_counts
  • convex/missions.ts — Auto-schedule weather snapshot on start()
  • convex/weather.ts — New: snapWeatherForMission action + patchWeather mutation
  • convex/tickCounts.ts — Added photos field, generateUploadUrl, resolve photo URLs in queries
  • src/lib/weather.ts — Added precipitationProbability to hourly fetch and types
  • src/app/control-center/page.tsx — Confirmation dialogs, battery %, New Mission link
  • src/app/control-center/new-mission/page.tsx — New: pre-flight checks + weather advisory + launch
  • src/app/control-center/missions/page.tsx — Removed Route column, battery %
  • src/app/control-center/missions/[id]/page.tsx — Confirmations, captures teaser, GPS map, weather card, post-mission log with photos, battery drain moved
  • src/app/control-center/missions/[id]/captures/page.tsx — New: captures browsing with grid/list + lightbox
  • src/app/control-center/tick-log/page.tsx — Renamed to Post-Mission Log, simplified display, photo thumbnails
  • src/components/app-sidebar.tsx — Added New Mission, renamed Tick Log to Post-Mission Log
  • docs/articles/system-overview.md — Updated Operation Flow
  • docs/articles/full-spec.md — Updated How the System Operates + Operations
  • docs/articles/build-09-pi-api-integration.md — weatherSnapshot schema, data flow diagram
  • docs/articles/weather-api.md — Auto-capture flow documentation

Key Takeaways

  • Weather uses Open-Meteo (free, no API key) — fetched server-side via Convex action, not from the Pi
  • Weather checks are advisory-only with blocking: false — system failures block launch, weather never does
  • scheduler.runAfter(0, ...) is the pattern for triggering async side effects from Convex mutations
  • Convex actions (not mutations) are required for HTTP fetches — used internalAction since it's only called by the scheduler
  • Photo uploads use the standard Convex pattern: generateUploadUrl mutation → POST file → get storageId → save with record
  • ctx.storage.getUrl(id) resolves storage IDs to URLs in queries