Initial reusable HA kiosk MQTT controls
This commit is contained in:
commit
0b7e6a0107
17 files changed
+3249
No files matched your search
@@ -0,0 +1,143 @@
|
||||
# HA Kiosk MQTT Control
|
||||
|
||||
Reusable Linux/X11 touchscreen kiosk controls for Home Assistant over MQTT. The
|
||||
project combines local display and brightness management, a restartable browser,
|
||||
retained MQTT state and availability, and a Home Assistant package for controls.
|
||||
|
||||
The reference installation is a Dell portrait touchscreen kiosk. Device values
|
||||
are configurable so the same controls can be deployed to other kiosks.
|
||||
|
||||
## Features
|
||||
|
||||
- Display modes: Screen Lock, Screen Off, Screensaver, and Screen On.
|
||||
- Touch and optional camera-motion wake, shared presence timer and brightness ramp.
|
||||
- Current/presence brightness, volume, mute, and physical display state.
|
||||
- Periodic retained-state publication to recover Home Assistant entities after a
|
||||
broker retained-store reset.
|
||||
- MQTT heartbeat watchdog that restarts the screen-control service when its
|
||||
command subscriber has stopped receiving messages.
|
||||
- Separate Chrome systemd service with automatic restart.
|
||||
- Retained availability with Last Will.
|
||||
- Optional performance telemetry and MQTT Discovery sensors.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Linux desktop session running X11 (the included touch and DPMS controls use X11).
|
||||
- Google Chrome/Chromium and a kiosk dashboard URL.
|
||||
- `mosquitto-clients`, `xinput`, `brightnessctl`, `xset`, `xscreensaver`,
|
||||
`wpctl`, `stdbuf`, `awk`, `grep`, and Bash.
|
||||
- A Home Assistant MQTT integration and an MQTT broker reachable from the kiosk.
|
||||
- Optional camera motion service publishing the configured motion state topic.
|
||||
- Optional telemetry: Python 3 with `psutil` and `paho-mqtt`.
|
||||
|
||||
Wayland support is not currently implemented.
|
||||
|
||||
## Configure a kiosk
|
||||
|
||||
1. Create the per-user directories, then copy the scripts and units into place:
|
||||
|
||||
```sh
|
||||
install -d -m 700 ~/.config/ha-kiosk
|
||||
install -d ~/.local/lib/ha-kiosk-mqtt-control ~/.config/systemd/user
|
||||
cp runtime/*.sh ~/.local/lib/ha-kiosk-mqtt-control/
|
||||
chmod 755 ~/.local/lib/ha-kiosk-mqtt-control/*.sh
|
||||
cp runtime/*.service ~/.config/systemd/user/
|
||||
```
|
||||
2. If no config exists yet, copy `runtime/config.example` to
|
||||
`~/.config/ha-kiosk/config`; protect it with `chmod 600`. Edit the kiosk
|
||||
identifier, MQTT roots, dashboard URL, display/touchscreen values, and optional
|
||||
motion integration. The `KIOSK_ID` topic segment must match the segment used
|
||||
in the rendered HA package. `KIOSK_ENTITY_PREFIX` must match the package's
|
||||
`--entity-prefix` (and is used by optional telemetry). Preserve an existing
|
||||
config when upgrading rather than replacing it with the example.
|
||||
3. Configure the system Mosquitto clients so `mosquitto_pub` and
|
||||
`mosquitto_sub` can reach the same broker as Home Assistant. The control and
|
||||
availability shell scripts currently call those standard clients without
|
||||
passing authentication flags; use a broker/network policy that allows the
|
||||
kiosk's client connection, or integrate a credential-safe client wrapper
|
||||
appropriate to your broker. Do not put passwords in this repository or in
|
||||
command-line arguments. The optional Python telemetry publisher accepts
|
||||
broker credentials from its protected systemd environment file.
|
||||
4. If no systemd environment file exists yet, copy
|
||||
`runtime/systemd.env.example` to `~/.config/ha-kiosk/systemd.env` and set
|
||||
`KIOSK_ID` and `STATUS_ROOT` to match `config`. This environment file is used
|
||||
by systemd for the availability service's orderly-stop publication.
|
||||
5. Install `ha-kiosk-browser.service`, `ha-kiosk-screen-control.service`, and
|
||||
`ha-kiosk-availability.service` from `runtime/` into
|
||||
`~/.config/systemd/user/`. Before enabling the browser unit, disable any
|
||||
existing desktop/autostart entry that launches the same browser, so there is
|
||||
only one browser service owner.
|
||||
6. Run `systemctl --user daemon-reload`, then enable and start
|
||||
`ha-kiosk-browser.service`, `ha-kiosk-screen-control.service`, and
|
||||
`ha-kiosk-availability.service`.
|
||||
7. Enable lingering for the kiosk user if user services must run before login:
|
||||
`sudo loginctl enable-linger "$USER"`.
|
||||
|
||||
The screen-control script reads `~/.config/ha-kiosk/config`. The browser launcher
|
||||
reads the same file for `KIOSK_URL`, display and Chrome profile values, and touch
|
||||
mapping values. Systemd environment files use systemd syntax, not shell sourcing.
|
||||
|
||||
## Home Assistant package
|
||||
|
||||
Render the MQTT entities from the parameterized package template:
|
||||
|
||||
```sh
|
||||
python3 home-assistant/render-package.py \
|
||||
--name "My Kiosk" \
|
||||
--entity-prefix my_kiosk \
|
||||
--command-root kiosk/commands/my_kiosk \
|
||||
--status-root kiosk/status/my_kiosk \
|
||||
--manufacturer Generic \
|
||||
--model "Linux Touchscreen Kiosk" \
|
||||
--output /path/to/homeassistant/packages/my_kiosk.yaml
|
||||
```
|
||||
|
||||
The `--command-root` and `--status-root` values are full per-device MQTT topic
|
||||
roots (including the device segment). They should equal `COMMAND_ROOT/KIOSK_ID`
|
||||
and `STATUS_ROOT/KIOSK_ID` from the kiosk config. The example uses the neutral
|
||||
`kiosk/commands` and `kiosk/status` namespaces. The generated package provides the
|
||||
MQTT controls, availability, and diagnostic entities. Add it to a Home Assistant
|
||||
package directory and validate the HA configuration before reloading the MQTT
|
||||
integration or restarting Home Assistant. Existing dashboards and automations may refer to the entity IDs, so
|
||||
review those references when changing the entity prefix.
|
||||
|
||||
The package expects the kiosk to publish the topics rooted at the supplied
|
||||
command/status roots. It uses MQTT retained availability and has no secrets.
|
||||
|
||||
## Optional telemetry
|
||||
|
||||
Copy `telemetry/telemetry.env.example` to
|
||||
`~/.config/ha-kiosk/telemetry.env`, set the broker values, and protect it with
|
||||
`chmod 600`. Copy `telemetry/kiosk-telemetry.service` into
|
||||
`~/.config/systemd/user/`, then reload systemd and enable
|
||||
`kiosk-telemetry.service`. Keep the real environment file out of Git;
|
||||
`.gitignore` excludes it. Telemetry uses Home Assistant MQTT Discovery.
|
||||
|
||||
## Recovery behavior
|
||||
|
||||
- All control and diagnostic states are republished retained every 30 seconds.
|
||||
- A non-retained control heartbeat is sent on the same cadence. If the command
|
||||
subscriber does not return the heartbeat within 90 seconds, systemd restarts
|
||||
screen control.
|
||||
- Chrome runs in a separate `Restart=always` service, so restarting screen
|
||||
control does not take down the browser.
|
||||
- The availability watcher publishes retained `ON`, while Mosquitto's Last Will
|
||||
publishes retained `OFF` when the connection is lost.
|
||||
|
||||
## Updating
|
||||
|
||||
Back up the per-device configuration and current scripts, install the new
|
||||
version, run `bash -n` on shell scripts, reload user systemd, and restart the
|
||||
services individually. Check `systemctl --user status` and the retained MQTT
|
||||
state topics after the update.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the GNU General Public License, version 3 or any
|
||||
later version. See `LICENSE`.
|
||||
|
||||
## Credentials and repository
|
||||
|
||||
Never commit MQTT credentials, SSH private keys, Home Assistant tokens, or a
|
||||
real per-kiosk config. The Gitea repository is public, so keep secrets and actual
|
||||
per-kiosk settings out of commits.
|
||||
Reference in new issue
Block a user