Blame
|
1 | # Home Assistant |
||||||
| 2 | ||||||||
| 3 | ← [[Home]] |
|||||||
| 4 | ||||||||
| 5 | QEMU VM 200 (`haos16.3`) running Home Assistant OS. 2 cores, 4 GB RAM, 32 GB disk (local-lvm), OVMF/q35. |
|||||||
| 6 | ||||||||
| 7 | - **IP:** `192.168.2.129` |
|||||||
| 8 | - **URL:** `homeassist.carr-family.org` (static Traefik route) |
|||||||
| 9 | - **API:** REST at `http://192.168.2.129:8123/api/` |
|||||||
| 10 | - **API Bearer token:** `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NzA0YWE1NGYxNTY0YWEzYmQ5M2JlMDY4YjEwY2YyMCIsImlhdCI6MTc4MTM3MzI1NCwiZXhwIjoyMDk2NzMzMjU0fQ.xBbynT7he_kdh2MylXCJ4E6ZEEYC-s870HhJEVvKb7I` |
|||||||
| 11 | - **Lovelace:** Storage mode — update via websocket `lovelace/config/save` (REST API returns 404 in this HA version) |
|||||||
| 12 | ||||||||
| 13 | --- |
|||||||
| 14 | ||||||||
| 15 | ## USB Passthrough (VM config) |
|||||||
| 16 | ||||||||
| 17 | | USB ID | Device | |
|||||||
| 18 | |--------|--------| |
|||||||
| 19 | | `0a12:0001` | Bluetooth adapter | |
|||||||
| 20 | | `1a86:7523` | Zigbee stick | |
|||||||
| 21 | | `303a:1001` | ESP32-C6 (added 2026-06-13) | |
|||||||
| 22 | ||||||||
| 23 | --- |
|||||||
| 24 | ||||||||
| 25 | ## Areas & Key Entities |
|||||||
| 26 | ||||||||
| 27 | | Area | Key Entities | |
|||||||
| 28 | |------|-------------| |
|||||||
| 29 | | Entryway | `climate.entryway`, `sensor.entryway_temperature`, `sensor.entryway_humidity` | |
|||||||
| 30 | | Living Room | `light.patio_left`, `light.wiz_tunable_white_49a46c` (Patio Right), `media_player.sound_bar` | |
|||||||
| 31 | | Bedroom | `switch.lamp_socket_1` (Bedroom Lamp), `media_player.bedroom` | |
|||||||
| 32 | | Homelab | `light.ikea_of_sweden_tradfri_bulb_e26_ww_806lm` (Office Light), `switch.ikea_of_sweden_tretakt_smart_plug`, qBittorrent sensors | |
|||||||
| 33 | | Kitchen | `media_player.coffee_station`, `media_player.mini_tv` | |
|||||||
| 34 | | Elliot's Room | `media_player.elliot_s_alexa` | |
|||||||
| 35 | | Play Area | `camera.c100_mainstream`, `media_player.bedroom_old` | |
|||||||
| 36 | | Laundry Room | `sensor.loki_weight/visits_today`, `sensor.milo_weight/visits_today`, `sensor.enzo_weight/visits_today` (cat litter box) | |
|||||||
| 37 | ||||||||
| 38 | --- |
|||||||
| 39 | ||||||||
| 40 | ## Overview Dashboard |
|||||||
| 41 | ||||||||
| 42 | Sections view, 3 columns. |
|||||||
| 43 | ||||||||
| 44 | | Section | Cards | |
|||||||
| 45 | |---------|-------| |
|||||||
| 46 | | Overview | Weather forecast, Thermostat (`climate.entryway`), Damien presence | |
|||||||
| 47 | | Lights | Patio Left, Patio Right, Office, Bedroom Lamp, Homelab Plug | |
|||||||
| 48 | | Climate | Entryway temperature, Entryway humidity | |
|||||||
| 49 | | Media | Living Room TV (media-control) | |
|||||||
| 50 | | Downloads | qBittorrent download/upload speed, active torrents, speed limit toggle | |
|||||||
| 51 | ||||||||
| 52 | --- |
|||||||
| 53 | ||||||||
| 54 | ## Updating Dashboard via Code |
|||||||
| 55 | ||||||||
| 56 | Lovelace is in storage mode, so the REST API (`/api/lovelace/config`) returns 404. Use the WebSocket API instead: |
|||||||
| 57 | ||||||||
| 58 | ```python |
|||||||
| 59 | import asyncio, json, websockets |
|||||||
| 60 | ||||||||
| 61 | async def push_lovelace(token, config): |
|||||||
| 62 | async with websockets.connect("ws://192.168.2.129:8123/api/websocket") as ws: |
|||||||
| 63 | await ws.recv() # auth_required |
|||||||
| 64 | await ws.send(json.dumps({"type": "auth", "access_token": token})) |
|||||||
| 65 | await ws.recv() # auth_ok |
|||||||
| 66 | await ws.send(json.dumps({"id": 1, "type": "lovelace/config/save", "config": config})) |
|||||||
| 67 | print(await ws.recv()) |
|||||||
| 68 | ||||||||
| 69 | TOKEN = "eyJhbGci..." # see API token above |
|||||||
| 70 | asyncio.run(push_lovelace(TOKEN, your_config_dict)) |
|||||||
| 71 | ``` |
|||||||
| 72 | ||||||||
| 73 | --- |
|||||||
| 74 | ||||||||
| 75 | ## REST API Examples |
|||||||
| 76 | ||||||||
| 77 | ```bash |
|||||||
| 78 | TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." |
|||||||
| 79 | ||||||||
| 80 | # Get all entity states |
|||||||
| 81 | curl -s http://192.168.2.129:8123/api/states \ |
|||||||
| 82 | -H "Authorization: Bearer $TOKEN" | jq '.[].entity_id' |
|||||||
| 83 | ||||||||
| 84 | # Get a specific entity |
|||||||
| 85 | curl -s http://192.168.2.129:8123/api/states/climate.entryway \ |
|||||||
| 86 | -H "Authorization: Bearer $TOKEN" |
|||||||
| 87 | ||||||||
| 88 | # Call a service |
|||||||
| 89 | curl -s -X POST http://192.168.2.129:8123/api/services/light/turn_on \ |
|||||||
| 90 | -H "Authorization: Bearer $TOKEN" \ |
|||||||
| 91 | -H "Content-Type: application/json" \ |
|||||||
| 92 | -d '{"entity_id": "light.patio_left"}' |
|||||||
| 93 | ``` |
|||||||
