Fix floor persistence and improve movement detection
- Store floor assignments in SQLite database for persistence - Floor now saves correctly for live-tracked BT devices - Add statistical movement detection (5-sample average + stddev) - Require 1.5m + 2σ deviation to mark device as moving - Reduces false positives from RSSI noise/fluctuations - Add /api/device/floors endpoint for bulk floor retrieval Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -75,6 +75,7 @@ class DeviceDatabase:
|
||||
total_observations INTEGER DEFAULT 0,
|
||||
custom_label TEXT, -- User-assigned name
|
||||
is_favorite INTEGER DEFAULT 0,
|
||||
assigned_floor INTEGER, -- User-assigned floor
|
||||
notes TEXT,
|
||||
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
||||
@@ -160,6 +161,12 @@ class DeviceDatabase:
|
||||
cursor.execute("CREATE INDEX IF NOT EXISTS idx_movement_device ON movement_events(device_id, timestamp)")
|
||||
cursor.execute("CREATE INDEX IF NOT EXISTS idx_alerts_type ON alerts(alert_type, acknowledged)")
|
||||
|
||||
# Add assigned_floor column if it doesn't exist (migration for existing DBs)
|
||||
try:
|
||||
cursor.execute("ALTER TABLE devices ADD COLUMN assigned_floor INTEGER")
|
||||
except sqlite3.OperationalError:
|
||||
pass # Column already exists
|
||||
|
||||
conn.commit()
|
||||
|
||||
def record_scan(self, scan_id: str, timestamp: str, location_label: str,
|
||||
@@ -463,6 +470,34 @@ class DeviceDatabase:
|
||||
""", (1 if is_favorite else 0, device_id))
|
||||
conn.commit()
|
||||
|
||||
def set_device_floor(self, device_id: str, floor: Optional[int]):
|
||||
"""Set assigned floor for a device"""
|
||||
conn = self._get_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("""
|
||||
UPDATE devices SET assigned_floor = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE device_id = ?
|
||||
""", (floor, device_id))
|
||||
conn.commit()
|
||||
|
||||
def get_device_floor(self, device_id: str) -> Optional[int]:
|
||||
"""Get assigned floor for a device"""
|
||||
conn = self._get_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("SELECT assigned_floor FROM devices WHERE device_id = ?", (device_id,))
|
||||
row = cursor.fetchone()
|
||||
return row['assigned_floor'] if row else None
|
||||
|
||||
def get_all_device_floors(self) -> dict:
|
||||
"""Get all device floor assignments as a dict"""
|
||||
conn = self._get_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("SELECT device_id, assigned_floor FROM devices WHERE assigned_floor IS NOT NULL")
|
||||
return {row['device_id']: row['assigned_floor'] for row in cursor.fetchall()}
|
||||
|
||||
def get_recent_activity(self, hours: int = 24) -> dict:
|
||||
"""Get activity summary for the last N hours"""
|
||||
conn = self._get_connection()
|
||||
|
||||
Reference in New Issue
Block a user