Mosquitto:
- Change restart: always (was unless-stopped) to survive daemon restarts
- Add healthcheck (pub/sub ping) for depends_on conditions
- All downstream services use condition: service_healthy
Party-lock:
- Add MQTT connection retry loop (was crashing on DNS race after restart)
Zigbee2mqtt:
- Add entrypoint wrapper that auto-applies BLZ bridge patch at startup
- Bridge patch no longer needs manual 'just z2m-patch-bridge' after image pulls
Mopidy:
- Add python3-gi + python3-gi-cairo via apt (fixes 'No module named gi')
- Set PYTHONPATH to expose system gi module to Python 3.12
The Pine64 BLZ fork's zigbee2mqtt image crashes on start because
Bridge.start() calls firstCoordinatorEndpoint().deviceIeeeAddress
before the onMQTTMessage listener is registered. The BLZ coordinator
does not register its endpoint (the coordinator is the dongle itself,
no ZDO loopback), so firstCoordinatorEndpoint() returns undefined.
The crash happens in publishInfo() BEFORE onMQTTMessage is wired up,
which means every bridge MQTT request (permit_join, device rename,
group ops, etc.) silently no-ops — even though the message is
received.
Add infra/zigbee2mqtt/scripts/blz-bridge-patch.js that applies two
surgical fixes (idempotent):
1. Optional chain on the .deviceIeeeAddress access so the missing
endpoint doesn't throw.
2. Move onMQTTMessage registration BEFORE publishInfo/devices/
groups/definitions, and wrap each publish in try/catch so
Bridge.start() completes even if a single publish fails.
Add 'just z2m-patch-bridge' to apply the patch on the live container
after fresh image pulls.