51 lines
2.4 KiB
Bash
Executable File
51 lines
2.4 KiB
Bash
Executable File
#!/bin/sh
|
|
# Starts the camera gesture pointer. Installed to /usr/local/bin/gesture-control,
|
|
# launched from configs/sway/config.
|
|
#
|
|
# Session-scoped (a sway exec) rather than a systemd unit, for two reasons that point
|
|
# the same way:
|
|
#
|
|
# 1. Privacy. The only thing gesture control can do is move and click the pointer of
|
|
# the on-screen session. A system unit would hold /dev/video0 open from boot to
|
|
# shutdown, including while no session exists and there is nothing to point at —
|
|
# which is exactly the wrong default for a camera in someone's living room. Tying
|
|
# the camera's lifetime to the session's means "screen is up" and "camera is open"
|
|
# cannot drift apart.
|
|
#
|
|
# 2. Blast radius. Continuous ML inference is a different failure profile from
|
|
# thinclient-agent, which is the machine's SOLE MQTT control surface and must stay
|
|
# reliable (see the security-boundary note in thinclient_agent/mqtt_discovery.py).
|
|
# A crash here, or a camera that wedges, must not be able to take HA control of the
|
|
# room down with it. This is the same call configs/eww/fullscreen-watcher.sh makes
|
|
# and for the same reason — a separate process, not another job inside the daemon.
|
|
#
|
|
# The runtime "enabled" flag is deliberately NOT checked here. gesture_pointer.py checks
|
|
# it itself, before it imports OpenCV or MediaPipe, so there is exactly one place that
|
|
# decides whether the camera is opened rather than two that can disagree.
|
|
set -eu
|
|
|
|
VENV=/opt/gesture-control/venv
|
|
LOCK="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/gesture-control.pid"
|
|
|
|
# exec_always in the sway config re-runs this on every `swaymsg reload`; without this
|
|
# guard each reload would leave another process holding the camera.
|
|
if [ -f "$LOCK" ] && kill -0 "$(cat "$LOCK" 2>/dev/null)" 2>/dev/null; then
|
|
exit 0
|
|
fi
|
|
echo $$ > "$LOCK"
|
|
trap 'rm -f "$LOCK"' EXIT INT TERM
|
|
|
|
if [ ! -x "$VENV/bin/python3" ]; then
|
|
echo "gesture-control: not installed on this image (ENABLE_GESTURE_CONTROL was false" >&2
|
|
echo " at build time). See live-build/config/hooks/normal/1100-gesture-control.hook.chroot." >&2
|
|
exit 0
|
|
fi
|
|
|
|
# thinclient_agent.input_control and .runtime_state are stdlib-only and are imported
|
|
# from inside this venv rather than duplicated — one ydotool call path for the whole
|
|
# image, not a second one that drifts.
|
|
PYTHONPATH=/opt/thinclient-agent
|
|
export PYTHONPATH
|
|
|
|
exec "$VENV/bin/python3" /opt/gesture-control/gesture_pointer.py
|