Commit Graph

8 Commits

Author SHA1 Message Date
david 573821426c audio: add PipeWire+BT audio-bridge, mopidy (Qobuz+local), librespot (Spotify Connect)
- audio-bridge: alpine + pipewire + pipewire-pulse + wireplumber + bluez + dbus + tini
  Routes audio from librespot/mopidy/phone-BT to USB DAC (Q5K) via ALSA.
  Privileged + host network for bluetoothd HCI access.
- mopidy: built from python:3.12-slim-bookworm + pip (no ghcr.io dep).
  Qobuz (auth from developer.qobuz.com) + local files. PA bridge to audio-bridge.
- librespot: built from rust:1.85.1 on RPi (cross-compile too slow under qemu).
  Spotify Connect target named 'Klubhaus'. PA bridge to audio-bridge.

Both mopidy and librespot build locally to avoid ghcr.io auth/rate-limit issues.
PEQ stays on Q5K side (Qudelix app, 20 bands) for source-independent EQ.
2026-07-01 04:49:15 -07:00
david 09a4328960 doorbell-listener: poll every 5s (was 30s) for tighter lag
ntfy /json?poll=1 is regular polling, not long-poll. Worst-case
lag = 2 × POLL_INTERVAL × N_topics = 120s at 30s. Reducing to 5s
caps lag at ~20s with 2 topics. For sub-second latency, switch to
ntfy SSE (/<topic>/sse) - tracked separately.
2026-07-01 02:46:40 -07:00
david 7ed170acd4 doorbell-listener: 1s flash interval (was 2s), 14 toggles total
Each blink is now 1s (was 2s); 14 toggles over 13s gives sharper
'rapid fire' cadence. Even count keeps the plug ending at its
starting state.
2026-07-01 02:45:23 -07:00
david 1ac9ef948b nodered: bake Dashboard 2.0 into Dockerfile for idempotent install
NR's automatic package.json install at container start was slow and
required internet. Move npm install to image build time, preserve the
installed node_modules via an anonymous volume so the bind mount of
./nodered:/data doesn't clobber them.
2026-07-01 01:50:39 -07:00
david 758edc0a9a infra: tune flash params + persist zigbee network key for paired devices
- FLASH_INTERVAL_SECONDS 3 -> 2 (user preference)
- Add network_key / pan_id / ext_pan_id to zigbee2mqtt configuration
  so paired devices can rejoin after a config wipe. Network key
  preserved from previous working state on RPi.
- Doorbell listener flash logic with even toggle count so plug ends
  at starting state
2026-07-01 01:11:41 -07:00
david 1ef49652b0 doorbell-listener: flash plug on alert (configurable interval/duration)
On a fresh (< MAX_AGE_SECONDS) ntfy message, spawn a thread that
publishes N TOGGLEs spaced FLASH_INTERVAL_SECONDS apart so total
runtime is FLASH_DURATION_SECONDS. Defaults: 5 toggles @ 3s = 15s.

Env vars (all in compose.yaml):
  FLASH_INTERVAL_SECONDS  default 3
  FLASH_DURATION_SECONDS  default 15
  MAX_AGE_SECONDS         default 180 (replay protection)

Each alert gets its own thread; concurrent alerts spawn concurrent
flashes. z2m just flips state per toggle, so the lamp alternates
regardless of overlap.
2026-07-01 00:41:48 -07:00
david 90927ccc0e Add doorbell-listener: ntfy → zigbee2mqtt Sideboard Lamp toggle
Polls ntfy.sh for ALERT_klubhaus_topic(_test) and publishes
{state: TOGGLE} to zigbee2mqtt/Sideboard Lamp/set on each new
message event. Dual-topic subscription so switching from test to
production requires no code change; sender still uses test topic.

- infra/doorbell-listener/: uv-based Docker service (arm64)
- compose: depends_on mosquitto, persists last_id per topic
- justfile: doorbell-publish, doorbell-logs, doorbell-rebuild,
  restart-all now includes doorbell-listener
2026-07-01 00:30:08 -07:00
david de260eec62 Add infra/ — full stack config as deployed on RPi 3B+
Captures everything needed to rebuild the stack from scratch:

infra/compose.yaml
- mosquitto (eclipse-mosquitto:latest)
- zigbee2mqtt (ghcr.io/pine64/zigbee2mqtt:latest-dev, BLZ fork)
- nodered (nodered/node-red:latest)

infra/mosquitto/config/mosquitto.conf
- anonymous listener on 1883, file logging, persistence on

infra/zigbee2mqtt/
- configuration.yaml: 5 paired devices with friendly names, 1 group
- coordinator_backup.json: zigbee network key + pan id (recovery)
- state.json: per-device persisted state (ON/OFF, linkquality)

infra/nodered/
- settings.js: nodered defaults (flowFile: flows.json, no auth)
- start.sh: patches Dashboard 2.0 SPA with <base href> at startup

Also:
- Updated z2m groups section to rename Laser & Fog -> DJ Booth
  (matches the friendly_name already in devices section)
- Pushed the same change to live /root/zigbee2mqtt/configuration.yaml
  and restarted the zigbee2mqtt container
- .gitignore: output/ (regenerated on every build, churns uuid ids)
- README.md: link to infra/README.md for rebuild procedure
2026-06-30 23:19:37 -07:00