55 Commits

Author SHA1 Message Date
User
9fc7c65454 fix: filter scanner BT MACs in API responses
- /api/latest now filters out devices matching peer bt_mac
- Prevents scanner devices from appearing in scan results

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 18:09:06 +01:00
User
579cea57dc fix: filter scanner BT MACs in database recording
- Skip recording BT observations for addresses matching peer bt_mac
- Prevents scanners from being stored as regular devices
- Filters at database level, not just frontend display

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 18:07:11 +01:00
User
5def3e2214 fix: filter scanner BT MACs during BLE Radar import
- Skip devices whose address matches a registered peer's bt_mac
- Prevents scanners from appearing as regular devices
- Shows count of filtered scanners in import stats

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 18:01:58 +01:00
User
cc6d9ee58d feat: add BLE Radar database import
- Add import_ble_radar.py module for importing BLE Radar exports
- Add /api/import/ble-radar endpoint for file upload
- Add import section to dashboard with file picker
- CLI: python -m rf_mapper.import_ble_radar <file.sqlite>
- Imports devices, RSSI, favorites, and custom labels

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 17:54:31 +01:00
User
b1efb4ae3c docs: enhance CLAUDE.md with maintenance table
- Add table of key docs with "When to Update" guidance
- Include TASKS.md, TODO.md, ROADMAP.md, CHANGELOG.md
- Add deployment section with node update commands
- Add Multi-scanner sync and Termux support to key files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 17:39:15 +01:00
User
91536860ad docs: update CLI commands to use python -m rf_mapper
- Replace rf-mapper with python -m rf_mapper throughout docs
- Add note about activating venv first
- Updated: CLAUDE.md, PROJECT.md, USAGE.md, CHEATSHEET.md, HOME_ASSISTANT.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 17:38:44 +01:00
User
322c53d513 feat: auto-remove stale devices after 60s timeout
- Add deviceLastSeen tracking for all WiFi and BT devices
- Add cleanupStaleDevices() that runs every 10 seconds
- Remove devices not seen for 60 seconds (STALE_DEVICE_TIMEOUT_MS)
- Works regardless of live tracking state
- Updates lastSeen in all scan paths: manual, WS, polling, node switch

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 17:32:05 +01:00
User
9c9f27e55f docs: update TASKS, TODO, CHANGELOG for v1.0.1
- Node control API (start/stop/restart peers via SSH)
- Home Assistant node control integration
- Termux/Android: skip BT scanning, optional location check
- Filter controls display only, always scan both WiFi/BT

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 17:06:00 +01:00
User
bc2e23c3ca fix: always scan WiFi and BT, filter controls display only
The filter checkboxes now only control whether devices are displayed
on the map, not whether they are scanned. Both WiFi and Bluetooth
are always scanned regardless of filter state.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 16:48:52 +01:00
User
e27200c5b5 fix: make Termux location check optional
Location services check now optional since scanner coordinates
are configured in config.yaml. Allows rf-mapper to start on
Termux even when GPS is unavailable (indoors).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 16:41:33 +01:00
User
cee36e2ce1 feat: add node control API for starting/stopping peers via SSH
New endpoints on master node:
- POST /api/nodes/<id>/start - Start rf-mapper on peer
- POST /api/nodes/<id>/stop - Stop rf-mapper on peer
- POST /api/nodes/<id>/restart - Restart rf-mapper on peer
- GET /api/nodes/<id>/status - Check peer status

Uses SSH with scanner_id as hostname (relies on ~/.ssh/config).
Enables Home Assistant integration to control peer nodes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 14:16:38 +01:00
User
3ff43de5ea fix: skip Bluetooth scanning on Termux/Android
Bleak requires D-Bus which isn't available on Android. Detect Termux
environment and skip both Classic BT and BLE scanning gracefully.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:52:23 +01:00
User
b0e6d1107c feat: replace hcitool BLE scanning with bleak library
Use bleak's BleakScanner for BLE device discovery instead of
hcitool lescan subprocess. Provides real RSSI values from
advertisement packets instead of hardcoded -70dB estimate.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:13:28 +01:00
User
4fef21c06f feat: filter scanner Bluetooth devices from display
- Add bt_mac field to scanner config for identifying scanner BT adapters
- Store bt_mac in peers table for peer scanners
- Filter out devices matching scanner BT MACs from all views
- Prevents scanners from appearing as devices in device lists/maps

Config: scanner.bt_mac = "XX:XX:XX:XX:XX:XX"
API: /api/peers/register accepts bt_mac field

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:00:42 +01:00
User
446bec278d fix: prevent duplicate scanner markers when viewing peer nodes
- Use viewing scanner name (peer or local) for center marker
- Filter out the peer being viewed from peer markers list
- Fixes duplicate grokbox markers when viewing grokbox from master

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:44:31 +01:00
User
b695e19079 feat: add caching for peer proxy requests
- Cache successful GET responses from peers (5 min TTL)
- Return cached data when peer is unreachable
- Add _cached, _cached_at, _cache_age_seconds flags
- Add /api/node/<id>/health proxy endpoint

Enables master dashboard to show peer data even when
peers are temporarily unreachable (e.g., mobile devices,
VPN disconnections).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:38:15 +01:00
User
5b9612dfae feat: add /api/health endpoint for monitoring
- Returns status, version, uptime, scanner_id
- Component status: database, peer_sync, auto_scanner
- Returns 200 for healthy, 503 for unhealthy
- Tracks app start time for uptime calculation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:24:04 +01:00
User
522174721d docs: add multi-node master dashboard documentation
- Architecture overview with diagram
- Enabling master mode (is_master config)
- Node selector UI indicators
- Switching between local and peer views
- Live tracking on remote nodes
- Proxy API endpoints for peer data
- Peer registration examples
- WebSocket peer connection details
- Troubleshooting section for common issues

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:11:14 +01:00
User
f787ccd426 chore: gitignore INVENTORY.md (site-specific)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:03:40 +01:00
User
7ccbf486c5 docs: update TASKS.md with multi-node master dashboard
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:59:40 +01:00
User
7e469d6a0a fix: consolidate scanner display with capabilities
Show each scanner as a single marker with WiFi/Bluetooth capabilities
listed in the popup, instead of separate entries per capability.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:54:53 +01:00
User
ae235ebef8 fix: display scanner name instead of "Your Position"
Show the scanner's configured name (or hostname if not set) in map
markers and popups instead of the generic "Your Position" label.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:51:01 +01:00
User
588102ddf4 feat: add multi-node master dashboard
Enable a designated "master" node to view device data from any peer node
within the same dashboard, without page redirects.

- Add is_master config option to ScannerConfig
- Add proxy endpoints /api/node/<id>/* for peer data
- Add node selector dropdown UI (shown only on master)
- Add peer WebSocket connection support for real-time updates
- Live tracking uses node-specific scan endpoint
- Map centers on selected peer's position

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:47:28 +01:00
User
f04ce5aed3 docs: update TODO with completed features
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:32:16 +01:00
User
9b275f4606 docs: add Termux/Android setup and troubleshooting
- Document Android/Termux requirements (Termux:API, permissions)
- Add ADB command to disable phantom process killer
- Document check-termux command for prerequisite verification
- Add Termux boot script example for auto-start
- Add troubleshooting section for common Termux issues

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:31:52 +01:00
User
320d012200 fix: use termux-battery-status directly instead of which
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:27:22 +01:00
User
b6aa3ede56 feat: add Termux/Android prerequisite detection
Detects when running in Termux on Android and checks for required
prerequisites before starting the server:
- Termux:API package installed
- Location services enabled and accessible
- Wake lock available

Exits with informative error message if prerequisites not met.
Adds `rf-mapper check-termux` command for manual verification.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:22:36 +01:00
User
8a533a0670 fix: allow popup overflow for floor dropdown visibility
Set overflow: visible on MapLibre popup to prevent clipping
of floor select dropdown when it expands.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:03:41 +01:00
User
1cc403eea6 fix: use CSS-based coverage rings on scanner markers
Coverage rings now render as CSS pseudo-elements on scanner markers,
following the same floor offset positioning. Toggle .heatmap-enabled
class on map container to show/hide coverage visualization.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:42:30 +01:00
User
4b4cc47e67 fix: use coverage circles instead of heatmap layer
Replace heatmap layer with concentric circle layers around scanner
positions. This avoids the z-index issue where heatmap appeared at
floor 0 below all markers.

Shows three coverage rings:
- Green inner (good signal ~5m)
- Yellow middle (fair signal ~10m)
- Red outer (weak signal ~15m)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:39:20 +01:00
User
24de6c7f06 feat: add multi-scanner trilateration and signal heat map
- Add database methods for multi-scanner RSSI queries
- Add weighted trilateration function supporting 2+ scanners
- Add /api/positions/trilaterated endpoint
- Add /api/heatmap/signal endpoint for heat map data
- Update frontend to show trilaterated positions with gold markers
- Add heat map toggle button for signal coverage visualization

Trilateration uses RSSI from multiple scanners to calculate device
positions with confidence scores. Devices seen by 2+ scanners within
60 seconds get trilaterated positions shown with gold border markers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:33:57 +01:00
User
5fbf096a04 feat: integrate WebSocket with live tracking
- Add WebSocket state variables (wsEnabled, wsConnected)
- Add initWebSocket() function with connection and event handling
- Add handleWebSocketScanUpdate() for processing WS scan events
- Modify startLiveTracking() to use WS mode with HTTP fallback
- Update index.html to load socket.io and websocket.js scripts
- Show [WS] indicator in status when using WebSocket mode

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:56:10 +01:00
User
8f4fa4e186 feat: add WebSocket client with fallback
- Add Socket.IO client library (v4.7.5)
- Create RFMapperWS class with:
  - Automatic reconnection (5 attempts)
  - HTTP polling fallback
  - Event listener system for scanUpdate, connected, disconnected
  - Floor subscription support

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:55:55 +01:00
User
14757f2e57 feat: add SocketIO server integration
- Initialize SocketIO with threading mode
- Add WebSocket event handlers (connect, disconnect, subscribe_floor)
- Add broadcast_scan_update() function for pushing scan results
- Integrate broadcast with BT scan endpoint
- Update run_server() to use socketio.run()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:55:44 +01:00
User
fed08aa6dd feat: add flask-socketio dependency
Add flask-socketio>=5.3.0 for WebSocket support in the web interface.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:55:28 +01:00
User
98e2c6fc42 docs: update project docs for v1.0.0 release
- PROJECT.md: Add peer sync feature description and architecture
- ROADMAP.md: Update to v1.0.0, mark peer sync complete
- TASKS.md: Add peer sync completed tasks, update sprint
- TODO.md: Add multi-scanner section, mark items done
- CHANGELOG.md: Add v0.4.0 (HA) and v1.0.0 (peer sync) entries

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:41:24 +01:00
User
ea88343ae7 fix: use peer's current position for synced devices
- Load peer scanner positions from /api/peers
- Use peer's CURRENT position instead of stored position
- Ensures device positions update when peer scanner moves

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
v1.0.0
2026-02-01 04:29:25 +01:00
User
04bbd0b0af feat: show peer scanners on 3D map
- Added peer scanner markers to MapLibre 3D view
- Peer scanners shown with cyan icon and absolute position
- Styled with distinct color and shadow

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:28:08 +01:00
User
8e25bf8871 feat: preserve source scanner for synced devices
When devices are synced from a peer, they now retain their original
source scanner reference. This ensures:

- Device positions are calculated relative to the scanner that
  detected them, not the local scanner
- Moving the local scanner won't affect synced devices' positions
- Popup shows "Source: <scanner_id>" for remotely-synced devices

Database changes:
- Added source_scanner_id, source_scanner_lat, source_scanner_lon
  columns to devices table
- get_devices_since() includes source scanner info in sync data
- bulk_update_devices() accepts and stores source scanner position
- Added get_all_device_sources() method

API changes:
- /api/sync/devices GET includes scanner_lat and scanner_lon
- /api/sync/devices POST accepts source_scanner_lat/lon
- /api/device/floors includes sources dict

Frontend changes:
- loadDevicePositions() loads source scanner info
- getDevicePosition() uses source scanner position for synced devices
- Popup shows source scanner info for remotely-synced devices

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:23:42 +01:00
User
2973178cb8 chore: update GPS coordinates
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:15:42 +01:00
User
827830b043 fix: create missing devices during peer sync
- bulk_update_devices now creates devices if they don't exist locally
  but have useful metadata (floor, label, or favorite status)
- Sync trigger endpoint now reports both pulled and pushed device counts
- Enables full bidirectional sync of device metadata between peers

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:15:36 +01:00
User
6a3e3e8448 feat: add distinct scanner markers on map and radar
- Scanner positions shown as magenta stars (this scanner)
- Peer scanners shown as cyan stars
- Clear visual distinction from WiFi (orange circles) and BT (blue circles)
- Radar view also shows scanner as star shape

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:06:21 +01:00
User
bd21edb7d7 chore: remove runtime files from repo 2026-02-01 04:04:53 +01:00
User
a1de52fbcd style: use distinct colors for WiFi and Bluetooth devices
WiFi devices now shown in orange (#f59f00), Bluetooth in blue (#4dabf7).
Makes it easier to distinguish device types on map and in device list.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:04:39 +01:00
User
46b7b01e98 fix: exclude position offsets from peer sync
Position offsets (custom_lat_offset, custom_lon_offset) are relative
to each scanner's location, so syncing them between scanners would
place devices incorrectly. Only sync: floor, label, favorite, notes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:52:59 +01:00
User
ea0ee0c190 fix: include saved floor assignments in scan API responses
The /api/scan, /api/scans/<filename>, and /api/latest endpoints
now look up saved floor assignments from the database and include
them in responses. Previously only /api/scan/bt did this.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:46:12 +01:00
User
7eb76498b0 fix: don't update updated_at on device observations
The updated_at timestamp should only change when user metadata
changes (floor, label, position, notes), not on every scan
observation. This was breaking peer sync because observation
timestamps were overwriting metadata timestamps.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:43:34 +01:00
User
7cc7c47805 feat: add Home Assistant integration and improve CLI/UI
Home Assistant Integration:
- New homeassistant.py module with webhook support
- Webhooks for scan results, new devices, and device departures
- Absence detection with configurable timeout
- Documentation in docs/HOME_ASSISTANT.md

CLI Improvements:
- Replace 'web' command with start/stop/restart/status
- Background daemon mode with PID file management
- Foreground mode for debugging (--foreground)

Web UI Enhancements:
- Improved device list styling and layout
- Better floor assignment UI
- Enhanced map visualization

Documentation:
- Add CHANGELOG.md
- Add docs/API.md with full endpoint reference
- Add docs/CHEATSHEET.md for quick reference
- Update project documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:31:02 +01:00
User
0ffd220022 fix: use configured wifi_interface for WiFi scanning
The scan_wifi() calls were using the default "wlan0" instead of
the configured interface from config.yaml. This broke WiFi scanning
on systems with non-standard interface names like wlo1.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:29:48 +01:00
User
fa5178a5be feat: add peer sync for multi-scanner deployments
Enable scanner instances to discover each other and synchronize
device metadata (floors, positions, labels, favorites) automatically.

New features:
- Peer registration API with mutual auto-registration
- Background sync thread with configurable interval
- Timestamp-based conflict resolution (newest wins)
- Config options: peers, sync_interval_seconds, accept_registrations

API endpoints:
- GET/POST /api/peers - list peers, register new peer
- DELETE /api/peers/<id> - remove peer
- GET/POST /api/sync/devices - device sync for peers
- POST /api/sync/trigger - manual sync trigger

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:19:04 +01:00