fix(scripts): diagnostics follow the web autostart default and api_v3 package

#556 made a missing web_display_autostart mean "start" (only an explicit
false/off keeps the web interface down), but the diagnostics still said
otherwise: diagnose_web_ui.sh reported a missing key as "defaults to
false", diagnose_web_interface.sh said the web interface "will not start
unless this is set to true" and recommended enabling it, and
debug_web_manual.py printed False. Troubleshooting a down web UI pointed
users at a non-cause.

Both shell scripts now evaluate the setting with the launcher's own
autostart_enabled() (inline fallback if it cannot be imported) and report
on / off / not set (on) / unparseable config; debug_web_manual.py uses
the same function. They also check web_interface/blueprints/api_v3/
__init__.py: api_v3.py became a package in #553, so every healthy
checkout was reported as missing a file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-09-17 08:58:31 -04:00
co-authored by Claude Opus 5
parent dcb1ce034d
commit 659bafba38
3 changed files with 115 additions and 25 deletions
+7 -2
View File
@@ -54,8 +54,13 @@ def main():
config = config_manager.load_config() config = config_manager.load_config()
print(" ✅ Config loaded") print(" ✅ Config loaded")
autostart = config.get('web_display_autostart', False) # Same rule ledmatrix-web.service applies: only an explicit false/off
print(f" 🔧 web_display_autostart: {autostart}") # keeps the web interface down; a missing key means on.
sys.path.insert(0, str(project_root / 'scripts' / 'utils'))
from start_web_conditionally import autostart_enabled
raw = config.get('web_display_autostart', '(not set, defaults to on)')
state = 'starts' if autostart_enabled(config) else 'will NOT start'
print(f" 🔧 web_display_autostart: {raw} (web interface {state})")
except Exception as e: except Exception as e:
print(f" ❌ Config check failed: {e}") print(f" ❌ Config check failed: {e}")
traceback.print_exc() traceback.print_exc()
+54 -10
View File
@@ -20,6 +20,38 @@ PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$PROJECT_DIR" cd "$PROJECT_DIR"
# Report web_display_autostart the way scripts/utils/start_web_conditionally.py
# (what ledmatrix-web.service runs) decides it: only an explicit false/off keeps
# the web interface down; a missing key or an unreadable config starts it.
# Prints "on <value>", "off <value>", "default" (key not set) or "unreadable".
web_autostart_state() {
(cd "$1" && python3 - 2>/dev/null <<'PY'
import json, os, sys
sys.path.insert(0, os.path.join(os.getcwd(), "scripts", "utils"))
try:
from start_web_conditionally import autostart_enabled
except Exception:
def autostart_enabled(config):
value = config.get("web_display_autostart", True)
if isinstance(value, str):
return value.strip().lower() not in ("off", "false", "no", "0")
return bool(value)
try:
with open(os.path.join("config", "config.json"), encoding="utf-8") as f:
config = json.load(f)
except Exception:
config = None
if not isinstance(config, dict):
print("unreadable")
elif "web_display_autostart" not in config:
print("default")
else:
raw = json.dumps(config["web_display_autostart"])
print(("on " if autostart_enabled(config) else "off ") + raw)
PY
) || echo "unknown"
}
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE}1. SERVICE STATUS${NC}" echo -e "${BLUE}1. SERVICE STATUS${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
@@ -41,14 +73,26 @@ if [ -f "$PROJECT_DIR/config/config.json" ]; then
echo -e "${GREEN}✓ Config file found${NC}" echo -e "${GREEN}✓ Config file found${NC}"
# Check web_display_autostart setting # Check web_display_autostart setting
AUTOSTART=$(grep -o '"web_display_autostart"[[:space:]]*:[[:space:]]*[a-z]*' "$PROJECT_DIR/config/config.json" | grep -o '[a-z]*$') AUTOSTART=$(web_autostart_state "$PROJECT_DIR")
if [ "$AUTOSTART" == "true" ]; then case "$AUTOSTART" in
echo -e "${GREEN}✓ web_display_autostart: true${NC}" on\ *)
else echo -e "${GREEN}✓ web_display_autostart: ${AUTOSTART#on }${NC}"
echo -e "${YELLOW}⚠ web_display_autostart: ${AUTOSTART:-not set}${NC}" ;;
echo -e "${YELLOW} Web interface will not start unless this is set to true${NC}" off\ *)
fi echo -e "${YELLOW}⚠ web_display_autostart: ${AUTOSTART#off }${NC}"
echo -e "${YELLOW} Web interface will not start with this value${NC}"
;;
default)
echo -e "${GREEN}✓ web_display_autostart: not set (defaults to on)${NC}"
;;
unreadable)
echo -e "${YELLOW}⚠ config.json could not be parsed (the web interface still starts so it can be repaired)${NC}"
;;
*)
echo -e "${YELLOW}⚠ web_display_autostart: could not be evaluated (python3 unavailable?)${NC}"
;;
esac
else else
echo -e "${RED}✗ Config file not found at: $PROJECT_DIR/config/config.json${NC}" echo -e "${RED}✗ Config file not found at: $PROJECT_DIR/config/config.json${NC}"
fi fi
@@ -63,7 +107,7 @@ declare -a REQUIRED_FILES=(
"web_interface/app.py" "web_interface/app.py"
"web_interface/start.py" "web_interface/start.py"
"web_interface/requirements.txt" "web_interface/requirements.txt"
"web_interface/blueprints/api_v3.py" "web_interface/blueprints/api_v3/__init__.py"
"web_interface/blueprints/pages_v3.py" "web_interface/blueprints/pages_v3.py"
"scripts/utils/start_web_conditionally.py" "scripts/utils/start_web_conditionally.py"
) )
@@ -134,8 +178,8 @@ if ! sudo systemctl is-active --quiet ledmatrix-web; then
echo " sudo systemctl start ledmatrix-web" echo " sudo systemctl start ledmatrix-web"
fi fi
if [ "$AUTOSTART" != "true" ]; then if [ "${AUTOSTART%% *}" = "off" ]; then
echo -e "${YELLOW}→ Enable web_display_autostart in config/config.json${NC}" echo -e "${YELLOW}→ Set web_display_autostart to true in config/config.json (or remove it; missing means on)${NC}"
fi fi
if [ "$ALL_FILES_OK" = false ]; then if [ "$ALL_FILES_OK" = false ]; then
+52 -11
View File
@@ -22,6 +22,38 @@ fi
PROJECT_DIR="${HOME}/LEDMatrix" PROJECT_DIR="${HOME}/LEDMatrix"
# Report web_display_autostart the way scripts/utils/start_web_conditionally.py
# (what ledmatrix-web.service runs) decides it: only an explicit false/off keeps
# the web interface down; a missing key or an unreadable config starts it.
# Prints "on <value>", "off <value>", "default" (key not set) or "unreadable".
web_autostart_state() {
(cd "$1" && python3 - 2>/dev/null <<'PY'
import json, os, sys
sys.path.insert(0, os.path.join(os.getcwd(), "scripts", "utils"))
try:
from start_web_conditionally import autostart_enabled
except Exception:
def autostart_enabled(config):
value = config.get("web_display_autostart", True)
if isinstance(value, str):
return value.strip().lower() not in ("off", "false", "no", "0")
return bool(value)
try:
with open(os.path.join("config", "config.json"), encoding="utf-8") as f:
config = json.load(f)
except Exception:
config = None
if not isinstance(config, dict):
print("unreadable")
elif "web_display_autostart" not in config:
print("default")
else:
raw = json.dumps(config["web_display_autostart"])
print(("on " if autostart_enabled(config) else "off ") + raw)
PY
) || echo "unknown"
}
echo "1. Checking service status..." echo "1. Checking service status..."
echo "------------------------------" echo "------------------------------"
if systemctl is-active --quiet ledmatrix-web 2>/dev/null || sudo systemctl is-active --quiet ledmatrix-web 2>/dev/null; then if systemctl is-active --quiet ledmatrix-web 2>/dev/null || sudo systemctl is-active --quiet ledmatrix-web 2>/dev/null; then
@@ -47,16 +79,25 @@ echo "3. Checking configuration file..."
echo "------------------------------" echo "------------------------------"
if [ -f "${PROJECT_DIR}/config/config.json" ]; then if [ -f "${PROJECT_DIR}/config/config.json" ]; then
echo -e "${GREEN}✓ Config file exists${NC}" echo -e "${GREEN}✓ Config file exists${NC}"
AUTOSTART=$(grep -o '"web_display_autostart":\s*\(true\|false\)' "${PROJECT_DIR}/config/config.json" | grep -o '\(true\|false\)' || echo "not found") AUTOSTART=$(web_autostart_state "$PROJECT_DIR")
if [ "$AUTOSTART" = "true" ]; then case "$AUTOSTART" in
echo -e "${GREEN}✓ web_display_autostart is set to TRUE${NC}" on\ *)
elif [ "$AUTOSTART" = "false" ]; then echo -e "${GREEN}✓ web_display_autostart is ${AUTOSTART#on } (web UI starts)${NC}"
echo -e "${RED}✗ web_display_autostart is set to FALSE (web UI won't start!)${NC}" ;;
off\ *)
echo -e "${RED}✗ web_display_autostart is ${AUTOSTART#off } (web UI won't start!)${NC}"
echo " Fix: Edit config.json and set 'web_display_autostart': true" echo " Fix: Edit config.json and set 'web_display_autostart': true"
else ;;
echo -e "${YELLOW}⚠ web_display_autostart setting not found (defaults to false)${NC}" default)
echo " Fix: Add 'web_display_autostart': true to config.json" echo -e "${GREEN}✓ web_display_autostart is not set (defaults to on; web UI starts)${NC}"
fi ;;
unreadable)
echo -e "${YELLOW}⚠ config.json could not be parsed (the web UI still starts so it can be repaired)${NC}"
;;
*)
echo -e "${YELLOW}⚠ Could not evaluate web_display_autostart (python3 unavailable?)${NC}"
;;
esac
else else
echo -e "${RED}✗ Config file NOT FOUND at ${PROJECT_DIR}/config/config.json${NC}" echo -e "${RED}✗ Config file NOT FOUND at ${PROJECT_DIR}/config/config.json${NC}"
fi fi
@@ -82,7 +123,7 @@ FILES_TO_CHECK=(
"web_interface/start.py" "web_interface/start.py"
"web_interface/app.py" "web_interface/app.py"
"web_interface/requirements.txt" "web_interface/requirements.txt"
"web_interface/blueprints/api_v3.py" "web_interface/blueprints/api_v3/__init__.py"
"web_interface/blueprints/pages_v3.py" "web_interface/blueprints/pages_v3.py"
) )
@@ -175,7 +216,7 @@ echo "Diagnostic Summary"
echo "==========================================" echo "=========================================="
echo "" echo ""
echo "Most common issues:" echo "Most common issues:"
echo " 1. web_display_autostart is false or missing in config.json" echo " 1. web_display_autostart is set to false in config.json (a missing key means on)"
echo " 2. Service not enabled or not started" echo " 2. Service not enabled or not started"
echo " 3. Missing dependencies (Flask, etc.)" echo " 3. Missing dependencies (Flask, etc.)"
echo " 4. Import errors in web_interface/app.py" echo " 4. Import errors in web_interface/app.py"