Insert or update a discovered Bluetooth device. GPS position logic: - best_lat/best_lon: position at strongest RSSI (closest sighting) - latitude/longitude: confirmed position, updated only after GPS_CONFIRM_PINGS consecutive pings at a new location (>GPS_DRIFT_THR
(self, mac, name, rssi, device_type, lat, lon, alt)
| 510 | longitude = COALESCE(longitude, ?), |
| 511 | altitude = COALESCE(altitude, ?), |
| 512 | best_lat = COALESCE(best_lat, ?), |
| 513 | best_lon = COALESCE(best_lon, ?) |
| 514 | WHERE bssid = ? |
| 515 | """, (ssid, security, rssi, now, count, |
| 516 | lat, lon, alt, lat, lon, bssid)) |
| 517 | else: |
| 518 | conn.execute(""" |
| 519 | UPDATE networks SET |
| 520 | ssid = COALESCE(NULLIF(?, ''), ssid), |
| 521 | security = COALESCE(NULLIF(?, ''), security), |
| 522 | rssi = ?, last_seen = ?, scan_count = ? |
| 523 | WHERE bssid = ? |
| 524 | """, (ssid, security, rssi, now, count, bssid)) |
| 525 | else: |
| 526 | conn.execute(""" |
| 527 | INSERT INTO networks |
| 528 | (bssid, ssid, security, channel, frequency, rssi, |
| 529 | latitude, longitude, altitude, speed_kmh, hdop, |
| 530 | first_seen, last_seen, best_rssi, best_lat, best_lon, |
| 531 | scan_count, interface, band, is_camera) |
| 532 | VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, ?) |
| 533 | """, (bssid, ssid, security, channel, frequency, rssi, |
| 534 | lat, lon, alt, speed, hdop, |
| 535 | now, now, rssi, lat, lon, interface, band, is_camera)) |
| 536 | self.unique_bssids.add(bssid) |
| 537 | self.network_count = len(self.unique_bssids) |
| 538 | return True |
| 539 | |
| 540 | # Per-interface observation row — records what THIS adapter |
| 541 | # actually saw, independent of which adapter "owns" the |
| 542 | # canonical networks row. Used for antenna-coverage stats. |
| 543 | if interface: |
| 544 | obs = conn.execute( |
| 545 | "SELECT best_rssi, scan_count FROM network_observations " |
| 546 | "WHERE bssid = ? AND interface = ?", |
| 547 | (bssid, interface) |
| 548 | ).fetchone() |
| 549 | if obs: |
| 550 | obs_best = obs[0] if obs[0] is not None else -100 |
| 551 | obs_count = (obs[1] or 0) + 1 |
| 552 | new_best = max(obs_best, rssi) |
| 553 | conn.execute( |
| 554 | "UPDATE network_observations SET " |
| 555 | "last_seen = ?, last_rssi = ?, best_rssi = ?, " |
| 556 | "scan_count = ? WHERE bssid = ? AND interface = ?", |
| 557 | (now, rssi, new_best, obs_count, bssid, interface) |
| 558 | ) |
| 559 | else: |
| 560 | conn.execute( |
| 561 | "INSERT INTO network_observations " |
| 562 | "(bssid, interface, first_seen, last_seen, " |
| 563 | "best_rssi, last_rssi, scan_count) " |
| 564 | "VALUES (?, ?, ?, ?, ?, ?, 1)", |
| 565 | (bssid, interface, now, now, rssi, rssi) |
| 566 | ) |
| 567 | |
| 568 | except Exception as e: |
| 569 | logger.error(f"DB upsert error: {e}") |
no test coverage detected