mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-19 06:38:45 +02:00
fix(spoolbuddy): add idle-watchdog diagnostics and Wayland autodetect (#937)
Follow-up to the SpoolBuddy LCD power-off fix. Field-testing on a
Raspberry Pi OS Bookworm kiosk showed the watchdog appearing absent
from `ps ax | grep spool` — actually it had already `exec`'d into
`swayidle`, but with no logging there was no way to confirm that
without manually re-running the script.
- spoolbuddy-idle.sh now redirects stdout+stderr to
~/.cache/spoolbuddy-idle.log and prints WAYLAND_DISPLAY,
XDG_RUNTIME_DIR, PATH, the resolved timeout, and the final
`swayidle` command line on every start.
- Auto-detect WAYLAND_DISPLAY by scanning $XDG_RUNTIME_DIR for a
wayland-* socket (10s retry loop) so the script survives the race
where labwc launches autostart before exporting its env.
- Default XDG_RUNTIME_DIR to /run/user/$(id -u) if unset.
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@ All notable changes to Bambuddy will be documented in this file.
|
||||
- **LDAP Default Fallback Group** — Settings → Authentication → LDAP → Advanced now has a "Default group" selector. When an LDAP user authenticates but is not listed in any mapped LDAP group, they are automatically assigned to this fallback group instead of being left without permissions. Previously such users could log in successfully but landed on empty pages because every permission check failed. Leave the setting empty to preserve the old behavior. A warning is logged each time the fallback is applied so administrators can spot missing group assignments.
|
||||
|
||||
### Changed
|
||||
- **SpoolBuddy Kiosk LCD Now Powers Off on Idle** ([#937](https://github.com/maziggy/bambuddy/issues/937)) — The SpoolBuddy kiosk's "screen blank timeout" setting previously only painted a black CSS overlay over the browser window; the HDMI panel's backlight stayed on indefinitely, wasting power and letting OLED/LED panels burn in. The blanking path is now moved down to the OS layer: the install script installs `swayidle` and `wlopm`, and labwc's autostart launches a new watchdog (`spoolbuddy/install/spoolbuddy-idle.sh`) that queries the backend once on boot for the device's `display_blank_timeout` and hands it to `swayidle`, which powers HDMI off via `wlopm --off HDMI-A-1` after the configured idle period and powers it back on via `wlopm --on` when labwc delivers any input event (touch, keypress). The redundant CSS overlay and its pointer/keyboard listeners have been removed from `SpoolBuddyLayout` — one source of truth now. Screen blanking is opt-in: `display_blank_timeout=0` (the default) skips launching swayidle entirely and the display stays on forever, preserving current behavior for users who didn't pick a timeout. The default for users who newly enable blanking is 300 seconds. Changes made to the timeout in SpoolBuddy Settings → Display take effect on the next kiosk restart — tap Quick Menu → Restart Browser to apply without a full reboot. A new `GET /api/v1/spoolbuddy/devices/{device_id}/display` endpoint (gated on `inventory:update`, same as the existing `PUT` and heartbeat endpoints) is what the kiosk-side watchdog reads, so no new permissions are required on the device's API key. Thanks to @TravisWilder for reporting.
|
||||
- **SpoolBuddy Kiosk LCD Now Powers Off on Idle** ([#937](https://github.com/maziggy/bambuddy/issues/937)) — The SpoolBuddy kiosk's "screen blank timeout" setting previously only painted a black CSS overlay over the browser window; the HDMI panel's backlight stayed on indefinitely, wasting power and letting OLED/LED panels burn in. The blanking path is now moved down to the OS layer: the install script installs `swayidle` and `wlopm`, and labwc's autostart launches a new watchdog (`spoolbuddy/install/spoolbuddy-idle.sh`) that queries the backend once on boot for the device's `display_blank_timeout` and hands it to `swayidle`, which powers HDMI off via `wlopm --off HDMI-A-1` after the configured idle period and powers it back on via `wlopm --on` when labwc delivers any input event (touch, keypress). The redundant CSS overlay and its pointer/keyboard listeners have been removed from `SpoolBuddyLayout` — one source of truth now. Screen blanking is opt-in: `display_blank_timeout=0` (the default) skips launching swayidle entirely and the display stays on forever, preserving current behavior for users who didn't pick a timeout. The default for users who newly enable blanking is 300 seconds. Changes made to the timeout in SpoolBuddy Settings → Display take effect on the next kiosk restart — tap Quick Menu → Restart Browser to apply without a full reboot. A new `GET /api/v1/spoolbuddy/devices/{device_id}/display` endpoint (gated on `inventory:update`, same as the existing `PUT` and heartbeat endpoints) is what the kiosk-side watchdog reads, so no new permissions are required on the device's API key. The watchdog also writes a full startup trace (env vars, resolved timeout, the exact `swayidle` command it execs) to `~/.cache/spoolbuddy-idle.log` so any future breakage on a different kiosk setup is trivially diagnosable, and auto-detects `WAYLAND_DISPLAY` from `XDG_RUNTIME_DIR` with a short retry loop in case labwc hasn't finished exporting its env by the time autostart runs. Thanks to @TravisWilder for reporting.
|
||||
|
||||
### Fixed
|
||||
- **Energy Snapshot Capture Crashes on PostgreSQL** — With an external PostgreSQL database configured, the hourly smart-plug energy snapshot loop (introduced with the #941 fix) logged `asyncpg.DataError: invalid input for query argument $2: ... can't subtract offset-naive and offset-aware datetimes` every hour and failed to persist any snapshots, so date-filtered energy statistics in total-consumption mode stayed empty on Postgres installs. The engine already had a `before_cursor_execute` hook that strips `tzinfo` from bound datetime parameters before they reach asyncpg (the `smart_plug_energy_snapshots.recorded_at` column is `TIMESTAMP WITHOUT TIME ZONE` to match the rest of the schema), but the hook only stripped datetimes one level deep — when SQLAlchemy's `insertmanyvalues` feature batched multiple snapshot rows into a single `INSERT ... SELECT FROM (VALUES ...)` statement, parameters arrived as nested containers (lists of tuples, or a list inside an outer container) and the inner datetimes slipped through untouched. The hook now recursively walks any nesting of dict/list/tuple and strips `tzinfo` at any depth, so every parameter shape SQLAlchemy may use is handled. SQLite installs were never affected (SQLite ignores tzinfo entirely).
|
||||
|
||||
@@ -12,10 +12,39 @@
|
||||
|
||||
set -u
|
||||
|
||||
LOG_FILE="${SPOOLBUDDY_IDLE_LOG:-$HOME/.cache/spoolbuddy-idle.log}"
|
||||
mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null || true
|
||||
exec >>"$LOG_FILE" 2>&1
|
||||
echo "=== $(date -Is) spoolbuddy-idle starting (pid=$$) ==="
|
||||
echo "WAYLAND_DISPLAY=${WAYLAND_DISPLAY:-<unset>}"
|
||||
echo "XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-<unset>}"
|
||||
echo "PATH=$PATH"
|
||||
|
||||
DEFAULT_TIMEOUT=300
|
||||
ENV_FILE="${SPOOLBUDDY_ENV_FILE:-/opt/bambuddy/spoolbuddy/.env}"
|
||||
OUTPUT="${SPOOLBUDDY_DISPLAY_OUTPUT:-HDMI-A-1}"
|
||||
|
||||
# Wait for labwc to actually bring up its Wayland socket. Autostart fires
|
||||
# before labwc finishes exporting WAYLAND_DISPLAY on some systems, which
|
||||
# makes swayidle exit immediately.
|
||||
if [ -z "${WAYLAND_DISPLAY:-}" ] && [ -n "${XDG_RUNTIME_DIR:-}" ]; then
|
||||
for _ in $(seq 1 20); do
|
||||
sock=$(ls -1 "$XDG_RUNTIME_DIR"/wayland-* 2>/dev/null | grep -v '\.lock$' | head -n1 || true)
|
||||
if [ -n "$sock" ]; then
|
||||
WAYLAND_DISPLAY="$(basename "$sock")"
|
||||
export WAYLAND_DISPLAY
|
||||
echo "auto-detected WAYLAND_DISPLAY=$WAYLAND_DISPLAY"
|
||||
break
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
fi
|
||||
if [ -z "${XDG_RUNTIME_DIR:-}" ]; then
|
||||
XDG_RUNTIME_DIR="/run/user/$(id -u)"
|
||||
export XDG_RUNTIME_DIR
|
||||
echo "defaulted XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR"
|
||||
fi
|
||||
|
||||
if [ -r "$ENV_FILE" ]; then
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
@@ -58,9 +87,11 @@ fi
|
||||
|
||||
if [ "$TIMEOUT" -le 0 ]; then
|
||||
# Blanking explicitly disabled — don't launch swayidle at all.
|
||||
echo "timeout<=0, sleeping forever"
|
||||
exec sleep infinity
|
||||
fi
|
||||
|
||||
echo "execing swayidle with timeout=$TIMEOUT output=$OUTPUT"
|
||||
exec swayidle -w \
|
||||
timeout "$TIMEOUT" "wlopm --off $OUTPUT" \
|
||||
resume "wlopm --on $OUTPUT"
|
||||
|
||||
Reference in New Issue
Block a user