#!/bin/bash # Webcam presence detection daemon. # Checks for a face every 2 minutes; holds a systemd-inhibit idle lock while # the user is detected so hypridle never fires during an active session. # # Camera selection: set PRESENCE_DETECT_CAMERA env var or write # CAMERA= to ~/.config/presence-detect.conf # # Exit codes from python helper: 0=face, 1=no face, 2=camera error SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PYTHON_DETECT="$SCRIPT_DIR/python/presence_detect.py" INHIBIT_PID_FILE="/tmp/presence-inhibit.pid" PRESENCE_CFG="${XDG_CONFIG_HOME:-$HOME/.config}/presence-detect.conf" INTERVAL=120 # seconds between checks _camera_id() { if [[ -n "$PRESENCE_DETECT_CAMERA" ]]; then echo "$PRESENCE_DETECT_CAMERA" elif [[ -f "$PRESENCE_CFG" ]]; then grep -oP 'CAMERA=\K[0-9]+' "$PRESENCE_CFG" 2>/dev/null || echo 0 else echo 0 fi } _inhibit_running() { [[ -f "$INHIBIT_PID_FILE" ]] && kill -0 "$(cat "$INHIBIT_PID_FILE")" 2>/dev/null } _start_inhibit() { _inhibit_running && return systemd-inhibit --what=idle --who="presence-detect" \ --why="User presence detected" --mode=block \ sleep infinity & echo $! > "$INHIBIT_PID_FILE" logger -t presence-detect "Presence detected — idle inhibited" } _stop_inhibit() { _inhibit_running || return kill "$(cat "$INHIBIT_PID_FILE")" 2>/dev/null rm -f "$INHIBIT_PID_FILE" logger -t presence-detect "No presence — idle inhibit released" } _cleanup() { _stop_inhibit exit 0 } trap _cleanup SIGTERM SIGINT SIGHUP while true; do CAMERA="$(_camera_id)" python3 "$PYTHON_DETECT" "$CAMERA" 2>/dev/null rc=$? case $rc in 0) _start_inhibit ;; 1) _stop_inhibit ;; # rc=2 = camera unavailable — leave current inhibit state unchanged esac sleep "$INTERVAL" done