mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-18 04:49:13 +00:00
Both shipped in #538 with no interface at all: the bridge could only be configured by editing integrations/mqtt_bridge/bridge_config.json over SSH, and the Pixlet editor was a script you had to know existed. Neither appeared anywhere in the web UI. They are now two sections in the Tools tab. **MQTT bridge.** Service state (installed / running / stopped), install, start, stop and restart, and a form for every setting: broker host and port, username, TLS, command topic, client id, API base, request timeout, on-demand duration and log level. The password is write-only. GET returns every other field plus a password_set flag, never the value -- this interface has no authentication, so anything it hands back is readable by anyone who can reach the port. Submitting a blank password keeps whatever is stored; there is an explicit Clear for removing one. The file is written through a temp file in the same directory and chmod 0600, so a crash mid-write cannot leave a config the bridge would refuse to load. Values are range-checked server-side (port, timeouts, log level, http(s) API base). **Pixlet editor.** Lists the apps on disk and starts a session per app, with a banner showing which app is open, a link to the editor, a countdown, and Stop. The banner survives a page reload because status is polled while a session runs, and Edit is disabled while one is open. Two changes to the script make that safe to drive from a browser: - It binds 0.0.0.0 by default (PIXLET_EDITOR_HOST overrides). Loopback-only meant the URL shown in a browser was unreachable and needed an SSH tunnel, which is the confusing path. The no-auth argument for loopback does not hold when web_interface already serves 0.0.0.0:5000 unauthenticated and can reconfigure everything. - The session ends by itself after PIXLET_EDITOR_TIMEOUT (default 30 min), enforced by `timeout` inside the script rather than by the caller. The display is stopped while editing, so a forgotten session would otherwise leave the panel dark and read as broken hardware -- the timeout is the whole reason a Start button is defensible. Two bugs found while testing that lifecycle, both of which would have bitten the Stop button: - GNU timeout runs its child in a NEW process group, so signalling the script's group killed only bash and orphaned pixlet with the port still bound. Now --foreground keeps one group, and the EXIT trap kills the recorded child too. - The liveness check treated a zombie as running: the script is a child of the web process and stays unreaped after exiting, and signal 0 succeeds against a zombie, so a finished session would have read as running forever. It now reaps non-blockingly and falls back to /proc state for a process that is not ours. Covered by test/js/dom/test_tools_sections.js (26 assertions, real DOM against the server-rendered partial): form prefill, the blank-means-unchanged password contract, the running-session banner and countdown, and that the editor link uses the host the page was loaded from. Also chmod +x on both scripts, which the docs tell you to run directly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014RRtqXDCnvnY6EQwhT5CV9
65 lines
2.1 KiB
Bash
Executable File
65 lines
2.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Home Assistant MQTT bridge installation script.
|
|
#
|
|
# Optional. Installs integrations/mqtt_bridge as a service so Home Assistant
|
|
# can force display modes, toggle power and set brightness over MQTT.
|
|
# See integrations/mqtt_bridge/README.md.
|
|
|
|
set -e
|
|
|
|
PROJECT_ROOT_DIR=$(cd "$(dirname "$0")/../.." && pwd)
|
|
BRIDGE_DIR="$PROJECT_ROOT_DIR/integrations/mqtt_bridge"
|
|
SERVICE_NAME="ledmatrix-mqtt-bridge"
|
|
UNIT_SRC="$PROJECT_ROOT_DIR/systemd/$SERVICE_NAME.service"
|
|
UNIT_DEST="/etc/systemd/system/$SERVICE_NAME.service"
|
|
|
|
if [ "$EUID" -eq 0 ]; then
|
|
SYSTEMCTL_CMD="systemctl"
|
|
SUDO=""
|
|
else
|
|
SYSTEMCTL_CMD="sudo systemctl"
|
|
SUDO="sudo"
|
|
fi
|
|
|
|
echo "Installing LED Matrix MQTT bridge"
|
|
echo "Project root directory: $PROJECT_ROOT_DIR"
|
|
|
|
if [ ! -f "$BRIDGE_DIR/bridge_config.json" ]; then
|
|
cp "$BRIDGE_DIR/bridge_config.example.json" "$BRIDGE_DIR/bridge_config.json"
|
|
chmod 600 "$BRIDGE_DIR/bridge_config.json"
|
|
echo ""
|
|
echo "⚠ Created $BRIDGE_DIR/bridge_config.json from the example."
|
|
echo " Edit it with your broker details, then re-run this script."
|
|
echo " The service will refuse to start until the placeholder password is replaced."
|
|
echo ""
|
|
fi
|
|
|
|
echo "Installing Python dependencies..."
|
|
python3 -m pip install -r "$BRIDGE_DIR/requirements.txt" 2>/dev/null \
|
|
|| python3 -m pip install --break-system-packages -r "$BRIDGE_DIR/requirements.txt"
|
|
|
|
echo "Installing $UNIT_DEST..."
|
|
sed "s|__PROJECT_ROOT_DIR__|$PROJECT_ROOT_DIR|g" "$UNIT_SRC" \
|
|
| $SUDO tee "$UNIT_DEST" > /dev/null
|
|
|
|
$SYSTEMCTL_CMD daemon-reload
|
|
$SYSTEMCTL_CMD enable "$SERVICE_NAME.service"
|
|
$SYSTEMCTL_CMD restart "$SERVICE_NAME.service" || true
|
|
|
|
echo ""
|
|
if $SYSTEMCTL_CMD is-active --quiet "$SERVICE_NAME.service" 2>/dev/null; then
|
|
echo "✓ MQTT bridge is running"
|
|
echo " The matrix should appear in Home Assistant under Settings > Devices > MQTT."
|
|
else
|
|
echo "⚠ MQTT bridge is not running. Check the logs:"
|
|
echo " sudo journalctl -u $SERVICE_NAME -n 50"
|
|
fi
|
|
|
|
echo ""
|
|
echo "Useful commands:"
|
|
echo " sudo systemctl status $SERVICE_NAME"
|
|
echo " sudo journalctl -u $SERVICE_NAME -f"
|
|
echo " sudo systemctl disable --now $SERVICE_NAME # Undo"
|
|
echo ""
|