144 lines
6.8 KiB
Markdown
144 lines
6.8 KiB
Markdown
# 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.
|