// One discovery cycle: scan → drop homelab guests → upsert → mark-absent → prune. // Homelab containers/hosts are excluded from the IoT/personal devices band — they // live in the network_hosts inventory, not here. We drop any MAC that's in // network_hosts OR carries the Proxmox guest OUI (bc:24:11). Deps injected for // tests. Prune only runs after a successful, non-empty scan. import { runScan } from './scan.js'; import * as devices from '../db/repos/lan_devices.js'; import * as netHosts from '../db/repos/network_hosts.js'; import { log } from '../log.js'; const HOMELAB_OUI = 'bc:24:11'; // Proxmox auto-generated guest MAC prefix export async function runDeviceScanCycle({ scan = runScan, repo = devices, hosts = netHosts } = {}) { const inventory = new Set((await hosts.all()).map(h => String(h.mac || '').toLowerCase())); const rows = (await scan()).filter(r => !inventory.has(r.mac) && !r.mac.startsWith(HOMELAB_OUI)); if (!rows.length) { log.warn('device scan found no non-homelab hosts; skipping upsert/prune'); return { seen: 0 }; } await repo.upsertScan(rows); await repo.markAbsent(rows.map(r => r.mac)); const pruned = await repo.prune(); log.info({ seen: rows.length, pruned }, 'device scan cycle complete'); return { seen: rows.length, pruned }; }