User: the Ring bridge should start on its own, not via a manual command. Made
ring-mqtt part of the always-on stack (dropped the `addons` compose profile) —
it starts with `docker compose up -d`, idle until you log in. The setup guide no
longer shows a start command; it just links to the bridge UI for the Ring login
(+ 2FA) and reflects the real bridge status. README updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Document the opt-in ring-mqtt bridge flow (gen-passwd → --profile addons →
ring-mqtt web UI login → Add-ons install), the PWA install-to-home-screen, and
the previously-undocumented mqtt-listener / mosquitto / discovery / ring-mqtt
services with their ports.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Real bidirectional MQTT so devices are live, not mock (handoff §13.3):
- Mosquitto 2 broker (auth + per-client ACLs for laravel/shelly/sidecar from day
one); passwd generated by docker/mosquitto/gen-passwd.sh (gitignored).
- mqtt-listener daemon: subscribes `+/status/#`, parse + dispatch only (H2),
exponential reconnect backoff, graceful SIGTERM. php-mqtt/laravel-client.
- Ingest path (H4): IngestShellyMessage resolves device by mqtt_prefix, upserts
device_states, refreshes last_seen, broadcasts DeviceStateChanged
(ShouldBroadcastNow) on the private `home` channel.
- Control path (H1): DeviceDriver contract + ShellyMqttDriver (command topic +
Shelly.Reboot RPC) behind DeviceCommandService, which audits every command to
the new `commands` table. Device detail toggles + restart route through it;
flash reflects the real result.
- Live UI: dashboard + device pages listen via Echo (#[On('echo-private:home,
.DeviceStateChanged')]) and re-render instantly.
- Vendor specifics isolated in Support/Mqtt + Support/Drivers (H3).
Verified end-to-end in a real browser: publishing an MQTT status turned a light
"An" on the dashboard in 3.0s with no reload, 0 console errors. R12 30/30;
15 feature tests green (incl. ingest + command audit). README/bootstrap document
the broker passwd step.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Document that production must set APP_ENV=production + APP_DEBUG=false (else
exceptions leak and the demo household seeds); note it in .env.example too.
- HomeStatus::warnings now iterates devices → entities using the already-loaded
device, instead of $entity->device, removing an N+1 on dashboard render.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Document the first-run path (deps/assets/key/migrate aren't auto-installed
because vendor/node_modules/public-build are gitignored): add
docker/app/bootstrap.sh and a README with the exact sequence to run before
`docker compose up`.
- Seeder: fall back with `?:` so a present-but-empty HOMEOS_ADMIN_PASSWORD can
never create a blank-password admin; .env.example ships a non-empty dev value.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>