Skip to main content
Ungathered Thoughts

Discovering local devices using HASS

I've been working with Observability and the Grafana stack lately, and while having a re-organise got thinking about surveying and harvesting information about our home network.

Home network is a dynamic environment - devices come and go, are forgotten. I had observed that Home Assistant (HASS) was quite good at "discovering" new devices on the network, and got thinking about how I could utilise this myself.

Information recorded manually gets outdated and unreliable fast, while information retrieved by surveying gives you a current view but can lack historic context. The trick is combining what's discovered with knowledge you'd like to preserve; discovery can give you "a device is connected, named X and has details Y", while preserving knowledge can tell you who it belonged to or why it was introduced.

First question was, how to find hosts HASS sees. HASS has an API! Let's explore - we will need:

Let's see what the states are in HASS.

curl -X GET -H "Authorization: Bearer ${HASS_TOKEN}" \
  -H "Content-Type: application/json" \
  ${HASS_URL}/api/states

I get a response like:

[
{
"entity_id": "person.chris_burgess",
"state": "home",
"attributes": {
"editable": true,
"id": "chris_burgess",
"device_trackers": [
"device_tracker.chris_oneplus",
"device_tracker.chriss_ipad_2",
"device_tracker.nexus_5x",
"device_tracker.cph2529"
],
"latitude": -45.00,
"longitude": 170.00,
"gps_accuracy": 10,
"source": "device_tracker.abcdef1",
"user_id": "aabbccdd",
"friendly_name": "Chris Burgess"
},
"last_changed": "2025-04-21T19:11:33.996324+00:00",
"last_reported": "2025-04-21T22:36:42.920973+00:00",
"last_updated": "2025-04-21T22:36:42.920973+00:00",
"context": {
"id": "01234",
"parent_id": null,
"user_id": null
}
},
{
"entity_id": "device_tracker.ubuntu_server_2",
"state": "home",
"attributes": {
"source_type": "router",
"ip": "10.0.0.2",
"mac": "AB:CD:11:22:33:44",
"host_name": "ahem",
"last_time_reachable": "2025-04-21T22:43:16+00:00",
"connected_to": "fritz.box",
"connection_type": "LAN",
"icon": "mdi:lan-connect",
"friendly_name": "ahem"
},
"last_changed": "2025-04-21T19:12:32.411093+00:00",
"last_reported": "2025-04-21T22:43:18.691542+00:00",
"last_updated": "2025-04-21T22:43:18.691542+00:00",
"context": {
"id": "01234",
"parent_id": null,
"user_id": null
}
},
{
"entity_id": "device_tracker.the_nas",
"state": "home",
"attributes": {
"source_type": "router",
"ip": "10.0.0.3",
"mac": "AB:CD:11:22:33:44",
"host_name": "the-nas",
"last_time_reachable": "2025-04-21T22:43:16+00:00",
"connected_to": "fritz.box",
"connection_type": "LAN",
"icon": "mdi:lan-connect",
"friendly_name": "nas"
},
"last_changed": "2025-04-21T19:12:32.429386+00:00",
"last_reported": "2025-04-21T22:43:18.692900+00:00",
"last_updated": "2025-04-21T22:43:18.692900+00:00",
"context": {
"id": "01234",
"parent_id": null,
"user_id": null
}
},
// ...
]

Let's filter that down to hosts we're interested in:

curl -X GET -H "Authorization: Bearer ${HASS_TOKEN}" -H "Content-Type: application/json" ${HASS_URL}/api/states  | jq '.[] | select(.state == "home" and .attributes.host_name != null) | {entity_id, state, host_name: .attributes.host_name}'

How about as a Markdown list:

curl -X GET -H "Authorization: Bearer ${HASS_TOKEN}" -H "Content-Type: application/json" ${HASS_URL}/api/states  | jq -r '.[] | select(.state == "home" and .attributes.host_name != null) | "- \(.attributes.host_name) (\(.attributes.ip))"' | sort

Or as a table:

echo "| friendly name | host name | ip | notes |"
echo "|--|--|--|--|"
curl -X GET \
-H "Authorization: Bearer ${HASS_TOKEN}" \
-H "Content-Type: application/json" \
${HASS_URL}/api/states | jq -r '.[] | select(.state == "home" and .attributes.host_name != null) | "| \(.attributes.friendly_name) | `\(.attributes.host_name)` | `\(.attributes.ip)` | |"'

The output of the last might look like (after comments added):

friendly name host name ip notes
9b7eb8b9-dff1-d401-5507-09a8aaaea195 9b7eb8b9-dff1-d401-5507-09a8aaaea195 10.0.0.59 ?
a1f6389c-bb13-c10f-3af0-cd147e51a662 a1f6389c-bb13-c10f-3af0-cd147e51a662 10.0.0.52 ?
aooga aooga 10.0.0.101 VM running some services
baluga baluga 10.0.0.102
Android-2 Android-2 10.0.0.51 Visitor phone
laptop-1 work-laptop 10.0.0.54 Work laptop
Chromecast-Audio Chromecast-Audio 10.0.0.59 Best device
Chromecast Chromecast 10.0.0.103
NAS-1 NAS device 10.0.0.53
DSP-W123 DSP-W118 10.0.0.104
ESP-ABCDE1 ESP-ABCDE1 10.0.0.55
ESP-123ABC ESP-123ABC 10.0.0.56
ESP-DEF432 ESP-DEF432 10.0.0.57
esphome-web-809081 esphome-web-809081 10.0.0.58

This is useful, I now have a list of devices to review, and a table to keep notes in!