POST /api/devices/:ip/deep-check runs deep-check-device.sh on the
CT122 host via SSH (reaches its own LAN IP), returns mDNS/SSDP/port
scan results. "Deep check" button on unknown device rows in the
dashboard shows results inline below the row.
Verified end-to-end via SSH before wiring into the API: correctly
identified Home Assistant via SSDP (friendlyName/manufacturer/model),
and confirmed both a shell-injection attempt and an out-of-subnet IP
get rejected cleanly by the forced command's input validation.
Closes#15 (all four pieces: OUI, mDNS, manual labels, deep check).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Runs as a host-level systemd timer on CT122 (scripts/discover-devices.sh)
rather than inside the api container, since real ARP entries live in the
host's network namespace, not Docker's bridge network. See
docs/device-discovery.md for the full writeup, including why literal
passive-only ARP reading was dropped (near-empty result in practice).
API reads the resulting JSON file each poll cycle, cross-references
config/hosts.yaml's knownDevices list by IP, and serves /api/devices.
Dashboard gets a new "Network Devices" table.
Closes#9.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>