4 Commits

Author SHA1 Message Date
Chuck
b374bfa8c6 docs: fix plugin config + store + dependency docs
PLUGIN_STORE_GUIDE.md
- 19 occurrences of port 5050 -> 5000
- All API paths missing /v3 (e.g. /api/plugins/install ->
  /api/v3/plugins/install). Bulk fix.

PLUGIN_REGISTRY_SETUP_GUIDE.md
- Same port + /api/v3 fixes (3 occurrences each)
- "Go to Plugin Store tab" -> "Open the Plugin Manager tab and scroll
  to the Install from GitHub section" (the real flow for registry
  setup is the GitHub install section, not the Plugin Store search)

PLUGIN_CONFIG_QUICK_START.md
- Port 5001 -> 5000 (5001 is the dev_server.py default, not the web UI)
- "Plugin Store tab" install flow -> real Plugin Manager + Plugin Store
  section + per-plugin tab in second nav row
- Removed reference to PLUGIN_CONFIG_TABS_SUMMARY.md (archived doc)

PLUGIN_CONFIGURATION_TABS.md
- "Plugin Management vs Configuration" section confusingly described
  a "Plugins Tab" that doesn't exist as a single thing. Rewrote to
  describe the real two-piece structure: Plugin Manager tab (browse,
  install, toggle) vs per-plugin tabs (configure individual plugins).

PLUGIN_DEPENDENCY_GUIDE.md
- Port 5001 -> 5000

PLUGIN_DEPENDENCY_TROUBLESHOOTING.md
- Wrong port (8080) and wrong UI nav ("Plugin Store or Plugin
  Management"). Fixed to the real flow.

PLUGIN_QUICK_REFERENCE.md
- "Plugin Location: ./plugins/ directory" -> default is plugin-repos/
  (verified in config/config.template.json:130 and
  display_controller.py:132). plugins/ is a fallback.
- File structure diagram showed plugins/ -> plugin-repos/.
- Web UI install flow: "Plugin Store tab" -> "Plugin Manager tab ->
  Plugin Store section". Also fixed Configure ⚙️ button (doesn't
  exist) and "Drag and drop reorder" (not implemented).
- API examples: replaced ad-hoc Python pseudocode with real curl
  examples against /api/v3/plugins/* endpoints. Pointed at
  REST_API_REFERENCE.md for the full list.
- "Migration Path Phase 1-5" was a roadmap written before the plugin
  system shipped. The plugin system is now stable and live. Removed
  the migration phases as they're history, not a roadmap.
- "Quick Migration" section called scripts/migrate_to_plugins.py
  which doesn't exist anywhere in the repo. Removed.
- "Plugin Registry Structure" referenced
  ChuckBuilds/ledmatrix-plugin-registry which doesn't exist. The
  real registry is ChuckBuilds/ledmatrix-plugins. Fixed.
- "Next Steps" / "Questions to Resolve" sections were
  pre-implementation planning notes. Replaced with a "Known
  Limitations" section that documents the actually-real gaps
  (sandboxing, resource limits, ratings, auto-updates).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:10:05 -04:00
Chuck
49287bdd1a docs: fix ADVANCED_FEATURES and REST_API_REFERENCE
REST_API_REFERENCE.md
- Wrong path: /fonts/delete/<font_family> -> /fonts/<font_family>
  (verified the real DELETE route in
  web_interface/blueprints/api_v3.py).
- Diffed the documented routes against the real api_v3 blueprint
  (92 routes vs the 71 documented). Added missing sections:
  - Error tracking (/errors/summary, /errors/plugin/<id>, /errors/clear)
  - Health (/health)
  - Schedule dim/power (/config/dim-schedule GET/POST)
  - Plugin-specific endpoints (calendar/list-calendars,
    of-the-day/json/upload+delete, plugins/<id>/static/<path>)
  - Starlark Apps (12 endpoints: status, install-pixlet, apps CRUD,
    repository browse/install, upload)
  - Font preview (/fonts/preview)
- Updated table of contents with the new sections.
- Added a footer note that the API blueprint mounts at /api/v3
  (app.py:144) and that SSE stream endpoints are defined directly on
  the Flask app at app.py:607-615.

ADVANCED_FEATURES.md
- Vegas Scroll Mode section was actually accurate (verified all
  config keys match src/vegas_mode/config.py:15-30).

- On-Demand Display section had multiple bugs:
  - 5 occurrences of port 5050 -> 5000
  - All API paths missing /v3 (e.g. /api/display/on-demand/start
    should be /api/v3/display/on-demand/start)
  - "Settings -> Plugin Management -> Show Now Button" UI flow doesn't
    exist. Real flow: open the plugin's tab in the second nav row,
    click Run On-Demand / Stop On-Demand.
  - "Python API Methods" section showed
    controller.show_on_demand() / clear_on_demand() /
    is_on_demand_active() / get_on_demand_info() — none of these
    methods exist on DisplayController. The on-demand machinery is
    all internal (_set_on_demand_*, _activate_on_demand, etc) and
    is driven through the cache_manager. Replaced the section with
    a note pointing to the REST API.
  - All Use Case Examples used the same fictional Python calls.
    Replaced with curl examples against the real API.

- Cache Management section claimed "On-demand display uses Redis cache
  keys". LEDMatrix doesn't use Redis — verified with grep that
  src/cache_manager.py has no redis import. The cache is file-based,
  managed by CacheManager (file at /var/cache/ledmatrix/ or fallback
  paths). Rewrote the manual recovery section:
  - Removed redis-cli commands
  - Replaced cache.delete() Python calls with cache.clear_cache()
    (the real public method per the same bug already flagged in
    PLUGIN_API_REFERENCE.md)
  - Replaced "Settings -> Cache Management" with the real Cache tab
  - Documented the actual cache directory candidates

- Background Data Service section:
  - Used "nfl_scoreboard" as the plugin id in the example.
    The real plugin is "football-scoreboard" (handles both NFL and
    NCAA). Fixed.
  - "Implementation Status: Phase 1 NFL only / Phase 2 planned"
    section was severely outdated. The background service is now
    used by all sports scoreboards (football, hockey, baseball,
    basketball, soccer, lacrosse, F1, UFC), the odds ticker, and
    the leaderboard plugin. Replaced with a current "Plugins using
    the background service" note.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 21:55:34 -04:00
Chuck
1d31465df0 docs: fix WEB_INTERFACE_GUIDE and WIFI_NETWORK_SETUP
WEB_INTERFACE_GUIDE.md
- Web UI port: 5050 -> 5000 (4 occurrences)
- Tab list was almost entirely fictional. Documented tabs:
  General Settings, Display Settings, Durations, Sports Configuration,
  Plugin Management, Plugin Store, Font Management. None of these
  exist. Real tabs (verified in web_interface/templates/v3/base.html:
  935-1000): Overview, General, WiFi, Schedule, Display, Config Editor,
  Fonts, Logs, Cache, Operation History, plus Plugin Manager and
  per-plugin tabs in the second nav row. Rewrote the navigation
  section, the General/Display/Plugin sections, and the Common Tasks
  walkthroughs to match.
- Quick Actions list referenced "Test Display" button (doesn't exist).
  Replaced with the real button list verified in
  partials/overview.html:88-152: Start/Stop Display, Restart Display
  Service, Restart Web Service, Update Code, Reboot, Shutdown.
- API endpoints used /api/* paths. The api_v3 blueprint mounts at
  /api/v3 (web_interface/app.py:144), so the real paths are
  /api/v3/config/main, /api/v3/system/status, etc. Fixed.
- Removed bogus "Sports Configuration tab" walkthrough; sports
  favorites live inside each scoreboard plugin's own tab now.
- Plugin directory listed as /plugins/. Real default is plugin-repos/
  (verified in config/config.template.json:130 and
  display_controller.py:132); plugins/ is a fallback.
- Removed "Swipe navigation between tabs" mobile claim (not implemented).

WIFI_NETWORK_SETUP.md
- 21 occurrences of port 5050 -> 5000.
- All /api/wifi/* curl examples used the wrong path. The real wifi
  API routes are at /api/v3/wifi/* (api_v3.py:6367-6609). Fixed.
- ap_password default was documented as "" (empty/open network) but
  config/wifi_config.json ships with "ledmatrix123". Updated the
  Quick Start, Configuration table, AP Mode Settings section, and
  Security Recommendations to match. Also clarified that setting
  ap_password to "" is the way to make it an open network.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 21:39:11 -04:00
Chuck
2a7a318cf7 docs: refresh and correct stale documentation across repo
Walked the README and docs/ tree against current code and fixed several
real bugs and many stale references. Highlights:

User-facing
- README.md: web interface install instructions referenced
  install_web_service.sh at the repo root, but it actually lives at
  scripts/install/install_web_service.sh.
- docs/GETTING_STARTED.md: every web UI port reference said 5050, but
  the real server in web_interface/start.py:123 binds 5000. Same bug
  was duplicated in docs/TROUBLESHOOTING.md (17 occurrences). Fixed
  both.
- docs/GETTING_STARTED.md: rewrote tab-by-tab instructions. The doc
  referenced "Plugin Store", "Plugin Management", "Sports Configuration",
  "Durations", and "Font Management" tabs - none of which exist. Real
  tabs (verified in web_interface/templates/v3/base.html) are: Overview,
  General, WiFi, Schedule, Display, Config Editor, Fonts, Logs, Cache,
  Operation History, Plugin Manager (+ per-plugin tabs).
- docs/GETTING_STARTED.md: removed references to a "Test Display"
  button (doesn't exist) and "Show Now" / "Stop" plugin buttons. Real
  controls are "Run On-Demand" / "Stop On-Demand" inside each plugin's
  tab (partials/plugin_config.html:792).
- docs/TROUBLESHOOTING.md: removed dead reference to
  troubleshoot_weather.sh (doesn't exist anywhere in the repo); weather
  is now a plugin in ledmatrix-plugins.

Developer-facing
- docs/PLUGIN_API_REFERENCE.md: documented draw_image() doesn't exist
  on DisplayManager. Real plugins paste onto display_manager.image
  directly (verified in src/base_classes/{baseball,basketball,football,
  hockey}.py). Replaced with the canonical pattern.
- docs/PLUGIN_API_REFERENCE.md: documented cache_manager.delete() doesn't
  exist. Real method is clear_cache(key=None). Updated the section.
- docs/PLUGIN_API_REFERENCE.md: added 10 missing BasePlugin methods that
  the doc never mentioned: dynamic-duration hooks, live-priority hooks,
  and the full Vegas-mode interface.
- docs/PLUGIN_DEVELOPMENT_GUIDE.md: same draw_image fix.
- docs/DEVELOPMENT.md: corrected the "Plugin Submodules" section. Plugins
  are NOT git submodules - .gitmodules only contains
  rpi-rgb-led-matrix-master. Plugins are installed at runtime into the
  plugins directory configured by plugin_system.plugins_directory
  (default plugin-repos/). Both internal links in this doc were also
  broken (missing relative path adjustment).
- docs/HOW_TO_RUN_TESTS.md: removed pytest-timeout from install line
  (not in requirements.txt) and corrected the test/integration/ path
  (real integration tests are at test/web_interface/integration/).
  Replaced the fictional file structure diagram with the real one.
- docs/EMULATOR_SETUP_GUIDE.md: clone URL was a placeholder; default
  pixel_size was documented as 16 but emulator_config.json ships with 5.

Index
- docs/README.md: rewrote. Old index claimed "16-17 files after
  consolidation" but docs/ actually has 38 .md files. Four were missing
  from the index entirely (CONFIG_DEBUGGING, DEV_PREVIEW,
  PLUGIN_ERROR_HANDLING, STARLARK_APPS_GUIDE). Trimmed the navel-gazing
  consolidation/statistics sections.

Out of scope but worth flagging:
- src/plugin_system/resource_monitor.py:343 and src/common/api_helper.py:287
  call cache_manager.delete(key) but no such method exists on
  CacheManager. Both call sites would AttributeError at runtime if hit.
  Not fixed in this docs PR - either add a delete() shim or convert
  callers to clear_cache().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 20:45:19 -04:00
20 changed files with 894 additions and 792 deletions

View File

@@ -782,14 +782,18 @@ The LEDMatrix system includes Web Interface that runs on port 5000 and provides
### Installing the Web Interface Service ### Installing the Web Interface Service
> The first-time installer (`first_time_install.sh`) already installs the
> web service. The steps below only apply if you need to (re)install it
> manually.
1. Make the install script executable: 1. Make the install script executable:
```bash ```bash
chmod +x install_web_service.sh chmod +x scripts/install/install_web_service.sh
``` ```
2. Run the install script with sudo: 2. Run the install script with sudo:
```bash ```bash
sudo ./install_web_service.sh sudo ./scripts/install/install_web_service.sh
``` ```
The script will: The script will:

View File

@@ -437,26 +437,26 @@ When on-demand expires or is cleared, the display returns to the next highest pr
### Web Interface Controls ### Web Interface Controls
**Access:** Navigate to Settings → Plugin Management Each installed plugin has its own tab in the second nav row of the web
UI. Inside the plugin's tab, scroll to **On-Demand Controls**:
**Controls:** - **Run On-Demand** — triggers the plugin immediately, even if it's
- **Show Now Button** - Triggers plugin immediately disabled in the rotation
- **Duration Slider** - Set display time (0 = indefinite) - **Stop On-Demand** — clears on-demand and returns to the normal
- **Pin Checkbox** - Keep showing until manually cleared rotation
- **Stop Button** - Clear on-demand and return to rotation
- **Shift+Click Stop** - Stop the entire display service
**Status Card:** The display service must be running. The status banner at the top of
- Real-time status updates the plugin tab shows the active on-demand plugin, mode, and remaining
- Shows active plugin and remaining time time when something is active.
- Pin status indicator
### REST API Reference ### REST API Reference
The API is mounted at `/api/v3` (`web_interface/app.py:144`).
#### Start On-Demand Display #### Start On-Demand Display
```bash ```bash
POST /api/display/on-demand/start POST /api/v3/display/on-demand/start
# Body: # Body:
{ {
@@ -467,20 +467,20 @@ POST /api/display/on-demand/start
# Examples: # Examples:
# 30-second preview # 30-second preview
curl -X POST http://localhost:5050/api/display/on-demand/start \ curl -X POST http://localhost:5000/api/v3/display/on-demand/start \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "weather", "duration": 30}' -d '{"plugin_id": "weather", "duration": 30}'
# Pin indefinitely # Pin indefinitely
curl -X POST http://localhost:5050/api/display/on-demand/start \ curl -X POST http://localhost:5000/api/v3/display/on-demand/start \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "hockey-scores", "pinned": true}' -d '{"plugin_id": "hockey-scoreboard", "pinned": true}'
``` ```
#### Stop On-Demand Display #### Stop On-Demand Display
```bash ```bash
POST /api/display/on-demand/stop POST /api/v3/display/on-demand/stop
# Body: # Body:
{ {
@@ -489,10 +489,10 @@ POST /api/display/on-demand/stop
# Examples: # Examples:
# Clear on-demand # Clear on-demand
curl -X POST http://localhost:5050/api/display/on-demand/stop curl -X POST http://localhost:5000/api/v3/display/on-demand/stop
# Stop service too # Stop service too
curl -X POST http://localhost:5050/api/display/on-demand/stop \ curl -X POST http://localhost:5000/api/v3/display/on-demand/stop \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"stop_service": true}' -d '{"stop_service": true}'
``` ```
@@ -500,10 +500,10 @@ curl -X POST http://localhost:5050/api/display/on-demand/stop \
#### Get On-Demand Status #### Get On-Demand Status
```bash ```bash
GET /api/display/on-demand/status GET /api/v3/display/on-demand/status
# Example: # Example:
curl http://localhost:5050/api/display/on-demand/status curl http://localhost:5000/api/v3/display/on-demand/status
# Response: # Response:
{ {
@@ -516,35 +516,10 @@ curl http://localhost:5050/api/display/on-demand/status
} }
``` ```
### Python API Methods > There is no public Python on-demand API. The display controller's
> on-demand machinery is internal — drive it through the REST endpoints
```python > above (or the web UI buttons), which write a request into the cache
from src.display_controller import DisplayController > manager (`display_on_demand_config` key) that the controller polls.
controller = DisplayController()
# Show plugin for 30 seconds
controller.show_on_demand('weather', duration=30)
# Pin plugin until manually cleared
controller.show_on_demand('hockey-scores', pinned=True)
# Show indefinitely (not pinned, clears on expiry if duration set later)
controller.show_on_demand('weather', duration=0)
# Use plugin's default duration
controller.show_on_demand('weather')
# Clear on-demand
controller.clear_on_demand()
# Check status
is_active = controller.is_on_demand_active()
# Get detailed info
info = controller.get_on_demand_info()
# Returns: {'active': bool, 'mode': str, 'duration': float, 'remaining': float, 'pinned': bool}
```
### Duration Modes ### Duration Modes
@@ -557,27 +532,31 @@ info = controller.get_on_demand_info()
### Use Case Examples ### Use Case Examples
**Quick Check (30-second preview):** **Quick check (30-second preview):**
```python ```bash
controller.show_on_demand('weather', duration=30) curl -X POST http://localhost:5000/api/v3/display/on-demand/start \
-H "Content-Type: application/json" \
-d '{"plugin_id": "ledmatrix-weather", "duration": 30}'
``` ```
**Pin Important Information:** **Pin important information:**
```python ```bash
controller.show_on_demand('game-score', pinned=True) curl -X POST http://localhost:5000/api/v3/display/on-demand/start \
-H "Content-Type: application/json" \
-d '{"plugin_id": "hockey-scoreboard", "pinned": true}'
# ... later ... # ... later ...
controller.clear_on_demand() curl -X POST http://localhost:5000/api/v3/display/on-demand/stop
``` ```
**Indefinite Display:** **Indefinite display:**
```python ```bash
controller.show_on_demand('welcome-message', duration=0) curl -X POST http://localhost:5000/api/v3/display/on-demand/start \
-H "Content-Type: application/json" \
-d '{"plugin_id": "text-display", "duration": 0}'
``` ```
**Testing Plugin:** **Testing a plugin during development:** the same call works, or just
```python click **Run On-Demand** in the plugin's tab.
controller.show_on_demand('my-new-plugin', duration=60)
```
### Best Practices ### Best Practices
@@ -613,7 +592,10 @@ controller.show_on_demand('my-new-plugin', duration=60)
### Overview ### Overview
On-demand display uses Redis cache keys to manage state across service restarts and coordinate between web interface and display controller. Understanding these keys helps troubleshoot stuck states. On-demand display uses cache keys (managed by `src/cache_manager.py`
file-based, not Redis) to coordinate state between the web interface
and the display controller across service restarts. Understanding these
keys helps troubleshoot stuck states.
### Cache Keys ### Cache Keys
@@ -688,19 +670,26 @@ On-demand display uses Redis cache keys to manage state across service restarts
### Manual Recovery Procedures ### Manual Recovery Procedures
**Via Web Interface (Recommended):** **Via Web Interface (Recommended):**
1. Navigate to Settings → Cache Management 1. Open the **Cache** tab in the web UI
2. Search for "on_demand" keys 2. Find the `display_on_demand_*` entries
3. Select keys to delete 3. Delete them
4. Click "Delete Selected" 4. Restart display: `sudo systemctl restart ledmatrix`
5. Restart display: `sudo systemctl restart ledmatrix`
**Via Command Line:** **Via Command Line:**
```bash
# Clear specific key
redis-cli DEL display_on_demand_config
# Clear all on-demand keys The cache is stored as JSON files under one of:
redis-cli KEYS "display_on_demand_*" | xargs redis-cli DEL
- `/var/cache/ledmatrix/` (preferred when the service has permission)
- `~/.cache/ledmatrix/`
- `/opt/ledmatrix/cache/`
- `/tmp/ledmatrix-cache/` (fallback)
```bash
# Find the cache dir actually in use
journalctl -u ledmatrix | grep -i "cache directory" | tail -1
# Clear all on-demand keys (replace path with the one above)
rm /var/cache/ledmatrix/display_on_demand_*
# Restart service # Restart service
sudo systemctl restart ledmatrix sudo systemctl restart ledmatrix
@@ -711,19 +700,22 @@ sudo systemctl restart ledmatrix
from src.cache_manager import CacheManager from src.cache_manager import CacheManager
cache = CacheManager() cache = CacheManager()
cache.delete('display_on_demand_config') cache.clear_cache('display_on_demand_config')
cache.delete('display_on_demand_state') cache.clear_cache('display_on_demand_state')
cache.delete('display_on_demand_request') cache.clear_cache('display_on_demand_request')
cache.delete('display_on_demand_processed_id') cache.clear_cache('display_on_demand_processed_id')
``` ```
> The actual public method is `clear_cache(key=None)` — there is no
> `delete()` method on `CacheManager`.
### Cache Impact on Running Service ### Cache Impact on Running Service
**IMPORTANT:** Clearing cache keys does NOT immediately affect the running controller in memory. **IMPORTANT:** Clearing cache keys does NOT immediately affect the running controller in memory.
**To fully reset:** **To fully reset:**
1. Stop the service: `sudo systemctl stop ledmatrix` 1. Stop the service: `sudo systemctl stop ledmatrix`
2. Clear cache keys (web UI or redis-cli) 2. Clear cache keys (web UI Cache tab or `rm` from the cache directory)
3. Clear systemd environment: `sudo systemctl daemon-reload` 3. Clear systemd environment: `sudo systemctl daemon-reload`
4. Start the service: `sudo systemctl start ledmatrix` 4. Start the service: `sudo systemctl start ledmatrix`
@@ -767,7 +759,7 @@ Enable background service per plugin in `config/config.json`:
```json ```json
{ {
"nfl_scoreboard": { "football-scoreboard": {
"enabled": true, "enabled": true,
"background_service": { "background_service": {
"enabled": true, "enabled": true,
@@ -801,18 +793,13 @@ Enable background service per plugin in `config/config.json`:
- Returns immediately: < 0.1 seconds - Returns immediately: < 0.1 seconds
- Background refresh (if stale): async, no blocking - Background refresh (if stale): async, no blocking
### Implementation Status ### Plugins using the background service
**Phase 1 (Complete):** The background data service is now used by all of the sports scoreboard
- ✅ NFL scoreboard implemented plugins (football, hockey, baseball, basketball, soccer, lacrosse, F1,
- ✅ Background threading architecture UFC), the odds ticker, and the leaderboard plugin. Each plugin's
- ✅ Cache integration `background_service` block (under its own config namespace) follows the
- ✅ Error handling and retry logic same shape as the example above.
**Phase 2 (Planned):**
- ⏳ NCAAFB (college football)
- ⏳ NBA (basketball)
- ⏳ NHL (hockey)
- ⏳ MLB (baseball) - ⏳ MLB (baseball)
### Error Handling & Fallback ### Error Handling & Fallback

View File

@@ -141,19 +141,27 @@ stage('Checkout') {
--- ---
## Plugin Submodules ## Plugins
Plugin submodules are located in the `plugins/` directory and are managed similarly: Plugins are **not** git submodules of this repository. The plugins
directory (configured by `plugin_system.plugins_directory` in
`config/config.json`, default `plugin-repos/`) is populated at install
time by the plugin loader as users install plugins from the Plugin Store
or from a GitHub URL via the web interface. Plugin source lives in a
separate repository:
[ChuckBuilds/ledmatrix-plugins](https://github.com/ChuckBuilds/ledmatrix-plugins).
**Initialize all plugin submodules:** To work on a plugin locally without going through the Plugin Store, clone
```bash that repo and symlink (or copy) the plugin directory into your configured
git submodule update --init --recursive plugins/ plugins directory — by default `plugin-repos/<plugin-id>/`. The plugin
``` loader will pick it up on the next display restart. The directory name
must match the plugin's `id` in `manifest.json`.
**Initialize a specific plugin:** For more information, see:
```bash
git submodule update --init --recursive plugins/hockey-scoreboard
```
For more information about plugins, see the [Plugin Development Guide](.cursor/plugins_guide.md) and [Plugin Architecture Specification](docs/PLUGIN_ARCHITECTURE_SPEC.md).
- [PLUGIN_DEVELOPMENT_GUIDE.md](PLUGIN_DEVELOPMENT_GUIDE.md) — end-to-end
plugin development workflow
- [PLUGIN_ARCHITECTURE_SPEC.md](PLUGIN_ARCHITECTURE_SPEC.md) — plugin system
specification
- [DEV_PREVIEW.md](DEV_PREVIEW.md) — preview plugins on a desktop without a
Pi

View File

@@ -32,10 +32,15 @@ The LEDMatrix emulator allows you to run and test LEDMatrix displays on your com
### 1. Clone the Repository ### 1. Clone the Repository
```bash ```bash
git clone https://github.com/your-username/LEDMatrix.git git clone --recurse-submodules https://github.com/ChuckBuilds/LEDMatrix.git
cd LEDMatrix cd LEDMatrix
``` ```
> The emulator does **not** require building the
> `rpi-rgb-led-matrix-master` submodule (it uses `RGBMatrixEmulator`
> instead), so `--recurse-submodules` is optional here. Run it anyway if
> you also want to test the real-hardware code path.
### 2. Install Emulator Dependencies ### 2. Install Emulator Dependencies
Install the emulator-specific requirements: Install the emulator-specific requirements:
@@ -58,12 +63,13 @@ pip install -r requirements.txt
### 1. Emulator Configuration File ### 1. Emulator Configuration File
The emulator uses `emulator_config.json` for configuration. Here's the default configuration: The emulator uses `emulator_config.json` for configuration. Here's the
default configuration as it ships in the repo:
```json ```json
{ {
"pixel_outline": 0, "pixel_outline": 0,
"pixel_size": 16, "pixel_size": 5,
"pixel_style": "square", "pixel_style": "square",
"pixel_glow": 6, "pixel_glow": 6,
"display_adapter": "pygame", "display_adapter": "pygame",
@@ -90,7 +96,7 @@ The emulator uses `emulator_config.json` for configuration. Here's the default c
| Option | Description | Default | Values | | Option | Description | Default | Values |
|--------|-------------|---------|--------| |--------|-------------|---------|--------|
| `pixel_outline` | Pixel border thickness | 0 | 0-5 | | `pixel_outline` | Pixel border thickness | 0 | 0-5 |
| `pixel_size` | Size of each pixel | 16 | 8-64 | | `pixel_size` | Size of each pixel | 5 | 1-64 (816 is typical for testing) |
| `pixel_style` | Pixel shape | "square" | "square", "circle" | | `pixel_style` | Pixel shape | "square" | "square", "circle" |
| `pixel_glow` | Glow effect intensity | 6 | 0-20 | | `pixel_glow` | Glow effect intensity | 6 | 0-20 |
| `display_adapter` | Display backend | "pygame" | "pygame", "browser" | | `display_adapter` | Display backend | "pygame" | "pygame", "browser" |

View File

@@ -39,7 +39,7 @@ This guide will help you set up your LEDMatrix display for the first time and ge
**If you see "LEDMatrix-Setup" WiFi network:** **If you see "LEDMatrix-Setup" WiFi network:**
1. Connect your device to "LEDMatrix-Setup" (open network, no password) 1. Connect your device to "LEDMatrix-Setup" (open network, no password)
2. Open browser to: `http://192.168.4.1:5050` 2. Open browser to: `http://192.168.4.1:5000`
3. Navigate to the WiFi tab 3. Navigate to the WiFi tab
4. Click "Scan" to find your WiFi network 4. Click "Scan" to find your WiFi network
5. Select your network, enter password 5. Select your network, enter password
@@ -48,14 +48,14 @@ This guide will help you set up your LEDMatrix display for the first time and ge
**If already connected to WiFi:** **If already connected to WiFi:**
1. Find your Pi's IP address (check your router, or run `hostname -I` on the Pi) 1. Find your Pi's IP address (check your router, or run `hostname -I` on the Pi)
2. Open browser to: `http://your-pi-ip:5050` 2. Open browser to: `http://your-pi-ip:5000`
### 3. Access the Web Interface ### 3. Access the Web Interface
Once connected, access the web interface: Once connected, access the web interface:
``` ```
http://your-pi-ip:5050 http://your-pi-ip:5000
``` ```
You should see: You should see:
@@ -69,84 +69,82 @@ You should see:
### Step 1: Configure Display Hardware ### Step 1: Configure Display Hardware
1. Navigate to Settings → **Display Settings** 1. Open the **Display** tab
2. Set your matrix configuration: 2. Set your matrix configuration:
- **Rows**: 32 or 64 (match your hardware) - **Rows**: 32 or 64 (match your hardware)
- **Columns**: 64, 128, or 256 (match your hardware) - **Columns**: 64 or 96 (match your hardware)
- **Chain Length**: Number of panels chained together - **Chain Length**: Number of panels chained horizontally
- **Brightness**: 50-75% recommended for indoor use - **Hardware Mapping**: usually `adafruit-hat-pwm` (with the PWM jumper
3. Click **Save Configuration** mod) or `adafruit-hat` (without). See the root README for the full list.
4. Click **Restart Display** to apply changes - **Brightness**: 7090 is fine for indoor use
3. Click **Save**
4. From the **Overview** tab, click **Restart Display Service** to apply
**Tip:** If the display doesn't look right, try different hardware mapping options. **Tip:** if the display shows garbage or nothing, the most common culprits
are an incorrect `hardware_mapping`, a `gpio_slowdown` value that doesn't
match your Pi model, or panels needing the E-line mod. See
[TROUBLESHOOTING.md](TROUBLESHOOTING.md).
### Step 2: Set Timezone and Location ### Step 2: Set Timezone and Location
1. Navigate to Settings → **General Settings** 1. Open the **General** tab
2. Set your timezone (e.g., "America/New_York") 2. Set your timezone (e.g., `America/New_York`) and location
3. Set your location (city, state, country) 3. Click **Save**
4. Click **Save Configuration**
**Why it matters:** Correct timezone ensures accurate time display. Location enables weather and location-based features. Correct timezone ensures accurate time display, and location is used by
weather and other location-aware plugins.
### Step 3: Install Plugins ### Step 3: Install Plugins
1. Navigate to **Plugin Store** tab 1. Open the **Plugin Manager** tab
2. Browse available plugins: 2. Scroll to the **Plugin Store** section to browse available plugins
- **Time & Date**: Clock, calendar 3. Click **Install** on the plugins you want
- **Weather**: Weather forecasts 4. Wait for installation to finish — installed plugins appear in the
- **Sports**: NHL, NBA, NFL, MLB scores **Installed Plugins** section above and get their own tab in the second
- **Finance**: Stocks, crypto nav row
- **Custom**: Community plugins 5. Toggle the plugin to enabled
3. Click **Install** on desired plugins 6. From **Overview**, click **Restart Display Service**
4. Wait for installation to complete
5. Navigate to **Plugin Management** tab
6. Enable installed plugins (toggle switch)
7. Click **Restart Display**
**Popular First Plugins:** You can also install community plugins straight from a GitHub URL using the
- `clock-simple` - Simple digital clock **Install from GitHub** section further down the same tab — see
- `weather` - Weather forecast [PLUGIN_STORE_GUIDE.md](PLUGIN_STORE_GUIDE.md) for details.
- `nhl-scores` - NHL scores (if you're a hockey fan)
### Step 4: Configure Plugins ### Step 4: Configure Plugins
1. Navigate to **Plugin Management** tab 1. Each installed plugin gets its own tab in the second navigation row
2. Find a plugin you installed 2. Open that plugin's tab to edit its settings (favorite teams, API keys,
3. Click the ⚙️ **Configure** button update intervals, display duration, etc.)
4. Edit settings (e.g., favorite teams, update intervals) 3. Click **Save**
5. Click **Save** 4. Restart the display service from **Overview** so the new settings take
6. Click **Restart Display** effect
**Example: Weather Plugin** **Example: Weather Plugin**
- Set your location (city, state, country) - Set your location (city, state, country)
- Add API key from OpenWeatherMap (free signup) - Add an API key from OpenWeatherMap (free signup) to
- Set update interval (300 seconds recommended) `config/config_secrets.json` or directly in the plugin's config screen
- Set the update interval (300 seconds is reasonable)
--- ---
## Testing Your Display ## Testing Your Display
### Quick Test ### Run a single plugin on demand
1. Navigate to **Overview** tab The fastest way to verify a plugin works without waiting for the rotation:
2. Click **Test Display** button
3. You should see a test pattern on your LED matrix
### Manual Plugin Trigger 1. Open the plugin's tab (second nav row)
2. Scroll to **On-Demand Controls**
3. Click **Run On-Demand** — the plugin runs immediately even if disabled
4. Click **Stop On-Demand** to return to the normal rotation
1. Navigate to **Plugin Management** tab ### Check the live preview and logs
2. Find a plugin
3. Click **Show Now** button
4. The plugin should display immediately
5. Click **Stop** to return to rotation
### Check Logs - The **Overview** tab shows a **Live Display Preview** that mirrors what's
on the matrix in real time — handy for debugging without looking at the
1. Navigate to **Logs** tab panel.
2. Watch real-time logs - The **Logs** tab streams the display and web service logs. Look for
3. Look for any ERROR messages `ERROR` lines if something isn't working; normal operation just shows
4. Normal operation shows INFO messages about plugin rotation `INFO` messages about plugin rotation.
--- ---
@@ -156,12 +154,12 @@ You should see:
**Check:** **Check:**
1. Power supply connected and adequate (5V, 4A minimum) 1. Power supply connected and adequate (5V, 4A minimum)
2. LED matrix connected to GPIO pins correctly 2. LED matrix connected to the bonnet/HAT correctly
3. Display service running: `sudo systemctl status ledmatrix` 3. Display service running: `sudo systemctl status ledmatrix`
4. Hardware configuration matches your matrix (rows/columns) 4. Hardware configuration matches your matrix (rows/cols/chain length)
**Fix:** **Fix:**
1. Restart display: Settings → Overview → Restart Display 1. Restart from the **Overview** tab → **Restart Display Service**
2. Or via SSH: `sudo systemctl restart ledmatrix` 2. Or via SSH: `sudo systemctl restart ledmatrix`
### Web Interface Won't Load ### Web Interface Won't Load
@@ -169,8 +167,8 @@ You should see:
**Check:** **Check:**
1. Pi is connected to network: `ping your-pi-ip` 1. Pi is connected to network: `ping your-pi-ip`
2. Web service running: `sudo systemctl status ledmatrix-web` 2. Web service running: `sudo systemctl status ledmatrix-web`
3. Correct port: Use `:5050` not `:5000` 3. Correct port: the web UI listens on `:5000`
4. Firewall not blocking port 5050 4. Firewall not blocking port 5000
**Fix:** **Fix:**
1. Restart web service: `sudo systemctl restart ledmatrix-web` 1. Restart web service: `sudo systemctl restart ledmatrix-web`
@@ -179,15 +177,15 @@ You should see:
### Plugins Not Showing ### Plugins Not Showing
**Check:** **Check:**
1. Plugins are enabled (toggle switch in Plugin Management) 1. Plugin is enabled (toggle on the **Plugin Manager** tab)
2. Display has been restarted after enabling 2. Display service was restarted after enabling
3. Plugin duration is reasonable (not too short) 3. Plugin's display duration is non-zero
4. No errors in logs for the plugin 4. No errors in the **Logs** tab for that plugin
**Fix:** **Fix:**
1. Enable plugin in Plugin Management 1. Enable the plugin from **Plugin Manager**
2. Restart display 2. Click **Restart Display Service** on **Overview**
3. Check logs for plugin-specific errors 3. Check the **Logs** tab for plugin-specific errors
### Weather Plugin Shows "No Data" ### Weather Plugin Shows "No Data"
@@ -207,18 +205,18 @@ You should see:
### Customize Your Display ### Customize Your Display
**Adjust Display Durations:** **Adjust display durations:**
- Navigate to Settings → Durations - Each plugin's tab has a **Display Duration (seconds)** field — set how
- Set how long each plugin displays long that plugin stays on screen each rotation.
- Save and restart
**Organize Plugin Order:** **Organize plugin order:**
- Use Plugin Management to enable/disable plugins - Use the **Plugin Manager** tab to enable/disable plugins. The display
- Display cycles through enabled plugins in order cycles through enabled plugins in the order they appear.
**Add More Plugins:** **Add more plugins:**
- Check Plugin Store regularly for new plugins - Check the **Plugin Store** section of **Plugin Manager** for new plugins.
- Install from GitHub URLs for custom/community plugins - Install community plugins straight from a GitHub URL via
**Install from GitHub** on the same tab.
### Enable Advanced Features ### Enable Advanced Features
@@ -279,26 +277,35 @@ sudo journalctl -u ledmatrix-web -f
│ ├── config.json # Main configuration │ ├── config.json # Main configuration
│ ├── config_secrets.json # API keys and secrets │ ├── config_secrets.json # API keys and secrets
│ └── wifi_config.json # WiFi settings │ └── wifi_config.json # WiFi settings
├── plugins/ # Installed plugins ├── plugin-repos/ # Installed plugins (default location)
├── cache/ # Cached data ├── cache/ # Cached data
└── web_interface/ # Web interface files └── web_interface/ # Web interface files
``` ```
> The plugin install location is configurable via
> `plugin_system.plugins_directory` in `config.json`. The default is
> `plugin-repos/`; the loader also searches `plugins/` as a fallback.
### Web Interface ### Web Interface
``` ```
Main Interface: http://your-pi-ip:5050 Main Interface: http://your-pi-ip:5000
Tabs: System tabs:
- Overview: System stats and quick actions - Overview System stats, live preview, quick actions
- General Settings: Timezone, location, autostart - General Timezone, location, plugin-system settings
- Display Settings: Hardware configuration - WiFi Network selection and AP-mode setup
- Durations: Plugin display times - Schedule Power and dim schedules
- Sports Configuration: Per-league settings - Display Matrix hardware configuration
- Plugin Management: Enable/disable, configure - Config Editor Raw config.json editor
- Plugin Store: Install new plugins - Fonts Upload and manage fonts
- Font Management: Upload and manage fonts - Logs Real-time log viewing
- Logs: Real-time log viewing - Cache Cached data inspection and cleanup
- Operation History Recent service operations
Plugin tabs (second row):
- Plugin Manager Browse the Plugin Store, install/enable plugins
- <plugin-id> One tab per installed plugin for its config
``` ```
### WiFi Access Point ### WiFi Access Point
@@ -306,7 +313,7 @@ Tabs:
``` ```
Network Name: LEDMatrix-Setup Network Name: LEDMatrix-Setup
Password: (none - open network) Password: (none - open network)
URL when connected: http://192.168.4.1:5050 URL when connected: http://192.168.4.1:5000
``` ```
--- ---

View File

@@ -13,7 +13,7 @@ Make sure you have the testing packages installed:
pip install -r requirements.txt pip install -r requirements.txt
# Or install just the test dependencies # Or install just the test dependencies
pip install pytest pytest-cov pytest-mock pytest-timeout pip install pytest pytest-cov pytest-mock
``` ```
### 2. Set Environment Variables ### 2. Set Environment Variables
@@ -85,8 +85,14 @@ pytest -m slow
# Run all tests in the test directory # Run all tests in the test directory
pytest test/ pytest test/
# Run all integration tests # Run plugin tests only
pytest test/integration/ pytest test/plugins/
# Run web interface tests only
pytest test/web_interface/
# Run web interface integration tests
pytest test/web_interface/integration/
``` ```
## Understanding Test Output ## Understanding Test Output
@@ -231,20 +237,41 @@ pytest --maxfail=3
``` ```
test/ test/
├── conftest.py # Shared fixtures and configuration ├── conftest.py # Shared fixtures and configuration
├── test_display_controller.py # Display controller tests ├── test_display_controller.py # Display controller tests
├── test_plugin_system.py # Plugin system tests ├── test_display_manager.py # Display manager tests
├── test_display_manager.py # Display manager tests ├── test_plugin_system.py # Plugin system tests
├── test_config_service.py # Config service tests ├── test_plugin_loader.py # Plugin discovery/loading tests
├── test_cache_manager.py # Cache manager tests ├── test_plugin_loading_failures.py # Plugin failure-mode tests
├── test_font_manager.py # Font manager tests ├── test_cache_manager.py # Cache manager tests
├── test_error_handling.py # Error handling tests ├── test_config_manager.py # Config manager tests
├── test_config_manager.py # Config manager tests ├── test_config_service.py # Config service tests
├── integration/ # Integration tests ├── test_config_validation_edge_cases.py # Config edge cases
├── test_e2e.py # End-to-end tests ├── test_font_manager.py # Font manager tests
│ └── test_plugin_integration.py # Plugin integration tests ── test_layout_manager.py # Layout manager tests
├── test_error_scenarios.py # Error scenario tests ├── test_text_helper.py # Text helper tests
── test_edge_cases.py # Edge case tests ── test_error_handling.py # Error handling tests
├── test_error_aggregator.py # Error aggregation tests
├── test_schema_manager.py # Schema manager tests
├── test_web_api.py # Web API tests
├── test_nba_*.py # NBA-specific test suites
├── plugins/ # Per-plugin test suites
│ ├── test_clock_simple.py
│ ├── test_calendar.py
│ ├── test_basketball_scoreboard.py
│ ├── test_soccer_scoreboard.py
│ ├── test_odds_ticker.py
│ ├── test_text_display.py
│ ├── test_visual_rendering.py
│ └── test_plugin_base.py
└── web_interface/
├── test_config_manager_atomic.py
├── test_state_reconciliation.py
├── test_plugin_operation_queue.py
├── test_dedup_unique_arrays.py
└── integration/ # Web interface integration tests
├── test_config_flows.py
└── test_plugin_operations.py
``` ```
### Test Categories ### Test Categories

View File

@@ -114,6 +114,95 @@ Get display duration for this plugin. Can be overridden for dynamic durations.
Return plugin info for display in web UI. Override to provide additional state information. Return plugin info for display in web UI. Override to provide additional state information.
### Dynamic-duration hooks
Plugins that render multi-step content (e.g. cycling through several games)
can extend their display time until they've shown everything. To opt in,
either set `dynamic_duration.enabled: true` in the plugin's config or
override `supports_dynamic_duration()`.
#### `supports_dynamic_duration() -> bool`
Return `True` if this plugin should use dynamic durations. Default reads
`config["dynamic_duration"]["enabled"]`.
#### `get_dynamic_duration_cap() -> Optional[float]`
Maximum number of seconds the controller will keep this plugin on screen
in dynamic mode. Default reads
`config["dynamic_duration"]["max_duration_seconds"]`.
#### `is_cycle_complete() -> bool`
Override this to return `True` only after the plugin has rendered all of
its content for the current rotation. Default returns `True` immediately,
which means a single `display()` call counts as a full cycle.
#### `reset_cycle_state() -> None`
Called by the controller before each new dynamic-duration session. Reset
internal counters/iterators here.
### Live priority hooks
Live priority lets a plugin temporarily take over the rotation when it has
urgent content (live games, breaking news). Enable by setting
`live_priority: true` in the plugin's config and overriding
`has_live_content()`.
#### `has_live_priority() -> bool`
Whether live priority is enabled in config (default reads
`config["live_priority"]`).
#### `has_live_content() -> bool`
Override to return `True` when the plugin currently has urgent content.
Default returns `False`.
#### `get_live_modes() -> List[str]`
List of display modes to show during a live takeover. Default returns the
plugin's `display_modes` from its manifest.
### Vegas scroll hooks
Vegas mode shows multiple plugins as a single continuous scroll instead of
rotating one at a time. Plugins control how their content appears via
these hooks. See [ADVANCED_FEATURES.md](ADVANCED_FEATURES.md) for the user
side of Vegas mode.
#### `get_vegas_content() -> Optional[PIL.Image | List[PIL.Image] | None]`
Return content to inject into the scroll. Multi-item plugins (sports,
odds, news) should return a *list* of PIL Images so each item scrolls
independently. Static plugins (clock, weather) can return a single image.
Returning `None` falls back to capturing whatever `display()` produces.
#### `get_vegas_content_type() -> str`
`'multi'`, `'static'`, or `'none'`. Affects how Vegas mode treats the
plugin. Default `'static'`.
#### `get_vegas_display_mode() -> VegasDisplayMode`
Returns one of `VegasDisplayMode.SCROLL`, `FIXED_SEGMENT`, or `STATIC`.
Read from `config["vegas_mode"]` or override directly.
#### `get_supported_vegas_modes() -> List[VegasDisplayMode]`
The set of Vegas modes this plugin can render. Used by the UI to populate
the mode selector for this plugin.
#### `get_vegas_segment_width() -> Optional[int]`
For `FIXED_SEGMENT` plugins, the width in pixels of the segment they
occupy in the scroll. `None` lets the controller pick a default.
> The full source for `BasePlugin` lives in
> `src/plugin_system/base_plugin.py`. If a method here disagrees with the
> source, the source wins — please open an issue or PR to fix the doc.
--- ---
## Display Manager ## Display Manager
@@ -228,23 +317,31 @@ date_str = self.display_manager.format_date_with_ordinal(datetime.now())
### Image Rendering ### Image Rendering
#### `draw_image(image: PIL.Image, x: int, y: int) -> None` The display manager doesn't provide a dedicated `draw_image()` method.
Instead, plugins paste directly onto the underlying PIL Image
(`display_manager.image`), then call `update_display()` to push the buffer
to the matrix.
Draw a PIL Image object on the canvas.
**Parameters**:
- `image`: PIL Image object
- `x` (int): X position (left edge)
- `y` (int): Y position (top edge)
**Example**:
```python ```python
from PIL import Image from PIL import Image
logo = Image.open("assets/logo.png")
self.display_manager.draw_image(logo, x=10, y=10) logo = Image.open("assets/logo.png").convert("RGB")
self.display_manager.image.paste(logo, (10, 10))
self.display_manager.update_display() self.display_manager.update_display()
``` ```
For transparency support, paste using a mask:
```python
icon = Image.open("assets/icon.png").convert("RGBA")
self.display_manager.image.paste(icon, (5, 5), icon)
self.display_manager.update_display()
```
This is the same pattern the bundled scoreboard base classes
(`src/base_classes/baseball.py`, `basketball.py`, `football.py`,
`hockey.py`) use, so it's the canonical way to render arbitrary images.
### Weather Icons ### Weather Icons
#### `draw_weather_icon(condition: str, x: int, y: int, size: int = 16) -> None` #### `draw_weather_icon(condition: str, x: int, y: int, size: int = 16) -> None`
@@ -440,12 +537,23 @@ self.cache_manager.set("weather_data", {
}) })
``` ```
#### `delete(key: str) -> None` #### `clear_cache(key: Optional[str] = None) -> None`
Remove a specific cache entry. Remove a specific cache entry, or all cache entries when called without
arguments.
**Parameters**: **Parameters**:
- `key` (str): Cache key to delete - `key` (str, optional): Cache key to delete. If omitted, every cached
entry (memory + disk) is cleared.
**Example**:
```python
# Drop one stale entry
self.cache_manager.clear_cache("weather_data")
# Nuke everything (rare — typically only used by maintenance tooling)
self.cache_manager.clear_cache()
```
### Advanced Methods ### Advanced Methods

View File

@@ -29,10 +29,14 @@ Each installed plugin now gets its own dedicated configuration tab in the web in
3. Click **Save Configuration** 3. Click **Save Configuration**
4. Restart the display service to apply changes 4. Restart the display service to apply changes
### Plugin Management vs Configuration ### Plugin Manager vs Per-Plugin Configuration
- **Plugins Tab**: Used for plugin management (install, enable/disable, update, uninstall) - **Plugin Manager tab** (second nav row): used for browsing the
- **Plugin-Specific Tabs**: Used for configuring plugin behavior and settings Plugin Store, installing plugins, toggling installed plugins on/off,
and updating/uninstalling them
- **Per-plugin tabs** (one per installed plugin, also in the second
nav row): used for configuring that specific plugin's behavior and
settings via a form auto-generated from its `config_schema.json`
## For Plugin Developers ## For Plugin Developers

View File

@@ -4,13 +4,14 @@
### For Users ### For Users
1. Open the web interface: `http://your-pi-ip:5001` 1. Open the web interface: `http://your-pi-ip:5000`
2. Go to the **Plugin Store** tab 2. Open the **Plugin Manager** tab
3. Install a plugin (e.g., "Hello World") 3. Find a plugin in the **Plugin Store** section (e.g., "Hello World")
4. Notice a new tab appears with the plugin's name and click **Install**
5. Click on the plugin's tab to configure it 4. Notice a new tab appears in the second nav row with the plugin's name
6. Modify settings and click **Save Configuration** 5. Click that tab to configure the plugin
7. Restart the display to see changes 6. Modify settings and click **Save**
7. From **Overview**, click **Restart Display Service** to see changes
That's it! Each installed plugin automatically gets its own configuration tab. That's it! Each installed plugin automatically gets its own configuration tab.
@@ -171,9 +172,11 @@ User enters: `255, 0, 0`
### For Users ### For Users
1. **Reset Anytime**: Use "Reset to Defaults" to restore original settings 1. **Reset Anytime**: Use "Reset to Defaults" to restore original settings
2. **Navigate Back**: Click "Back to Plugin Management" to return to Plugins tab 2. **Navigate Back**: Switch to the **Plugin Manager** tab to see the
full list of installed plugins
3. **Check Help Text**: Each field has a description explaining what it does 3. **Check Help Text**: Each field has a description explaining what it does
4. **Restart Required**: Remember to restart the display after saving 4. **Restart Required**: Remember to restart the display service from
**Overview** after saving
### For Developers ### For Developers
@@ -206,8 +209,10 @@ User enters: `255, 0, 0`
## 📚 Next Steps ## 📚 Next Steps
- Read the full documentation: [PLUGIN_CONFIGURATION_TABS.md](PLUGIN_CONFIGURATION_TABS.md) - Read the full documentation: [PLUGIN_CONFIGURATION_TABS.md](PLUGIN_CONFIGURATION_TABS.md)
- Check implementation details: [PLUGIN_CONFIG_TABS_SUMMARY.md](PLUGIN_CONFIG_TABS_SUMMARY.md) - Check the configuration architecture: [PLUGIN_CONFIG_ARCHITECTURE.md](PLUGIN_CONFIG_ARCHITECTURE.md)
- Browse example plugins: `plugins/hello-world/`, `plugins/clock-simple/` - Browse example plugins in the
[ledmatrix-plugins](https://github.com/ChuckBuilds/ledmatrix-plugins)
repo, especially `plugins/hello-world/` and `plugins/clock-simple/`
- Join the community for help and suggestions - Join the community for help and suggestions
## 🎉 That's It! ## 🎉 That's It!

View File

@@ -37,7 +37,7 @@ sudo systemctl start ledmatrix-web
### ✅ Scenario 2: Web Interface Plugin Installation ### ✅ Scenario 2: Web Interface Plugin Installation
**What:** Installing/enabling plugins via web interface at `http://pi-ip:5001` **What:** Installing/enabling plugins via web interface at `http://pi-ip:5000`
- **Web service runs as:** root (ledmatrix-web.service) - **Web service runs as:** root (ledmatrix-web.service)
- **Installs to:** System-wide - **Installs to:** System-wide

View File

@@ -77,10 +77,12 @@ sudo chmod -R 755 /root/.cache
The web interface handles dependency installation correctly in the service context: The web interface handles dependency installation correctly in the service context:
1. Access the web interface (usually http://ledpi:8080) 1. Access the web interface (`http://ledpi:5000` or `http://your-pi-ip:5000`)
2. Navigate to Plugin Store or Plugin Management 2. Open the **Plugin Manager** tab (use the **Plugin Store** section to
3. Install plugins through the web UI find the plugin, or **Install from GitHub**)
4. The system will automatically handle dependencies 3. Install the plugin through the web UI
4. The system automatically handles dependency installation in the
service context (which has the right permissions)
## Prevention ## Prevention

View File

@@ -466,7 +466,9 @@ When developing plugins, you'll need to use the APIs provided by the LEDMatrix s
**Display Manager** (`self.display_manager`): **Display Manager** (`self.display_manager`):
- `clear()`, `update_display()` - Core display operations - `clear()`, `update_display()` - Core display operations
- `draw_text()`, `draw_image()` - Rendering methods - `draw_text()` - Text rendering. For images, paste directly onto
`display_manager.image` (a PIL Image) and call `update_display()`;
there is no `draw_image()` helper method.
- `draw_weather_icon()`, `draw_sun()`, `draw_cloud()` - Weather icons - `draw_weather_icon()`, `draw_sun()`, `draw_cloud()` - Weather icons
- `get_text_width()`, `get_font_height()` - Text utilities - `get_text_width()`, `get_font_height()` - Text utilities
- `set_scrolling_state()`, `defer_update()` - Scrolling state management - `set_scrolling_state()`, `defer_update()` - Scrolling state management

View File

@@ -2,14 +2,20 @@
## Overview ## Overview
Transform LEDMatrix into a modular, plugin-based system where users can create, share, and install custom displays via a GitHub-based store (similar to HACS for Home Assistant). LEDMatrix is a modular, plugin-based system where users create, share,
and install custom displays via a GitHub-based store (similar in spirit
to HACS for Home Assistant). This page is a quick reference; for the
full design see [PLUGIN_ARCHITECTURE_SPEC.md](PLUGIN_ARCHITECTURE_SPEC.md)
and [PLUGIN_DEVELOPMENT_GUIDE.md](PLUGIN_DEVELOPMENT_GUIDE.md).
## Key Decisions ## Key Decisions
**Gradual Migration**: Existing managers stay, plugins added alongside **Plugin-First**: All display features (calendar excepted) are now plugins
**Migration Required**: Breaking changes in v3.0, tools provided **GitHub Store**: Discovery from `ledmatrix-plugins` registry plus
**GitHub Store**: Simple discovery, packages from repos any GitHub URL
**Plugin Location**: `./plugins/` directory **Plugin Location**: configured by `plugin_system.plugins_directory`
in `config.json` (default `plugin-repos/`; the loader also searches
`plugins/` as a fallback)
## File Structure ## File Structure
@@ -19,15 +25,16 @@ LEDMatrix/
│ └── plugin_system/ │ └── plugin_system/
│ ├── base_plugin.py # Plugin interface │ ├── base_plugin.py # Plugin interface
│ ├── plugin_manager.py # Load/unload plugins │ ├── plugin_manager.py # Load/unload plugins
│ ├── plugin_loader.py # Discovery + dynamic import
│ └── store_manager.py # Install from GitHub │ └── store_manager.py # Install from GitHub
├── plugins/ ├── plugin-repos/ # Default plugin install location
│ ├── clock-simple/ │ ├── clock-simple/
│ │ ├── manifest.json # Metadata │ │ ├── manifest.json # Metadata
│ │ ├── manager.py # Main plugin class │ │ ├── manager.py # Main plugin class
│ │ ├── requirements.txt # Dependencies │ │ ├── requirements.txt # Dependencies
│ │ ├── config_schema.json # Validation │ │ ├── config_schema.json # Validation
│ │ └── README.md │ │ └── README.md
│ └── nhl-scores/ │ └── hockey-scoreboard/
│ └── ... (same structure) │ └── ... (same structure)
└── config/config.json # Plugin configs └── config/config.json # Plugin configs
``` ```
@@ -109,100 +116,45 @@ git push origin v1.0.0
### Web UI ### Web UI
1. **Browse Store**: Plugin Store tab → Search/filter 1. **Browse Store**: Plugin Manager tab → Plugin Store section → Search/filter
2. **Install**: Click "Install" button 2. **Install**: Click **Install** in the plugin's row
3. **Configure**: Plugin Manager → Click ⚙️ Configure 3. **Configure**: open the plugin's tab in the second nav row
4. **Enable/Disable**: Toggle switch 4. **Enable/Disable**: toggle switch in the **Installed Plugins** list
5. **Reorder**: Drag and drop in rotation list 5. **Reorder**: order is set by the position in `display_modes` /
plugin order; rearranging via drag-and-drop is not yet supported
### API ### REST API
```python The API is mounted at `/api/v3` (`web_interface/app.py:144`).
# Install plugin
POST /api/plugins/install
{"plugin_id": "my-plugin"}
# Install from custom URL
POST /api/plugins/install-from-url
{"repo_url": "https://github.com/User/plugin"}
# List installed
GET /api/plugins/installed
# Toggle
POST /api/plugins/toggle
{"plugin_id": "my-plugin", "enabled": true}
```
### Command Line
```python
from src.plugin_system.store_manager import PluginStoreManager
store = PluginStoreManager()
# Install
store.install_plugin('nhl-scores')
# Install from URL
store.install_from_url('https://github.com/User/plugin')
# Update
store.update_plugin('nhl-scores')
# Uninstall
store.uninstall_plugin('nhl-scores')
```
## Migration Path
### Phase 1: v2.0.0 (Plugin Infrastructure)
- Plugin system alongside existing managers
- 100% backward compatible
- Web UI shows plugin store
### Phase 2: v2.1.0 (Example Plugins)
- Reference plugins created
- Migration examples
- Developer docs
### Phase 3: v2.2.0 (Migration Tools)
- Auto-migration script
- Config converter
- Testing tools
### Phase 4: v2.5.0 (Deprecation)
- Warnings on legacy managers
- Migration guide
- 95% backward compatible
### Phase 5: v3.0.0 (Plugin-Only)
- Legacy managers removed from core
- Packaged as official plugins
- **Breaking change - migration required**
## Quick Migration
```bash ```bash
# 1. Backup # Install plugin from the registry
cp config/config.json config/config.json.backup curl -X POST http://your-pi-ip:5000/api/v3/plugins/install \
-H "Content-Type: application/json" \
-d '{"plugin_id": "hockey-scoreboard"}'
# 2. Run migration # Install from custom URL
python3 scripts/migrate_to_plugins.py curl -X POST http://your-pi-ip:5000/api/v3/plugins/install-from-url \
-H "Content-Type: application/json" \
-d '{"repo_url": "https://github.com/User/plugin"}'
# 3. Review # List installed
cat config/config.json.migrated curl http://your-pi-ip:5000/api/v3/plugins/installed
# 4. Apply # Toggle
mv config/config.json.migrated config/config.json curl -X POST http://your-pi-ip:5000/api/v3/plugins/toggle \
-H "Content-Type: application/json" \
# 5. Restart -d '{"plugin_id": "hockey-scoreboard", "enabled": true}'
sudo systemctl restart ledmatrix
``` ```
See [REST_API_REFERENCE.md](REST_API_REFERENCE.md) for the full list.
## Plugin Registry Structure ## Plugin Registry Structure
**ChuckBuilds/ledmatrix-plugin-registry/plugins.json**: The official registry lives at
[`ChuckBuilds/ledmatrix-plugins`](https://github.com/ChuckBuilds/ledmatrix-plugins).
The Plugin Store reads `plugins.json` at the root of that repo, which
follows this shape:
```json ```json
{ {
"plugins": [ "plugins": [
@@ -245,42 +197,30 @@ sudo systemctl restart ledmatrix
- ✅ Community handles custom displays - ✅ Community handles custom displays
- ✅ Easier to review changes - ✅ Easier to review changes
## What's Missing? ## Known Limitations
This specification covers the technical architecture. Additional considerations: The plugin system is shipped and stable, but some things are still
intentionally simple:
1. **Sandboxing**: Current design has no isolation (future enhancement) 1. **Sandboxing**: plugins run in the same process as the display loop;
2. **Resource Limits**: No CPU/memory limits per plugin (future) there is no isolation. Review code before installing third-party
3. **Plugin Ratings**: Registry needs rating/review system plugins.
4. **Auto-Updates**: Manual update only (could add auto-update) 2. **Resource limits**: there's a resource monitor that warns about
5. **Dependency Conflicts**: No automatic resolution slow plugins, but no hard CPU/memory caps.
6. **Version Pinning**: Limited version constraint checking 3. **Plugin ratings**: not yet — the Plugin Store shows version,
7. **Plugin Testing**: No automated testing framework author, and category but no community rating system.
8. **Marketplace**: No paid plugins (all free/open source) 4. **Auto-updates**: manual via the Plugin Manager tab; no automatic
background updates.
## Next Steps 5. **Dependency conflicts**: each plugin's `requirements.txt` is
installed via pip; conflicting versions across plugins are not
1. ✅ Review this specification resolved automatically.
2. Start Phase 1 implementation 6. **Plugin testing framework**: see
3. Create first 3-4 example plugins [HOW_TO_RUN_TESTS.md](HOW_TO_RUN_TESTS.md) and
4. Set up plugin registry repo [DEV_PREVIEW.md](DEV_PREVIEW.md) — there are tools, but no
5. Build web UI components mandatory test gate.
6. Test on Pi hardware
7. Release v2.0.0 alpha
## Questions to Resolve
Before implementing, consider:
1. Should we support plugin dependencies (plugin A requires plugin B)?
2. How to handle breaking changes in core display_manager API?
3. Should plugins be able to add new web UI pages?
4. What about plugins that need hardware beyond LED matrix?
5. How to prevent malicious plugins?
6. Should there be plugin quotas (max API calls, etc.)?
7. How to handle plugin conflicts (two clocks competing)?
--- ---
**See PLUGIN_ARCHITECTURE_SPEC.md for full details** **See [PLUGIN_ARCHITECTURE_SPEC.md](PLUGIN_ARCHITECTURE_SPEC.md) for the
full architectural specification.**

View File

@@ -95,14 +95,14 @@ Official plugin registry for [LEDMatrix](https://github.com/ChuckBuilds/LEDMatri
All plugins can be installed through the LEDMatrix web interface: All plugins can be installed through the LEDMatrix web interface:
1. Open web interface (http://your-pi-ip:5050) 1. Open web interface (http://your-pi-ip:5000)
2. Go to Plugin Store tab 2. Open the **Plugin Manager** tab
3. Browse or search for plugins 3. Browse or search the **Plugin Store** section
4. Click Install 4. Click **Install**
Or via API: Or via API:
```bash ```bash
curl -X POST http://your-pi-ip:5050/api/plugins/install \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/install \
-d '{"plugin_id": "clock-simple"}' -d '{"plugin_id": "clock-simple"}'
``` ```
@@ -152,7 +152,7 @@ Before submitting, ensure your plugin:
1. **Test Your Plugin** 1. **Test Your Plugin**
```bash ```bash
# Install via URL on your Pi # Install via URL on your Pi
curl -X POST http://your-pi:5050/api/plugins/install-from-url \ curl -X POST http://your-pi:5000/api/v3/plugins/install-from-url \
-d '{"repo_url": "https://github.com/you/ledmatrix-your-plugin"}' -d '{"repo_url": "https://github.com/you/ledmatrix-your-plugin"}'
``` ```
@@ -311,7 +311,7 @@ git push
# 1. Receive PR on ledmatrix-plugins repo # 1. Receive PR on ledmatrix-plugins repo
# 2. Review using VERIFICATION.md checklist # 2. Review using VERIFICATION.md checklist
# 3. Test installation: # 3. Test installation:
curl -X POST http://pi:5050/api/plugins/install-from-url \ curl -X POST http://pi:5000/api/v3/plugins/install-from-url \
-d '{"repo_url": "https://github.com/contributor/plugin"}' -d '{"repo_url": "https://github.com/contributor/plugin"}'
# 4. If approved, merge PR # 4. If approved, merge PR

View File

@@ -12,7 +12,7 @@ The LEDMatrix Plugin Store allows you to discover, install, and manage display p
```bash ```bash
# Web UI: Plugin Store → Search → Click Install # Web UI: Plugin Store → Search → Click Install
# API: # API:
curl -X POST http://your-pi-ip:5050/api/plugins/install \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/install \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "clock-simple"}' -d '{"plugin_id": "clock-simple"}'
``` ```
@@ -21,7 +21,7 @@ curl -X POST http://your-pi-ip:5050/api/plugins/install \
```bash ```bash
# Web UI: Plugin Store → "Install from URL" → Paste URL # Web UI: Plugin Store → "Install from URL" → Paste URL
# API: # API:
curl -X POST http://your-pi-ip:5050/api/plugins/install-from-url \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/install-from-url \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"repo_url": "https://github.com/user/ledmatrix-plugin"}' -d '{"repo_url": "https://github.com/user/ledmatrix-plugin"}'
``` ```
@@ -29,20 +29,20 @@ curl -X POST http://your-pi-ip:5050/api/plugins/install-from-url \
### Manage Plugins ### Manage Plugins
```bash ```bash
# List installed # List installed
curl "http://your-pi-ip:5050/api/plugins/installed" curl "http://your-pi-ip:5000/api/v3/plugins/installed"
# Enable/disable # Enable/disable
curl -X POST http://your-pi-ip:5050/api/plugins/toggle \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/toggle \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "clock-simple", "enabled": true}' -d '{"plugin_id": "clock-simple", "enabled": true}'
# Update # Update
curl -X POST http://your-pi-ip:5050/api/plugins/update \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/update \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "clock-simple"}' -d '{"plugin_id": "clock-simple"}'
# Uninstall # Uninstall
curl -X POST http://your-pi-ip:5050/api/plugins/uninstall \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/uninstall \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "clock-simple"}' -d '{"plugin_id": "clock-simple"}'
``` ```
@@ -56,7 +56,7 @@ curl -X POST http://your-pi-ip:5050/api/plugins/uninstall \
The official plugin store contains curated, verified plugins that have been reviewed by maintainers. The official plugin store contains curated, verified plugins that have been reviewed by maintainers.
**Via Web Interface:** **Via Web Interface:**
1. Open the web interface at http://your-pi-ip:5050 1. Open the web interface at http://your-pi-ip:5000
2. Navigate to the "Plugin Store" tab 2. Navigate to the "Plugin Store" tab
3. Browse or search for plugins 3. Browse or search for plugins
4. Click "Install" on the desired plugin 4. Click "Install" on the desired plugin
@@ -65,7 +65,7 @@ The official plugin store contains curated, verified plugins that have been revi
**Via REST API:** **Via REST API:**
```bash ```bash
curl -X POST http://your-pi-ip:5050/api/plugins/install \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/install \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "clock-simple"}' -d '{"plugin_id": "clock-simple"}'
``` ```
@@ -101,7 +101,7 @@ Install any plugin directly from a GitHub repository, even if it's not in the of
**Via REST API:** **Via REST API:**
```bash ```bash
curl -X POST http://your-pi-ip:5050/api/plugins/install-from-url \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/install-from-url \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"repo_url": "https://github.com/user/ledmatrix-my-plugin"}' -d '{"repo_url": "https://github.com/user/ledmatrix-my-plugin"}'
``` ```
@@ -131,13 +131,13 @@ else:
**Via REST API:** **Via REST API:**
```bash ```bash
# Search by query # Search by query
curl "http://your-pi-ip:5050/api/plugins/store/search?q=hockey" curl "http://your-pi-ip:5000/api/v3/plugins/store/search?q=hockey"
# Filter by category # Filter by category
curl "http://your-pi-ip:5050/api/plugins/store/search?category=sports" curl "http://your-pi-ip:5000/api/v3/plugins/store/search?category=sports"
# Filter by tags # Filter by tags
curl "http://your-pi-ip:5050/api/plugins/store/search?tags=nhl&tags=hockey" curl "http://your-pi-ip:5000/api/v3/plugins/store/search?tags=nhl&tags=hockey"
``` ```
**Via Python:** **Via Python:**
@@ -168,7 +168,7 @@ results = store.search_plugins(tags=["nhl", "hockey"])
**Via REST API:** **Via REST API:**
```bash ```bash
curl "http://your-pi-ip:5050/api/plugins/installed" curl "http://your-pi-ip:5000/api/v3/plugins/installed"
``` ```
**Via Python:** **Via Python:**
@@ -192,7 +192,7 @@ for plugin_id in installed:
**Via REST API:** **Via REST API:**
```bash ```bash
curl -X POST http://your-pi-ip:5050/api/plugins/toggle \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/toggle \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "clock-simple", "enabled": true}' -d '{"plugin_id": "clock-simple", "enabled": true}'
``` ```
@@ -207,7 +207,7 @@ curl -X POST http://your-pi-ip:5050/api/plugins/toggle \
**Via REST API:** **Via REST API:**
```bash ```bash
curl -X POST http://your-pi-ip:5050/api/plugins/update \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/update \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "clock-simple"}' -d '{"plugin_id": "clock-simple"}'
``` ```
@@ -230,7 +230,7 @@ success = store.update_plugin('clock-simple')
**Via REST API:** **Via REST API:**
```bash ```bash
curl -X POST http://your-pi-ip:5050/api/plugins/uninstall \ curl -X POST http://your-pi-ip:5000/api/v3/plugins/uninstall \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "clock-simple"}' -d '{"plugin_id": "clock-simple"}'
``` ```
@@ -351,15 +351,15 @@ All API endpoints return JSON with this structure:
| Method | Endpoint | Description | | Method | Endpoint | Description |
|--------|----------|-------------| |--------|----------|-------------|
| GET | `/api/plugins/store/list` | List all plugins in store | | GET | `/api/v3/plugins/store/list` | List all plugins in store |
| GET | `/api/plugins/store/search` | Search for plugins | | GET | `/api/v3/plugins/store/search` | Search for plugins |
| GET | `/api/plugins/installed` | List installed plugins | | GET | `/api/v3/plugins/installed` | List installed plugins |
| POST | `/api/plugins/install` | Install from registry | | POST | `/api/v3/plugins/install` | Install from registry |
| POST | `/api/plugins/install-from-url` | Install from GitHub URL | | POST | `/api/v3/plugins/install-from-url` | Install from GitHub URL |
| POST | `/api/plugins/uninstall` | Uninstall plugin | | POST | `/api/v3/plugins/uninstall` | Uninstall plugin |
| POST | `/api/plugins/update` | Update plugin | | POST | `/api/v3/plugins/update` | Update plugin |
| POST | `/api/plugins/toggle` | Enable/disable plugin | | POST | `/api/v3/plugins/toggle` | Enable/disable plugin |
| POST | `/api/plugins/config` | Update plugin config | | POST | `/api/v3/plugins/config` | Update plugin config |
--- ---
@@ -369,7 +369,7 @@ All API endpoints return JSON with this structure:
```bash ```bash
# Install # Install
curl -X POST http://192.168.1.100:5050/api/plugins/install \ curl -X POST http://192.168.1.100:5000/api/v3/plugins/install \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "clock-simple"}' -d '{"plugin_id": "clock-simple"}'
@@ -390,12 +390,12 @@ sudo systemctl restart ledmatrix
```bash ```bash
# Install your own plugin during development # Install your own plugin during development
curl -X POST http://192.168.1.100:5050/api/plugins/install-from-url \ curl -X POST http://192.168.1.100:5000/api/v3/plugins/install-from-url \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"repo_url": "https://github.com/myusername/ledmatrix-my-custom-plugin"}' -d '{"repo_url": "https://github.com/myusername/ledmatrix-my-custom-plugin"}'
# Enable it # Enable it
curl -X POST http://192.168.1.100:5050/api/plugins/toggle \ curl -X POST http://192.168.1.100:5000/api/v3/plugins/toggle \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"plugin_id": "my-custom-plugin", "enabled": true}' -d '{"plugin_id": "my-custom-plugin", "enabled": true}'

View File

@@ -1,199 +1,84 @@
# LEDMatrix Documentation # LEDMatrix Documentation
Welcome to the LEDMatrix documentation! This directory contains comprehensive guides, specifications, and reference materials for the LEDMatrix project. This directory contains guides, references, and architectural notes for the
LEDMatrix project. If you are setting up a Pi for the first time, start with
the [project root README](../README.md) — it covers hardware, OS imaging, and
the one-shot installer. The pages here go deeper.
## 📚 Documentation Overview ## I'm a new user
This documentation has been recently consolidated (January 2026) to reduce redundancy while maintaining comprehensive coverage. We've reduced from 51 main documents to 16-17 well-organized files (~68% reduction) by merging duplicates, archiving ephemeral content, and unifying writing styles. 1. [GETTING_STARTED.md](GETTING_STARTED.md) — first-time setup walkthrough
2. [WEB_INTERFACE_GUIDE.md](WEB_INTERFACE_GUIDE.md) — using the web UI
3. [PLUGIN_STORE_GUIDE.md](PLUGIN_STORE_GUIDE.md) — installing and managing plugins
4. [WIFI_NETWORK_SETUP.md](WIFI_NETWORK_SETUP.md) — WiFi and AP-mode setup
5. [TROUBLESHOOTING.md](TROUBLESHOOTING.md) — common issues and fixes
6. [SSH_UNAVAILABLE_AFTER_INSTALL.md](SSH_UNAVAILABLE_AFTER_INSTALL.md) — recovering SSH after install
7. [CONFIG_DEBUGGING.md](CONFIG_DEBUGGING.md) — diagnosing config problems
## 📖 Quick Start ## I want to write a plugin
### For New Users Start here:
1. **Installation**: Follow the main [README.md](../README.md) in the project root
2. **First Setup**: See [GETTING_STARTED.md](GETTING_STARTED.md) for first-time setup guide
3. **Web Interface**: Use [WEB_INTERFACE_GUIDE.md](WEB_INTERFACE_GUIDE.md) to learn the control panel
4. **Troubleshooting**: Check [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for common issues
### For Developers 1. [PLUGIN_DEVELOPMENT_GUIDE.md](PLUGIN_DEVELOPMENT_GUIDE.md) — end-to-end workflow
1. **Plugin Development**: See [PLUGIN_DEVELOPMENT_GUIDE.md](PLUGIN_DEVELOPMENT_GUIDE.md) for complete guide 2. [PLUGIN_QUICK_REFERENCE.md](PLUGIN_QUICK_REFERENCE.md) — cheat sheet
2. **Advanced Patterns**: Read [ADVANCED_PLUGIN_DEVELOPMENT.md](ADVANCED_PLUGIN_DEVELOPMENT.md) for advanced techniques 3. [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md) — display, cache, and plugin-manager APIs
3. **API Reference**: Check [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md) for available methods 4. [PLUGIN_ERROR_HANDLING.md](PLUGIN_ERROR_HANDLING.md) — error-handling patterns
4. **Configuration**: See [PLUGIN_CONFIGURATION_GUIDE.md](PLUGIN_CONFIGURATION_GUIDE.md) for config schemas 5. [DEV_PREVIEW.md](DEV_PREVIEW.md) — preview plugins on your dev machine without a Pi
6. [EMULATOR_SETUP_GUIDE.md](EMULATOR_SETUP_GUIDE.md) — running the matrix emulator
### For API Integration Going deeper:
1. **REST API**: See [REST_API_REFERENCE.md](REST_API_REFERENCE.md) for all web interface endpoints
2. **Plugin API**: See [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md) for plugin developer APIs
3. **Developer Reference**: See [DEVELOPER_QUICK_REFERENCE.md](DEVELOPER_QUICK_REFERENCE.md) for common tasks
## 📋 Documentation Categories - [ADVANCED_PLUGIN_DEVELOPMENT.md](ADVANCED_PLUGIN_DEVELOPMENT.md) — advanced patterns
- [PLUGIN_ARCHITECTURE_SPEC.md](PLUGIN_ARCHITECTURE_SPEC.md) — full plugin-system spec
- [PLUGIN_DEPENDENCY_GUIDE.md](PLUGIN_DEPENDENCY_GUIDE.md) /
[PLUGIN_DEPENDENCY_TROUBLESHOOTING.md](PLUGIN_DEPENDENCY_TROUBLESHOOTING.md)
- [PLUGIN_WEB_UI_ACTIONS.md](PLUGIN_WEB_UI_ACTIONS.md) (+ [example JSON](PLUGIN_WEB_UI_ACTIONS_EXAMPLE.json))
- [PLUGIN_CUSTOM_ICONS.md](PLUGIN_CUSTOM_ICONS.md) /
[PLUGIN_CUSTOM_ICONS_FEATURE.md](PLUGIN_CUSTOM_ICONS_FEATURE.md)
- [PLUGIN_REGISTRY_SETUP_GUIDE.md](PLUGIN_REGISTRY_SETUP_GUIDE.md) (+ [registry template](plugin_registry_template.json))
- [STARLARK_APPS_GUIDE.md](STARLARK_APPS_GUIDE.md) — Starlark-based mini-apps
- [widget-guide.md](widget-guide.md) — widget development
### 🚀 Getting Started & User Guides ## Configuring plugins
- [GETTING_STARTED.md](GETTING_STARTED.md) - First-time setup and quick start guide
- [WEB_INTERFACE_GUIDE.md](WEB_INTERFACE_GUIDE.md) - Complete web interface user guide
- [WIFI_NETWORK_SETUP.md](WIFI_NETWORK_SETUP.md) - WiFi configuration and AP mode setup
- [PLUGIN_STORE_GUIDE.md](PLUGIN_STORE_GUIDE.md) - Installing and managing plugins
- [TROUBLESHOOTING.md](TROUBLESHOOTING.md) - Common issues and solutions
### ⚡ Advanced Features - [PLUGIN_CONFIG_QUICK_START.md](PLUGIN_CONFIG_QUICK_START.md) — minimal config you need
- [ADVANCED_FEATURES.md](ADVANCED_FEATURES.md) - Vegas scroll mode, on-demand display, cache management, background services, permissions - [PLUGIN_CONFIGURATION_GUIDE.md](PLUGIN_CONFIGURATION_GUIDE.md) — schema design
- [PLUGIN_CONFIGURATION_TABS.md](PLUGIN_CONFIGURATION_TABS.md) — multi-tab UI configs
- [PLUGIN_CONFIG_ARCHITECTURE.md](PLUGIN_CONFIG_ARCHITECTURE.md) — how the config system works
- [PLUGIN_CONFIG_CORE_PROPERTIES.md](PLUGIN_CONFIG_CORE_PROPERTIES.md) — properties every plugin honors
### 🔌 Plugin Development ## Advanced features
- [PLUGIN_DEVELOPMENT_GUIDE.md](PLUGIN_DEVELOPMENT_GUIDE.md) - Complete plugin development workflow
- [PLUGIN_QUICK_REFERENCE.md](PLUGIN_QUICK_REFERENCE.md) - Plugin development quick reference
- [ADVANCED_PLUGIN_DEVELOPMENT.md](ADVANCED_PLUGIN_DEVELOPMENT.md) - Advanced patterns and examples
- [PLUGIN_CONFIGURATION_GUIDE.md](PLUGIN_CONFIGURATION_GUIDE.md) - Configuration schema design
- [PLUGIN_CONFIGURATION_TABS.md](PLUGIN_CONFIGURATION_TABS.md) - Configuration tabs feature
- [PLUGIN_CONFIG_QUICK_START.md](PLUGIN_CONFIG_QUICK_START.md) - Quick configuration guide
- [PLUGIN_DEPENDENCY_GUIDE.md](PLUGIN_DEPENDENCY_GUIDE.md) - Managing plugin dependencies
- [PLUGIN_DEPENDENCY_TROUBLESHOOTING.md](PLUGIN_DEPENDENCY_TROUBLESHOOTING.md) - Dependency troubleshooting
### 🏗️ Plugin Features & Extensions - [ADVANCED_FEATURES.md](ADVANCED_FEATURES.md) — Vegas scroll, on-demand display,
- [PLUGIN_CUSTOM_ICONS.md](PLUGIN_CUSTOM_ICONS.md) - Custom plugin icons cache management, background services, permissions
- [PLUGIN_CUSTOM_ICONS_FEATURE.md](PLUGIN_CUSTOM_ICONS_FEATURE.md) - Custom icons implementation - [FONT_MANAGER.md](FONT_MANAGER.md) — font system
- [PLUGIN_IMPLEMENTATION_SUMMARY.md](PLUGIN_IMPLEMENTATION_SUMMARY.md) - Plugin system implementation
- [PLUGIN_REGISTRY_SETUP_GUIDE.md](PLUGIN_REGISTRY_SETUP_GUIDE.md) - Setting up plugin registry
- [PLUGIN_WEB_UI_ACTIONS.md](PLUGIN_WEB_UI_ACTIONS.md) - Web UI actions for plugins
### 📡 API Reference ## Reference
- [REST_API_REFERENCE.md](REST_API_REFERENCE.md) - Complete REST API documentation (71+ endpoints)
- [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md) - Plugin developer API (Display Manager, Cache Manager, Plugin Manager)
- [DEVELOPER_QUICK_REFERENCE.md](DEVELOPER_QUICK_REFERENCE.md) - Quick reference for common developer tasks
### 🏛️ Architecture & Design - [REST_API_REFERENCE.md](REST_API_REFERENCE.md) — all web-interface HTTP endpoints
- [PLUGIN_ARCHITECTURE_SPEC.md](PLUGIN_ARCHITECTURE_SPEC.md) - Complete plugin system specification - [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md) — Python APIs available to plugins
- [PLUGIN_CONFIG_ARCHITECTURE.md](PLUGIN_CONFIG_ARCHITECTURE.md) - Configuration system architecture - [DEVELOPER_QUICK_REFERENCE.md](DEVELOPER_QUICK_REFERENCE.md) — common dev tasks
- [PLUGIN_CONFIG_CORE_PROPERTIES.md](PLUGIN_CONFIG_CORE_PROPERTIES.md) - Core configuration properties - [PLUGIN_IMPLEMENTATION_SUMMARY.md](PLUGIN_IMPLEMENTATION_SUMMARY.md) — what the plugin system actually does
### 🛠️ Development & Tools ## Contributing to LEDMatrix itself
- [DEVELOPMENT.md](DEVELOPMENT.md) - Development environment setup
- [EMULATOR_SETUP_GUIDE.md](EMULATOR_SETUP_GUIDE.md) - Set up development environment with emulator
- [HOW_TO_RUN_TESTS.md](HOW_TO_RUN_TESTS.md) - Testing documentation
- [MULTI_ROOT_WORKSPACE_SETUP.md](MULTI_ROOT_WORKSPACE_SETUP.md) - Multi-workspace development
- [FONT_MANAGER.md](FONT_MANAGER.md) - Font management system
### 🔄 Migration & Updates - [DEVELOPMENT.md](DEVELOPMENT.md) — environment setup
- [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md) - Breaking changes and migration instructions - [HOW_TO_RUN_TESTS.md](HOW_TO_RUN_TESTS.md) — running the test suite
- [SSH_UNAVAILABLE_AFTER_INSTALL.md](SSH_UNAVAILABLE_AFTER_INSTALL.md) - SSH troubleshooting after install - [MULTI_ROOT_WORKSPACE_SETUP.md](MULTI_ROOT_WORKSPACE_SETUP.md) — multi-repo workspace
- [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md) — breaking changes between releases
### 📚 Miscellaneous ## Archive
- [widget-guide.md](widget-guide.md) - Widget development guide
- Template files:
- [plugin_registry_template.json](plugin_registry_template.json) - Plugin registry template
- [PLUGIN_WEB_UI_ACTIONS_EXAMPLE.json](PLUGIN_WEB_UI_ACTIONS_EXAMPLE.json) - Web UI actions example
## 🎯 Key Resources by Use Case `docs/archive/` holds older guides that have been superseded or describe
features that have been removed. They are kept for historical context and
git history but should not be relied on.
### I'm new to LEDMatrix ## Contributing to the docs
1. [GETTING_STARTED.md](GETTING_STARTED.md) - Start here for first-time setup
2. [WEB_INTERFACE_GUIDE.md](WEB_INTERFACE_GUIDE.md) - Learn the control panel
3. [PLUGIN_STORE_GUIDE.md](PLUGIN_STORE_GUIDE.md) - Install plugins
### I want to create a plugin - Markdown only, professional tone, minimal emoji.
1. [PLUGIN_DEVELOPMENT_GUIDE.md](PLUGIN_DEVELOPMENT_GUIDE.md) - Complete development guide - Prefer adding to an existing page over creating a new one. If you add a
2. [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md) - Available methods and APIs new page, link it from this index in the section it belongs to.
3. [ADVANCED_PLUGIN_DEVELOPMENT.md](ADVANCED_PLUGIN_DEVELOPMENT.md) - Advanced patterns - If a page becomes obsolete, move it to `docs/archive/` rather than
4. [PLUGIN_CONFIGURATION_GUIDE.md](PLUGIN_CONFIGURATION_GUIDE.md) - Configuration setup deleting it, so links don't rot.
5. [PLUGIN_ARCHITECTURE_SPEC.md](PLUGIN_ARCHITECTURE_SPEC.md) - Complete specification - Keep examples runnable — paths, commands, and config keys here should
match what's actually in the repo.
### I need to troubleshoot an issue
1. [TROUBLESHOOTING.md](TROUBLESHOOTING.md) - Comprehensive troubleshooting guide
2. [WIFI_NETWORK_SETUP.md](WIFI_NETWORK_SETUP.md) - WiFi/network issues
3. [PLUGIN_DEPENDENCY_TROUBLESHOOTING.md](PLUGIN_DEPENDENCY_TROUBLESHOOTING.md) - Dependency issues
### I want to use advanced features
1. [ADVANCED_FEATURES.md](ADVANCED_FEATURES.md) - Vegas scroll, on-demand display, background services
2. [FONT_MANAGER.md](FONT_MANAGER.md) - Font management
3. [REST_API_REFERENCE.md](REST_API_REFERENCE.md) - API integration
### I want to understand the architecture
1. [PLUGIN_ARCHITECTURE_SPEC.md](PLUGIN_ARCHITECTURE_SPEC.md) - System architecture
2. [PLUGIN_CONFIG_ARCHITECTURE.md](PLUGIN_CONFIG_ARCHITECTURE.md) - Configuration architecture
3. [PLUGIN_IMPLEMENTATION_SUMMARY.md](PLUGIN_IMPLEMENTATION_SUMMARY.md) - Implementation details
## 🔄 Recent Consolidations (January 2026)
### Major Consolidation Effort
- **Before**: 51 main documentation files
- **After**: 16-17 well-organized files
- **Reduction**: ~68% fewer files
- **Archived**: 33 files (consolidated sources + ephemeral docs)
### New Consolidated Guides
- **GETTING_STARTED.md** - New first-time user guide
- **WEB_INTERFACE_GUIDE.md** - Consolidated web interface documentation
- **WIFI_NETWORK_SETUP.md** - Consolidated WiFi setup (5 files → 1)
- **PLUGIN_STORE_GUIDE.md** - Consolidated plugin store guides (2 files → 1)
- **TROUBLESHOOTING.md** - Consolidated troubleshooting (4 files → 1)
- **ADVANCED_FEATURES.md** - Consolidated advanced features (6 files → 1)
### What Was Archived
- Ephemeral debug documents (DEBUG_WEB_ISSUE.md, BROWSER_ERRORS_EXPLANATION.md, etc.)
- Implementation summaries (PLUGIN_CONFIG_TABS_SUMMARY.md, STARTUP_OPTIMIZATION_SUMMARY.md, etc.)
- Consolidated source files (WIFI_SETUP.md, V3_INTERFACE_README.md, etc.)
- Testing documentation (CAPTIVE_PORTAL_TESTING.md, etc.)
All archived files are preserved in `docs/archive/` with full git history.
### Benefits
- ✅ Easier to find information (fewer files to search)
- ✅ No duplicate content
- ✅ Consistent writing style (professional technical)
- ✅ Updated outdated references
- ✅ Fixed broken internal links
- ✅ Better organization for users vs developers
## 📝 Contributing to Documentation
### Documentation Standards
- Use Markdown format with consistent headers
- Professional technical writing style
- Minimal emojis (1-2 per major section for navigation)
- Include code examples where helpful
- Provide both quick start and detailed reference sections
- Cross-reference related documentation
### Adding New Documentation
1. Consider if content should be added to existing docs first
2. Place in appropriate category (see sections above)
3. Update this README.md with the new document
4. Follow naming conventions (FEATURE_NAME.md)
5. Use consistent formatting and voice
### Consolidation Guidelines
- **User Guides**: Consolidate by topic (WiFi, troubleshooting, etc.)
- **Developer Guides**: Keep development vs reference vs architecture separate
- **Debug Documents**: Archive after issues are resolved
- **Implementation Summaries**: Archive completed implementation details
- **Ephemeral Content**: Archive, don't keep in main docs
## 🔗 Related Documentation
- [Main Project README](../README.md) - Installation and basic usage
- [Web Interface README](../web_interface/README.md) - Web interface details
- [GitHub Issues](https://github.com/ChuckBuilds/LEDMatrix/issues) - Bug reports and feature requests
- [GitHub Discussions](https://github.com/ChuckBuilds/LEDMatrix/discussions) - Community support
## 📊 Documentation Statistics
- **Main Documents**: 16-17 files (after consolidation)
- **Archived Documents**: 33 files (in docs/archive/)
- **Categories**: 9 major sections
- **Primary Language**: English
- **Format**: Markdown (.md)
- **Last Major Update**: January 2026
- **Coverage**: Installation, user guides, development, troubleshooting, architecture, API references
### Documentation Highlights
- ✅ Comprehensive user guides for first-time setup
- ✅ Complete REST API documentation (71+ endpoints)
- ✅ Complete Plugin API reference (Display Manager, Cache Manager, Plugin Manager)
- ✅ Advanced plugin development guide with examples
- ✅ Consolidated configuration documentation
- ✅ Professional technical writing throughout
- ✅ ~68% reduction in file count while maintaining coverage
---
*This documentation index was last updated: January 2026*
*For questions or suggestions about the documentation, please open an issue or start a discussion on GitHub.*

View File

@@ -24,6 +24,17 @@ All endpoints return JSON responses with a standard format:
- [Cache](#cache) - [Cache](#cache)
- [WiFi](#wifi) - [WiFi](#wifi)
- [Streams](#streams) - [Streams](#streams)
- [Logs](#logs)
- [Error tracking](#error-tracking)
- [Health](#health)
- [Schedule (dim/power)](#schedule-dimpower)
- [Plugin-specific endpoints](#plugin-specific-endpoints)
- [Starlark Apps](#starlark-apps)
> The API blueprint is mounted at `/api/v3` (`web_interface/app.py:144`).
> SSE stream endpoints (`/api/v3/stream/*`) are defined directly on the
> Flask app at `app.py:607-615`. There are about 92 routes total — see
> `web_interface/blueprints/api_v3.py` for the canonical list.
--- ---
@@ -1201,10 +1212,16 @@ Upload a custom font file.
### Delete Font ### Delete Font
**DELETE** `/api/v3/fonts/delete/<font_family>` **DELETE** `/api/v3/fonts/<font_family>`
Delete an uploaded font. Delete an uploaded font.
### Font Preview
**GET** `/api/v3/fonts/preview?family=<font_family>&text=<sample>`
Render a small preview image of a font for use in the web UI font picker.
--- ---
## Cache ## Cache
@@ -1439,6 +1456,130 @@ Get recent log entries.
--- ---
## Error tracking
### Get Error Summary
**GET** `/api/v3/errors/summary`
Aggregated counts of recent errors across all plugins and core
components, used by the web UI's error indicator.
### Get Plugin Errors
**GET** `/api/v3/errors/plugin/<plugin_id>`
Recent errors for a specific plugin.
### Clear Errors
**POST** `/api/v3/errors/clear`
Clear the in-memory error aggregator.
---
## Health
### Health Check
**GET** `/api/v3/health`
Lightweight liveness check used by the WiFi monitor and external
monitoring tools.
---
## Schedule (dim/power)
### Get Dim Schedule
**GET** `/api/v3/config/dim-schedule`
Read the dim/power schedule that automatically reduces brightness or
turns the display off at configured times.
### Update Dim Schedule
**POST** `/api/v3/config/dim-schedule`
Update the dim schedule. Body matches the structure returned by GET.
---
## Plugin-specific endpoints
A handful of endpoints belong to individual built-in or shipped plugins.
### Calendar
**GET** `/api/v3/plugins/calendar/list-calendars`
List the calendars available on the authenticated Google account.
Used by the calendar plugin's config UI.
### Of The Day
**POST** `/api/v3/plugins/of-the-day/json/upload`
Upload a JSON data file for the Of-The-Day plugin's category data.
**POST** `/api/v3/plugins/of-the-day/json/delete`
Delete a previously uploaded Of-The-Day data file.
### Plugin Static Assets
**GET** `/api/v3/plugins/<plugin_id>/static/<path:file_path>`
Serve a static asset (image, font, etc.) from a plugin's directory.
Used internally by the web UI to render plugin previews and icons.
---
## Starlark Apps
The Starlark plugin lets you run [Tronbyt](https://github.com/tronbyt/apps)
Starlark apps on the matrix. These endpoints expose its UI.
### Status
**GET** `/api/v3/starlark/status`
Returns whether the Pixlet binary is installed and the Starlark plugin
is operational.
### Install Pixlet
**POST** `/api/v3/starlark/install-pixlet`
Download and install the Pixlet binary on the Pi.
### Apps
**GET** `/api/v3/starlark/apps` — list installed Starlark apps
**GET** `/api/v3/starlark/apps/<app_id>` — get app details
**DELETE** `/api/v3/starlark/apps/<app_id>` — uninstall an app
**GET** `/api/v3/starlark/apps/<app_id>/config` — get app config schema
**PUT** `/api/v3/starlark/apps/<app_id>/config` — update app config
**POST** `/api/v3/starlark/apps/<app_id>/render` — render app to a frame
**POST** `/api/v3/starlark/apps/<app_id>/toggle` — enable/disable app
### Repository (Tronbyt community apps)
**GET** `/api/v3/starlark/repository/categories` — browse categories
**GET** `/api/v3/starlark/repository/browse?category=<cat>` — browse apps
**POST** `/api/v3/starlark/repository/install` — install an app from the
community repository
### Upload custom app
**POST** `/api/v3/starlark/upload`
Upload a custom Starlark `.star` file as a new app.
---
## Error Responses ## Error Responses
All endpoints may return error responses in the following format: All endpoints may return error responses in the following format:

View File

@@ -47,13 +47,15 @@ bash scripts/diagnose_web_interface.sh
# WiFi setup verification # WiFi setup verification
./scripts/verify_wifi_setup.sh ./scripts/verify_wifi_setup.sh
# Weather plugin troubleshooting
./troubleshoot_weather.sh
# Captive portal troubleshooting # Captive portal troubleshooting
./scripts/troubleshoot_captive_portal.sh ./scripts/troubleshoot_captive_portal.sh
``` ```
> Weather is provided by the `ledmatrix-weather` plugin (installed via the
> Plugin Store). To troubleshoot weather, check that plugin's tab in the
> web UI for its API key and recent error messages, then watch the
> **Logs** tab.
### 4. Check Configuration ### 4. Check Configuration
```bash ```bash
@@ -85,7 +87,7 @@ python3 web_interface/start.py
#### Service Not Running/Starting #### Service Not Running/Starting
**Symptoms:** **Symptoms:**
- Cannot access web interface at http://your-pi-ip:5050 - Cannot access web interface at http://your-pi-ip:5000
- `systemctl status ledmatrix-web` shows `inactive (dead)` - `systemctl status ledmatrix-web` shows `inactive (dead)`
**Solutions:** **Solutions:**
@@ -157,13 +159,13 @@ sudo systemctl restart ledmatrix-web
**Symptoms:** **Symptoms:**
- Error: `Address already in use` - Error: `Address already in use`
- Service fails to bind to port 5050 - Service fails to bind to port 5000
**Solutions:** **Solutions:**
1. **Check what's using the port:** 1. **Check what's using the port:**
```bash ```bash
sudo lsof -i :5050 sudo lsof -i :5000
``` ```
2. **Kill the conflicting process:** 2. **Kill the conflicting process:**
@@ -265,7 +267,7 @@ sudo systemctl cat ledmatrix-web | grep User
6. **Manually enable AP mode:** 6. **Manually enable AP mode:**
```bash ```bash
# Via API # Via API
curl -X POST http://localhost:5050/api/wifi/ap/enable curl -X POST http://localhost:5000/api/wifi/ap/enable
# Via Python # Via Python
python3 -c " python3 -c "
@@ -291,9 +293,8 @@ sudo systemctl cat ledmatrix-web | grep User
``` ```
2. **Use correct IP address and port:** 2. **Use correct IP address and port:**
- Correct: `http://192.168.4.1:5050` - Correct: `http://192.168.4.1:5000`
- NOT: `http://192.168.4.1` (port 80) - NOT: `http://192.168.4.1` (port 80 — nothing listens there)
- NOT: `http://192.168.4.1:5000`
3. **Check wlan0 has correct IP:** 3. **Check wlan0 has correct IP:**
```bash ```bash
@@ -309,7 +310,7 @@ sudo systemctl cat ledmatrix-web | grep User
5. **Test from the Pi itself:** 5. **Test from the Pi itself:**
```bash ```bash
curl http://192.168.4.1:5050 curl http://192.168.4.1:5000
# Should return HTML # Should return HTML
``` ```
@@ -340,11 +341,11 @@ sudo systemctl cat ledmatrix-web | grep User
4. **Manual captive portal testing:** 4. **Manual captive portal testing:**
- Try these URLs manually: - Try these URLs manually:
- `http://192.168.4.1:5050` - `http://192.168.4.1:5000`
- `http://captive.apple.com` - `http://captive.apple.com`
- `http://connectivitycheck.gstatic.com/generate_204` - `http://connectivitycheck.gstatic.com/generate_204`
#### Firewall Blocking Port 5050 #### Firewall Blocking Port 5000
**Symptoms:** **Symptoms:**
- Services running but cannot connect - Services running but cannot connect
@@ -357,9 +358,9 @@ sudo systemctl cat ledmatrix-web | grep User
sudo ufw status sudo ufw status
``` ```
2. **Allow port 5050:** 2. **Allow port 5000:**
```bash ```bash
sudo ufw allow 5050/tcp sudo ufw allow 5000/tcp
``` ```
3. **Check iptables:** 3. **Check iptables:**
@@ -372,7 +373,7 @@ sudo systemctl cat ledmatrix-web | grep User
sudo ufw disable sudo ufw disable
# Test if it works, then re-enable and add rule # Test if it works, then re-enable and add rule
sudo ufw enable sudo ufw enable
sudo ufw allow 5050/tcp sudo ufw allow 5000/tcp
``` ```
--- ---
@@ -403,9 +404,9 @@ sudo systemctl cat ledmatrix-web | grep User
``` ```
3. **Verify in web interface:** 3. **Verify in web interface:**
- Navigate to Plugin Management tab - Open the **Plugin Manager** tab
- Toggle the switch to enable - Toggle the plugin switch to enable
- Restart display - From **Overview**, click **Restart Display Service**
#### Plugin Not Loading #### Plugin Not Loading
@@ -690,12 +691,12 @@ nslookup api.openweathermap.org
dig api.openweathermap.org dig api.openweathermap.org
# Test HTTP endpoint # Test HTTP endpoint
curl -I http://your-pi-ip:5050 curl -I http://your-pi-ip:5000
curl http://192.168.4.1:5050 curl http://192.168.4.1:5000
# Check listening ports # Check listening ports
sudo lsof -i :5050 sudo lsof -i :5000
sudo netstat -tuln | grep 5050 sudo netstat -tuln | grep 5000
# Check network interfaces # Check network interfaces
ip addr show ip addr show
@@ -808,7 +809,7 @@ echo ""
echo "4. Network Status:" echo "4. Network Status:"
ip addr show | grep -E "(wlan|eth|inet )" ip addr show | grep -E "(wlan|eth|inet )"
curl -s http://localhost:5050 > /dev/null && echo "Web interface: OK" || echo "Web interface: FAILED" curl -s http://localhost:5000 > /dev/null && echo "Web interface: OK" || echo "Web interface: FAILED"
echo "" echo ""
echo "5. File Structure:" echo "5. File Structure:"
@@ -837,22 +838,22 @@ A properly functioning system should show:
``` ```
2. **Web Interface Accessible:** 2. **Web Interface Accessible:**
- Navigate to http://your-pi-ip:5050 - Navigate to http://your-pi-ip:5000
- Page loads successfully - Page loads successfully
- Display preview visible - Display preview visible
3. **Logs Show Normal Operation:** 3. **Logs Show Normal Operation:**
``` ```
INFO: Web interface started on port 5050 INFO: Web interface started on port 5000
INFO: Loaded X plugins INFO: Loaded X plugins
INFO: Display rotation active INFO: Display rotation active
``` ```
4. **Process Listening on Port:** 4. **Process Listening on Port:**
```bash ```bash
$ sudo lsof -i :5050 $ sudo lsof -i :5000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python3 1234 ledpi 3u IPv4 12345 0t0 TCP *:5050 (LISTEN) python3 1234 ledpi 3u IPv4 12345 0t0 TCP *:5000 (LISTEN)
``` ```
5. **Plugins Loading:** 5. **Plugins Loading:**

View File

@@ -17,7 +17,7 @@ The LEDMatrix web interface provides a complete control panel for managing your
2. Open a web browser and navigate to: 2. Open a web browser and navigate to:
``` ```
http://your-pi-ip:5050 http://your-pi-ip:5000
``` ```
3. The interface will load with the Overview tab displaying system stats and a live display preview. 3. The interface will load with the Overview tab displaying system stats and a live display preview.
@@ -31,17 +31,28 @@ sudo systemctl status ledmatrix-web
## Navigation ## Navigation
The interface uses a tab-based layout for easy navigation between features: The interface uses a two-row tab layout. The system tabs are always
present:
- **Overview** - System stats, quick actions, and display preview - **Overview** System stats, quick actions, live display preview
- **General Settings** - Timezone, location, and autostart configuration - **General** Timezone, location, plugin-system settings
- **Display Settings** - Hardware configuration, brightness, and display options - **WiFi** — Network selection and AP-mode setup
- **Durations** - Display rotation timing configuration - **Schedule** — Power and dim schedules
- **Sports Configuration** - Per-league settings and on-demand modes - **Display** — Matrix hardware configuration (rows, cols, hardware
- **Plugin Management** - Install, configure, enable/disable plugins mapping, GPIO slowdown, brightness, PWM)
- **Plugin Store** - Discover and install plugins - **Config Editor** — Raw `config.json` editor with validation
- **Font Management** - Upload fonts, manage overrides, and preview - **Fonts** Upload and manage fonts
- **Logs** - Real-time log streaming with filtering and search - **Logs** Real-time log streaming
- **Cache** — Cached data inspection and cleanup
- **Operation History** — Recent service operations
A second nav row holds plugin tabs:
- **Plugin Manager** — browse the **Plugin Store** section, install
plugins from GitHub, enable/disable installed plugins
- **&lt;plugin-id&gt;** — one tab per installed plugin for its own
configuration form (auto-generated from the plugin's
`config_schema.json`)
--- ---
@@ -57,131 +68,84 @@ The Overview tab provides at-a-glance information and quick actions:
- Disk usage - Disk usage
- Network status - Network status
**Quick Actions:** **Quick Actions** (verified in `web_interface/templates/v3/partials/overview.html`):
- **Start/Stop Display** - Control the display service - **Start Display** / **Stop Display** — control the display service
- **Restart Display** - Restart to apply configuration changes - **Restart Display Service** — apply configuration changes
- **Test Display** - Run a quick test pattern - **Restart Web Service** — restart the web UI itself
- **Update Code** — `git pull` the latest version (stashes local changes)
- **Reboot System** / **Shutdown System** — confirm-gated power controls
**Display Preview:** **Display Preview:**
- Live preview of what's currently shown on the LED matrix - Live preview of what's currently shown on the LED matrix
- Updates in real-time - Updates in real-time
- Useful for remote monitoring - Useful for remote monitoring
### General Settings Tab ### General Tab
Configure basic system settings: Configure basic system settings:
**Timezone:** - **Timezone** — used by all time/date displays
- Set your local timezone for accurate time display - **Location** — city/state/country for weather and other location-aware
- Auto-detects common timezones plugins
- **Plugin System Settings** — including the `plugins_directory` (default
`plugin-repos/`) used by the plugin loader
- **Autostart** options for the display service
**Location:** Click **Save** to write changes to `config/config.json`. Most changes
- Set latitude/longitude for location-based features require a display service restart from **Overview**.
- Used by weather plugins and sunrise/sunset calculations
**Autostart:** ### Display Tab
- Enable/disable display autostart on boot
- Configure systemd service settings
**Save Changes:**
- Click "Save Configuration" to apply changes
- Restart the display for changes to take effect
### Display Settings Tab
Configure your LED matrix hardware: Configure your LED matrix hardware:
**Matrix Configuration:** **Matrix configuration:**
- Rows: Number of LED rows (typically 32 or 64) - `rows` — LED rows (typically 32 or 64)
- Columns: Number of LED columns (typically 64, 128, or 256) - `cols` — LED columns (typically 64 or 96)
- Chain Length: Number of chained panels - `chain_length` — number of horizontally chained panels
- Parallel Chains: Number of parallel chains - `parallel` — number of parallel chains
- `hardware_mapping` — `adafruit-hat-pwm` (with PWM jumper mod),
`adafruit-hat` (without), `regular`, or `regular-pi1`
- `gpio_slowdown` — must match your Pi model (3 for Pi 3, 4 for Pi 4, etc.)
- `brightness` — 0100%
- `pwm_bits`, `pwm_lsb_nanoseconds`, `pwm_dither_bits` — PWM tuning
- Dynamic Duration — global cap for plugins that extend their display
time based on content
**Display Options:** Changes require **Restart Display Service** from the Overview tab.
- Brightness: Adjust LED brightness (0-100%)
- Hardware Mapping: GPIO pin mapping
- Slowdown GPIO: Timing adjustment for compatibility
**Save and Apply:** ### Plugin Manager Tab
- Changes require a display restart
- Use "Test Display" to verify configuration
### Durations Tab The Plugin Manager has three main sections:
Control how long each plugin displays: 1. **Installed Plugins** — toggle installed plugins on/off, see version
info. Each installed plugin also gets its own tab in the second nav
row for its configuration form.
2. **Plugin Store** — browse plugins from the official
`ledmatrix-plugins` registry. Click **Install** to fetch and
install. Filter by category and search.
3. **Install from GitHub** — install third-party plugins by pasting a
GitHub repository URL. **Install Single Plugin** for a single-plugin
repo, **Load Registry** for a multi-plugin monorepo.
**Global Settings:** When a plugin is installed and enabled:
- Default Duration: Default time for plugins without specific durations - A new tab for that plugin appears in the second nav row
- Transition Speed: Speed of transitions between plugins - Open the tab to edit its config (auto-generated form from
`config_schema.json`)
- The tab also exposes **Run On-Demand** / **Stop On-Demand** controls
to render that plugin immediately, even if it's disabled in the
rotation
**Per-Plugin Durations:** ### Per-plugin Configuration Tabs
- Set custom display duration for each plugin
- Override global default for specific plugins
- Measured in seconds
### Sports Configuration Tab Each installed plugin has its own tab in the second nav row. The form
fields are auto-generated from the plugin's `config_schema.json`, so
options always match the plugin's current code.
Configure sports-specific settings: To temporarily run a plugin outside the normal rotation, use the
**Run On-Demand** / **Stop On-Demand** buttons inside its tab. This
works even when the plugin is disabled.
**Per-League Settings:** ### Fonts Tab
- Favorite teams
- Show favorite teams only
- Include scores/standings
- Refresh intervals
**On-Demand Modes:**
- Live Priority: Show live games immediately
- Game Day Mode: Enhanced display during game days
- Score Alerts: Highlight score changes
### Plugin Management Tab
Manage installed plugins:
**Plugin List:**
- View all installed plugins
- See plugin status (enabled/disabled)
- Check last update time
**Actions:**
- **Enable/Disable**: Toggle plugin using the switch
- **Configure**: Click ⚙️ to edit plugin settings
- **Update**: Update plugin to latest version
- **Uninstall**: Remove plugin completely
**Configuration:**
- Edit plugin-specific settings
- Changes are saved to `config/config.json`
- Restart display to apply changes
**Note:** See [PLUGIN_STORE_GUIDE.md](PLUGIN_STORE_GUIDE.md) for information on installing plugins.
### Plugin Store Tab
Discover and install new plugins:
**Browse Plugins:**
- View available plugins in the official store
- Filter by category (sports, weather, time, finance, etc.)
- Search by name, description, or author
**Install Plugins:**
- Click "Install" next to any plugin
- Wait for installation to complete
- Restart the display to activate
**Install from URL:**
- Install plugins from any GitHub repository
- Paste the repository URL in the "Install from URL" section
- Review the warning about unverified plugins
- Click "Install from URL"
**Plugin Information:**
- View plugin descriptions, ratings, and screenshots
- Check compatibility and requirements
- Read user reviews (when available)
### Font Management Tab
Manage fonts for your display: Manage fonts for your display:
@@ -229,37 +193,37 @@ View real-time system logs:
### Changing Display Brightness ### Changing Display Brightness
1. Navigate to the **Display Settings** tab 1. Open the **Display** tab
2. Adjust the **Brightness** slider (0-100%) 2. Adjust the **Brightness** slider (0100)
3. Click **Save Configuration** 3. Click **Save**
4. Restart the display for changes to take effect 4. Click **Restart Display Service** on the **Overview** tab
### Installing a New Plugin ### Installing a New Plugin
1. Navigate to the **Plugin Store** tab 1. Open the **Plugin Manager** tab
2. Browse or search for the desired plugin 2. Scroll to the **Plugin Store** section and browse or search
3. Click **Install** next to the plugin 3. Click **Install** next to the plugin
4. Wait for installation to complete 4. Toggle the plugin on in **Installed Plugins**
5. Restart the display 5. Click **Restart Display Service** on **Overview**
6. Enable the plugin in the **Plugin Management** tab
### Configuring a Plugin ### Configuring a Plugin
1. Navigate to the **Plugin Management** tab 1. Open the plugin's tab in the second nav row (each installed plugin
2. Find the plugin you want to configure has its own tab)
3. Click the ⚙️ **Configure** button 2. Edit the auto-generated form
4. Edit the settings in the form 3. Click **Save**
5. Click **Save** 4. Restart the display service from **Overview**
6. Restart the display to apply changes
### Setting Favorite Sports Teams ### Setting Favorite Sports Teams
1. Navigate to the **Sports Configuration** tab Sports favorites live in the relevant plugin's tab — there is no
2. Select the league (NHL, NBA, MLB, NFL) separate "Sports Configuration" tab. For example:
3. Choose your favorite teams from the dropdown
4. Enable "Show favorite teams only" if desired 1. Install **Hockey Scoreboard** from **Plugin Manager → Plugin Store**
5. Click **Save Configuration** 2. Open the **Hockey Scoreboard** tab in the second nav row
6. Restart the display 3. Add your favorites under `favorite_teams.<league>` (e.g.
`favorite_teams.nhl`)
4. Click **Save** and restart the display service
### Troubleshooting Display Issues ### Troubleshooting Display Issues
@@ -296,12 +260,10 @@ The interface is fully responsive and works on mobile devices:
- Touch-friendly interface - Touch-friendly interface
- Responsive layout adapts to screen size - Responsive layout adapts to screen size
- All features available on mobile - All features available on mobile
- Swipe navigation between tabs
**Tips for Mobile:** **Tips for Mobile:**
- Use landscape mode for better visibility - Use landscape mode for better visibility
- Pinch to zoom on display preview - Pinch to zoom on display preview
- Long-press for context menus
--- ---
@@ -322,15 +284,21 @@ The web interface is built on a REST API that you can access programmatically:
**API Base URL:** **API Base URL:**
``` ```
http://your-pi-ip:5050/api http://your-pi-ip:5000/api/v3
``` ```
The API blueprint mounts at `/api/v3` (see
`web_interface/app.py:144`). All endpoints below are relative to that
base.
**Common Endpoints:** **Common Endpoints:**
- `GET /api/config/main` - Get configuration - `GET /api/v3/config/main` Get main configuration
- `POST /api/config/main` - Update configuration - `POST /api/v3/config/main` Update main configuration
- `GET /api/system/status` - Get system status - `GET /api/v3/system/status` Get system status
- `POST /api/system/action` - Control display (start/stop/restart) - `POST /api/v3/system/action` Control display (start/stop/restart, reboot, etc.)
- `GET /api/plugins/installed` - List installed plugins - `GET /api/v3/plugins/installed` List installed plugins
- `POST /api/v3/plugins/install` — Install a plugin from the store
- `POST /api/v3/plugins/install-from-url` — Install a plugin from a GitHub URL
**Note:** See [REST_API_REFERENCE.md](REST_API_REFERENCE.md) for complete API documentation. **Note:** See [REST_API_REFERENCE.md](REST_API_REFERENCE.md) for complete API documentation.
@@ -353,7 +321,7 @@ http://your-pi-ip:5050/api
sudo systemctl start ledmatrix-web sudo systemctl start ledmatrix-web
``` ```
3. Check that port 5050 is not blocked by firewall 3. Check that port 5000 is not blocked by firewall
4. Verify the Pi's IP address is correct 4. Verify the Pi's IP address is correct
### Changes Not Applying ### Changes Not Applying
@@ -429,7 +397,9 @@ The web interface uses modern web technologies:
- Web service: `sudo journalctl -u ledmatrix-web -f` - Web service: `sudo journalctl -u ledmatrix-web -f`
**Plugins:** **Plugins:**
- Plugin directory: `/plugins/` - Plugin directory: configurable via
`plugin_system.plugins_directory` in `config.json` (default
`plugin-repos/`); the loader also searches `plugins/` as a fallback
- Plugin config: `/config/config.json` (per-plugin sections) - Plugin config: `/config/config.json` (per-plugin sections)
--- ---

View File

@@ -21,13 +21,15 @@ The LEDMatrix WiFi system provides automatic network configuration with intellig
**If not connected to WiFi:** **If not connected to WiFi:**
1. Wait 90 seconds after boot (AP mode activation grace period) 1. Wait 90 seconds after boot (AP mode activation grace period)
2. Connect to WiFi network: **LEDMatrix-Setup** (open network) 2. Connect to WiFi network **LEDMatrix-Setup** (default password
3. Open browser to: `http://192.168.4.1:5050` `ledmatrix123` — change it in `config/wifi_config.json` if you want
4. Navigate to the WiFi tab an open network or a different password)
3. Open browser to: `http://192.168.4.1:5000`
4. Open the **WiFi** tab
5. Scan, select your network, and connect 5. Scan, select your network, and connect
**If already connected:** **If already connected:**
1. Open browser to: `http://your-pi-ip:5050` 1. Open browser to: `http://your-pi-ip:5000`
2. Navigate to the WiFi tab 2. Navigate to the WiFi tab
3. Configure as needed 3. Configure as needed
@@ -76,7 +78,7 @@ WiFi settings are stored in `config/wifi_config.json`:
```json ```json
{ {
"ap_ssid": "LEDMatrix-Setup", "ap_ssid": "LEDMatrix-Setup",
"ap_password": "", "ap_password": "ledmatrix123",
"ap_channel": 7, "ap_channel": 7,
"auto_enable_ap_mode": true, "auto_enable_ap_mode": true,
"saved_networks": [ "saved_networks": [
@@ -93,10 +95,10 @@ WiFi settings are stored in `config/wifi_config.json`:
| Setting | Default | Description | | Setting | Default | Description |
|---------|---------|-------------| |---------|---------|-------------|
| `ap_ssid` | `LEDMatrix-Setup` | Network name for AP mode | | `ap_ssid` | `LEDMatrix-Setup` | Network name broadcast in AP mode |
| `ap_password` | `` (empty) | AP password (empty = open network) | | `ap_password` | `ledmatrix123` | AP password. Set to `""` to make the network open (no password). |
| `ap_channel` | `7` | WiFi channel (use 1, 6, or 11 for non-overlapping) | | `ap_channel` | `7` | WiFi channel (1, 6, or 11 are non-overlapping) |
| `auto_enable_ap_mode` | `true` | Automatically enable AP mode when disconnected | | `auto_enable_ap_mode` | `true` | Automatically enable AP mode when both WiFi and Ethernet are disconnected |
| `saved_networks` | `[]` | Array of saved WiFi credentials | | `saved_networks` | `[]` | Array of saved WiFi credentials |
### Auto-Enable AP Mode Behavior ### Auto-Enable AP Mode Behavior
@@ -130,10 +132,10 @@ WiFi settings are stored in `config/wifi_config.json`:
**Via API:** **Via API:**
```bash ```bash
# Scan for networks # Scan for networks
curl "http://your-pi-ip:5050/api/wifi/scan" curl "http://your-pi-ip:5000/api/v3/wifi/scan"
# Connect to network # Connect to network
curl -X POST http://your-pi-ip:5050/api/wifi/connect \ curl -X POST http://your-pi-ip:5000/api/v3/wifi/connect \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"ssid": "YourNetwork", "password": "your-password"}' -d '{"ssid": "YourNetwork", "password": "your-password"}'
``` ```
@@ -147,10 +149,10 @@ curl -X POST http://your-pi-ip:5050/api/wifi/connect \
**Via API:** **Via API:**
```bash ```bash
# Enable AP mode # Enable AP mode
curl -X POST http://your-pi-ip:5050/api/wifi/ap/enable curl -X POST http://your-pi-ip:5000/api/v3/wifi/ap/enable
# Disable AP mode # Disable AP mode
curl -X POST http://your-pi-ip:5050/api/wifi/ap/disable curl -X POST http://your-pi-ip:5000/api/v3/wifi/ap/disable
``` ```
**Note:** Manual enable still requires both WiFi and Ethernet to be disconnected. **Note:** Manual enable still requires both WiFi and Ethernet to be disconnected.
@@ -211,16 +213,17 @@ The system checks connections in this order:
### AP Mode Settings ### AP Mode Settings
- **SSID**: LEDMatrix-Setup (configurable) - **SSID**: `LEDMatrix-Setup` (configurable via `ap_ssid`)
- **Network**: Open (no password by default) - **Network**: WPA2, default password `ledmatrix123` (configurable via
`ap_password` — set to `""` for an open network)
- **IP Address**: 192.168.4.1 - **IP Address**: 192.168.4.1
- **DHCP Range**: 192.168.4.2 - 192.168.4.20 - **DHCP Range**: 192.168.4.2 192.168.4.20
- **Channel**: 7 (configurable) - **Channel**: 7 (configurable via `ap_channel`)
### Accessing Services in AP Mode ### Accessing Services in AP Mode
When AP mode is active: When AP mode is active:
- Web Interface: `http://192.168.4.1:5050` - Web Interface: `http://192.168.4.1:5000`
- SSH: `ssh ledpi@192.168.4.1` - SSH: `ssh ledpi@192.168.4.1`
- Captive portal may automatically redirect browsers - Captive portal may automatically redirect browsers
@@ -237,7 +240,9 @@ When AP mode is active:
} }
``` ```
**Note:** The default is an open network for easy initial setup. For deployments in public areas, consider adding a password. **Note:** The default password is `ledmatrix123` for easy initial
setup. Change it for any deployment in a public area, or set
`ap_password` to `""` if you specifically want an open network.
**2. Use Non-Overlapping WiFi Channels:** **2. Use Non-Overlapping WiFi Channels:**
- Channels 1, 6, 11 are non-overlapping (2.4GHz) - Channels 1, 6, 11 are non-overlapping (2.4GHz)
@@ -398,7 +403,7 @@ Interface should exist
**Check 4: Try Manual Enable** **Check 4: Try Manual Enable**
- Use web interface: WiFi tab → Enable AP Mode - Use web interface: WiFi tab → Enable AP Mode
- Or via API: `curl -X POST http://localhost:5050/api/wifi/ap/enable` - Or via API: `curl -X POST http://localhost:5000/api/v3/wifi/ap/enable`
### Cannot Connect to WiFi Network ### Cannot Connect to WiFi Network
@@ -551,36 +556,36 @@ The WiFi setup feature exposes the following API endpoints:
| Method | Endpoint | Description | | Method | Endpoint | Description |
|--------|----------|-------------| |--------|----------|-------------|
| GET | `/api/wifi/status` | Get current WiFi connection status | | GET | `/api/v3/wifi/status` | Get current WiFi connection status |
| GET | `/api/wifi/scan` | Scan for available WiFi networks | | GET | `/api/v3/wifi/scan` | Scan for available WiFi networks |
| POST | `/api/wifi/connect` | Connect to a WiFi network | | POST | `/api/v3/wifi/connect` | Connect to a WiFi network |
| POST | `/api/wifi/ap/enable` | Enable access point mode | | POST | `/api/v3/wifi/ap/enable` | Enable access point mode |
| POST | `/api/wifi/ap/disable` | Disable access point mode | | POST | `/api/v3/wifi/ap/disable` | Disable access point mode |
| GET | `/api/wifi/ap/auto-enable` | Get auto-enable setting | | GET | `/api/v3/wifi/ap/auto-enable` | Get auto-enable setting |
| POST | `/api/wifi/ap/auto-enable` | Set auto-enable setting | | POST | `/api/v3/wifi/ap/auto-enable` | Set auto-enable setting |
### Example Usage ### Example Usage
```bash ```bash
# Get WiFi status # Get WiFi status
curl "http://your-pi-ip:5050/api/wifi/status" curl "http://your-pi-ip:5000/api/v3/wifi/status"
# Scan for networks # Scan for networks
curl "http://your-pi-ip:5050/api/wifi/scan" curl "http://your-pi-ip:5000/api/v3/wifi/scan"
# Connect to network # Connect to network
curl -X POST http://your-pi-ip:5050/api/wifi/connect \ curl -X POST http://your-pi-ip:5000/api/v3/wifi/connect \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"ssid": "MyNetwork", "password": "mypassword"}' -d '{"ssid": "MyNetwork", "password": "mypassword"}'
# Enable AP mode # Enable AP mode
curl -X POST http://your-pi-ip:5050/api/wifi/ap/enable curl -X POST http://your-pi-ip:5000/api/v3/wifi/ap/enable
# Check auto-enable setting # Check auto-enable setting
curl "http://your-pi-ip:5050/api/wifi/ap/auto-enable" curl "http://your-pi-ip:5000/api/v3/wifi/ap/auto-enable"
# Set auto-enable # Set auto-enable
curl -X POST http://your-pi-ip:5050/api/wifi/ap/auto-enable \ curl -X POST http://your-pi-ip:5000/api/v3/wifi/ap/auto-enable \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"auto_enable_ap_mode": true}' -d '{"auto_enable_ap_mode": true}'
``` ```