fix(server): discover HDMI connector during install

This commit is contained in:
Brad Stein 2026-04-22 15:09:00 -03:00
parent bbd239bfd0
commit 9d61f855e6

View File

@ -30,24 +30,51 @@ is_attached_state() {
return 1
}
normalize_hdmi_connector() {
local name="$1"
if [[ $name =~ (HDMI-A-[0-9]+)$ ]]; then
printf '%s\n' "${BASH_REMATCH[1]}"
else
printf '%s\n' "$name"
fi
}
read_existing_hdmi_connector() {
local line value
line=$(grep -E '^LESAVKA_HDMI_CONNECTOR=' /etc/lesavka/server.env 2>/dev/null | tail -n1 || true)
[[ -n $line ]] || return 0
value=${line#*=}
value=${value%\"}
value=${value#\"}
value=${value%\'}
value=${value#\'}
normalize_hdmi_connector "$value"
}
describe_hdmi_connectors() {
local dev name status id
for dev in /sys/class/drm/card*-HDMI-A-*; do
[[ -e $dev/status ]] || continue
name=$(basename "$dev")
status=$(cat "$dev/status" 2>/dev/null || true)
id=$(cat "$dev/connector_id" 2>/dev/null || true)
printf ' %s (%s): %s\n' "$(normalize_hdmi_connector "$name")" "${id:-no-id}" "${status:-unknown}" >&2
done
}
detect_connected_hdmi_connector() {
local dev name stable_name status score suffix
local best="" best_score=0 best_suffix=0
local dev name stable_name status score
local best="" best_score=0 best_count=0
declare -A scores=()
# HDMI status can briefly flap during gadget/display bring-up. Sample a few
# times and prefer the connector that stays connected; ties prefer HDMI-A-2,
# which is the dedicated downstream capture leg on the current Pi layout.
# Store the logical connector suffix, not the DRM card prefix, so this stays
# valid if Linux renumbers cardN across boots.
# HDMI status can briefly flap during gadget/display bring-up, so sample a
# few times. Store the logical connector suffix, not the DRM card prefix, so
# this stays valid if Linux renumbers cardN across boots.
for _ in 1 2 3 4 5; do
for dev in /sys/class/drm/card*-HDMI-A-*; do
[[ -e $dev/status ]] || continue
name=$(basename "$dev")
stable_name=$name
if [[ $name =~ (HDMI-A-[0-9]+)$ ]]; then
stable_name=${BASH_REMATCH[1]}
fi
stable_name=$(normalize_hdmi_connector "$name")
status=$(cat "$dev/status" 2>/dev/null || true)
if [[ $status == connected ]]; then
scores[$stable_name]=$(( ${scores[$stable_name]:-0} + 1 ))
@ -58,15 +85,51 @@ detect_connected_hdmi_connector() {
for name in "${!scores[@]}"; do
score=${scores[$name]}
suffix=${name##*-}
if (( score > best_score || (score == best_score && suffix > best_suffix) )); then
if (( score > best_score )); then
best=$name
best_score=$score
best_suffix=$suffix
fi
done
printf '%s\n' "$best"
(( best_score > 0 )) || return 0
for name in "${!scores[@]}"; do
if (( scores[$name] == best_score )); then
best_count=$((best_count + 1))
fi
done
if (( best_count == 1 )); then
printf '%s\n' "$best"
return 0
fi
echo "❌ multiple HDMI connectors are equally connected; refusing to guess." >&2
describe_hdmi_connectors
echo " Disconnect the non-target HDMI output or run once with LESAVKA_HDMI_CONNECTOR=HDMI-A-N." >&2
return 1
}
resolve_hdmi_connector() {
local detected existing
if [[ -n ${LESAVKA_HDMI_CONNECTOR:-} ]]; then
normalize_hdmi_connector "$LESAVKA_HDMI_CONNECTOR"
return 0
fi
if ! detected=$(detect_connected_hdmi_connector); then
return 1
fi
if [[ -n $detected ]]; then
printf '%s\n' "$detected"
return 0
fi
existing=$(read_existing_hdmi_connector)
if [[ -n $existing ]]; then
echo "⚠️ no connected HDMI connector detected; preserving existing LESAVKA_HDMI_CONNECTOR=$existing." >&2
printf '%s\n' "$existing"
fi
}
run_as_user() {
@ -232,7 +295,7 @@ sudo install -Dm755 "$SRC_DIR/scripts/daemon/lesavka-uvc.sh" /usr/local/b
echo "==> 5b. Runtime environment defaults"
sudo install -d -m 0755 /etc/lesavka
HDMI_CONNECTOR=${LESAVKA_HDMI_CONNECTOR:-$(detect_connected_hdmi_connector)}
HDMI_CONNECTOR=$(resolve_hdmi_connector)
if [[ -n $HDMI_CONNECTOR ]]; then
echo " ↪ HDMI connector: $HDMI_CONNECTOR"
else