Public Access
88 lines
3.4 KiB
Markdown
88 lines
3.4 KiB
Markdown
# Tag albums
|
|
|
|
Tells Home Assistant which album to play when an RFID card (a **Tag**) is scanned, and provides a web page to give new cards an album (an **Assignment**). See [CONTEXT.md](CONTEXT.md) for the vocabulary.
|
|
|
|
How it fits together:
|
|
|
|
1. The ESPHome RFID reader sends `tag_scanned` to Home Assistant, as before.
|
|
2. HA's `Play album by tag` script calls `POST /api/scans`. The service records the **Scan** and answers with the album, or `assigned: false`.
|
|
3. A card the service hasn't seen before becomes an **Unassigned tag**. It appears on the web page within a few seconds, where you search the Music Assistant library and assign an album.
|
|
4. When a card is removed, HA's `Stop album by tag` script calls `GET /api/tags/{tag_id}`. It stops the player only if that tag has an album.
|
|
|
|
## API
|
|
|
|
Both endpoints need `Authorization: Bearer <API_TOKEN>`.
|
|
|
|
| Endpoint | Purpose |
|
|
|---|---|
|
|
| `POST /api/scans` `{"tag_id": "53-13-0B-2A"}` | Record a Scan; creates the Tag on first sight. Returns `{"tag_id", "assigned": true, "artist", "album"}` or `{"tag_id", "assigned": false}`. |
|
|
| `GET /api/tags/{tag_id}` | Read-only lookup, same response. `404` if the tag has never been seen. |
|
|
|
|
Tag IDs are normalised to upper case.
|
|
|
|
The web page (`/`) has no login: keep the service on the LAN.
|
|
|
|
## Configuration
|
|
|
|
Environment variables:
|
|
|
|
| Variable | Meaning |
|
|
|---|---|
|
|
| `API_TOKEN` | Shared secret Home Assistant sends in the `Authorization` header |
|
|
| `HA_URL` | Home Assistant base URL, e.g. `https://ha.home.knbg` |
|
|
| `HA_TOKEN` | HA long-lived access token, used to search the Music Assistant library |
|
|
| `DB_PATH` | SQLite file (default `tag_albums.sqlite3`); its directory must be writable |
|
|
|
|
HTTPS to HA is verified against the system trust store, so a home CA must be installed on the host. If it isn't, point `SSL_CERT_FILE` at the CA bundle.
|
|
|
|
## Development
|
|
|
|
```sh
|
|
uv sync
|
|
uv run pytest
|
|
API_TOKEN=dev HA_URL=https://ha.home.knbg HA_TOKEN=... uv run tag-albums serve --port 8087
|
|
```
|
|
|
|
## Deploying in a FreeBSD jail
|
|
|
|
```sh
|
|
pkg install python311 py311-uv git # or any Python >= 3.11
|
|
pw useradd tagalbums -d /nonexistent -s /usr/sbin/nologin
|
|
git clone <repo> /usr/local/tag-albums && cd /usr/local/tag-albums && uv sync --no-dev
|
|
install -d -o tagalbums /var/db/tag_albums
|
|
|
|
cat > /usr/local/etc/tag_albums.env <<'EOF'
|
|
API_TOKEN=<random, e.g. openssl rand -hex 32>
|
|
HA_URL=https://ha.home.knbg
|
|
HA_TOKEN=<HA long-lived token>
|
|
DB_PATH=/var/db/tag_albums/tag_albums.sqlite3
|
|
EOF
|
|
chmod 600 /usr/local/etc/tag_albums.env
|
|
|
|
install -m 755 deploy/rc.d/tag_albums /usr/local/etc/rc.d/tag_albums
|
|
sysrc tag_albums_enable=YES
|
|
service tag_albums start
|
|
```
|
|
|
|
Logs go to syslog with the tag `tag_albums`. The port defaults to 8087 (`sysrc tag_albums_port=...`).
|
|
|
|
### Importing the old tag_albums.yaml
|
|
|
|
One time, before switching Home Assistant over:
|
|
|
|
```sh
|
|
cd /usr/local/tag-albums
|
|
env DB_PATH=/var/db/tag_albums/tag_albums.sqlite3 \
|
|
su -m tagalbums -c '.venv/bin/tag-albums import-yaml /path/to/tag_albums.yaml'
|
|
```
|
|
|
|
## Home Assistant side
|
|
|
|
These pieces live in the `home-assistant-config` repo:
|
|
|
|
- `configuration.yaml`: two `rest_command`s, `tag_albums_scan` and `tag_albums_lookup`, pointing at `http://tag-albums.home.knbg:8087`.
|
|
- `secrets.yaml`: `tag_albums_auth: "Bearer <API_TOKEN>"`.
|
|
- `scripts.yaml`: `play_album_by_tag` and `stop_album_by_tag` call those commands.
|
|
|
|
If the service is down, a scan plays nothing and `play_album_by_tag` writes a warning to the HA log.
|