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/<id> 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/<id> -> doesn't exist
  - POST /api/v3/plugins/<id>/config -> POST /api/v3/plugins/config
  - GET /api/v3/plugins/<id>/enable + /disable -> POST /api/v3/plugins/toggle
  - GET /api/v3/store/plugins -> /api/v3/plugins/store/list
  - POST /api/v3/store/install/<id> -> POST /api/v3/plugins/install
  - POST /api/v3/store/uninstall/<id> -> POST /api/v3/plugins/uninstall
  - POST /api/v3/store/update/<id> -> 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) <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-04-07 09:19:47 -04:00
parent b374bfa8c6
commit 2f3433cebc
9 changed files with 103 additions and 52 deletions

View File

@@ -250,19 +250,29 @@ WARNING - Plugin ID 'Football-Scoreboard' may conflict with 'football-scoreboard
## Checking Configuration via API ## Checking Configuration via API
The API blueprint mounts at `/api/v3` (`web_interface/app.py:144`).
```bash ```bash
# Get current config # Get full main config (includes all plugin sections)
curl http://localhost:5000/api/v3/config curl http://localhost:5000/api/v3/config/main
# Get specific plugin config # Save updated main config
curl http://localhost:5000/api/v3/config/plugin/football-scoreboard curl -X POST http://localhost:5000/api/v3/config/main \
# Validate config without saving
curl -X POST http://localhost:5000/api/v3/config/validate \
-H "Content-Type: application/json" \ -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/<id>` 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 ## Backup and Recovery
### Manual Backup ### Manual Backup

View File

@@ -62,7 +62,7 @@ display_manager.defer_update(lambda: self.update_cache(), priority=0)
# Basic caching # Basic caching
cached = cache_manager.get("key", max_age=3600) cached = cache_manager.get("key", max_age=3600)
cache_manager.set("key", data) cache_manager.set("key", data)
cache_manager.delete("key") cache_manager.clear_cache("key") # there is no delete() method
# Advanced caching # Advanced caching
data = cache_manager.get_cached_data_with_strategy("key", data_type="weather") data = cache_manager.get_cached_data_with_strategy("key", data_type="weather")

View File

@@ -1,5 +1,24 @@
# LEDMatrix Plugin Architecture Specification # 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 ## 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. 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 1. **Gradual Migration**: Existing managers remain in core while new plugin infrastructure is built
2. **Migration Required**: Breaking changes with migration tools provided 2. **Migration Required**: Breaking changes with migration tools provided
3. **GitHub-Based Store**: Simple discovery system, packages served from GitHub repos 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/`)*
--- ---

View File

@@ -31,7 +31,7 @@
┌─────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────┐
│ Flask Backend │ │ Flask Backend │
│ ┌───────────────────────────────────────────────────────┐ │ │ ┌───────────────────────────────────────────────────────┐ │
│ │ /api/plugins/installed │ │ │ │ /api/v3/plugins/installed │ │
│ │ • Discover plugins in plugins/ directory │ │ │ │ • Discover plugins in plugins/ directory │ │
│ │ • Load manifest.json for each plugin │ │ │ │ • Load manifest.json for each plugin │ │
│ │ • Load config_schema.json if exists │ │ │ │ • Load config_schema.json if exists │ │
@@ -40,7 +40,7 @@
│ └───────────────────────────────────────────────────────┘ │ │ └───────────────────────────────────────────────────────┘ │
│ │ │ │
│ ┌───────────────────────────────────────────────────────┐ │ │ ┌───────────────────────────────────────────────────────┐ │
│ │ /api/plugins/config │ │ │ │ /api/v3/plugins/config │ │
│ │ • Receive key-value pair │ │ │ │ • Receive key-value pair │ │
│ │ • Update config.json │ │ │ │ • Update config.json │ │
│ │ • Return success/error │ │ │ │ • Return success/error │ │
@@ -88,7 +88,7 @@ DOMContentLoaded Event
refreshPlugins() refreshPlugins()
GET /api/plugins/installed GET /api/v3/plugins/installed
├─→ For each plugin directory: ├─→ For each plugin directory:
│ ├─→ Read manifest.json │ ├─→ Read manifest.json
@@ -146,7 +146,7 @@ savePluginConfiguration(pluginId)
│ │ • array: split(',') │ │ • array: split(',')
│ │ • string: as-is │ │ • string: as-is
│ │ │ │
│ └─→ POST /api/plugins/config │ └─→ POST /api/v3/plugins/config
│ { │ {
│ plugin_id: "hello-world", │ plugin_id: "hello-world",
│ key: "message", │ key: "message",
@@ -174,7 +174,7 @@ Refresh Plugins
Window Load Window Load
└── DOMContentLoaded └── DOMContentLoaded
└── refreshPlugins() └── refreshPlugins()
├── fetch('/api/plugins/installed') ├── fetch('/api/v3/plugins/installed')
├── renderInstalledPlugins(plugins) ├── renderInstalledPlugins(plugins)
└── generatePluginTabs(plugins) └── generatePluginTabs(plugins)
└── For each plugin: └── For each plugin:
@@ -198,19 +198,19 @@ User Interactions
│ ├── Process form data │ ├── Process form data
│ ├── Convert types per schema │ ├── Convert types per schema
│ └── For each field: │ └── For each field:
│ └── POST /api/plugins/config │ └── POST /api/v3/plugins/config
└── resetPluginConfig(pluginId) └── resetPluginConfig(pluginId)
├── Get schema defaults ├── Get schema defaults
└── For each field: └── For each field:
└── POST /api/plugins/config └── POST /api/v3/plugins/config
``` ```
### Backend (Python) ### Backend (Python)
``` ```
Flask Routes Flask Routes
├── /api/plugins/installed (GET) ├── /api/v3/plugins/installed (GET)
│ └── api_plugins_installed() │ └── api_plugins_installed()
│ ├── PluginManager.discover_plugins() │ ├── PluginManager.discover_plugins()
│ ├── For each plugin: │ ├── For each plugin:
@@ -219,7 +219,7 @@ Flask Routes
│ │ └── Load config from config.json │ │ └── Load config from config.json
│ └── Return JSON response │ └── Return JSON response
└── /api/plugins/config (POST) └── /api/v3/plugins/config (POST)
└── api_plugin_config() └── api_plugin_config()
├── Parse request JSON ├── Parse request JSON
├── Load current config ├── Load current config
@@ -279,7 +279,7 @@ LEDMatrix/
### 3. Individual Config Updates ### 3. Individual Config Updates
**Why**: Simplifies backend API **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 **Benefit**: Atomic updates, easier error handling
### 4. Type Conversion in Frontend ### 4. Type Conversion in Frontend

View File

@@ -304,7 +304,7 @@ Result: `[logo] Company Metrics` tab
To test custom icons: 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**: 2. **Check installed plugins**:
- Hello World should show 👋 - Hello World should show 👋
- Clock Simple should show 🕐 - Clock Simple should show 🕐

View File

@@ -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) # Connect to your WiFi network (replace with your SSID and password)
sudo nmcli device wifi connect "YourWiFiSSID" password "YourPassword" 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 # 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: 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` 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://<pi-ip-address>:5001` 2. **Via WiFi**: If WiFi is connected, visit `http://<pi-ip-address>:5000`
3. **Via Ethernet**: Visit `http://<pi-ip-address>:5001` 3. **Via Ethernet**: Visit `http://<pi-ip-address>:5000`
The web interface allows you to: The web interface allows you to:
- Configure WiFi connections - Configure WiFi connections

View File

@@ -91,7 +91,7 @@ Pixlet is the rendering engine that executes Starlark apps. The plugin will atte
#### Auto-Install via Web UI #### 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. 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 ### 2. Enable the Starlark Apps Plugin
1. Open the web UI 1. Open the web UI (`http://your-pi-ip:5000`)
2. Navigate to **Plugins** 2. Open the **Plugin Manager** tab
3. Find **Starlark Apps** in the installed plugins list 3. Find **Starlark Apps** in the **Installed Plugins** list
4. Enable the plugin 4. Enable the plugin (it then gets its own tab in the second nav row)
5. Configure settings: 5. Configure settings:
- **Magnify**: Auto-calculated based on your display size (or set manually) - **Magnify**: Auto-calculated based on your display size (or set manually)
- **Render Interval**: How often apps re-render (default: 300s) - **Render Interval**: How often apps re-render (default: 300s)
@@ -122,7 +122,7 @@ Verify installation:
### 3. Browse and Install Apps ### 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) 2. Browse available apps (974+ options)
3. Filter by category: Weather, Sports, Finance, Games, Clocks, etc. 3. Filter by category: Weather, Sports, Finance, Games, Clocks, etc.
4. Click **Install** on desired apps 4. Click **Install** on desired apps
@@ -307,7 +307,7 @@ Many apps require API keys for external services:
**Symptom**: "Pixlet binary not found" error **Symptom**: "Pixlet binary not found" error
**Solutions**: **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` 2. Manual install: `bash scripts/download_pixlet.sh`
3. Check permissions: `chmod +x bin/pixlet/pixlet-*` 3. Check permissions: `chmod +x bin/pixlet/pixlet-*`
4. Verify architecture: `uname -m` matches binary name 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 **Symptom**: Content appears stretched, squished, or cropped
**Solutions**: **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 2. Try `center_small_output=true` to preserve aspect ratio
3. Adjust `magnify` manually (1-8) for your display size 3. Adjust `magnify` manually (1-8) for your display size
4. Some apps assume 64×32 - may not scale perfectly to all sizes 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**: **Solutions**:
1. Check render interval: **App Config → Render Interval** (300s default) 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 3. Clear cache: Restart LEDMatrix service
4. API rate limits: Some services throttle requests 4. API rate limits: Some services throttle requests
5. Check app logs for API errors 5. Check app logs for API errors

View File

@@ -4,16 +4,26 @@ This directory contains scripts for installing and configuring the LEDMatrix sys
## Scripts ## 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_service.sh`** - Installs the main LED Matrix display service (systemd)
- **`install_web_service.sh`** - Installs the web interface service (systemd) - **`install_web_service.sh`** - Installs the web interface service (systemd)
- **`install_wifi_monitor.sh`** - Installs the WiFi monitor daemon service - **`install_wifi_monitor.sh`** - Installs the WiFi monitor daemon service
- **`setup_cache.sh`** - Sets up persistent cache directory with proper permissions - **`setup_cache.sh`** - Sets up persistent cache directory with proper permissions
- **`configure_web_sudo.sh`** - Configures passwordless sudo access for web interface actions - **`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) - **`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 ## 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. **Note:** Most installation scripts require `sudo` privileges to install systemd services and configure system settings.

View File

@@ -66,38 +66,50 @@ Once running, access the web interface at:
The web interface reads configuration from: The web interface reads configuration from:
- `config/config.json` - Main configuration - `config/config.json` - Main configuration
- `config/secrets.json` - API keys and secrets - `config/config_secrets.json` - API keys and secrets
## API Documentation ## 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 ### Configuration
- `GET /api/v3/config/main` - Get main configuration - `GET /api/v3/config/main` - Get main configuration
- `POST /api/v3/config/main` - Save main configuration - `POST /api/v3/config/main` - Save main configuration
- `GET /api/v3/config/secrets` - Get secrets 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 ### Display & System Control
- `POST /api/v3/display/start` - Start display service - `GET /api/v3/system/status` - System status
- `POST /api/v3/display/stop` - Stop display service - `POST /api/v3/system/action` - Control display (action body:
- `POST /api/v3/display/restart` - Restart display service `start_display`, `stop_display`, `restart_display_service`,
- `GET /api/v3/display/status` - Get display service status `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 ### Plugins
- `GET /api/v3/plugins` - List installed plugins - `GET /api/v3/plugins/installed` - List installed plugins
- `GET /api/v3/plugins/<id>` - Get plugin details - `GET /api/v3/plugins/config?plugin_id=<id>` - Get plugin config
- `POST /api/v3/plugins/<id>/config` - Update plugin configuration - `POST /api/v3/plugins/config` - Update plugin configuration
- `GET /api/v3/plugins/<id>/enable` - Enable plugin - `GET /api/v3/plugins/schema?plugin_id=<id>` - Get plugin schema
- `GET /api/v3/plugins/<id>/disable` - Disable plugin - `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 ### Plugin Store
- `GET /api/v3/store/plugins` - List available plugins - `GET /api/v3/plugins/store/list` - List available registry plugins
- `POST /api/v3/store/install/<id>` - Install plugin - `POST /api/v3/plugins/store/refresh` - Refresh registry from GitHub
- `POST /api/v3/store/uninstall/<id>` - Uninstall plugin
- `POST /api/v3/store/update/<id>` - Update plugin
### Real-time Streams (SSE) ### 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/stats` - System statistics stream
- `GET /api/v3/stream/display` - Display preview stream - `GET /api/v3/stream/display` - Display preview stream
- `GET /api/v3/stream/logs` - Service logs stream - `GET /api/v3/stream/logs` - Service logs stream