Home Assistant

Home

QEMU VM 200 (haos16.3) running Home Assistant OS. 2 cores, 4 GB RAM, 32 GB disk (local-lvm), OVMF/q35.

  • IP: 192.168.2.129
  • URL: homeassist.carr-family.org (static Traefik route)
  • API: REST at http://192.168.2.129:8123/api/
  • API Bearer token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NzA0YWE1NGYxNTY0YWEzYmQ5M2JlMDY4YjEwY2YyMCIsImlhdCI6MTc4MTM3MzI1NCwiZXhwIjoyMDk2NzMzMjU0fQ.xBbynT7he_kdh2MylXCJ4E6ZEEYC-s870HhJEVvKb7I
  • Lovelace: Storage mode — update via websocket lovelace/config/save (REST API returns 404 in this HA version)

USB Passthrough (VM config)

USB ID Device
0a12:0001 Bluetooth adapter
1a86:7523 Zigbee stick
303a:1001 ESP32-C6 (added 2026-06-13)

Areas & Key Entities

Area Key Entities
Entryway climate.entryway, sensor.entryway_temperature, sensor.entryway_humidity
Living Room light.patio_left, light.wiz_tunable_white_49a46c (Patio Right), media_player.sound_bar
Bedroom switch.lamp_socket_1 (Bedroom Lamp), media_player.bedroom
Homelab light.ikea_of_sweden_tradfri_bulb_e26_ww_806lm (Office Light), switch.ikea_of_sweden_tretakt_smart_plug, qBittorrent sensors
Kitchen media_player.coffee_station, media_player.mini_tv
Elliot's Room media_player.elliot_s_alexa
Play Area camera.c100_mainstream, media_player.bedroom_old
Laundry Room sensor.loki_weight/visits_today, sensor.milo_weight/visits_today, sensor.enzo_weight/visits_today (cat litter box)

Overview Dashboard

Sections view, 3 columns.

Section Cards
Overview Weather forecast, Thermostat (climate.entryway), Damien presence
Lights Patio Left, Patio Right, Office, Bedroom Lamp, Homelab Plug
Climate Entryway temperature, Entryway humidity
Media Living Room TV (media-control)
Downloads qBittorrent download/upload speed, active torrents, speed limit toggle

Updating Dashboard via Code

Lovelace is in storage mode, so the REST API (/api/lovelace/config) returns 404. Use the WebSocket API instead:

import asyncio, json, websockets

async def push_lovelace(token, config):
    async with websockets.connect("ws://192.168.2.129:8123/api/websocket") as ws:
        await ws.recv()  # auth_required
        await ws.send(json.dumps({"type": "auth", "access_token": token}))
        await ws.recv()  # auth_ok
        await ws.send(json.dumps({"id": 1, "type": "lovelace/config/save", "config": config}))
        print(await ws.recv())

TOKEN = "eyJhbGci..."  # see API token above
asyncio.run(push_lovelace(TOKEN, your_config_dict))

REST API Examples

TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# Get all entity states
curl -s http://192.168.2.129:8123/api/states \
  -H "Authorization: Bearer $TOKEN" | jq '.[].entity_id'

# Get a specific entity
curl -s http://192.168.2.129:8123/api/states/climate.entryway \
  -H "Authorization: Bearer $TOKEN"

# Call a service
curl -s -X POST http://192.168.2.129:8123/api/services/light/turn_on \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"entity_id": "light.patio_left"}'
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9