SmartestHome/stream-dock/layer-active.sh

76 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# "Is the dock's lighting layer the one currently showing?"
#
# exit 0 yes — the rings belong to the lamps
# exit 1 no — the rings belong to whatever else is on screen
# exit 2 cannot tell — treated by led_sync.py exactly like "no"
#
# THIS SHIPS UNVERIFIED, AND EXITS 2 UNTIL YOU POINT IT AT SOMETHING REAL. OpenDeck
# keeps its state under ~/.config/opendeck, but the file and field that name the
# selected profile are not documented anywhere this repo could check, and guessing
# them would produce the worst possible failure: a gate that confidently answers
# "yes, lighting" on every layer. So the default answer is "I do not know", which
# leaves the rings on their idle chase, and finding the real answer takes three
# minutes with --discover.
#
# stream-dock/layer-active.sh --discover
#
# Then set these in the environment (led-sync.env, or the config's
# stream_dock.knob_leds.layer_gate_command if you would rather pass them as flags):
#
# STREAM_DOCK_LAYER_FILE the JSON file that changes when you switch layers
# STREAM_DOCK_LAYER_JQ a jq expression selecting the active layer's name
# STREAM_DOCK_LAYER the name of your lighting layer
#
# If your OpenDeck build turns out to expose the current profile some other way — a
# CLI, a socket — throw this script away and put that command in
# layer_gate_command instead. The gate is a contract about exit codes, nothing more.
set -uo pipefail
OPENDECK_CONFIG_DIR="${OPENDECK_CONFIG_DIR:-$HOME/.config/opendeck}"
LAYER="${STREAM_DOCK_LAYER:-lighting}"
LAYER_FILE="${STREAM_DOCK_LAYER_FILE:-}"
LAYER_JQ="${STREAM_DOCK_LAYER_JQ:-}"
if [[ "${1:-}" == "--discover" ]]; then
if [[ ! -d "$OPENDECK_CONFIG_DIR" ]]; then
echo "No OpenDeck config directory at $OPENDECK_CONFIG_DIR." >&2
echo "Set OPENDECK_CONFIG_DIR if yours lives elsewhere (a Flatpak install puts it" >&2
echo "under ~/.var/app/me.amankhanna.opendeck/config/opendeck)." >&2
exit 2
fi
echo "Watching $OPENDECK_CONFIG_DIR."
echo
echo " 1. Leave this running."
echo " 2. On the dock, switch AWAY from your lighting layer and back to it."
echo " 3. Whatever is listed below is where OpenDeck records the selection."
echo
snapshot="$(mktemp)"
find "$OPENDECK_CONFIG_DIR" -type f -printf '%T@ %p\n' | sort > "$snapshot"
echo "Switch layers now — press Ctrl-C when you have switched a couple of times."
trap 'echo; echo "Changed while you were switching:";
find "$OPENDECK_CONFIG_DIR" -type f -printf "%T@ %p\n" | sort | comm -13 "$snapshot" - | cut -d" " -f2- ;
rm -f "$snapshot"; exit 0' INT
while true; do sleep 1; done
fi
if [[ -z "$LAYER_FILE" || -z "$LAYER_JQ" ]]; then
echo "layer-active.sh: STREAM_DOCK_LAYER_FILE / STREAM_DOCK_LAYER_JQ are not set," >&2
echo "so this cannot tell which layer is showing. Run --discover." >&2
exit 2
fi
command -v jq >/dev/null || { echo "layer-active.sh: jq is not installed" >&2; exit 2; }
[[ -r "$LAYER_FILE" ]] || { echo "layer-active.sh: cannot read $LAYER_FILE" >&2; exit 2; }
current="$(jq -r "$LAYER_JQ" "$LAYER_FILE" 2>/dev/null)" || exit 2
# An empty or null result means the expression did not match the file's shape — which
# is a broken gate, not an answer of "no". Say so rather than silently reporting the
# lighting layer as hidden forever.
[[ -n "$current" && "$current" != "null" ]] || {
echo "layer-active.sh: '$LAYER_JQ' matched nothing in $LAYER_FILE" >&2
exit 2
}
[[ "$current" == "$LAYER" ]]