diff --git a/README.md b/README.md index a1a37947..1b5e10ee 100644 --- a/README.md +++ b/README.md @@ -782,14 +782,18 @@ The LEDMatrix system includes Web Interface that runs on port 5000 and provides ### 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: ```bash -chmod +x install_web_service.sh +chmod +x scripts/install/install_web_service.sh ``` 2. Run the install script with sudo: ```bash -sudo ./install_web_service.sh +sudo ./scripts/install/install_web_service.sh ``` The script will: diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 16bd95d3..0382980b 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -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:** -```bash -git submodule update --init --recursive plugins/ -``` +To work on a plugin locally without going through the Plugin Store, clone +that repo and symlink (or copy) the plugin directory into your configured +plugins directory — by default `plugin-repos//`. 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:** -```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). +For more information, see: +- [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 diff --git a/docs/EMULATOR_SETUP_GUIDE.md b/docs/EMULATOR_SETUP_GUIDE.md index e1727928..e30c3063 100644 --- a/docs/EMULATOR_SETUP_GUIDE.md +++ b/docs/EMULATOR_SETUP_GUIDE.md @@ -32,10 +32,15 @@ The LEDMatrix emulator allows you to run and test LEDMatrix displays on your com ### 1. Clone the Repository ```bash -git clone https://github.com/your-username/LEDMatrix.git +git clone --recurse-submodules https://github.com/ChuckBuilds/LEDMatrix.git 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 Install the emulator-specific requirements: @@ -58,12 +63,13 @@ pip install -r requirements.txt ### 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 { "pixel_outline": 0, - "pixel_size": 16, + "pixel_size": 5, "pixel_style": "square", "pixel_glow": 6, "display_adapter": "pygame", @@ -90,7 +96,7 @@ The emulator uses `emulator_config.json` for configuration. Here's the default c | Option | Description | Default | Values | |--------|-------------|---------|--------| | `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 (8–16 is typical for testing) | | `pixel_style` | Pixel shape | "square" | "square", "circle" | | `pixel_glow` | Glow effect intensity | 6 | 0-20 | | `display_adapter` | Display backend | "pygame" | "pygame", "browser" | diff --git a/docs/GETTING_STARTED.md b/docs/GETTING_STARTED.md index 55f9de09..9958ee19 100644 --- a/docs/GETTING_STARTED.md +++ b/docs/GETTING_STARTED.md @@ -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:** 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 4. Click "Scan" to find your WiFi network 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:** 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 Once connected, access the web interface: ``` -http://your-pi-ip:5050 +http://your-pi-ip:5000 ``` You should see: @@ -69,84 +69,82 @@ You should see: ### Step 1: Configure Display Hardware -1. Navigate to Settings → **Display Settings** +1. Open the **Display** tab 2. Set your matrix configuration: - **Rows**: 32 or 64 (match your hardware) - - **Columns**: 64, 128, or 256 (match your hardware) - - **Chain Length**: Number of panels chained together - - **Brightness**: 50-75% recommended for indoor use -3. Click **Save Configuration** -4. Click **Restart Display** to apply changes + - **Columns**: 64 or 96 (match your hardware) + - **Chain Length**: Number of panels chained horizontally + - **Hardware Mapping**: usually `adafruit-hat-pwm` (with the PWM jumper + mod) or `adafruit-hat` (without). See the root README for the full list. + - **Brightness**: 70–90 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 -1. Navigate to Settings → **General Settings** -2. Set your timezone (e.g., "America/New_York") -3. Set your location (city, state, country) -4. Click **Save Configuration** +1. Open the **General** tab +2. Set your timezone (e.g., `America/New_York`) and location +3. Click **Save** -**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 -1. Navigate to **Plugin Store** tab -2. Browse available plugins: - - **Time & Date**: Clock, calendar - - **Weather**: Weather forecasts - - **Sports**: NHL, NBA, NFL, MLB scores - - **Finance**: Stocks, crypto - - **Custom**: Community plugins -3. Click **Install** on desired plugins -4. Wait for installation to complete -5. Navigate to **Plugin Management** tab -6. Enable installed plugins (toggle switch) -7. Click **Restart Display** +1. Open the **Plugin Manager** tab +2. Scroll to the **Plugin Store** section to browse available plugins +3. Click **Install** on the plugins you want +4. Wait for installation to finish — installed plugins appear in the + **Installed Plugins** section above and get their own tab in the second + nav row +5. Toggle the plugin to enabled +6. From **Overview**, click **Restart Display Service** -**Popular First Plugins:** -- `clock-simple` - Simple digital clock -- `weather` - Weather forecast -- `nhl-scores` - NHL scores (if you're a hockey fan) +You can also install community plugins straight from a GitHub URL using the +**Install from GitHub** section further down the same tab — see +[PLUGIN_STORE_GUIDE.md](PLUGIN_STORE_GUIDE.md) for details. ### Step 4: Configure Plugins -1. Navigate to **Plugin Management** tab -2. Find a plugin you installed -3. Click the ⚙️ **Configure** button -4. Edit settings (e.g., favorite teams, update intervals) -5. Click **Save** -6. Click **Restart Display** +1. Each installed plugin gets its own tab in the second navigation row +2. Open that plugin's tab to edit its settings (favorite teams, API keys, + update intervals, display duration, etc.) +3. Click **Save** +4. Restart the display service from **Overview** so the new settings take + effect **Example: Weather Plugin** - Set your location (city, state, country) -- Add API key from OpenWeatherMap (free signup) -- Set update interval (300 seconds recommended) +- Add an API key from OpenWeatherMap (free signup) to + `config/config_secrets.json` or directly in the plugin's config screen +- Set the update interval (300 seconds is reasonable) --- ## Testing Your Display -### Quick Test +### Run a single plugin on demand -1. Navigate to **Overview** tab -2. Click **Test Display** button -3. You should see a test pattern on your LED matrix +The fastest way to verify a plugin works without waiting for the rotation: -### 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 -2. Find a plugin -3. Click **Show Now** button -4. The plugin should display immediately -5. Click **Stop** to return to rotation +### Check the live preview and logs -### Check Logs - -1. Navigate to **Logs** tab -2. Watch real-time logs -3. Look for any ERROR messages -4. Normal operation shows INFO messages about plugin rotation +- 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 + panel. +- The **Logs** tab streams the display and web service logs. Look for + `ERROR` lines if something isn't working; normal operation just shows + `INFO` messages about plugin rotation. --- @@ -156,12 +154,12 @@ You should see: **Check:** 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` -4. Hardware configuration matches your matrix (rows/columns) +4. Hardware configuration matches your matrix (rows/cols/chain length) **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` ### Web Interface Won't Load @@ -169,8 +167,8 @@ You should see: **Check:** 1. Pi is connected to network: `ping your-pi-ip` 2. Web service running: `sudo systemctl status ledmatrix-web` -3. Correct port: Use `:5050` not `:5000` -4. Firewall not blocking port 5050 +3. Correct port: the web UI listens on `:5000` +4. Firewall not blocking port 5000 **Fix:** 1. Restart web service: `sudo systemctl restart ledmatrix-web` @@ -179,15 +177,15 @@ You should see: ### Plugins Not Showing **Check:** -1. Plugins are enabled (toggle switch in Plugin Management) -2. Display has been restarted after enabling -3. Plugin duration is reasonable (not too short) -4. No errors in logs for the plugin +1. Plugin is enabled (toggle on the **Plugin Manager** tab) +2. Display service was restarted after enabling +3. Plugin's display duration is non-zero +4. No errors in the **Logs** tab for that plugin **Fix:** -1. Enable plugin in Plugin Management -2. Restart display -3. Check logs for plugin-specific errors +1. Enable the plugin from **Plugin Manager** +2. Click **Restart Display Service** on **Overview** +3. Check the **Logs** tab for plugin-specific errors ### Weather Plugin Shows "No Data" @@ -207,18 +205,18 @@ You should see: ### Customize Your Display -**Adjust Display Durations:** -- Navigate to Settings → Durations -- Set how long each plugin displays -- Save and restart +**Adjust display durations:** +- Each plugin's tab has a **Display Duration (seconds)** field — set how + long that plugin stays on screen each rotation. -**Organize Plugin Order:** -- Use Plugin Management to enable/disable plugins -- Display cycles through enabled plugins in order +**Organize plugin order:** +- Use the **Plugin Manager** tab to enable/disable plugins. The display + cycles through enabled plugins in the order they appear. -**Add More Plugins:** -- Check Plugin Store regularly for new plugins -- Install from GitHub URLs for custom/community plugins +**Add more plugins:** +- Check the **Plugin Store** section of **Plugin Manager** for new plugins. +- Install community plugins straight from a GitHub URL via + **Install from GitHub** on the same tab. ### Enable Advanced Features @@ -279,26 +277,35 @@ sudo journalctl -u ledmatrix-web -f │ ├── config.json # Main configuration │ ├── config_secrets.json # API keys and secrets │ └── wifi_config.json # WiFi settings -├── plugins/ # Installed plugins +├── plugin-repos/ # Installed plugins (default location) ├── cache/ # Cached data └── 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 ``` -Main Interface: http://your-pi-ip:5050 +Main Interface: http://your-pi-ip:5000 -Tabs: -- Overview: System stats and quick actions -- General Settings: Timezone, location, autostart -- Display Settings: Hardware configuration -- Durations: Plugin display times -- Sports Configuration: Per-league settings -- Plugin Management: Enable/disable, configure -- Plugin Store: Install new plugins -- Font Management: Upload and manage fonts -- Logs: Real-time log viewing +System tabs: +- Overview System stats, live preview, quick actions +- General Timezone, location, plugin-system settings +- WiFi Network selection and AP-mode setup +- Schedule Power and dim schedules +- Display Matrix hardware configuration +- Config Editor Raw config.json editor +- Fonts Upload and manage fonts +- 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 +- One tab per installed plugin for its config ``` ### WiFi Access Point @@ -306,7 +313,7 @@ Tabs: ``` Network Name: LEDMatrix-Setup Password: (none - open network) -URL when connected: http://192.168.4.1:5050 +URL when connected: http://192.168.4.1:5000 ``` --- diff --git a/docs/HOW_TO_RUN_TESTS.md b/docs/HOW_TO_RUN_TESTS.md index 53464602..bb6f1664 100644 --- a/docs/HOW_TO_RUN_TESTS.md +++ b/docs/HOW_TO_RUN_TESTS.md @@ -13,7 +13,7 @@ Make sure you have the testing packages installed: pip install -r requirements.txt # 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 @@ -85,8 +85,14 @@ pytest -m slow # Run all tests in the test directory pytest test/ -# Run all integration tests -pytest test/integration/ +# Run plugin tests only +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 @@ -231,20 +237,41 @@ pytest --maxfail=3 ``` test/ -├── conftest.py # Shared fixtures and configuration -├── test_display_controller.py # Display controller tests -├── test_plugin_system.py # Plugin system tests -├── test_display_manager.py # Display manager tests -├── test_config_service.py # Config service tests -├── test_cache_manager.py # Cache manager tests -├── test_font_manager.py # Font manager tests -├── test_error_handling.py # Error handling tests -├── test_config_manager.py # Config manager tests -├── integration/ # Integration tests -│ ├── test_e2e.py # End-to-end tests -│ └── test_plugin_integration.py # Plugin integration tests -├── test_error_scenarios.py # Error scenario tests -└── test_edge_cases.py # Edge case tests +├── conftest.py # Shared fixtures and configuration +├── test_display_controller.py # Display controller tests +├── test_display_manager.py # Display manager tests +├── test_plugin_system.py # Plugin system tests +├── test_plugin_loader.py # Plugin discovery/loading tests +├── test_plugin_loading_failures.py # Plugin failure-mode tests +├── test_cache_manager.py # Cache manager tests +├── test_config_manager.py # Config manager tests +├── test_config_service.py # Config service tests +├── test_config_validation_edge_cases.py # Config edge cases +├── test_font_manager.py # Font manager tests +├── test_layout_manager.py # Layout manager tests +├── test_text_helper.py # Text helper 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 diff --git a/docs/PLUGIN_API_REFERENCE.md b/docs/PLUGIN_API_REFERENCE.md index 33228e51..6e3b4ca3 100644 --- a/docs/PLUGIN_API_REFERENCE.md +++ b/docs/PLUGIN_API_REFERENCE.md @@ -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. +### 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 @@ -228,23 +317,31 @@ date_str = self.display_manager.format_date_with_ordinal(datetime.now()) ### 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 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() ``` +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 #### `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**: -- `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 diff --git a/docs/PLUGIN_DEVELOPMENT_GUIDE.md b/docs/PLUGIN_DEVELOPMENT_GUIDE.md index 7939626b..5315bbe1 100644 --- a/docs/PLUGIN_DEVELOPMENT_GUIDE.md +++ b/docs/PLUGIN_DEVELOPMENT_GUIDE.md @@ -466,7 +466,9 @@ When developing plugins, you'll need to use the APIs provided by the LEDMatrix s **Display Manager** (`self.display_manager`): - `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 - `get_text_width()`, `get_font_height()` - Text utilities - `set_scrolling_state()`, `defer_update()` - Scrolling state management diff --git a/docs/README.md b/docs/README.md index 5cd3db2d..24345c52 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,199 +1,84 @@ # 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 -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 +Start here: -### For Developers -1. **Plugin Development**: See [PLUGIN_DEVELOPMENT_GUIDE.md](PLUGIN_DEVELOPMENT_GUIDE.md) for complete guide -2. **Advanced Patterns**: Read [ADVANCED_PLUGIN_DEVELOPMENT.md](ADVANCED_PLUGIN_DEVELOPMENT.md) for advanced techniques -3. **API Reference**: Check [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md) for available methods -4. **Configuration**: See [PLUGIN_CONFIGURATION_GUIDE.md](PLUGIN_CONFIGURATION_GUIDE.md) for config schemas +1. [PLUGIN_DEVELOPMENT_GUIDE.md](PLUGIN_DEVELOPMENT_GUIDE.md) — end-to-end workflow +2. [PLUGIN_QUICK_REFERENCE.md](PLUGIN_QUICK_REFERENCE.md) — cheat sheet +3. [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md) — display, cache, and plugin-manager APIs +4. [PLUGIN_ERROR_HANDLING.md](PLUGIN_ERROR_HANDLING.md) — error-handling patterns +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 -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 +Going deeper: -## 📋 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 -- [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 +## Configuring plugins -### ⚡ Advanced Features -- [ADVANCED_FEATURES.md](ADVANCED_FEATURES.md) - Vegas scroll mode, on-demand display, cache management, background services, permissions +- [PLUGIN_CONFIG_QUICK_START.md](PLUGIN_CONFIG_QUICK_START.md) — minimal config you need +- [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 -- [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 +## Advanced features -### 🏗️ Plugin Features & Extensions -- [PLUGIN_CUSTOM_ICONS.md](PLUGIN_CUSTOM_ICONS.md) - Custom plugin icons -- [PLUGIN_CUSTOM_ICONS_FEATURE.md](PLUGIN_CUSTOM_ICONS_FEATURE.md) - Custom icons implementation -- [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 +- [ADVANCED_FEATURES.md](ADVANCED_FEATURES.md) — Vegas scroll, on-demand display, + cache management, background services, permissions +- [FONT_MANAGER.md](FONT_MANAGER.md) — font system -### 📡 API 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 +## Reference -### 🏛️ Architecture & Design -- [PLUGIN_ARCHITECTURE_SPEC.md](PLUGIN_ARCHITECTURE_SPEC.md) - Complete plugin system specification -- [PLUGIN_CONFIG_ARCHITECTURE.md](PLUGIN_CONFIG_ARCHITECTURE.md) - Configuration system architecture -- [PLUGIN_CONFIG_CORE_PROPERTIES.md](PLUGIN_CONFIG_CORE_PROPERTIES.md) - Core configuration properties +- [REST_API_REFERENCE.md](REST_API_REFERENCE.md) — all web-interface HTTP endpoints +- [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md) — Python APIs available to plugins +- [DEVELOPER_QUICK_REFERENCE.md](DEVELOPER_QUICK_REFERENCE.md) — common dev tasks +- [PLUGIN_IMPLEMENTATION_SUMMARY.md](PLUGIN_IMPLEMENTATION_SUMMARY.md) — what the plugin system actually does -### 🛠️ Development & Tools -- [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 +## Contributing to LEDMatrix itself -### 🔄 Migration & Updates -- [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md) - Breaking changes and migration instructions -- [SSH_UNAVAILABLE_AFTER_INSTALL.md](SSH_UNAVAILABLE_AFTER_INSTALL.md) - SSH troubleshooting after install +- [DEVELOPMENT.md](DEVELOPMENT.md) — environment setup +- [HOW_TO_RUN_TESTS.md](HOW_TO_RUN_TESTS.md) — running the test suite +- [MULTI_ROOT_WORKSPACE_SETUP.md](MULTI_ROOT_WORKSPACE_SETUP.md) — multi-repo workspace +- [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md) — breaking changes between releases -### 📚 Miscellaneous -- [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 +## Archive -## 🎯 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 -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 +## Contributing to the docs -### I want to create a plugin -1. [PLUGIN_DEVELOPMENT_GUIDE.md](PLUGIN_DEVELOPMENT_GUIDE.md) - Complete development guide -2. [PLUGIN_API_REFERENCE.md](PLUGIN_API_REFERENCE.md) - Available methods and APIs -3. [ADVANCED_PLUGIN_DEVELOPMENT.md](ADVANCED_PLUGIN_DEVELOPMENT.md) - Advanced patterns -4. [PLUGIN_CONFIGURATION_GUIDE.md](PLUGIN_CONFIGURATION_GUIDE.md) - Configuration setup -5. [PLUGIN_ARCHITECTURE_SPEC.md](PLUGIN_ARCHITECTURE_SPEC.md) - Complete specification - -### 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.* +- Markdown only, professional tone, minimal emoji. +- Prefer adding to an existing page over creating a new one. If you add a + new page, link it from this index in the section it belongs to. +- If a page becomes obsolete, move it to `docs/archive/` rather than + deleting it, so links don't rot. +- Keep examples runnable — paths, commands, and config keys here should + match what's actually in the repo. diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index 9761b6fc..e173e720 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -47,13 +47,15 @@ bash scripts/diagnose_web_interface.sh # WiFi setup verification ./scripts/verify_wifi_setup.sh -# Weather plugin troubleshooting -./troubleshoot_weather.sh - # Captive portal troubleshooting ./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 ```bash @@ -85,7 +87,7 @@ python3 web_interface/start.py #### Service Not Running/Starting **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)` **Solutions:** @@ -157,13 +159,13 @@ sudo systemctl restart ledmatrix-web **Symptoms:** - Error: `Address already in use` -- Service fails to bind to port 5050 +- Service fails to bind to port 5000 **Solutions:** 1. **Check what's using the port:** ```bash - sudo lsof -i :5050 + sudo lsof -i :5000 ``` 2. **Kill the conflicting process:** @@ -265,7 +267,7 @@ sudo systemctl cat ledmatrix-web | grep User 6. **Manually enable AP mode:** ```bash # Via API - curl -X POST http://localhost:5050/api/wifi/ap/enable + curl -X POST http://localhost:5000/api/wifi/ap/enable # Via Python python3 -c " @@ -291,9 +293,8 @@ sudo systemctl cat ledmatrix-web | grep User ``` 2. **Use correct IP address and port:** - - Correct: `http://192.168.4.1:5050` - - NOT: `http://192.168.4.1` (port 80) - - NOT: `http://192.168.4.1:5000` + - Correct: `http://192.168.4.1:5000` + - NOT: `http://192.168.4.1` (port 80 — nothing listens there) 3. **Check wlan0 has correct IP:** ```bash @@ -309,7 +310,7 @@ sudo systemctl cat ledmatrix-web | grep User 5. **Test from the Pi itself:** ```bash - curl http://192.168.4.1:5050 + curl http://192.168.4.1:5000 # Should return HTML ``` @@ -340,11 +341,11 @@ sudo systemctl cat ledmatrix-web | grep User 4. **Manual captive portal testing:** - Try these URLs manually: - - `http://192.168.4.1:5050` + - `http://192.168.4.1:5000` - `http://captive.apple.com` - `http://connectivitycheck.gstatic.com/generate_204` -#### Firewall Blocking Port 5050 +#### Firewall Blocking Port 5000 **Symptoms:** - Services running but cannot connect @@ -357,9 +358,9 @@ sudo systemctl cat ledmatrix-web | grep User sudo ufw status ``` -2. **Allow port 5050:** +2. **Allow port 5000:** ```bash - sudo ufw allow 5050/tcp + sudo ufw allow 5000/tcp ``` 3. **Check iptables:** @@ -372,7 +373,7 @@ sudo systemctl cat ledmatrix-web | grep User sudo ufw disable # Test if it works, then re-enable and add rule 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:** - - Navigate to Plugin Management tab - - Toggle the switch to enable - - Restart display + - Open the **Plugin Manager** tab + - Toggle the plugin switch to enable + - From **Overview**, click **Restart Display Service** #### Plugin Not Loading @@ -690,12 +691,12 @@ nslookup api.openweathermap.org dig api.openweathermap.org # Test HTTP endpoint -curl -I http://your-pi-ip:5050 -curl http://192.168.4.1:5050 +curl -I http://your-pi-ip:5000 +curl http://192.168.4.1:5000 # Check listening ports -sudo lsof -i :5050 -sudo netstat -tuln | grep 5050 +sudo lsof -i :5000 +sudo netstat -tuln | grep 5000 # Check network interfaces ip addr show @@ -808,7 +809,7 @@ echo "" echo "4. Network Status:" 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 "5. File Structure:" @@ -837,22 +838,22 @@ A properly functioning system should show: ``` 2. **Web Interface Accessible:** - - Navigate to http://your-pi-ip:5050 + - Navigate to http://your-pi-ip:5000 - Page loads successfully - Display preview visible 3. **Logs Show Normal Operation:** ``` - INFO: Web interface started on port 5050 + INFO: Web interface started on port 5000 INFO: Loaded X plugins INFO: Display rotation active ``` 4. **Process Listening on Port:** ```bash - $ sudo lsof -i :5050 + $ sudo lsof -i :5000 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:**