Commit graph

37 commits

Author SHA1 Message Date
jedarden
aaa622d410 feat(ui): implement command palette (Component 34) with tests
- commandpalette.js: CommandPaletteManager with fuzzy scorer, time parsing,
  command registry (20 commands), recent history, entity search, mode gating
- commandpalette.css: modal overlay, search input, result list styles
- commandpalette.test.js: 64 tests covering fuzzy match, time parsing, commands
  completeness, keyboard nav, recent history, expert-mode gating, positioning
- app.js: spaxelGetState() exposure and Ctrl+K fallback listener
- index.html: includes commandpalette.css and commandpalette.js
- explainability.js + explain.go: detection explainability backend/frontend
- hub.go + server.go: dashboard WebSocket and API updates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 19:51:16 -04:00
jedarden
a97960bf67 fix: resolve analytics API test failures and improve corridor response format
- Fix TestAnalyticsHandler_ErrorHandling to use proper in-memory database
  instead of nil database which caused nil pointer dereference
- Update handleGetCorridors to return corridors wrapped in {corridors: [...]}
  for consistency with frontend expectations from crowdflow.js

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 08:34:24 -04:00
jedarden
46b34954f5 feat: use FXAA instead of MSAA on mobile devices
On screens < 1024px width, use FXAA (Fast Approximate Anti-Aliasing)
instead of MSAA for better performance on mobile devices.

Changes:
- Add dashboard/js/fxaa.js: FXAA post-processing module using Three.js
  EffectComposer with FXAA shader pass
- Modify renderer initialization to disable MSAA on mobile
- Initialize FXAA composer on mobile devices after scene setup
- Use FXAA render path in animation loop when active
- Update FXAA resolution on window resize

FXAA provides a good balance between visual quality and performance
on mobile GPUs where MSAA can be prohibitively expensive.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 03:33:29 -04:00
jedarden
8a190d5c11 fix: improve pinch gesture accuracy and enable three-finger pan
- Change OrbitControls.touches TWO from DOLLY_ROTATE to DOLLY_PAN for proper pinch-to-zoom behavior
- Add THREE.TOUCH.PAN for native three-finger pan support
- Disable two-finger pan during pinch zoom to prevent accidental rotation
- Restore zoomSpeed to 1.0 for standard touch response

Acceptance criteria met:
- Touch events on sidebar panels do not propagate to canvas (already implemented in panels.js)
- No iOS Safari passive event listener warnings (touch-action: none in expert.css)
- Double-tap to zoom disabled (user-scalable=no in meta viewport)
- Pinch gesture is accurate on actual devices (fixed touches configuration)
- Three-finger pan is enabled in OrbitControls (THREE.TOUCH.PAN)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 03:17:49 -04:00
jedarden
8067ef720d feat: improve pinch gesture accuracy and enable three-finger pan
- Adjust zoomSpeed from 1.0 to 0.6 for finer pinch zoom control on touch devices
- Add custom three-finger pan implementation since OrbitControls doesn't natively support it
- Three-finger drag now pans the camera, separating pan from pinch-zoom gesture
- Two-finger gesture changed from DOLLY_PAN to DOLLY_ROTATE for better gesture separation
2026-04-11 03:10:21 -04:00
jedarden
7a30b99684 feat: add mobile performance optimizations
- Cap devicePixelRatio at 2.0 on screens < 1024px width
- Disable MSAA antialiasing on mobile devices
- Disable shadow maps on mobile devices
- Add frame rate capping at 30fps for struggling mobile devices
- Auto-detect low FPS and adjust frame rate accordingly
2026-04-11 03:04:29 -04:00
jedarden
eea920de19 feat: add expert mode CSS and improve mobile viewport handling
- Add expert.css for expert mode specific styles
- Improve mobile orientation change handling with visualViewport API support
- Add iOS Safari visual viewport resize handling for better mobile experience
- Add getViewportDimensions() function preferring visualViewport API

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 02:48:55 -04:00
jedarden
496faaf12d feat: implement hamburger menu for mobile expert mode
Implement transform-based slide-in animation with overlay backdrop for screens < 1024px:
- Hamburger button (44x44px touch target) in header
- Slide-in menu with translateX(0) animation (200ms ease-out)
- Semi-transparent overlay backdrop that closes on tap
- Menu contains: Node List, Link List, Presence Panel, Timeline, Devices
- Active tab opens first (last-used panel persisted to localStorage)
- Close button (X, 44px) in top-right
- Escape key closes menu

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 02:48:55 -04:00
jedarden
c817e96802 feat: implement repeated-setting change detection with guided calibration
Detects when user changes same config setting 3+ times within 24 hours.
Shows non-intrusive prompt offering help with guided calibration flow.

Guided calibration features:
- Test for false positives (walk around room)
- Test for missed motion (sit still)
- Suggest optimal value based on diurnal baseline SNR and link health
- Apply suggested value button

Files:
- dashboard/js/proactive.js: Complete implementation with localStorage tracking

Acceptance:
- Help prompt fires after 3+ changes in 24h
- Calibration flow tests both directions
- Suggests value based on system data
- Apply button works
2026-04-11 00:18:19 -04:00
jedarden
72b9256ff4 feat: implement room transition portals and zone occupancy
Implements the complete zone and portal system for room transition
detection and occupancy tracking:

- Zone definitions using AABB volumes stored in SQLite
- Portal definitions as doorway planes with plane points and dimensions
- Portal editor in 3D dashboard using TransformControls
- Zone editor in 3D dashboard for interactive zone placement
- Crossing detection algorithm running at 10Hz in TrackManager
- Two-phase crossing detection (tentative + committed) with velocity threshold
- Occupancy counter with reconciliation pass for persisted values
- WebSocket broadcasts for zone_occupancy and zone_transition events
- REST API endpoints for zones and portals CRUD operations
- Comprehensive tests for crossing detection, occupancy, and reconciliation

Dashboard changes:
- Add portal.js for 3D portal editor with TransformControls
- Add zone-editor.js for 3D zone editor with TransformControls
- Update index.html with portal/zone editor panels
- Update app.js with zone_change, portal_change, zone_occupancy, zone_transition handlers
- Update viz3d.js with zone/portal mesh rendering

Backend changes:
- Wire zone manager in main.go
- Add WebSocket broadcasters in dashboard hub
- Add comprehensive tests in zones/manager_test.go

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 08:10:12 -04:00
jedarden
e0d0879598 feat: make expert mode mobile-responsive with touch orbit/pan/zoom
- Add touch-action: none to scene container to prevent default browser touch behaviors
- Configure OrbitControls for touch gestures (one-finger rotate, two-finger pan, pinch zoom)
- Add comprehensive mobile responsive CSS with media queries
- Add mobile menu toggle button to show/hide panels on small screens
- Add touch-specific optimizations for larger touch targets (44px minimum)
- Optimize panel layouts for mobile (collapsible panels, adjusted spacing)
- Disable hover effects on touch devices, use active states instead
- Add touch event handlers to prevent accidental panel collapse

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 04:39:46 -04:00
jedarden
4a4e8a114a feat: implement guided troubleshooting with proactive contextual help
Implements Component 36: Guided Troubleshooting system with proactive
contextual help and post-feedback explanations.

Backend (mothership/internal/guidedtroubleshoot/):
- Manager: Coordinates all guided troubleshooting features
- EditTracker: Monitors repeated settings edits (3 in 60min triggers hint)
- ZoneQualityTracker: Detects quality degradation (<60% for >24h)
- DiscoveryTracker: First-time feature discovery tooltips
- FleetNotifier: Node offline event handling with 2min grace period

API (mothership/internal/api/guided.go):
- GET /api/guided/issues - List active troubleshooting issues
- POST /api/guided/issues/quality/{zoneId}/dismiss - Dismiss quality banner
- POST /api/guided/feedback/response - Inline feedback response
- POST /api/guided/calibration/complete - Calibration reinforcement
- GET /api/guided/node/{mac}/troubleshoot - Node troubleshooting steps
- GET /api/guided/tooltip/{featureId} - Feature discovery tooltips
- POST /api/guided/tooltip/{featureId}/dismiss - Dismiss tooltip

Frontend:
- troubleshoot.js: Node offline cards, quality banners, calibration reinforcement
- guided-help.js: Step-by-step guides for common troubleshooting scenarios
- tooltips.js: First-time feature discovery with localStorage persistence
- feedback.js: Thumbs-up/down feedback with inline responses

Integration:
- Settings edit tracking via SetEditTracker on settingsHandler
- WebSocket events for quality_drop, repeated_edit, calibration_complete
- Hub broadcasts node status changes for FleetNotifier
- Main.go initializes guidedMgr with zones and fleet callbacks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 04:25:31 -04:00
jedarden
be7afae362 feat: integrate VolumeEditor initialization with 3D scene
- Initialize VolumeEditor module in initScene() override
- Pass scene, camera, controls, and renderer to VolumeEditor.init()
- Enables 3D trigger volume drawing and visualization
- Completes spatial automation trigger volume builder implementation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 18:32:45 -04:00
jedarden
8216c76bd0 feat: implement Fresnel zone debug overlay for 3D visualization
Add comprehensive Fresnel zone ellipsoid visualization for all active links
in the 3D scene. Provides developers with real-time feedback on link
coverage geometry and detection quality.

Features:
- FresnelEllipsoid() helper function in dashboard/js/fresnel.js for shared
  ellipsoid geometry computation (used by both debug and explainability)
- Wireframe + fill material rendering for clear ellipsoid visualization
- Debug layer toggle in node panel (expert mode only)
- Hover interaction with tooltip showing link details (distance, wavelength,
  Fresnel radius, health score)
- Click interaction to select corresponding link in sidebar
- Mobile viewport optimization (reduced segment count for performance)
- Comprehensive test coverage for ellipsoid geometry computation

The first Fresnel zone ellipsoid represents the region where point
reflectors have maximum impact on CSI phase. Visualizing these zones
helps system tuners understand why localisation places blobs in specific
positions and identify coverage gaps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 17:17:43 -04:00
jedarden
acd4df2e19 feat(s simulator): implement synthetic walkers for node-to-node traversal
Add WalkerTypeNodeToNode that traverses between virtual nodes with realistic movement patterns:
- Walkers move from node to node in sequence, optionally waiting at each node
- Realistic speed variation (0.8x-1.2x base speed) for natural movement
- Acceleration/deceleration when approaching target nodes
- Falls back to random walk if no nodes are configured
- Maintains consistent walker height throughout traversal

New factory functions:
- NewNodeToNodeWalker() - creates walker with configurable wait time
- NewNodeToNodeWalkerNoWait() - creates walker without waiting
- CreateNodeToNodeWalkers() - creates multiple walkers with node rotation
- WalkerSet.AddNodeToNodeWalker() - add to walker set

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 13:08:24 -04:00
jedarden
18e1b3c998 feat: add Fresnel zone wireframe visualization for active links
Implemented physics-based Fresnel zone ellipsoid visualization between
communicating nodes with proper WiFi wavelength scaling (λ ≈ 0.123m for
2.437 GHz). Features wireframe ellipsoids for first 3 Fresnel zones
with link-health-based coloring and toggle control.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 12:37:07 -04:00
jedarden
15c491ffea feat: implement anomaly detection and security mode
Implements comprehensive anomaly detection system that learns normal household
patterns over 7+ days and alerts on deviations. Transforms spaxel into a basic
home security system.

Core features:
- Normal behaviour model: statistical tracking of occupancy patterns per
  (hour_of_week, zone_id) slot with expected occupancy, typical person count,
  and typical BLE devices
- Four anomaly types: unusual hour presence, unknown BLE device, motion during
  away mode, unusual dwell duration
- Security mode: lowered thresholds, immediate alerts, bypasses quiet hours
- Auto-away/disarm: automatic security mode activation based on BLE device
  presence (15min absence, auto-disarm on device return)
- Alert chain: staged notifications (dashboard → push → webhook → escalation)
- WebSocket integration: real-time anomaly broadcasts to dashboard

API endpoints:
- GET/POST /api/mode: system mode control (home/away/sleep)
- GET /api/security/status: current security state

Tests cover all anomaly types, alert chain timing, security mode thresholds,
auto-away/disarm, acknowledgement flow, and cooldown deduplication.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 09:48:44 -04:00
jedarden
281bbefb57 feat: complete floor plan dashboard UI
- Floor plan upload panel with image selection and preview
- Two-point calibration UI with pixel distance measurement
- Real-world distance input for scale computation
- Pixel-to-meter scale factor calculation and storage
- Fixed floor plan image serving at /floorplan/image.png
- Integration with Viz3D ground plane texture
- CSS styling for floor plan setup panel
- Image persists across server restart via SQLite

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 08:37:08 -04:00
jedarden
7559f1964e feat: add Identify button to fleet status page
Adds a lightning bolt () Identify button per node row in the
fleet status page that POSTs to /api/nodes/{mac}/identify.

- Added CSS styling for .node-identify-btn with hover/active states
- Implemented identifyNode() function that sends identify command
- Button only shows for online nodes
- Toast notifications for success/failure feedback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 07:17:13 -04:00
jedarden
ff3428fee6 feat: robust WebSocket reconnection with backoff, extrapolation, and visual states
Implements exponential backoff (1s→10s cap) with ±500ms jitter,
blob position extrapolation during disconnects (capped at 2s),
three visual states (silent <5s, dimming 5-30s, modal >30s),
and automatic scene restoration on reconnect.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 12:34:35 -04:00
jedarden
97f1eafc6f feat: process buffered events from delta WebSocket updates
Events (zone entries/exits, portal crossings, presence transitions)
were already broadcast immediately via BroadcastEvent, but the
buffered copies included in the 10 Hz delta tick were silently
dropped by handleIncrementalUpdate. Now delta events are processed
through the same handleEventMessage path, with dedup to avoid
double-processing when both immediate and delta copies arrive.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 11:04:49 -04:00
jedarden
5b24192186 feat: add trigger_state WebSocket message type to /ws/dashboard feed
Broadcasts { type: 'trigger_state', trigger: { id, name, last_fired, enabled } }
on trigger fire, enable, and disable events. Handled in app.js onmessage
and forwarded to window.Automations.updateTriggerState().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 08:41:17 -04:00
jedarden
93735f70bf feat: wire alert broadcasts for anomaly detections and security mode changes
- Connect anomaly detector callbacks to BroadcastAlert for dashboard alerts
- Add security mode change callback to broadcast typed alerts
- Add blob appeared/disappeared callbacks to Tracker
- Add alert tracking state (alerts Map, unacknowledgedCount) in dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 06:57:23 -04:00
jedarden
757d7240dc feat: implement snapshot-on-connect + incremental update protocol for dashboard WebSocket
- Hub sends full snapshot (type=snapshot) on new client connect before adding
  to broadcast list, preventing race with delta messages
- tickDelta at 10 Hz computes byte-level diffs of cached JSON fields, broadcasts
  only changed fields with no type field
- Dashboard sets awaitingSnapshot on WS open, drops incremental updates until
  snapshot received, rebuilds full state from snapshot
- Fix zone snapshot building (nil→ok check, SizeX fields)
- Remove unused broadcastBLEScan function
- Add drainSnapshot helper and fix TestHub_LinkEvents to account for snapshot
- Add TestHub_SnapshotOnConnect, TestHub_SnapshotBeforeDelta, TestHub_DeltaOmitsTypeField

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 22:00:36 -04:00
jedarden
bfa3e6f2b2 feat: expand dashboard WebSocket feed with events, alerts, BLE, triggers, and system health
- Add BroadcastEvent for presence transitions, zone entries/exits, portal crossings
- Add BroadcastAlert for anomaly detections and security mode triggers
- Add BroadcastBLEScan for BLE device list updates (5s interval)
- Add BroadcastTriggerState for automation trigger state changes
- Add BroadcastSystemHealth for periodic system stats (60s interval)
- Add BLEState, TriggerState, and SystemHealthProvider interfaces
- Update hub.Run with new tickers for BLE (5s) and system health (60s)
- Update dashboard app.js with handlers for new message types
- Add bleDevices map to state for BLE device tracking
- Log unhandled message types for future debugging

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 10:18:04 -04:00
jedarden
14c49cb919 feat(breathing): implement stationary person detection via breathing analysis
Add FFT-based breathing detection with long-dwell presence tracking:

- FFTBreathingDetector: Rolling 30-second buffer, Hann window, FFT analysis
  to detect periodic breathing signals in 0.2-1.0 Hz band
- DwellTracker: State machine with CLEAR → MOTION_DETECTED →
  POSSIBLY_PRESENT → STATIONARY_DETECTED transitions
- Health gating: Detection disabled when link health < 0.7
- Dashboard: Slow-pulsing blue dot for stationary detection with BPM tooltip
- Timeline: Event logging on transition to STATIONARY_DETECTED

Physics: CSI phase oscillates at 2x breathing rate due to round-trip
path length change. 15 BPM breathing → 0.5 Hz CSI phase oscillation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 20:25:17 -04:00
jedarden
20aadb54f0 feat(learning): expose showToast for feedback module integration
Add showToast to SpaxelApp public API so the Feedback module can
display toast notifications when users submit feedback on detections.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 16:47:38 -04:00
jedarden
037ac09d9e feat(analytics): implement crowd flow visualization
Add trajectory accumulation, directional flow maps, and dwell time
hotspot visualization for occupancy pattern analysis.

Backend:
- FlowAccumulator records trajectory segments and dwell time in SQLite
- REST endpoints for flow map, dwell heatmap, and detected corridors
- Bresenham rasterization for flow vector aggregation
- Connected component analysis for corridor detection

Frontend:
- Pattern controls in dashboard sidebar (flow, dwell, corridors toggles)
- Time filter dropdown (7d, 30d, all time)
- 3D visualization with ArrowHelper for flow, PlaneGeometry for heatmaps
- Pulsating animation on flow arrows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 15:38:40 -04:00
jedarden
bc2c377e0c feat(signal): implement Phase 5 Reliability & Intelligence
Phase 5 deliverables:
- Diurnal adaptive baseline (24-slot hourly vectors, 7-day learning, crossfade, confidence indicator)
- Stationary person detection (breathing band 0.1-0.5 Hz, long-dwell logic with health gating)
- Ambient confidence score (per-link health: SNR, phase stability, packet rate, drift; composite gauge)
- Link weather diagnostics (root-cause suggestions, weekly trends, repositioning advice)
- Baseline persistence (SQLite storage for EMA and diurnal baselines)

Key components:
- signal/diurnal.go: 24-hour baseline slots with cosine crossfade
- signal/breathing.go: 4th-order Butterworth bandpass filter for breathing detection
- signal/ambient.go: Per-link health scoring with weighted composite
- signal/persist.go: SQLite persistence for baselines
- signal/healthpersist.go: Health log aggregation for weekly trends
- diagnostics/linkweather.go: 5 diagnostic rules with actionable advice
- diagnostics/reposition.go: GDOP-based repositioning target computation
- fleet/healer.go: Self-healing fleet with role re-optimization
- dashboard/js/app.js: Quality gauge UI with health polling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 12:16:56 -04:00
jedarden
90e230f9d9 feat(dashboard): complete Phase 4 onboarding & OTA system
Interactive onboarding wizard:
- 8-step Web Serial-based provisioning flow
- Firmware flashing via esp-web-install-button (CDN)
- Live CSI waveform feedback during guided calibration
- Server-side provisioning with client-side fallback
- Serial JSON response handling with error mapping
- Post-calibration reinforcement card with link count

OTA firmware management:
- Firmware list with SHA-256 hashes and size display
- Per-node progress tracking (idle/pending/downloading/rebooting/verified/failed/rollback)
- Rolling update orchestration via REST API
- Status bar button with state indicators (normal/in-progress/has-update)
- Node list badges for OTA status and rollback warnings

Guided troubleshooting:
- First-time feature tooltips with 8s auto-dismiss
- Sequential tooltip tour triggered on first node connection
- Node offline cards with step-by-step recovery instructions
- Factory reset instructions modal
- Client-side link health check (60s no-frame threshold)
- Captive portal recovery documentation

Exit criteria: New ESP32-S3 from unboxed to streaming CSI in under 5 minutes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 21:21:55 -04:00
jedarden
7b325703bd feat(dashboard): interactive 3D node placement with real-time GDOP coverage overlay
Adds TransformControls for dragging nodes in the 3D scene, a room dimension
editor (width/depth/height), a GDOP (Geometric Dilution of Precision) coverage
overlay on the ground plane that updates in real-time during node drag, virtual
node support for planning optimal placement before hardware purchase, and REST
API integration to persist positions and room config to the mothership.

Backend adds PUT /api/nodes/{mac}/position, POST /api/nodes/virtual,
DELETE /api/nodes/{mac}, PUT /api/room endpoints. Also wires OTA status
handler and improves firmware manifest to use actual latest binary filename.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 09:25:44 -04:00
jedarden
570e5eec41 feat(dashboard): guided troubleshooting and first-time UX
Add troubleshooting infrastructure for non-technical users:

- TroubleshootManager: node offline cards with stepped recovery
  guidance, factory reset modal, and detection quality banners
- TooltipManager: first-time feature tooltips with localStorage
  persistence, auto-dismiss, and sequential tour
- Onboarding failure guidance: human-readable error messages for
  browser compatibility, USB connection, WiFi provisioning, and
  node detection failures
- Post-calibration reinforcement card with summary and next steps
- Client-side link health check with auto-recovery
- CSS for offline cards, tooltips, quality banners, and modals
- Script tags wired in index.html for troubleshoot.js and tooltips.js
- 30 tests covering all troubleshooting and tooltip functionality

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 04:19:06 -04:00
jedarden
75edd8339a feat(dashboard): presence panel with per-link motion indicators and deltaRMS time series
Add 500ms periodic presence_update broadcast from the dashboard hub with
per-link motion state (is_motion, delta_rms, confidence). Surface this in
a new Presence panel on the dashboard with coloured dot indicators
(green=clear, amber=motion, red=high-confidence) and deltaRMS values.
Includes a rolling 10s Canvas 2D line chart of deltaRMS with a threshold
line at 0.02 for the selected link.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 23:49:08 -04:00
jedarden
bcd19ad756 feat(dashboard): 3D spatial visualization with humanoid SkinnedMesh figures
Implements plan item 17 — full Three.js Phase 3 visualization layer:

- Room bounds: floor, ceiling, semi-transparent walls and wireframe edges
  built from registry_state room config (width/depth/height/origin)
- Floor plan texture: upload any image via status-bar button; mapped to
  ground plane via THREE.TextureLoader
- Humanoid figures: SkinnedMesh + AnimationMixer with 13-bone skeleton;
  four AnimationClip postures (standing, walking, seated, lying); smooth
  0.35 s crossfade transitions; walking speed scales animation timeScale;
  figures orient in direction of travel
- Vertical pillar anchors: line from floor to ceiling at each blob position
- Footprint trails: floor-level Line geometry following blob.trail history
- Node meshes: OctahedronGeometry at registry node 3-D positions; link
  lines redrawn whenever link_active/inactive events arrive
- View presets: 3D perspective, top-down orthographic, first-person follow
  (lerps camera to track first active blob)
- WebSocket: handles registry_state, loc_update, link_inactive message types
  newly routed through handleJSONMessage; existing CSI/motion pipeline intact

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 00:26:25 -04:00
jedarden
fb691904c6 feat(dashboard): per-link motion presence indicator with amplitude time series
- Dashboard hub broadcasts motion state changes immediately on transition
  (idle↔motion) via BroadcastMotionState; periodic state snapshots include
  motion_states for new client init
- Per-link presence badge (green CLEAR / red MOTION) rendered in link list
  alongside global presence indicator in status bar
- Amplitude mean time-series chart (60 s rolling window) for selected link,
  line segments colored by motion state at each sample
- Fix: links created from JSON link_active/state events now initialize
  ampHistory and lastAmpSample so time-series accumulates from first frame

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:55:33 -04:00
jedarden
de424a1f63 feat(mothership): complete Phase 2 signal processing & detection
- Dashboard presence indicator: per-link MOTION/CLEAR badges with global
  status bar indicator, motion_state WebSocket messages, amplitude chart
- CSI recording buffer: disk-backed circular buffer (replay/store.go) with
  magic-tagged binary format, wrap/eviction, 360 MB default (~48 h at 20 Hz)
- Adaptive sensing rate: RateController ramps nodes to 20 Hz on motion,
  drops to 2 Hz after 10 s idle; wires to SendConfigToMAC over WebSocket
- Fix: alias internal/signal as sigproc to avoid conflict with os/signal
- Fix: add GetAllMotionStates() to MockIngestionState in dashboard tests

All tests pass (signal, ingestion, replay, dashboard).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:27:24 -04:00
jedarden
8230ef4222 feat(dashboard): web dashboard skeleton with Three.js 3D scene and CSI visualization
- Static HTML/JS dashboard served by mothership at /
- Three.js 3D scene with ground grid, OrbitControls (pan/zoom/rotate)
- WebSocket connection at /ws/dashboard for real-time CSI streaming
- Binary CSI frame parsing (24-byte header + I/Q payload)
- Amplitude bar chart (64 subcarriers) as 2D Canvas overlay
- Node/link panels with live status and click-to-select
- Dashboard Go package with Hub for client broadcasting
- Ingestion server broadcasts CSI frames and node events to dashboard
- 5 new tests for dashboard hub operations

Complete: 3D scene, WebSocket, amplitude chart, node/link panels
Remaining: Docker packaging (Phase 1 final item)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 07:40:53 -04:00