Commit graph

68 commits

Author SHA1 Message Date
jedarden
1a52dde111 feat: implement morning briefing feature
Add daily summary card with push notification option.

- Add briefings table with person and sections_json columns (migration 013)
- Implement briefing generator with sections for alerts, sleep, people, anomalies, health, predictions, and learning
- Add briefing scheduler for automatic daily generation at configurable time
- Add push notification support via notify adapter
- Add API endpoints: GET/POST /api/briefing, /api/briefing/latest, /api/briefing/settings
- Add frontend briefing card with sections styled by type
- Add briefing settings panel for configuration (time, push notifications, auto-generate)
- Add briefing indicator icon when dismissed but available
- Integrate briefing scheduler into main.go with providers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 00:25:33 -04:00
jedarden
61e4035862 feat: implement command palette with fuzzy matching and mode awareness
- Ctrl+K/Cmd+K keyboard shortcut for power user efficiency
- Fuzzy matching across zones, people, nodes, events, settings, and help
- Categories: navigation, fleet, security, nodes, zones, view, mode, theme, help
- Recent commands tracking with localStorage persistence
- Keyboard navigation (arrows, Page Up/Down, Home/End, Enter)
- Search result highlighting with mark tags
- Help modal with contextual documentation
- Dismissible keyboard shortcut hint for first-time users
- Mode awareness: only available in expert mode (disabled in simple/ambient)
- Show toast notification when opened from restricted modes
- CSS with dark/light mode support and reduced motion preference
- Full keyboard accessibility with visible focus indicators
- Command registry API for dynamic command registration
2026-04-09 23:11:07 -04:00
jedarden
b9292db99f feat: implement spatial quick actions with follow camera
- Add userData.mac to node meshes for raycasting support in context menus
- Fix duplicate blobMeshes function definition in viz3d.js
- Fix typo: FeeddownPanel -> FeedbackPanel in quick-actions.js
- Enable right-click context menus on 3D elements (blobs, nodes, zones, portals, triggers)
- Add long-press support for mobile devices
- Implement follow camera functionality that tracks selected person
- Add follow mode indicator with stop button and ESC key support

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 23:02:54 -04:00
jedarden
6b22ba65ac feat: implement spatial quick actions with follow camera
- Add right-click context menus on 3D elements (blobs, nodes, zones)
- Implement follow camera functionality with visual indicator
- Add zone detection in context menu based on position
- Integrate with state management system for data lookups
- Support both mouse right-click and touch long-press interactions
- Add ESC key handler to stop following

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 22:54:36 -04:00
jedarden
6d30c63414 feat: implement ambient dashboard mode for wall-mounted tablets
- Add /ambient route serving dedicated ambient.html page
- Simplified top-down floor plan using Canvas 2D (no Three.js)
- Time-of-day aware palettes: morning (bright/cool), day (neutral), evening (warm amber), night (dim)
- People rendered as glowing colored dots (BLE-identified) or neutral dots (unknown)
- Room labels with occupancy counts
- Auto-dim after 30 minutes of inactivity
- Alert mode with pulsing red border and action buttons
- Morning briefing integration with auto-dismiss
- WebSocket for real-time blob and zone updates
- Lightweight implementation targeting <30 MB RAM for older tablets
- OLED-safe night mode with true black background
2026-04-09 22:26:37 -04:00
jedarden
425d503449 feat: implement simple mode UI with WebSocket integration
- Add card-based mobile-first UI for non-technical users
- Implement room occupancy cards with real-time updates
- Add activity feed with WebSocket integration
- Support progressive disclosure from simple to expert mode
- Integrate with router for hash-based navigation (#simple)
- Handle WebSocket messages for blobs, zones, events, and alerts
- Add room detail modals and security mode toggle

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 22:08:03 -04:00
jedarden
cdd9c64800 feat: complete pre-deployment simulator implementation
Implements comprehensive pre-deployment simulator for WiFi CSI-based
positioning that allows users to predict detection quality before
purchasing hardware.

Components:
- Virtual space definition with rooms, walls, and material properties
- Virtual nodes with configurable roles (TX/RX/TX_RX/PASSIVE/IDLE)
- Synthetic walkers (random walk, path-following, node-to-node)
- GDOP overlay for coverage quality visualization
- Signal propagation model with path loss and wall attenuation
- Fresnel zone accumulation for blob detection
- REST API endpoints for simulator control
- Dashboard integration with space/node/walker management
- Coverage optimization recommendations

The simulator produces realistic synthetic CSI data matching
real-world conditions by using the same propagation models and
localization algorithms as the live system.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 21:30:47 -04:00
jedarden
a70e3e433d feat: implement GDOP overlay for simulator visualization
- Add GET /api/simulator/gdop/heatmap endpoint in both simulator handlers
- Fix viz3d.js to call correct endpoint (GET instead of POST)
- Update response format handling to parse gdop_map and grid_dimensions
- Generate colors from GDOP values using quality thresholds
- Position overlay correctly in 3D scene

The GDOP overlay now visualizes accuracy metrics across the virtual space
with color-coded quality indicators (green=excellent, yellow=good, orange=fair, red=poor).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 21:30:47 -04:00
jedarden
6d975f472b feat: implement time-travel debugging and CSI replay
This commit implements the replay feature that allows users to pause the
live 3D view, scrub through a 48-hour recording buffer, and replay the 3D
scene exactly as it was at any historical moment.

Key components:
- Recording buffer with SeekToTimestamp for time-travel navigation
- Replay engine with session management (start, stop, seek, play, pause)
- Replay signal processing pipeline with tunable parameters
- REST API endpoints for replay control
- Dashboard UI with timeline scrubber, playback controls, and tuning panel
- Comprehensive test coverage for all replay functionality

Acceptance criteria met:
- Seek to any point in 48-hour window completes in < 1 second
- Replay produces identical blob positions to original live processing
- Parameter sliders re-process in < 3 seconds
- "Apply to Live" correctly writes parameter changes
- Timeline scrubber event markers correctly align
- "Back to Live" correctly resumes live detection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 19:27:42 -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
245bbe89bb docs: verify REST API implementation completeness
All required REST API endpoints have been verified as implemented:

- Settings (GET/POST /api/settings): SQLite-backed with cache
- Zones & Portals (CRUD): WebSocket broadcast for live 3D view
- Automation Triggers (CRUD + test): VolumeTriggersHandler with webhook/MQTT/Ntfy
- Notifications (config + test): Inline handlers with quiet-hours support
- Replay/Time-Travel (sessions, start, stop, seek, tune): CSI recording buffer
- BLE Devices (list, update): Device registry with person assignment

All handlers include OpenAPI-style godoc comments and proper error handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 18:18:42 -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
c3572e4305 feat: implement time-travel debugging and CSI replay
This commit adds complete time-travel debugging capabilities for CSI data,
enabling users to pause the live 3D view, scrub through historical data,
and replay the 3D scene exactly as it was at any point in the 48-hour recording
window.

Key features:
- ReplayEngine with state machine (LIVE, PAUSED, REPLAYING, SEEKING)
- Replay pipeline separate from live pipeline with tunable parameters
- WebSocket command handlers for replay control (seek, play, pause, set_params, apply_to_live)
- Timeline scrubber UI with playback controls and parameter tuning panel
- Seek performance < 1 second for all active links
- Parameter sliders for motion threshold, baseline tau, fresnel decay, subcarriers, breathing sensitivity

Implementation:
- mothership/internal/replay/engine.go: ReplayEngine with state machine
- mothership/internal/replay/pipeline.go: Replay signal processing pipeline
- mothership/internal/replay/types.go: Session types and TunableParams
- mothership/internal/dashboard/server.go: WebSocket command handlers
- dashboard/js/replay.js: Timeline scrubber UI with playback controls
- mothership/internal/dashboard/hub.go: BroadcastReplayBlobs method

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 16:50:40 -04:00
jedarden
1995b06820 feat: add anomaly_detected and sleep_session_end to valid event types
- Update isValidEventType to include anomaly_detected and sleep_session_end
- These event types were already supported in simple mode filtering
- Ensures consistency between type validation and mode filtering
2026-04-09 15:30:45 -04:00
jedarden
d879e2268b feat: add search and filter to timeline with category checkboxes
Implement comprehensive filter bar with:
- Type filter checkboxes for event categories (Presence, Zones, Alerts, System, Learning)
- Person and zone dropdowns for filtering
- Date range selector with preset options (Today/Last 7 days/Last 30 days/Custom)
- Text search input for fuzzy matching on descriptions
- Client-side filtering for loaded events (instant feedback)
- Server-side filtering for date-range queries
- Load more pagination works for 500+ results

Backend changes:
- Add support for 'since'/'until' date range parameters in /api/events
- Add zone_id and person_id query parameter aliases
- Add POST /api/events/{id}/feedback endpoint for feedback submission

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 14:33:33 -04:00
jedarden
54cab1e89d wip: various improvements
- Visualization improvements in 3D view
- Event API enhancements
- Replay system refinements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 13:52:10 -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
eb6e479bea feat: implement detection explainability system
Add X-ray overlay showing contributing links to detections with confidence breakdown.

- Users can click "Why?" on any blob to see detailed explanation
- Contributing links are highlighted with Fresnel zone visualization
- Per-link contribution breakdown shows deltaRMS, zone number, weight
- BLE identity match details displayed when available
- Confidence gauge shows overall detection certainty

Explainability is accessible via:
- Right-click context menu on blob figures
- "Why?" button in blob hover tooltip
- Click directly on humanoid blob figures
- Timeline event "Why?" buttons

Accepts: Users can see exactly why a detection was triggered with visual overlays and confidence metrics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 11:48:55 -04:00
jedarden
0cb2353a08 feat: implement activity timeline with tap-to-jump and inline feedback
Phase 8 implementation: Activity Timeline (Component 27)

- Tap-to-jump navigation: Click any event to create replay session and seek to that moment
- Inline feedback display: Thumbs up/down buttons on each event for detection feedback
- Replay API integration: Creates replay window around event timestamp (±5 seconds)
- Feedback API: New /api/feedback endpoint for correct/incorrect/missed detection reports
- Event loading improvements: Real-time WebSocket event insertion with animation
- Filter UI: Type, zone, person, time range, and search filters
- Load more pagination: Keyset cursor-based pagination for large event sets

Acceptance criteria met:
- Users can view all system events chronologically
- Tap any event to jump to that moment in time via replay mode
- Inline feedback buttons allow marking detections correct/incorrect

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 11:07:16 -04:00
jedarden
af8800caef feat: add self-improving localization REST API
Implement REST API endpoints for managing learned weights and tracking
improvement in the self-improving localization system.

- Add LocalizationHandler with endpoints for:
  - GET /api/localization/weights - get all learned link weights
  - GET /api/localization/weights/{linkID} - get specific link weight
  - POST /api/localization/weights/reset - reset all weights to default
  - GET /api/localization/spatial-weights - get spatial weights per zone
  - GET /api/localization/groundtruth/* - ground truth sample management
  - GET /api/localization/accuracy/* - position accuracy tracking
  - GET /api/localization/learning/* - learning progress and history

- Integrate spatial weight learner into fusion engine:
  - Add AddLinkInfluenceWithSpatialWeights to grid.go for per-cell weight application
  - Update Fuse() in fusion.go to use spatial weight functions when available
  - Apply both sigma adjustments and spatial weights for Fresnel zone computation

- Add comprehensive table-driven tests for all API endpoints

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 10:06:06 -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
3da0c32ba3 feat: dashboard PIN change flow
- Backend: Add POST /api/auth/change-pin endpoint
  - Requires valid session; body: {old_pin, new_pin}
  - Verifies old PIN against bcrypt hash; returns 403 on mismatch
  - Hashes new PIN with bcrypt cost=12
  - Existing sessions remain valid after PIN change
  - Returns {ok:true} on success

- Dashboard: Security section in settings panel
  - Add "Security" section with Change PIN button
  - Modal form: old PIN → new PIN → confirm new PIN → Submit
  - Inline error display for incorrect current PIN (403)
  - Success toast notification on PIN change
  - Validation: 4-8 digits, numeric only, PINs must match, new ≠ old

- Tests: Add comprehensive tests for change PIN endpoint
  - Success case: old PIN verified, new PIN works
  - Wrong old PIN: returns 403, original PIN still works
  - Unauthenticated: returns 401
  - Invalid new PIN: validation for length, digits, etc.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 08:05:35 -04:00
jedarden
47e8fa7999 feat: add identify button to fleet status page and 3D view context menu
- Add 'Identify' button to fleet health panel role list for online nodes
- Add CSS styling for fleet identify button
- Add identifyNode function to FleetPanel public API
- 3D view context menu with 'Identify (blink LED)' already implemented

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 07:41:18 -04:00
jedarden
519b5cbe09 feat: add Identify context menu to 3D view
Add 'Identify (blink LED)' option to the right-click context menu
in the 3D view that POSTs to /api/nodes/{mac}/identify.

The context menu appears when right-clicking on a node mesh in the
3D visualization. Uses recursive raycasting to properly detect
both standard node meshes and router node groups.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 07:31:35 -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
24e652a389 feat: integrate OUI lookup into passive radar AP detection
- Add manufacturer display to AP detection banner
- Show "your router (Manufacturer)" when OUI is known
- Show "your router" as fallback when OUI unknown
- Expand OUI database with more manufacturer entries

The AP detection banner now shows the router manufacturer
when available from OUI lookup, making it easier for users
to identify their router during the onboarding process.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 06:35:44 -04:00
jedarden
636f3efba2 feat: complete anomaly detection & security mode dashboard UI
- Add anomaly.css and sleep.css to dashboard includes
- Add sleep.js for sleep quality monitoring
- Implement analytics API handler (flow, dwell, corridors)
- Add tracks API and tests for time-based data queries
- Add sleep monitor tests
- AnomalyDetector initialized and running in main()
- Anomaly events broadcast via WebSocket to dashboard
- Security mode arm/disarm persists across restarts (learning_state table)
- Learning progress tracking and display
- Alert banner with acknowledge functionality
- All API endpoints wired: /api/anomalies, /api/security/*, /api/analytics/*

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 05:59:54 -04:00
jedarden
bf40673b72 feat: wire anomaly detection & security mode API endpoints
AnomalyDetector is initialized in main() with periodic model updates.
Anomaly events are pushed to dashboard WS as 'alert' messages via
BroadcastAlert callback. Security mode arm/disarm state persists
across restarts via SQLite learning_state table.

Endpoints:
- GET /api/anomalies?since=24h — list recent anomaly events
- POST /api/security/arm — enable security mode
- POST /api/security/disarm — disable security mode
- GET /api/security/status — armed, learning_until, anomaly_count_24h

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 14:36:59 -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
cac25e86e8 feat: implement security mode dashboard UI
- Update learning progress display to show "X of Y days complete" format
- Add last anomaly location info to security dialog stats
- Add CSS styling for anomaly event type in timeline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 10:22:00 -04:00
jedarden
80ac99ca7c feat: implement security mode dashboard UI
- Add security status indicator in status bar with mode badge
  (DISARMED / LEARNING / ARMED / ALERT)
- Add arm/disarm toggle button with confirmation dialog
- Add learning period progress bar display
- Add alert banner for anomalies when armed
- Add acknowledge functionality for anomalies
- Integrate with WebSocket for real-time updates
- Add security.css with responsive styles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 10:14:51 -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
e74834a3bf feat: implement webhook action firing & fault tolerance for automations
Backend: HTTP client with 5s timeout, fire-and-forget webhook delivery,
4xx disables trigger with error message, 5xx/timeout increments error count,
test endpoint, enable/disable endpoints, webhook_log audit table,
WebSocket alert broadcasting on trigger errors.

Dashboard: error badge on trigger cards, Test Webhook button, webhook log
view, Re-enable button, real-time error alerts via WebSocket.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 21:39:51 -04:00
jedarden
22b745f274 feat: webhook action firing & fault tolerance for automations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 20:29:53 -04:00
jedarden
3781ab7f86 feat: implement BLE device discovery & registration dashboard panel
Implements a comprehensive 'People & Devices' panel for BLE device management:

Frontend (dashboard/js/ble-panel.js, dashboard/css/ble-panel.css):
- Device list sorted by sighting frequency (rssi_count)
- Registration modal with label, person assignment, color picker, device type
- Auto-type hints with icons (iPhone, Apple Watch, Fitbit, Tile, AirTag)
- Pre-registration form for manual MAC address entry
- Unregistered count badge on panel toggle
- Device details modal with sighting history

Backend (mothership/internal/ble/handler.go):
- GET /api/ble/devices with registered/discovered filters and hours parameter
- PUT /api/ble/devices/{mac} for updates (label, device_type, person_id)
- GET /api/ble/devices/{mac}/history for sighting timeline
- POST /api/ble/devices/preregister for manual device entry
- GET /api/people and POST /api/people for person management

Database (mothership/internal/ble/registry.go):
- Enhanced ble_devices table with person_id, device_type, manufacturer fields
- ble_device_sightings table for history timeline
- Auto-detection of device types from manufacturer data (Apple, Fitbit, Garmin, Tile)
- RSSI tracking and averaging

Integration (dashboard/index.html, mothership/cmd/mothership/main.go):
- BLE panel button with unregistered badge in dashboard
- BLE registry wired to dashboard hub for WebSocket broadcasts
- 5-second ticker broadcasts device state to connected clients

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 15:21:11 -04:00
jedarden
374b61a559 feat: implement BLE address rotation detection & identity continuity
Backend (mothership/ble/):
- RotationDetector with manufacturer data fingerprinting, time+RSSI proximity
- ble_device_aliases table for tracking rotated MAC addresses
- Identity matcher integration with alias resolution for blob-to-device scoring
- 5-minute grace period fallback when rotation is unresolved
- REST API: GET /api/ble/devices/{mac}/aliases, POST /api/ble/merge, POST /api/ble/split

Dashboard UI (dashboard/js/):
- Rotation icon indicator (🔄) in BLE device registry
- Manual merge/split UI with confirmation dialog
- Alias history expandable in device detail panel
- Possible rotations section with match confidence

Acceptance:
- Identity continuity across address rotation with >90% precision
- No duplicate person tracks created on rotation event
- Alias history queryable via GET /api/ble/devices/{mac}/aliases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 14:33:27 -04:00
jedarden
d2e5b4d4a0 feat: implement passive radar auto-detection of router AP
Automatically detect the home router as a passive radar TX source,
eliminating need for a dedicated active TX node.

Firmware changes:
- During hello message, include ap_bssid and ap_channel from esp_wifi_sta_get_ap_info()

Mothership changes:
- On hello: extract ap_bssid; if >=80% of nodes report same BSSID create virtual node entry with virtual=1
- OUI lookup: embedded IEEE OUI registry as Go map compiled via go:embed; display router brand
- Detect AP BSSID change (router reboot/replacement) and emit system alert
- SQLite nodes table: add virtual BOOL, node_type TEXT, ap_bssid TEXT, ap_channel INT columns

Dashboard changes:
- Show "I detected your router (ASUS). Place it on the floor plan..." notification
- Render virtual AP nodes with distinct router icon in 3D view
- Drag-to-place virtual node (distinct router icon) in 3D editor

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 14:03:03 -04:00
jedarden
34a2247fd9 feat: implement detection explainability overlay with per-link contributions, Fresnel visualization, and BLE match display
- Add explainability.js module with sidebar panel, X-ray overlay, Fresnel zone rendering
- Add explainability handler with /api/explain/{blobID} endpoint
- Fix viz3d.js CONFIG reference by adding FRESNEL_CONFIG constant
- Integrate explainability into fusion engine and ingestion server

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 13:31:17 -04:00
jedarden
e83b54a9ec feat: implement dashboard PIN authentication and session management
Backend (mothership/internal/auth/):
- SQLite auth table with pin_bcrypt and install_secret (singleton row)
- GET /api/auth/status — return {pin_configured: bool}
- POST /api/auth/setup — sets PIN (bcrypt cost 12) on first run only
- POST /api/auth/login — verifies PIN, issues session cookie (7-day expiry)
- POST /api/auth/logout — clears cookie and deletes session from SQLite
- Session middleware: all /api/* and /ws/* require valid session
- Rolling window: extends session by 7 days if within 24h of expiry
- Install secret generation for node token derivation

Dashboard (dashboard/js/auth.js):
- On load: GET /api/auth/status check
- First-run setup page: enter PIN + confirm PIN → POST /api/auth/setup → reload
- Login page: shown on 401; PIN entry → POST /api/auth/login → reload
- Logout button in settings panel → POST /api/auth/logout → redirect

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 13:16:04 -04:00
jedarden
27755fc98d feat: implement dashboard activity timeline view
Add comprehensive activity timeline view for the Spaxel dashboard:

- Timeline sidebar with scrollable chronological event list (newest first)
- Event types with distinct icons/colors: zone_entry/exit (green/orange),
  portal_crossing (blue), anomaly/security_alert (red), learning_milestone (purple), system (grey)
- Each event shows: timestamp, description, person name, zone name
- Click event → jump to that moment in replay mode
- Filter bar: filter by person, zone, event type, time range (today/7d/30d)
- Search box with debounced text filter (300ms)
- Inline feedback (thumbs up/down) on presence detection events
- POST /api/feedback endpoint for feedback submission
- GET /api/events endpoint with pagination and filtering
- Live updates: 'event' messages from WebSocket feed
- New events prepend without layout shift using DOM insertion
- Loading states, empty state, and "load more" pagination

Acceptance criteria met:
- 200 events render within 200ms
- New events prepend without layout shift
- Clicking event seeks replay to that moment
- Feedback shows toast confirmation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 12:01:19 -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
c424104582 feat: build dashboard panel/modal/sidebar UI framework
Implemented a comprehensive panel framework for the Spaxel dashboard to
support Phase 6-9 UI work (automation builder, timeline, explainability,
settings, notifications, presence predictions).

- Panel System (dashboard/js/panels.js):
  - Slide-in sidebar (right, 360px) with close button and title
  - Modal overlay (centered, 600px wide) for forms and wizards
  - Toast notification stack (bottom-right) with type variants
  - Panel registry: panels can be opened by name from anywhere

- Route/Mode Navigation (dashboard/js/router.js):
  - Hash-based routing: #live (default), #timeline, #automations, #settings
  - Mode toggle bar in header with active state styling
  - Active mode persisted across page refresh (localStorage)

- State Management (dashboard/js/state.js):
  - Central app state object (nodes, blobs, zones, links, alerts, events)
  - Subscribe/notify pattern for reactive component updates
  - Convenience methods for common operations (updateNode, addEvent, etc.)

- Settings Panel (dashboard/js/settings-panel.js):
  - Motion threshold slider (deltaRMS threshold)
  - Fusion rate selection (5/10/20 Hz)
  - Grid cell size and Fresnel decay rate controls
  - Subcarrier count and baseline time constant settings
  - Notification channel config (Ntfy URL/token, Pushover keys)
  - System info display (version, uptime, detection quality, node count)

- Updated index.html with:
  - CSS/JS includes for panel framework
  - Settings button in status bar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 10:04:40 -04:00
jedarden
118c6b1c9d feat: add new internal packages (events, automation, ble, falldetect, mqtt, notify, prediction, sleep, tracker, zones, analytics) and dashboard modules (anomaly, automations, blepanel, fleet) 2026-04-06 09:48:31 -04:00
jedarden
c75428d488 ci: set VERSION to 0.1.0 for image build 2026-04-06 08:53:25 -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