From 2f3433cebc40cf49327bb07e043874d66542e5cb Mon Sep 17 00:00:00 2001 From: Chuck Date: Tue, 7 Apr 2026 09:19:47 -0400 Subject: [PATCH] docs: fix misc remaining docs (architecture, dev quickref, sub-dir READMEs) PLUGIN_ARCHITECTURE_SPEC.md - Added a banner at the top noting this is a historical design doc written before the plugin system shipped. The doc is ~1900 lines with 13 stale /api/plugins/* paths (real is /api/v3/plugins/*), references to web_interface_v2.py (current is app.py), and a Migration Strategy / Implementation Roadmap that's now history. Banner points readers at the current docs (PLUGIN_DEVELOPMENT_GUIDE, PLUGIN_API_REFERENCE, REST_API_REFERENCE) without needing to retrofit every section. PLUGIN_CONFIG_ARCHITECTURE.md - 10 occurrences of /api/plugins/* missing /v3 prefix. Bulk fixed. DEVELOPER_QUICK_REFERENCE.md - cache_manager.delete("key") -> cache_manager.clear_cache("key") with comment noting delete() doesn't exist. Same bug already documented in PLUGIN_API_REFERENCE.md. SSH_UNAVAILABLE_AFTER_INSTALL.md - 4 occurrences of port 5001 -> 5000 in AP-mode and Ethernet/WiFi recovery instructions. PLUGIN_CUSTOM_ICONS_FEATURE.md - Port 5001 -> 5000. CONFIG_DEBUGGING.md - Documented /api/v3/config/plugin/ and /api/v3/config/validate endpoints don't exist. Replaced with the real endpoints: /api/v3/config/main, /api/v3/plugins/schema?plugin_id=, /api/v3/plugins/config?plugin_id=. Added a note that validation runs server-side automatically on POST. STARLARK_APPS_GUIDE.md - "Plugins -> Starlark Apps" UI navigation path doesn't exist (5 occurrences). Replaced with the real path: Plugin Manager tab, then the per-plugin Starlark Apps tab in the second nav row. - "Navigate to Plugins" install step -> Plugin Manager tab. web_interface/README.md - Documented several endpoints that don't exist in the api_v3 blueprint: - GET /api/v3/plugins (list) -> /api/v3/plugins/installed - GET /api/v3/plugins/ -> doesn't exist - POST /api/v3/plugins//config -> POST /api/v3/plugins/config - GET /api/v3/plugins//enable + /disable -> POST /api/v3/plugins/toggle - GET /api/v3/store/plugins -> /api/v3/plugins/store/list - POST /api/v3/store/install/ -> POST /api/v3/plugins/install - POST /api/v3/store/uninstall/ -> POST /api/v3/plugins/uninstall - POST /api/v3/store/update/ -> POST /api/v3/plugins/update - POST /api/v3/display/start/stop/restart -> POST /api/v3/system/action - GET /api/v3/display/status -> GET /api/v3/system/status - Also fixed config/secrets.json -> config/config_secrets.json - Replaced the per-section endpoint duplication with a current real endpoint list and a pointer to docs/REST_API_REFERENCE.md. - Documented that SSE stream endpoints are defined directly on the Flask app at app.py:607-615, not in the api_v3 blueprint. scripts/install/README.md - Was missing 3 of the 9 install scripts in the directory: one-shot-install.sh, configure_wifi_permissions.sh, and debug_install.sh. Added them with brief descriptions. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/CONFIG_DEBUGGING.md | 26 ++++++++++----- docs/DEVELOPER_QUICK_REFERENCE.md | 2 +- docs/PLUGIN_ARCHITECTURE_SPEC.md | 21 +++++++++++- docs/PLUGIN_CONFIG_ARCHITECTURE.md | 20 ++++++------ docs/PLUGIN_CUSTOM_ICONS_FEATURE.md | 2 +- docs/SSH_UNAVAILABLE_AFTER_INSTALL.md | 8 ++--- docs/STARLARK_APPS_GUIDE.md | 18 +++++------ scripts/install/README.md | 12 ++++++- web_interface/README.md | 46 +++++++++++++++++---------- 9 files changed, 103 insertions(+), 52 deletions(-) diff --git a/docs/CONFIG_DEBUGGING.md b/docs/CONFIG_DEBUGGING.md index 750b2b78..2454f755 100644 --- a/docs/CONFIG_DEBUGGING.md +++ b/docs/CONFIG_DEBUGGING.md @@ -250,19 +250,29 @@ WARNING - Plugin ID 'Football-Scoreboard' may conflict with 'football-scoreboard ## Checking Configuration via API +The API blueprint mounts at `/api/v3` (`web_interface/app.py:144`). + ```bash -# Get current config -curl http://localhost:5000/api/v3/config +# Get full main config (includes all plugin sections) +curl http://localhost:5000/api/v3/config/main -# Get specific plugin config -curl http://localhost:5000/api/v3/config/plugin/football-scoreboard - -# Validate config without saving -curl -X POST http://localhost:5000/api/v3/config/validate \ +# Save updated main config +curl -X POST http://localhost:5000/api/v3/config/main \ -H "Content-Type: application/json" \ - -d '{"football-scoreboard": {"enabled": true}}' + -d @new-config.json + +# Get config schema for a specific plugin +curl "http://localhost:5000/api/v3/plugins/schema?plugin_id=football-scoreboard" + +# Get a single plugin's current config +curl "http://localhost:5000/api/v3/plugins/config?plugin_id=football-scoreboard" ``` +> There is no dedicated `/config/plugin/` or `/config/validate` +> endpoint — config validation runs server-side automatically when you +> POST to `/config/main` or `/plugins/config`. See +> [REST_API_REFERENCE.md](REST_API_REFERENCE.md) for the full list. + ## Backup and Recovery ### Manual Backup diff --git a/docs/DEVELOPER_QUICK_REFERENCE.md b/docs/DEVELOPER_QUICK_REFERENCE.md index eefb7447..496c866f 100644 --- a/docs/DEVELOPER_QUICK_REFERENCE.md +++ b/docs/DEVELOPER_QUICK_REFERENCE.md @@ -62,7 +62,7 @@ display_manager.defer_update(lambda: self.update_cache(), priority=0) # Basic caching cached = cache_manager.get("key", max_age=3600) cache_manager.set("key", data) -cache_manager.delete("key") +cache_manager.clear_cache("key") # there is no delete() method # Advanced caching data = cache_manager.get_cached_data_with_strategy("key", data_type="weather") diff --git a/docs/PLUGIN_ARCHITECTURE_SPEC.md b/docs/PLUGIN_ARCHITECTURE_SPEC.md index 7cc36239..e21ffe33 100644 --- a/docs/PLUGIN_ARCHITECTURE_SPEC.md +++ b/docs/PLUGIN_ARCHITECTURE_SPEC.md @@ -1,5 +1,24 @@ # LEDMatrix Plugin Architecture Specification +> **Historical design document.** This spec was written *before* the +> plugin system was built. Most of it is still architecturally +> accurate, but specific details have drifted from the shipped +> implementation: +> +> - Code paths reference `web_interface_v2.py`; the current web UI is +> `web_interface/app.py` with v3 Blueprint-based templates. +> - The example Flask routes use `/api/plugins/*`; the real API +> blueprint is mounted at `/api/v3` (`web_interface/app.py:144`). +> - The default plugin location is `plugin-repos/` (configurable via +> `plugin_system.plugins_directory`), not `./plugins/`. +> - The "Migration Strategy" and "Implementation Roadmap" sections +> describe work that has now shipped. +> +> For the current system, see: +> [PLUGIN_DEVELOPMENT_GUIDE.md](PLUGIN_DEVELOPMENT_GUIDE.md), +> [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md), and +> [REST_API_REFERENCE.md](REST_API_REFERENCE.md). + ## Executive Summary This document outlines the transformation of the LEDMatrix project into a modular, plugin-based architecture that enables user-created displays. The goal is to create a flexible, extensible system similar to Home Assistant Community Store (HACS) where users can discover, install, and manage custom display managers from GitHub repositories. @@ -9,7 +28,7 @@ This document outlines the transformation of the LEDMatrix project into a modula 1. **Gradual Migration**: Existing managers remain in core while new plugin infrastructure is built 2. **Migration Required**: Breaking changes with migration tools provided 3. **GitHub-Based Store**: Simple discovery system, packages served from GitHub repos -4. **Plugin Location**: `./plugins/` directory in project root +4. **Plugin Location**: `./plugins/` directory in project root *(actual default is now `plugin-repos/`)* --- diff --git a/docs/PLUGIN_CONFIG_ARCHITECTURE.md b/docs/PLUGIN_CONFIG_ARCHITECTURE.md index f08d4eb8..28fa1ba3 100644 --- a/docs/PLUGIN_CONFIG_ARCHITECTURE.md +++ b/docs/PLUGIN_CONFIG_ARCHITECTURE.md @@ -31,7 +31,7 @@ ┌─────────────────────────────────────────────────────────────────┐ │ Flask Backend │ │ ┌───────────────────────────────────────────────────────┐ │ -│ │ /api/plugins/installed │ │ +│ │ /api/v3/plugins/installed │ │ │ │ • Discover plugins in plugins/ directory │ │ │ │ • Load manifest.json for each plugin │ │ │ │ • Load config_schema.json if exists │ │ @@ -40,7 +40,7 @@ │ └───────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────┐ │ -│ │ /api/plugins/config │ │ +│ │ /api/v3/plugins/config │ │ │ │ • Receive key-value pair │ │ │ │ • Update config.json │ │ │ │ • Return success/error │ │ @@ -88,7 +88,7 @@ DOMContentLoaded Event refreshPlugins() │ ▼ -GET /api/plugins/installed +GET /api/v3/plugins/installed │ ├─→ For each plugin directory: │ ├─→ Read manifest.json @@ -146,7 +146,7 @@ savePluginConfiguration(pluginId) │ │ • array: split(',') │ │ • string: as-is │ │ - │ └─→ POST /api/plugins/config + │ └─→ POST /api/v3/plugins/config │ { │ plugin_id: "hello-world", │ key: "message", @@ -174,7 +174,7 @@ Refresh Plugins Window Load └── DOMContentLoaded └── refreshPlugins() - ├── fetch('/api/plugins/installed') + ├── fetch('/api/v3/plugins/installed') ├── renderInstalledPlugins(plugins) └── generatePluginTabs(plugins) └── For each plugin: @@ -198,19 +198,19 @@ User Interactions │ ├── Process form data │ ├── Convert types per schema │ └── For each field: - │ └── POST /api/plugins/config + │ └── POST /api/v3/plugins/config │ └── resetPluginConfig(pluginId) ├── Get schema defaults └── For each field: - └── POST /api/plugins/config + └── POST /api/v3/plugins/config ``` ### Backend (Python) ``` Flask Routes - ├── /api/plugins/installed (GET) + ├── /api/v3/plugins/installed (GET) │ └── api_plugins_installed() │ ├── PluginManager.discover_plugins() │ ├── For each plugin: @@ -219,7 +219,7 @@ Flask Routes │ │ └── Load config from config.json │ └── Return JSON response │ - └── /api/plugins/config (POST) + └── /api/v3/plugins/config (POST) └── api_plugin_config() ├── Parse request JSON ├── Load current config @@ -279,7 +279,7 @@ LEDMatrix/ ### 3. Individual Config Updates **Why**: Simplifies backend API -**How**: Each field saved separately via `/api/plugins/config` +**How**: Each field saved separately via `/api/v3/plugins/config` **Benefit**: Atomic updates, easier error handling ### 4. Type Conversion in Frontend diff --git a/docs/PLUGIN_CUSTOM_ICONS_FEATURE.md b/docs/PLUGIN_CUSTOM_ICONS_FEATURE.md index e2ee6074..8e84a099 100644 --- a/docs/PLUGIN_CUSTOM_ICONS_FEATURE.md +++ b/docs/PLUGIN_CUSTOM_ICONS_FEATURE.md @@ -304,7 +304,7 @@ Result: `[logo] Company Metrics` tab To test custom icons: -1. **Open web interface** at `http://your-pi:5001` +1. **Open web interface** at `http://your-pi-ip:5000` 2. **Check installed plugins**: - Hello World should show 👋 - Clock Simple should show 🕐 diff --git a/docs/SSH_UNAVAILABLE_AFTER_INSTALL.md b/docs/SSH_UNAVAILABLE_AFTER_INSTALL.md index fdbbb3ff..d9830165 100644 --- a/docs/SSH_UNAVAILABLE_AFTER_INSTALL.md +++ b/docs/SSH_UNAVAILABLE_AFTER_INSTALL.md @@ -54,7 +54,7 @@ If the script reboots the Pi (which it recommends), network services may restart # Connect to your WiFi network (replace with your SSID and password) sudo nmcli device wifi connect "YourWiFiSSID" password "YourPassword" - # Or use the web interface at http://192.168.4.1:5001 + # Or use the web interface at http://192.168.4.1:5000 # Navigate to WiFi tab and connect to your network ``` @@ -177,9 +177,9 @@ sudo systemctl restart NetworkManager Even if SSH is unavailable, you can access the web interface: -1. **Via AP Mode**: Connect to **LEDMatrix-Setup** network and visit `http://192.168.4.1:5001` -2. **Via WiFi**: If WiFi is connected, visit `http://:5001` -3. **Via Ethernet**: Visit `http://:5001` +1. **Via AP Mode**: Connect to **LEDMatrix-Setup** network and visit `http://192.168.4.1:5000` +2. **Via WiFi**: If WiFi is connected, visit `http://:5000` +3. **Via Ethernet**: Visit `http://:5000` The web interface allows you to: - Configure WiFi connections diff --git a/docs/STARLARK_APPS_GUIDE.md b/docs/STARLARK_APPS_GUIDE.md index d4a85a71..522b275e 100644 --- a/docs/STARLARK_APPS_GUIDE.md +++ b/docs/STARLARK_APPS_GUIDE.md @@ -91,7 +91,7 @@ Pixlet is the rendering engine that executes Starlark apps. The plugin will atte #### Auto-Install via Web UI -Navigate to: **Plugins → Starlark Apps → Status → Install Pixlet** +Navigate to: **Plugin Manager → Starlark Apps tab (in the second nav row) → Status → Install Pixlet** This runs the bundled installation script which downloads the appropriate binary for your platform. @@ -110,10 +110,10 @@ Verify installation: ### 2. Enable the Starlark Apps Plugin -1. Open the web UI -2. Navigate to **Plugins** -3. Find **Starlark Apps** in the installed plugins list -4. Enable the plugin +1. Open the web UI (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab +3. Find **Starlark Apps** in the **Installed Plugins** list +4. Enable the plugin (it then gets its own tab in the second nav row) 5. Configure settings: - **Magnify**: Auto-calculated based on your display size (or set manually) - **Render Interval**: How often apps re-render (default: 300s) @@ -122,7 +122,7 @@ Verify installation: ### 3. Browse and Install Apps -1. Navigate to **Plugins → Starlark Apps → App Store** +1. Navigate to **Plugin Manager → Starlark Apps tab (in the second nav row) → App Store** 2. Browse available apps (974+ options) 3. Filter by category: Weather, Sports, Finance, Games, Clocks, etc. 4. Click **Install** on desired apps @@ -307,7 +307,7 @@ Many apps require API keys for external services: **Symptom**: "Pixlet binary not found" error **Solutions**: -1. Run auto-installer: **Plugins → Starlark Apps → Install Pixlet** +1. Run auto-installer: **Plugin Manager → Starlark Apps tab (in the second nav row) → Install Pixlet** 2. Manual install: `bash scripts/download_pixlet.sh` 3. Check permissions: `chmod +x bin/pixlet/pixlet-*` 4. Verify architecture: `uname -m` matches binary name @@ -338,7 +338,7 @@ Many apps require API keys for external services: **Symptom**: Content appears stretched, squished, or cropped **Solutions**: -1. Check magnify setting: **Plugins → Starlark Apps → Config** +1. Check magnify setting: **Plugin Manager → Starlark Apps tab (in the second nav row) → Config** 2. Try `center_small_output=true` to preserve aspect ratio 3. Adjust `magnify` manually (1-8) for your display size 4. Some apps assume 64×32 - may not scale perfectly to all sizes @@ -349,7 +349,7 @@ Many apps require API keys for external services: **Solutions**: 1. Check render interval: **App Config → Render Interval** (300s default) -2. Force re-render: **Plugins → Starlark Apps → {App} → Render Now** +2. Force re-render: **Plugin Manager → Starlark Apps tab (in the second nav row) → {App} → Render Now** 3. Clear cache: Restart LEDMatrix service 4. API rate limits: Some services throttle requests 5. Check app logs for API errors diff --git a/scripts/install/README.md b/scripts/install/README.md index 460091bd..0813f286 100644 --- a/scripts/install/README.md +++ b/scripts/install/README.md @@ -4,16 +4,26 @@ This directory contains scripts for installing and configuring the LEDMatrix sys ## Scripts +- **`one-shot-install.sh`** - Single-command installer; clones the + repo, checks prerequisites, then runs `first_time_install.sh`. + Invoked via `curl ... | bash` from the project root README. - **`install_service.sh`** - Installs the main LED Matrix display service (systemd) - **`install_web_service.sh`** - Installs the web interface service (systemd) - **`install_wifi_monitor.sh`** - Installs the WiFi monitor daemon service - **`setup_cache.sh`** - Sets up persistent cache directory with proper permissions - **`configure_web_sudo.sh`** - Configures passwordless sudo access for web interface actions +- **`configure_wifi_permissions.sh`** - Grants the `ledmatrix` user + the WiFi management permissions needed by the web interface and + the WiFi monitor service - **`migrate_config.sh`** - Migrates configuration files to new formats (if needed) +- **`debug_install.sh`** - Diagnostic helper used when an install + fails; collects environment info and recent logs ## Usage -These scripts are typically called by `first_time_install.sh` in the project root, but can also be run individually if needed. +These scripts are typically called by `first_time_install.sh` in the +project root (which itself is invoked by `one-shot-install.sh`), but +can also be run individually if needed. **Note:** Most installation scripts require `sudo` privileges to install systemd services and configure system settings. diff --git a/web_interface/README.md b/web_interface/README.md index 72532846..4f0cb0db 100644 --- a/web_interface/README.md +++ b/web_interface/README.md @@ -66,38 +66,50 @@ Once running, access the web interface at: The web interface reads configuration from: - `config/config.json` - Main configuration -- `config/secrets.json` - API keys and secrets +- `config/config_secrets.json` - API keys and secrets ## API Documentation -The V3 API is available at `/api/v3/` with the following endpoints: +The V3 API is mounted at `/api/v3/` (`app.py:144`). For the complete +list and request/response formats, see +[`docs/REST_API_REFERENCE.md`](../docs/REST_API_REFERENCE.md). Quick +reference for the most common endpoints: ### Configuration - `GET /api/v3/config/main` - Get main configuration - `POST /api/v3/config/main` - Save main configuration - `GET /api/v3/config/secrets` - Get secrets configuration -- `POST /api/v3/config/secrets` - Save secrets configuration +- `POST /api/v3/config/raw/main` - Save raw main config (Config Editor) +- `POST /api/v3/config/raw/secrets` - Save raw secrets -### Display Control -- `POST /api/v3/display/start` - Start display service -- `POST /api/v3/display/stop` - Stop display service -- `POST /api/v3/display/restart` - Restart display service -- `GET /api/v3/display/status` - Get display service status +### Display & System Control +- `GET /api/v3/system/status` - System status +- `POST /api/v3/system/action` - Control display (action body: + `start_display`, `stop_display`, `restart_display_service`, + `restart_web_service`, `git_pull`, `reboot_system`, `shutdown_system`) +- `GET /api/v3/display/current` - Current display frame +- `GET /api/v3/display/on-demand/status` - On-demand status +- `POST /api/v3/display/on-demand/start` - Trigger on-demand display +- `POST /api/v3/display/on-demand/stop` - Clear on-demand ### Plugins -- `GET /api/v3/plugins` - List installed plugins -- `GET /api/v3/plugins/` - Get plugin details -- `POST /api/v3/plugins//config` - Update plugin configuration -- `GET /api/v3/plugins//enable` - Enable plugin -- `GET /api/v3/plugins//disable` - Disable plugin +- `GET /api/v3/plugins/installed` - List installed plugins +- `GET /api/v3/plugins/config?plugin_id=` - Get plugin config +- `POST /api/v3/plugins/config` - Update plugin configuration +- `GET /api/v3/plugins/schema?plugin_id=` - Get plugin schema +- `POST /api/v3/plugins/toggle` - Enable/disable plugin +- `POST /api/v3/plugins/install` - Install from registry +- `POST /api/v3/plugins/install-from-url` - Install from GitHub URL +- `POST /api/v3/plugins/uninstall` - Uninstall plugin +- `POST /api/v3/plugins/update` - Update plugin ### Plugin Store -- `GET /api/v3/store/plugins` - List available plugins -- `POST /api/v3/store/install/` - Install plugin -- `POST /api/v3/store/uninstall/` - Uninstall plugin -- `POST /api/v3/store/update/` - Update plugin +- `GET /api/v3/plugins/store/list` - List available registry plugins +- `POST /api/v3/plugins/store/refresh` - Refresh registry from GitHub ### Real-time Streams (SSE) +SSE stream endpoints are defined directly on the Flask app +(`app.py:607-615`), not on the api_v3 blueprint: - `GET /api/v3/stream/stats` - System statistics stream - `GET /api/v3/stream/display` - Display preview stream - `GET /api/v3/stream/logs` - Service logs stream