docs(reference): add auto_update, drop drifted line numbers, fix UI and service details

- CONFIG_REFERENCE: document the top-level auto_update.enabled key (read
  by web_interface/auto_update.py and src/auto_update_setup.py); replace
  drifted file:line references with function names; the template's
  dim_schedule mode is "global".
- ADVANCED_FEATURES: core does not read a per-plugin background_service
  block (the sports plugins read their own), and priority is "higher
  number = higher priority" on FetchRequest but not used for ordering.
- WEB_INTERFACE_GUIDE: the General tab toggle is "Web Display Autostart"
  (web interface service), brightness is 1-100, and config paths are
  relative to the LEDMatrix folder, not /config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-09-22 16:29:41 -04:00
co-authored by Claude Opus 5.5
parent 8cb91480ed
commit d80c82905f
3 changed files with 30 additions and 22 deletions
+12 -6
View File
@@ -886,7 +886,13 @@ Cache Check → Background Fetch → Partial Data → Completion → Cache
### Configuration ### Configuration
Enable background service per plugin in `config/config.json`: Core does not read a `background_service` config block: the service itself
(`src/background_data_service.py`) is a process-wide singleton, and its
worker count is whatever the first caller of `get_background_service()`
passes. The sports scoreboard plugins read their own
`background_service` settings and pass them to it, so the exact keys and
where they sit (top level or per league) are defined by each plugin's
`config_schema.json`. A typical block looks like:
```json ```json
{ {
@@ -907,11 +913,11 @@ Enable background service per plugin in `config/config.json`:
| Setting | Default | Description | | Setting | Default | Description |
|---------|---------|-------------| |---------|---------|-------------|
| `enabled` | `false` | Enable background service for this plugin | | `enabled` | plugin-defined | Use the background service for this plugin's fetches |
| `max_workers` | `3` | Max concurrent background tasks | | `max_workers` | `3` | Max concurrent background tasks |
| `request_timeout` | `30` | Timeout per API request (seconds) | | `request_timeout` | `30` | Timeout per API request (seconds) |
| `max_retries` | `3` | Retry attempts on failure | | `max_retries` | `3` | Retry attempts on failure |
| `priority` | `1` | Task priority (1=highest, 10=lowest) | | `priority` | `1` | Stored on each request (higher number = higher priority, per `FetchRequest`), but the service runs requests in submission order; it does not reorder by priority |
### Performance Impact ### Performance Impact
@@ -928,9 +934,9 @@ Enable background service per plugin in `config/config.json`:
The background data service is used by all of the sports scoreboard The background data service is used by all of the sports scoreboard
plugins (football, hockey, baseball/MLB, basketball, soccer, lacrosse, plugins (football, hockey, baseball/MLB, basketball, soccer, lacrosse,
F1, UFC), the odds ticker, and the leaderboard plugin. Each plugin's F1, UFC), the odds ticker, and the leaderboard plugin. Each plugin reads
`background_service` block (under its own config namespace) follows the its own `background_service` block (under its own config namespace); check
same shape as the example above. that plugin's `config_schema.json` for the keys it accepts.
### Error Handling & Fallback ### Error Handling & Fallback
+10 -9
View File
@@ -16,6 +16,7 @@ tooling against it.
| Key | Type / default | Meaning | Read by | | Key | Type / default | Meaning | Read by |
|---|---|---|---| |---|---|---|---|
| `web_display_autostart` | bool, `true` | Whether the web interface service starts with the system | `scripts/utils/start_web_conditionally.py` | | `web_display_autostart` | bool, `true` | Whether the web interface service starts with the system | `scripts/utils/start_web_conditionally.py` |
| `auto_update.enabled` | bool, `false` | Weekly automatic updates: LEDMatrix code first (health-checked, rolled back on failure), then installed plugins. Toggle in the General tab or install with `first_time_install.sh --enable-auto-update` | `web_interface/auto_update.py`, `src/auto_update_setup.py` (`is_enabled()`) |
| `timezone` | string, `"America/New_York"` | IANA timezone for schedules and displays | `ConfigManager.get_timezone()` | | `timezone` | string, `"America/New_York"` | IANA timezone for schedules and displays | `ConfigManager.get_timezone()` |
| `target_fps` | int, `100` | Legacy "Scroll Frame Rate". Core scrolling no longer reads it: scroll frames are presented at `display.hardware.limit_refresh_rate_hz` divided by each scroll's frame hold, and speed comes from each plugin's scroll settings. Still exposed to plugins via `BasePlugin.global_config` | `src/plugin_system/base_plugin.py` | | `target_fps` | int, `100` | Legacy "Scroll Frame Rate". Core scrolling no longer reads it: scroll frames are presented at `display.hardware.limit_refresh_rate_hz` divided by each scroll's frame hold, and speed comes from each plugin's scroll settings. Still exposed to plugins via `BasePlugin.global_config` | `src/plugin_system/base_plugin.py` |
| `location` | object | `city` / `state` / `country`. Supplies the **default** for a plugin's own `location_city` / `location_state` / `location_country` setting, so weather, radar and friends follow this device without being configured twice. A value saved on the plugin itself still overrides it. | `SchemaManager.apply_device_location()`, then plugins via merged config | | `location` | object | `city` / `state` / `country`. Supplies the **default** for a plugin's own `location_city` / `location_state` / `location_country` setting, so weather, radar and friends follow this device without being configured twice. A value saved on the plugin itself still overrides it. | `SchemaManager.apply_device_location()`, then plugins via merged config |
@@ -29,18 +30,18 @@ tooling against it.
| `start_time` / `end_time` | `"HH:MM"`, `07:00`–`23:00` | Global-mode on/off times | | `start_time` / `end_time` | `"HH:MM"`, `07:00`–`23:00` | Global-mode on/off times |
| `days.<weekday>.{enabled,start_time,end_time}` | per-day objects | Per-day-mode overrides | | `days.<weekday>.{enabled,start_time,end_time}` | per-day objects | Per-day-mode overrides |
Read by `DisplayController` (`src/display_controller.py`, `_check_schedule` Read by `DisplayController._check_schedule()` (`src/display_controller.py`).
around line 603). Managed in the web UI under Schedule. Managed in the web UI under Schedule.
## `dim_schedule` — scheduled brightness dimming ## `dim_schedule` — scheduled brightness dimming
Same shape as `schedule`, plus: Same shape as `schedule` (the template sets its `mode` to `"global"`), plus:
| Key | Type / default | Meaning | | Key | Type / default | Meaning |
|---|---|---| |---|---|---|
| `dim_brightness` | int, `30` | Brightness percentage applied while the dim window is active | | `dim_brightness` | int, `30` | Brightness percentage applied while the dim window is active |
Read by `DisplayController` (`src/display_controller.py` around line 770; Read by `DisplayController._check_dim_schedule()` (`src/display_controller.py`;
saved via `POST /api/v3/config/dim-schedule`). The display returns to saved via `POST /api/v3/config/dim-schedule`). The display returns to
`display.hardware.brightness` outside the window. `display.hardware.brightness` outside the window.
@@ -101,10 +102,10 @@ logical image to multiple chained physical panels.
| Key | Type / default | Meaning | Read by | | Key | Type / default | Meaning | Read by |
|---|---|---|---| |---|---|---|---|
| `display_durations` | object, `{}` | Per-plugin display duration in seconds, keyed by plugin id (e.g. `"clock": 15`) | `src/display_controller.py:1030` | | `display_durations` | object, `{}` | Per-plugin display duration in seconds, keyed by plugin id (e.g. `"clock": 15`) | `DisplayController._get_display_duration()` (`src/display_controller.py`) |
| `plugin_rotation_order` | array, `[]` | Explicit rotation order of plugin ids; empty = all enabled plugins in discovery order | `src/display_controller.py:2894` | | `plugin_rotation_order` | array, `[]` | Explicit rotation order of plugin ids; empty = all enabled plugins in discovery order | `DisplayController._apply_plugin_rotation_order()` (`src/display_controller.py`) |
| `use_short_date_format` | bool, `true` | Compact date rendering in sports scoreboards | `src/base_classes/sports/core.py` | | `use_short_date_format` | bool, `true` | Compact date rendering in sports scoreboards | `src/base_classes/sports/core.py` |
| `dynamic_duration.max_duration_seconds` | int, optional | Cap for plugins that request dynamic display time | `src/display_controller.py:405` | | `dynamic_duration.max_duration_seconds` | int, optional | Cap for plugins that request dynamic display time | `DisplayController._get_global_dynamic_cap()` (`src/display_controller.py`) |
## `display.vegas_scroll` — continuous scroll mode ## `display.vegas_scroll` — continuous scroll mode
@@ -153,7 +154,7 @@ Read by `src/common/sync_manager.py` and `src/display_controller.py`.
|---|---|---| |---|---|---|
| `role` | `"standalone"` (default), `"leader"`, or `"follower"` | This device's role in a synced pair | | `role` | `"standalone"` (default), `"leader"`, or `"follower"` | This device's role in a synced pair |
| `port` | int, `5765` | TCP port used for sync traffic | | `port` | int, `5765` | TCP port used for sync traffic |
| `follower_position` | `"left"` (default) or `"right"` | Which half of the combined image this follower renders (`src/display_controller.py:522`) | | `follower_position` | `"left"` (default) or `"right"` | Which half of the combined image this follower renders (`src/display_controller.py`) |
## `plugin_system` ## `plugin_system`
@@ -174,5 +175,5 @@ See [PLUGIN_CONFIG_CORE_PROPERTIES.md](PLUGIN_CONFIG_CORE_PROPERTIES.md).
| Key | Meaning | | Key | Meaning |
|---|---| |---|---|
| `github.api_token` | Optional GitHub token the Plugin Store uses to avoid API rate limits (`src/plugin_system/store_manager.py:348`) | | `github.api_token` | Optional GitHub token the Plugin Store uses to avoid API rate limits (`src/plugin_system/store_manager.py`) |
| `<plugin-id>.*` | Secrets a plugin declares with `"x-secret": true` in its config schema; merged into that plugin's config at load time | | `<plugin-id>.*` | Secrets a plugin declares with `"x-secret": true` in its config schema; merged into that plugin's config at load time |
+8 -7
View File
@@ -95,7 +95,8 @@ Configure basic system settings:
plugins plugins
- **Plugin System Settings** — including the `plugins_directory` (default - **Plugin System Settings** — including the `plugins_directory` (default
`plugin-repos/`) used by the plugin loader `plugin-repos/`) used by the plugin loader
- **Autostart** options for the display service - **Web Display Autostart** — whether the web interface service starts
with the system (`web_display_autostart`)
- **Automatic updates** — once a week, update LEDMatrix and every installed - **Automatic updates** — once a week, update LEDMatrix and every installed
plugin with a newer version. Off by default. Runs 2–5 AM local time when plugin with a newer version. Off by default. Runs 2–5 AM local time when
possible, otherwise within a day of being due. The last result and next possible, otherwise within a day of being due. The last result and next
@@ -246,7 +247,7 @@ View real-time system logs:
### Changing Display Brightness ### Changing Display Brightness
1. Open the **Display** tab 1. Open the **Display** tab
2. Adjust the **Brightness** slider (0–100) 2. Adjust the **Brightness** slider (1–100)
3. Click **Save** 3. Click **Save**
4. Click **Restart Display Service** on the **Overview** tab 4. Click **Restart Display Service** on the **Overview** tab
@@ -428,10 +429,10 @@ The web interface uses modern web technologies:
### File Locations ### File Locations
**Configuration:** **Configuration** (relative to the LEDMatrix folder, e.g. `~/LEDMatrix`):
- Main config: `/config/config.json` - Main config: `config/config.json`
- Secrets: `/config/config_secrets.json` - Secrets: `config/config_secrets.json`
- WiFi config: `/config/wifi_config.json` - WiFi config: `config/wifi_config.json`
**Logs:** **Logs:**
- Display service: `sudo journalctl -u ledmatrix -f` - Display service: `sudo journalctl -u ledmatrix -f`
@@ -444,7 +445,7 @@ The web interface uses modern web technologies:
the Plugin Store install flow and the schema loader additionally the Plugin Store install flow and the schema loader additionally
probe `plugins/` so dev symlinks created by probe `plugins/` so dev symlinks created by
`scripts/dev/dev_plugin_setup.sh` keep working. `scripts/dev/dev_plugin_setup.sh` keep working.
- Plugin config: `/config/config.json` (per-plugin sections) - Plugin config: `config/config.json` (per-plugin sections)
--- ---