Files
tag-albums/README.md
T
twislaandClaude Opus 5.5 8ef3f13069 Vendor htmx, add Dockerfile, show a placeholder for missing covers
Serve htmx 2.0.4 from the package instead of the jsdelivr CDN. Add a Dockerfile for local testing. Cover images now sit in a styled placeholder box that stays visible when Music Assistant has no cover for an album.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 17:42:46 +00:00

4.1 KiB

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 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

uv sync
uv run pytest
API_TOKEN=dev HA_URL=https://ha.home.knbg HA_TOKEN=... uv run tag-albums serve --port 8087

Running with Docker

For local testing. The container has to trust the home CA to reach HA, so mount the CA certificate and point SSL_CERT_FILE at it:

docker build -t tag-albums .
docker run --rm -p 8087:8087 -v tag-albums-data:/data \
  -e API_TOKEN=dev -e HA_URL=https://ha.home.knbg -e HA_TOKEN=... \
  -v /usr/local/share/ca-certificates/KNBG_Root_CA_306526670621344964268144771797781855543.crt:/ca.crt:ro \
  -e SSL_CERT_FILE=/ca.crt \
  tag-albums

To import assignments, run tag-albums import-yaml inside the container, e.g. docker run --rm -v tag-albums-data:/data -v $PWD/tag_albums.yaml:/import.yaml:ro tag-albums tag-albums import-yaml /import.yaml.

Deploying in a FreeBSD jail

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:

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_commands, 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.