mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-10 17:16:36 +00:00
docs(plugin-config): match the config tab, icon and web-action docs to the code
- PLUGIN_CONFIG_QUICK_START / PLUGIN_CONFIGURATION_TABS / PLUGIN_CONFIGURATION_GUIDE: there is no "Reset to Defaults" button (the tab has Refresh, Update, Uninstall, Save Configuration); plugin config hot-reloads (ConfigService + on_config_change), so no restart; the schema is found by the fixed name config_schema.json, not a manifest config_schema field; the tab row is "Plugin Manager", not "Plugins"; forms are server-rendered from /v3/partials/plugin-config/<id>; the duration hook is get_display_duration()/display_duration; a class_name mismatch raises PluginError; the store requires id, name, class_name and display_modes (not version); plugin_system.debug/log_level do not exist (use run.py -d / LEDMATRIX_DEBUG). Drop "future" features that shipped. - PLUGIN_CONFIG_CORE_PROPERTIES: list all of CORE_PLUGIN_PROPERTIES, including skin, skin_options and the vegas_* tuning keys. - PLUGIN_CUSTOM_ICONS: icon is only a Font Awesome class (fallback fa-puzzle-piece); emoji/URL icons and getPluginIcon() never existed in v3. Note that /api/v3/plugins/installed currently omits icon. - PLUGIN_WEB_UI_ACTIONS (+ example JSON): success_message, error_message and step1_message are never read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@ The LEDMatrix system uses a plugin-based architecture where each plugin manages
|
|||||||
1. **Install a plugin** from the Plugin Store in the web interface
|
1. **Install a plugin** from the Plugin Store in the web interface
|
||||||
2. **Navigate to the plugin's configuration tab** (automatically created when installed)
|
2. **Navigate to the plugin's configuration tab** (automatically created when installed)
|
||||||
3. **Configure settings** using the auto-generated form
|
3. **Configure settings** using the auto-generated form
|
||||||
4. **Save configuration** and restart the display service
|
4. **Save configuration**; the running display applies it without a restart
|
||||||
|
|
||||||
For detailed information, see the sections below.
|
For detailed information, see the sections below.
|
||||||
|
|
||||||
@@ -189,19 +189,20 @@ plugin-repos/
|
|||||||
"author": "Your Name",
|
"author": "Your Name",
|
||||||
"entry_point": "manager.py",
|
"entry_point": "manager.py",
|
||||||
"class_name": "MyPlugin",
|
"class_name": "MyPlugin",
|
||||||
"display_modes": ["my_plugin"],
|
"display_modes": ["my_plugin"]
|
||||||
"config_schema": "config_schema.json"
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The required fields the plugin loader will check for are `id`,
|
The Plugin Store refuses a manifest that lacks any of `id`, `name`,
|
||||||
`name`, `version`, `class_name`, and `display_modes`. `entry_point`
|
`class_name` or `display_modes` (`store_manager.py`); the loader itself
|
||||||
defaults to `manager.py` if omitted. `config_schema` must be a
|
needs `class_name`. `version` is not required, but the store compares it
|
||||||
**file path** (relative to the plugin directory) — the schema itself
|
with the registry's `latest_version` to offer updates, so set it.
|
||||||
lives in a separate JSON file, not inline in the manifest. The
|
`entry_point` defaults to `manager.py` if omitted. The config schema is not
|
||||||
`class_name` value must match the actual class defined in the entry
|
named in the manifest: it is always the file `config_schema.json` in the
|
||||||
point file **exactly** (case-sensitive, no spaces); otherwise the
|
plugin directory. The `class_name` value must match the actual class
|
||||||
loader fails with `AttributeError` at load time.
|
defined in the entry point file **exactly** (case-sensitive, no spaces);
|
||||||
|
otherwise the loader fails with a `PluginError` ("Class ... not found in
|
||||||
|
module") at load time.
|
||||||
|
|
||||||
### Plugin Manager Class
|
### Plugin Manager Class
|
||||||
|
|
||||||
@@ -223,9 +224,11 @@ class MyPlugin(BasePlugin):
|
|||||||
"""Render plugin content to the LED matrix."""
|
"""Render plugin content to the LED matrix."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_duration(self):
|
# BasePlugin.get_display_duration() already returns
|
||||||
"""Get display duration for this plugin"""
|
# self.config['display_duration'] (default 15s); override it only to
|
||||||
return self.config.get('duration', 30)
|
# vary the duration with the content.
|
||||||
|
def get_display_duration(self):
|
||||||
|
return self.config.get('display_duration', 30)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Dynamic Duration Configuration
|
### Dynamic Duration Configuration
|
||||||
@@ -259,7 +262,7 @@ Each installed plugin automatically gets its own dedicated configuration tab in
|
|||||||
|
|
||||||
### Accessing Plugin Configuration
|
### Accessing Plugin Configuration
|
||||||
|
|
||||||
1. Navigate to the **Plugins** tab to see all installed plugins
|
1. Navigate to the **Plugin Manager** tab to see all installed plugins
|
||||||
2. Click the **Configure** button on any plugin card, or
|
2. Click the **Configure** button on any plugin card, or
|
||||||
3. Click directly on the plugin's tab button in the navigation bar
|
3. Click directly on the plugin's tab button in the navigation bar
|
||||||
|
|
||||||
@@ -278,7 +281,6 @@ Configuration forms are automatically generated from each plugin's `config_schem
|
|||||||
- **Type-safe inputs**: Form inputs match JSON Schema types
|
- **Type-safe inputs**: Form inputs match JSON Schema types
|
||||||
- **Default values**: Fields show current values or schema defaults
|
- **Default values**: Fields show current values or schema defaults
|
||||||
- **Real-time validation**: Input constraints enforced (min, max, maxLength, etc.)
|
- **Real-time validation**: Input constraints enforced (min, max, maxLength, etc.)
|
||||||
- **Reset to defaults**: One-click reset to restore original settings
|
|
||||||
- **Help text**: Each field shows description from schema
|
- **Help text**: Each field shows description from schema
|
||||||
|
|
||||||
For more details, see [Plugin Configuration Tabs](PLUGIN_CONFIGURATION_TABS.md).
|
For more details, see [Plugin Configuration Tabs](PLUGIN_CONFIGURATION_TABS.md).
|
||||||
@@ -337,20 +339,16 @@ The configuration system uses JSON Schema Draft-07 for validation:
|
|||||||
2. **Configuration errors**: Validate plugin configuration against schema
|
2. **Configuration errors**: Validate plugin configuration against schema
|
||||||
3. **Display issues**: Check display durations and plugin display methods
|
3. **Display issues**: Check display durations and plugin display methods
|
||||||
4. **Performance**: Monitor plugin update intervals and resource usage
|
4. **Performance**: Monitor plugin update intervals and resource usage
|
||||||
5. **Tab not showing**: Verify `config_schema.json` exists and is referenced in manifest
|
5. **Form missing or wrong**: Verify `config_schema.json` exists in the plugin directory and is valid JSON Schema
|
||||||
6. **Settings not saving**: Check validation errors and ensure all required fields are filled
|
6. **Settings not saving**: Check validation errors and ensure all required fields are filled
|
||||||
|
|
||||||
### Debug Mode
|
### Debug Mode
|
||||||
|
|
||||||
Enable debug logging to troubleshoot plugin issues:
|
There is no config key for debug logging. Run the display with debug
|
||||||
|
logging instead:
|
||||||
|
|
||||||
```json
|
```bash
|
||||||
{
|
python3 run.py -d # or: LEDMATRIX_DEBUG=true python3 run.py
|
||||||
"plugin_system": {
|
|
||||||
"debug": true,
|
|
||||||
"log_level": "debug"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## See Also
|
## See Also
|
||||||
|
|||||||
@@ -1,19 +1,8 @@
|
|||||||
# Plugin Configuration Tabs
|
# Plugin Configuration Tabs
|
||||||
|
|
||||||
> **Status note:** this doc was written during the rollout of the
|
|
||||||
> per-plugin configuration tab feature. The feature itself is shipped
|
|
||||||
> and working in the current v3 web interface, but a few file paths
|
|
||||||
> in the "Implementation Details" section below still reference the
|
|
||||||
> pre-v3 file layout (`web_interface_v2.py`, `templates/index_v2.html`).
|
|
||||||
> The current implementation lives in `web_interface/app.py`,
|
|
||||||
> `web_interface/blueprints/api_v3/` (plugin config handlers in
|
|
||||||
> `plugins.py`), and `web_interface/templates/v3/`.
|
|
||||||
> The user-facing description (Overview, Features, Form Generation
|
|
||||||
> Process) is still accurate.
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Each installed plugin now gets its own dedicated configuration tab in the web interface. This provides a clean, organized way to configure plugins without cluttering the main Plugins management tab.
|
Each installed plugin now gets its own dedicated configuration tab in the web interface. This provides a clean, organized way to configure plugins without cluttering the **Plugin Manager** tab.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -21,24 +10,27 @@ Each installed plugin now gets its own dedicated configuration tab in the web in
|
|||||||
- **JSON Schema-Based Forms**: Configuration forms are automatically generated based on each plugin's `config_schema.json`
|
- **JSON Schema-Based Forms**: Configuration forms are automatically generated based on each plugin's `config_schema.json`
|
||||||
- **Type-Safe Inputs**: Form inputs are created based on the JSON Schema type (boolean, number, string, array, enum)
|
- **Type-Safe Inputs**: Form inputs are created based on the JSON Schema type (boolean, number, string, array, enum)
|
||||||
- **Default Values**: All fields show current values or fallback to schema defaults
|
- **Default Values**: All fields show current values or fallback to schema defaults
|
||||||
- **Reset Functionality**: Users can reset all settings to defaults with one click
|
|
||||||
- **Real-Time Validation**: Input constraints from JSON Schema are enforced (min, max, maxLength, etc.)
|
- **Real-Time Validation**: Input constraints from JSON Schema are enforced (min, max, maxLength, etc.)
|
||||||
|
|
||||||
## User Experience
|
## User Experience
|
||||||
|
|
||||||
### Accessing Plugin Configuration
|
### Accessing Plugin Configuration
|
||||||
|
|
||||||
1. Navigate to the **Plugins** tab to see all installed plugins
|
1. Navigate to the **Plugin Manager** tab to see all installed plugins
|
||||||
2. Click the **Configure** button on any plugin card
|
2. Click the **Configure** button on any plugin card
|
||||||
3. You'll be automatically taken to that plugin's configuration tab
|
3. You'll be automatically taken to that plugin's configuration tab
|
||||||
4. Alternatively, click directly on the plugin's tab button (marked with a puzzle piece icon)
|
4. Alternatively, click directly on the plugin's tab button in the second nav row
|
||||||
|
|
||||||
### Configuring a Plugin
|
### Configuring a Plugin
|
||||||
|
|
||||||
1. Open the plugin's configuration tab
|
1. Open the plugin's configuration tab
|
||||||
2. Modify settings using the generated form
|
2. Modify settings using the generated form
|
||||||
3. Click **Save Configuration**
|
3. Click **Save Configuration**. The settings apply to the running display
|
||||||
4. Restart the display service to apply changes
|
without a restart: the display service reloads `config.json` when it
|
||||||
|
changes and calls the plugin's `on_config_change()`
|
||||||
|
|
||||||
|
The tab also has **Refresh** (reload the form), **Update** (update the
|
||||||
|
plugin) and **Uninstall** buttons.
|
||||||
|
|
||||||
### Plugin Manager vs Per-Plugin Configuration
|
### Plugin Manager vs Per-Plugin Configuration
|
||||||
|
|
||||||
@@ -53,22 +45,13 @@ Each installed plugin now gets its own dedicated configuration tab in the web in
|
|||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
To enable automatic configuration tab generation, your plugin must:
|
Every installed plugin gets a tab. To get a generated form in it, include a
|
||||||
|
`config_schema.json` file in the plugin's directory. The name is fixed: the
|
||||||
|
web interface finds the schema by that file name (`SchemaManager` in
|
||||||
|
`src/plugin_system/schema_manager.py`), and no manifest field points to it.
|
||||||
|
|
||||||
1. Include a `config_schema.json` file
|
**Note:** You can optionally specify a Font Awesome `icon` class for your
|
||||||
2. Reference it in your `manifest.json`:
|
plugin tab in `manifest.json`. See [Plugin Custom Icons Guide](PLUGIN_CUSTOM_ICONS.md) for details.
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "your-plugin",
|
|
||||||
"name": "Your Plugin",
|
|
||||||
"icon": "fas fa-star", // Optional: Custom tab icon
|
|
||||||
...
|
|
||||||
"config_schema": "config_schema.json"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note:** You can optionally specify a custom `icon` for your plugin tab. See [Plugin Custom Icons Guide](PLUGIN_CUSTOM_ICONS.md) for details.
|
|
||||||
|
|
||||||
### Supported JSON Schema Types
|
### Supported JSON Schema Types
|
||||||
|
|
||||||
@@ -209,69 +192,32 @@ Renders as: Dropdown select
|
|||||||
|
|
||||||
### Form Generation Process
|
### Form Generation Process
|
||||||
|
|
||||||
1. Web UI loads installed plugins via `/api/v3/plugins/installed`
|
Forms are rendered on the server, not generated in the browser:
|
||||||
2. For each plugin, the backend loads its `config_schema.json`
|
|
||||||
3. Frontend generates a tab button with plugin name
|
|
||||||
4. Frontend generates a form based on the JSON Schema
|
|
||||||
5. Current config values from `config.json` are populated
|
|
||||||
6. When saved, each field is sent to `/api/v3/plugins/config` endpoint
|
|
||||||
|
|
||||||
## Implementation Details
|
1. The web UI loads installed plugins via `/api/v3/plugins/installed` and adds
|
||||||
|
a tab button for each one
|
||||||
### Backend Changes
|
2. Opening a tab loads `/v3/partials/plugin-config/<plugin_id>`
|
||||||
|
(`web_interface/blueprints/pages_v3.py`), which loads the plugin's schema
|
||||||
**File**: `web_interface_v2.py`
|
through `SchemaManager` and its current values from `config.json`
|
||||||
|
3. `web_interface/templates/v3/partials/plugin_config.html` renders the form
|
||||||
- Modified `/api/v3/plugins/installed` endpoint to include `config_schema_data`
|
from the schema (widgets named by `x-widget` are rendered by the scripts in
|
||||||
- Loads each plugin's `config_schema.json` if it exists
|
`web_interface/static/v3/js/widgets/`)
|
||||||
- Returns schema data along with plugin info
|
4. **Save Configuration** posts the form to `/api/v3/plugins/config`
|
||||||
|
(`web_interface/blueprints/api_v3/plugins.py`), which validates it against
|
||||||
### Frontend Changes
|
the schema, writes `config.json` (secret fields go to
|
||||||
|
`config_secrets.json`) and shows a notification
|
||||||
**File**: `templates/index_v2.html`
|
|
||||||
|
|
||||||
New Functions:
|
|
||||||
- `generatePluginTabs(plugins)` - Creates tab buttons and content for each plugin
|
|
||||||
- `generatePluginConfigForm(plugin)` - Generates HTML form from JSON Schema
|
|
||||||
- `savePluginConfiguration(pluginId)` - Saves form data to backend
|
|
||||||
- `resetPluginConfig(pluginId)` - Resets all settings to defaults
|
|
||||||
- `configurePlugin(pluginId)` - Navigates to plugin's tab
|
|
||||||
|
|
||||||
### Data Flow
|
|
||||||
|
|
||||||
```
|
|
||||||
Page Load
|
|
||||||
→ refreshPlugins()
|
|
||||||
→ /api/v3/plugins/installed
|
|
||||||
→ Returns plugins with config_schema_data
|
|
||||||
→ generatePluginTabs()
|
|
||||||
→ Creates tab buttons
|
|
||||||
→ Creates tab content
|
|
||||||
→ generatePluginConfigForm()
|
|
||||||
→ Reads JSON Schema
|
|
||||||
→ Creates form inputs
|
|
||||||
→ Populates current values
|
|
||||||
|
|
||||||
User Saves
|
|
||||||
→ savePluginConfiguration()
|
|
||||||
→ Reads form data
|
|
||||||
→ Converts types per schema
|
|
||||||
→ Sends to /api/v3/plugins/config
|
|
||||||
→ Updates config.json
|
|
||||||
→ Shows success notification
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Plugin Tab Not Appearing
|
### Plugin Tab Not Appearing
|
||||||
|
|
||||||
- Ensure `config_schema.json` exists in plugin directory
|
- Check that the plugin is installed and appears in the **Plugin Manager** tab
|
||||||
- Verify `config_schema` field in `manifest.json`
|
|
||||||
- Check browser console for errors
|
- Check browser console for errors
|
||||||
- Try refreshing plugins (Plugins tab → Refresh button)
|
- Reload the page
|
||||||
|
|
||||||
### Form Not Generating Correctly
|
### Form Not Generating Correctly
|
||||||
|
|
||||||
|
- Ensure `config_schema.json` exists in the plugin directory
|
||||||
- Validate your `config_schema.json` against JSON Schema Draft 07
|
- Validate your `config_schema.json` against JSON Schema Draft 07
|
||||||
- Check that all properties have a `type` field
|
- Check that all properties have a `type` field
|
||||||
- Ensure `default` values match the specified type
|
- Ensure `default` values match the specified type
|
||||||
@@ -283,7 +229,6 @@ User Saves
|
|||||||
- Check that config keys match schema properties
|
- Check that config keys match schema properties
|
||||||
- Verify backend API is accessible
|
- Verify backend API is accessible
|
||||||
- Check browser network tab for API errors
|
- Check browser network tab for API errors
|
||||||
- Ensure display service is restarted after config changes
|
|
||||||
|
|
||||||
## Migration Guide
|
## Migration Guide
|
||||||
|
|
||||||
@@ -301,26 +246,21 @@ If your plugin doesn't have a config schema:
|
|||||||
2. Add descriptions for each property
|
2. Add descriptions for each property
|
||||||
3. Set appropriate defaults
|
3. Set appropriate defaults
|
||||||
4. Add validation constraints (min, max, etc.)
|
4. Add validation constraints (min, max, etc.)
|
||||||
5. Reference the schema in your `manifest.json`
|
|
||||||
|
|
||||||
### Backward Compatibility
|
### Backward Compatibility
|
||||||
|
|
||||||
- Plugins without `config_schema.json` still work normally
|
- Plugins without `config_schema.json` still work normally
|
||||||
- They simply won't have a configuration tab
|
- Their tab shows plain text, number and checkbox inputs for the keys already
|
||||||
|
in their `config.json` section, or "No configuration options available for
|
||||||
|
this plugin." when there are none
|
||||||
- Users can still edit config via the Raw JSON editor
|
- Users can still edit config via the Raw JSON editor
|
||||||
- The Configure button will navigate to a tab with a friendly message
|
|
||||||
|
|
||||||
## Future Enhancements
|
## Beyond the Basic Types
|
||||||
|
|
||||||
Potential improvements for future versions:
|
Nested objects (rendered as collapsible sections), `x-widget` widgets such as
|
||||||
|
`color-picker` and `file-upload`, and more are supported; see
|
||||||
- **Advanced Schema Features**: Support for nested objects, conditional fields
|
[PLUGIN_CONFIGURATION_GUIDE.md](PLUGIN_CONFIGURATION_GUIDE.md) and
|
||||||
- **Visual Validation**: Real-time validation feedback as user types
|
`web_interface/static/v3/js/widgets/README.md`.
|
||||||
- **Color Pickers**: Special input for RGB/color array types
|
|
||||||
- **File Uploads**: Support for image/asset uploads
|
|
||||||
- **Import/Export**: Save and share plugin configurations
|
|
||||||
- **Presets**: Quick-switch between saved configurations
|
|
||||||
- **Documentation Links**: Link schema fields to plugin documentation
|
|
||||||
|
|
||||||
## Example Plugins
|
## Example Plugins
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ The LEDMatrix plugin system automatically manages certain core properties that a
|
|||||||
|
|
||||||
## Core Properties
|
## Core Properties
|
||||||
|
|
||||||
The following properties are automatically managed by the system:
|
The following properties are automatically managed by the system (the list
|
||||||
|
is `CORE_PLUGIN_PROPERTIES` in `src/plugin_system/schema_manager.py`):
|
||||||
|
|
||||||
1. **`enabled`** (boolean)
|
1. **`enabled`** (boolean)
|
||||||
- Default: `true`
|
- Default: `true`
|
||||||
@@ -24,6 +25,24 @@ The following properties are automatically managed by the system:
|
|||||||
- Description: Enable live priority takeover when plugin has live content
|
- Description: Enable live priority takeover when plugin has live content
|
||||||
- Used by DisplayController for priority scheduling
|
- Used by DisplayController for priority scheduling
|
||||||
|
|
||||||
|
4. **`skin`** (string, object or null; no default)
|
||||||
|
- Description: Visual skin id, or a per-mode mapping like `{"live": "my-skin"}`
|
||||||
|
- Not an enum, so a stored value keeps validating after the skin is
|
||||||
|
uninstalled. Skins do not render with the current scoreboard plugins yet
|
||||||
|
(see [SKIN_SYSTEM.md](SKIN_SYSTEM.md)); the key is kept so stored values
|
||||||
|
keep loading and saving
|
||||||
|
|
||||||
|
5. **`skin_options`** (object; no default)
|
||||||
|
- Description: Options passed through to the selected skin
|
||||||
|
|
||||||
|
6. **`vegas_width_pct`**, **`vegas_overflow`**, **`vegas_max_width_screens`**
|
||||||
|
(untyped; no default)
|
||||||
|
- Description: Vegas mode tuning for this plugin — card width as a
|
||||||
|
percentage of the panel, `"rotate"` or `"truncate"` on overflow, and the
|
||||||
|
widest the card may be in screens
|
||||||
|
- Read by `src/vegas_mode/plugin_adapter.py` and `BasePlugin`, which
|
||||||
|
validate the values themselves and ignore a bad one with a log line
|
||||||
|
|
||||||
## How Core Properties Work
|
## How Core Properties Work
|
||||||
|
|
||||||
### Schema Validation
|
### Schema Validation
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
and click **Install**
|
and click **Install**
|
||||||
4. Notice a new tab appears in the second nav row with the plugin's name
|
4. Notice a new tab appears in the second nav row with the plugin's name
|
||||||
5. Click that tab to configure the plugin
|
5. Click that tab to configure the plugin
|
||||||
6. Modify settings and click **Save**
|
6. Modify settings and click **Save Configuration**. The running display
|
||||||
7. From **Overview**, click **Restart Display Service** to see changes
|
picks the change up by itself; no restart is needed
|
||||||
|
|
||||||
That's it! Each installed plugin automatically gets its own configuration tab.
|
That's it! Each installed plugin automatically gets its own configuration tab.
|
||||||
|
|
||||||
@@ -29,7 +29,6 @@ That's it! Each installed plugin automatically gets its own configuration tab.
|
|||||||
- ✅ Proper input types (toggles, numbers, dropdowns)
|
- ✅ Proper input types (toggles, numbers, dropdowns)
|
||||||
- ✅ Help text explaining each setting
|
- ✅ Help text explaining each setting
|
||||||
- ✅ Input validation (min/max, length, etc.)
|
- ✅ Input validation (min/max, length, etc.)
|
||||||
- ✅ One-click reset to defaults
|
|
||||||
|
|
||||||
## 📋 Example Walkthrough
|
## 📋 Example Walkthrough
|
||||||
|
|
||||||
@@ -40,7 +39,7 @@ Let's configure the "Hello World" plugin:
|
|||||||
After installing the plugin, you'll see a new tab:
|
After installing the plugin, you'll see a new tab:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Overview] [General] [...] [Plugins] [Hello World] ← New tab!
|
[Plugin Manager] [Hello World] ← New tab! (second nav row)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Configure Settings
|
### Step 2: Configure Settings
|
||||||
@@ -70,15 +69,16 @@ Display Duration
|
|||||||
How long to display in seconds
|
How long to display in seconds
|
||||||
[10 ]
|
[10 ]
|
||||||
|
|
||||||
[Save Configuration] [Back] [Reset to Defaults]
|
[Refresh] [Update] [Uninstall] [Save Configuration]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Save and Apply
|
### Step 3: Save and Apply
|
||||||
|
|
||||||
1. Modify any settings
|
1. Modify any settings
|
||||||
2. Click **Save Configuration**
|
2. Click **Save Configuration**
|
||||||
3. See confirmation: "Configuration saved for hello-world. Restart display to apply changes."
|
3. See the confirmation notification. Plugin settings apply live: the
|
||||||
4. Restart the display service
|
display service reloads `config.json` when it changes and passes the new
|
||||||
|
settings to the plugin's `on_config_change()`
|
||||||
|
|
||||||
## 🛠️ For Plugin Developers
|
## 🛠️ For Plugin Developers
|
||||||
|
|
||||||
@@ -105,19 +105,14 @@ Create `config_schema.json` in your plugin directory:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Reference it in `manifest.json`:
|
**Done!** The file name is fixed: the web interface looks for
|
||||||
|
`config_schema.json` in the plugin's directory; there is no manifest field
|
||||||
|
for it. Every installed plugin gets a tab; the schema is what turns it into a
|
||||||
|
form.
|
||||||
|
|
||||||
```json
|
**Bonus:** an `icon` field in `manifest.json` names a Font Awesome class for
|
||||||
{
|
the tab (`"icon": "fas fa-star"`). See
|
||||||
"id": "my-plugin",
|
[PLUGIN_CUSTOM_ICONS.md](PLUGIN_CUSTOM_ICONS.md).
|
||||||
"icon": "fas fa-star", // Optional: add a custom icon!
|
|
||||||
"config_schema": "config_schema.json"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Done!** Your plugin now has a configuration tab.
|
|
||||||
|
|
||||||
**Bonus:** Add an `icon` field for a custom tab icon! Use Font Awesome icons (`fas fa-star`), emoji (⭐), or custom images. See [PLUGIN_CUSTOM_ICONS.md](PLUGIN_CUSTOM_ICONS.md) for the full guide.
|
|
||||||
|
|
||||||
## 🎨 Supported Input Types
|
## 🎨 Supported Input Types
|
||||||
|
|
||||||
@@ -171,12 +166,10 @@ User enters: `255, 0, 0`
|
|||||||
|
|
||||||
### For Users
|
### For Users
|
||||||
|
|
||||||
1. **Reset Anytime**: Use "Reset to Defaults" to restore original settings
|
1. **Navigate Back**: Switch to the **Plugin Manager** tab to see the
|
||||||
2. **Navigate Back**: Switch to the **Plugin Manager** tab to see the
|
|
||||||
full list of installed plugins
|
full list of installed plugins
|
||||||
3. **Check Help Text**: Each field has a description explaining what it does
|
2. **Check Help Text**: Each field has a description explaining what it does
|
||||||
4. **Restart Required**: Remember to restart the display service from
|
3. **No Restart Needed**: Saved plugin settings apply to the running display
|
||||||
**Overview** after saving
|
|
||||||
|
|
||||||
### For Developers
|
### For Developers
|
||||||
|
|
||||||
@@ -189,18 +182,17 @@ User enters: `255, 0, 0`
|
|||||||
## 🔧 Troubleshooting
|
## 🔧 Troubleshooting
|
||||||
|
|
||||||
### Tab Not Showing
|
### Tab Not Showing
|
||||||
- Check that `config_schema.json` exists
|
- Check that the plugin is installed and listed under **Plugin Manager**
|
||||||
- Verify `config_schema` is in `manifest.json`
|
|
||||||
- Refresh the page
|
- Refresh the page
|
||||||
- Check browser console for errors
|
- Check browser console for errors
|
||||||
|
|
||||||
### Settings Not Saving
|
### Settings Not Saving
|
||||||
- Ensure plugin is properly installed
|
- Ensure plugin is properly installed
|
||||||
- Restart the display service after saving
|
|
||||||
- Check that all required fields are filled
|
- Check that all required fields are filled
|
||||||
- Look for validation errors in browser console
|
- Look for validation errors in browser console
|
||||||
|
|
||||||
### Form Looks Wrong
|
### Form Looks Wrong
|
||||||
|
- Check that `config_schema.json` is in the plugin's directory
|
||||||
- Validate your JSON Schema
|
- Validate your JSON Schema
|
||||||
- Check that types match your defaults
|
- Check that types match your defaults
|
||||||
- Ensure descriptions are strings
|
- Ensure descriptions are strings
|
||||||
|
|||||||
+34
-282
@@ -2,17 +2,28 @@
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Plugins can specify custom icons that appear next to their name in the web interface tabs. This makes your plugin instantly recognizable and adds visual polish to the UI.
|
A plugin can name an icon for its tab in the web interface's second nav row
|
||||||
|
(next to **Plugin Manager**) with the `icon` field in `manifest.json`.
|
||||||
|
|
||||||
## Icon Types Supported
|
> **Status:** the tab code honors `icon`, but `GET /api/v3/plugins/installed`
|
||||||
|
> (`web_interface/blueprints/api_v3/plugins.py`) does not currently include
|
||||||
|
> the manifest's `icon` in its response, so every tab shows the default
|
||||||
|
> puzzle piece. Setting `icon` is harmless and will take effect once the API
|
||||||
|
> passes it through again.
|
||||||
|
|
||||||
The system supports three types of icons:
|
## Font Awesome classes only
|
||||||
|
|
||||||
### 1. Font Awesome Icons (Recommended)
|
`icon` is used verbatim as the CSS class of an `<i>` element
|
||||||
|
(`iconEl.className = plugin.icon || 'fas fa-puzzle-piece'` in
|
||||||
|
`web_interface/static/v3/js/app-shell.js` and the same fallback in
|
||||||
|
`app-early.js`). So it must be a Font Awesome class string. Emoji, image
|
||||||
|
paths and URLs are not supported: they would end up as a meaningless class
|
||||||
|
name and render nothing.
|
||||||
|
|
||||||
The web interface uses Font Awesome 6, giving you access to thousands of icons.
|
The web interface bundles Font Awesome Free 6
|
||||||
|
(`web_interface/static/v3/vendor/fontawesome/`), so any free `fas`, `far` or
|
||||||
|
`fab` icon works.
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "my-plugin",
|
"id": "my-plugin",
|
||||||
@@ -21,292 +32,33 @@ The web interface uses Font Awesome 6, giving you access to thousands of icons.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Common Font Awesome Icons:**
|
Some common choices:
|
||||||
- Clock: `fas fa-clock`
|
|
||||||
|
- Clock / calendar: `fas fa-clock`, `fas fa-calendar-alt`
|
||||||
- Weather: `fas fa-cloud-sun`, `fas fa-cloud-rain`
|
- Weather: `fas fa-cloud-sun`, `fas fa-cloud-rain`
|
||||||
- Calendar: `fas fa-calendar`, `fas fa-calendar-alt`
|
- Sports: `fas fa-football-ball`, `fas fa-basketball-ball`, `fas fa-trophy`
|
||||||
- Sports: `fas fa-football-ball`, `fas fa-basketball-ball`
|
|
||||||
- Music: `fas fa-music`, `fas fa-headphones`
|
- Music: `fas fa-music`, `fas fa-headphones`
|
||||||
- Finance: `fas fa-chart-line`, `fas fa-dollar-sign`
|
- Finance: `fas fa-chart-line`, `fas fa-dollar-sign`
|
||||||
- News: `fas fa-newspaper`, `fas fa-rss`
|
- News: `fas fa-newspaper`, `fas fa-rss`
|
||||||
- Settings: `fas fa-cog`, `fas fa-sliders-h`
|
- Games: `fas fa-gamepad`, `fas fa-dice`
|
||||||
- Timer: `fas fa-stopwatch`, `fas fa-hourglass`
|
|
||||||
- Alert: `fas fa-bell`, `fas fa-exclamation-triangle`
|
|
||||||
- Heart: `fas fa-heart`, `far fa-heart` (outline)
|
|
||||||
- Star: `fas fa-star`, `far fa-star` (outline)
|
|
||||||
- Image: `fas fa-image`, `fas fa-camera`
|
|
||||||
- Video: `fas fa-video`, `fas fa-film`
|
|
||||||
- Game: `fas fa-gamepad`, `fas fa-dice`
|
|
||||||
|
|
||||||
**Browse all icons:** [Font Awesome Icon Gallery](https://fontawesome.com/icons)
|
Browse the rest in the [Font Awesome gallery](https://fontawesome.com/icons)
|
||||||
|
(filter to Free, version 6).
|
||||||
|
|
||||||
### 2. Emoji Icons (Fun & Simple)
|
## Default
|
||||||
|
|
||||||
Use any emoji character for a colorful, fun icon.
|
With no `icon` (or an empty one) the tab shows `fas fa-puzzle-piece`.
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "hello-world",
|
|
||||||
"name": "Hello World",
|
|
||||||
"icon": "👋"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Popular Emojis:**
|
|
||||||
- Time: ⏰ 🕐 ⏱️ ⏲️
|
|
||||||
- Weather: ☀️ ⛅ 🌤️ 🌧️ ⛈️ 🌩️ ❄️
|
|
||||||
- Sports: ⚽ 🏀 🏈 ⚾ 🎾 🏐
|
|
||||||
- Music: 🎵 🎶 🎸 🎹 🎤
|
|
||||||
- Money: 💰 💵 💴 💶 💷
|
|
||||||
- Calendar: 📅 📆
|
|
||||||
- News: 📰 📻 📡
|
|
||||||
- Fun: 🎮 🎲 🎯 🎨 🎭
|
|
||||||
- Nature: 🌍 🌎 🌏 🌳 🌺 🌸
|
|
||||||
- Food: 🍕 🍔 🍟 🍦 ☕ 🍰
|
|
||||||
|
|
||||||
### 3. Custom Image URLs (Advanced)
|
|
||||||
|
|
||||||
Use a custom image file for ultimate branding.
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "my-plugin",
|
|
||||||
"name": "My Plugin",
|
|
||||||
"icon": "/plugins/my-plugin/icon.png"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Requirements:**
|
|
||||||
- Image should be 16x16 to 32x32 pixels
|
|
||||||
- Supported formats: PNG, SVG, JPG, GIF
|
|
||||||
- Can be a relative path, absolute path, or external URL
|
|
||||||
- SVG recommended for best quality at any size
|
|
||||||
|
|
||||||
## How to Add an Icon
|
|
||||||
|
|
||||||
### Step 1: Choose Your Icon
|
|
||||||
|
|
||||||
Decide which type suits your plugin:
|
|
||||||
- **Font Awesome**: Professional, consistent with UI
|
|
||||||
- **Emoji**: Fun, colorful, no setup needed
|
|
||||||
- **Custom Image**: Unique branding, requires image file
|
|
||||||
|
|
||||||
### Step 2: Add to manifest.json
|
|
||||||
|
|
||||||
Add the `icon` field to your plugin's `manifest.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "my-weather-plugin",
|
|
||||||
"name": "Weather Display",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"author": "Your Name",
|
|
||||||
"description": "Shows weather information",
|
|
||||||
"icon": "fas fa-cloud-sun", // ← Add this line
|
|
||||||
"entry_point": "manager.py",
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 3: Test Your Plugin
|
|
||||||
|
|
||||||
1. Install or update your plugin
|
|
||||||
2. Open the web interface
|
|
||||||
3. Look for your plugin's tab
|
|
||||||
4. The icon should appear next to the plugin name
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
### Weather Plugin
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "weather-advanced",
|
|
||||||
"name": "Weather Advanced",
|
|
||||||
"icon": "fas fa-cloud-sun",
|
|
||||||
"description": "Advanced weather display with forecasts"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Result:** Tab shows: `☁️ Weather Advanced`
|
|
||||||
|
|
||||||
### Clock Plugin
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "digital-clock",
|
|
||||||
"name": "Digital Clock",
|
|
||||||
"icon": "⏰",
|
|
||||||
"description": "A beautiful digital clock"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Result:** Tab shows: `⏰ Digital Clock`
|
|
||||||
|
|
||||||
### Sports Scores Plugin
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "sports-scores",
|
|
||||||
"name": "Sports Scores",
|
|
||||||
"icon": "fas fa-trophy",
|
|
||||||
"description": "Live sports scores"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Result:** Tab shows: `🏆 Sports Scores`
|
|
||||||
|
|
||||||
### Custom Branding
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "company-dashboard",
|
|
||||||
"name": "Company Dashboard",
|
|
||||||
"icon": "/plugins/company-dashboard/logo.svg",
|
|
||||||
"description": "Company metrics display"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Result:** Tab shows: `[logo] Company Dashboard`
|
|
||||||
|
|
||||||
## Best Practices
|
|
||||||
|
|
||||||
### 1. Choose Meaningful Icons
|
|
||||||
- Icon should relate to plugin functionality
|
|
||||||
- Users should understand what the plugin does at a glance
|
|
||||||
- Avoid generic icons for specific functionality
|
|
||||||
|
|
||||||
### 2. Keep It Simple
|
|
||||||
- Simpler icons work better at small sizes
|
|
||||||
- Avoid icons with too much detail
|
|
||||||
- Test how your icon looks at 16x16 pixels
|
|
||||||
|
|
||||||
### 3. Match the UI Style
|
|
||||||
- Font Awesome icons match the interface best
|
|
||||||
- If using emoji, consider contrast with background
|
|
||||||
- Custom images should use similar color schemes
|
|
||||||
|
|
||||||
### 4. Consider Accessibility
|
|
||||||
- Icons should be recognizable without color
|
|
||||||
- Don't rely solely on color to convey meaning
|
|
||||||
- The plugin name should be descriptive
|
|
||||||
|
|
||||||
### 5. Test on Different Displays
|
|
||||||
- Check icon clarity on various screen sizes
|
|
||||||
- Ensure emoji render correctly on target devices
|
|
||||||
- Custom images should have good contrast
|
|
||||||
|
|
||||||
## Icon Categories
|
|
||||||
|
|
||||||
Here are recommended icons by plugin category:
|
|
||||||
|
|
||||||
### Time & Calendar
|
|
||||||
- `fas fa-clock`, `fas fa-calendar`, `fas fa-hourglass`
|
|
||||||
- Emoji: ⏰ 📅 ⏱️
|
|
||||||
|
|
||||||
### Weather
|
|
||||||
- `fas fa-cloud-sun`, `fas fa-temperature-high`, `fas fa-wind`
|
|
||||||
- Emoji: ☀️ 🌧️ ⛈️
|
|
||||||
|
|
||||||
### Finance & Stocks
|
|
||||||
- `fas fa-chart-line`, `fas fa-dollar-sign`, `fas fa-coins`
|
|
||||||
- Emoji: 💰 📈 💵
|
|
||||||
|
|
||||||
### Sports & Games
|
|
||||||
- `fas fa-football-ball`, `fas fa-trophy`, `fas fa-gamepad`
|
|
||||||
- Emoji: ⚽ 🏀 🎮
|
|
||||||
|
|
||||||
### Entertainment
|
|
||||||
- `fas fa-music`, `fas fa-film`, `fas fa-tv`
|
|
||||||
- Emoji: 🎵 🎬 📺
|
|
||||||
|
|
||||||
### News & Information
|
|
||||||
- `fas fa-newspaper`, `fas fa-rss`, `fas fa-info-circle`
|
|
||||||
- Emoji: 📰 📡 ℹ️
|
|
||||||
|
|
||||||
### Utilities
|
|
||||||
- `fas fa-tools`, `fas fa-cog`, `fas fa-wrench`
|
|
||||||
- Emoji: 🔧 ⚙️ 🛠️
|
|
||||||
|
|
||||||
### Social Media
|
|
||||||
- `fab fa-twitter`, `fab fa-facebook`, `fab fa-instagram`
|
|
||||||
- Emoji: 📱 💬 📧
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Icon Not Showing
|
1. Check the class name against the Font Awesome 6 Free gallery; a Pro-only
|
||||||
1. Check that the `icon` field is correctly spelled in `manifest.json`
|
or misspelled class renders as a blank space.
|
||||||
2. For Font Awesome icons, verify the class name is correct
|
2. Include the style prefix (`fas`, `far` or `fab`) as well as the icon
|
||||||
3. For custom images, check that the file path is accessible
|
class.
|
||||||
4. Refresh the plugins in the web interface
|
3. See the status note above: the icon is currently not passed through by
|
||||||
5. Check browser console for errors
|
the API.
|
||||||
|
|
||||||
### Emoji Looks Wrong
|
|
||||||
- Some emojis render differently on different platforms
|
|
||||||
- Try a different emoji if one doesn't work well
|
|
||||||
- Consider using Font Awesome instead for consistency
|
|
||||||
|
|
||||||
### Custom Image Not Loading
|
|
||||||
- Verify the image file exists in the specified path
|
|
||||||
- Check file permissions (should be readable)
|
|
||||||
- Try using an absolute path or URL
|
|
||||||
- Ensure image format is supported (PNG, SVG, JPG, GIF)
|
|
||||||
- Check image dimensions (16x16 to 32x32 recommended)
|
|
||||||
|
|
||||||
### Icon Too Large/Small
|
|
||||||
- Font Awesome and emoji icons automatically size correctly
|
|
||||||
- For custom images, adjust the image file dimensions
|
|
||||||
- SVG images scale best
|
|
||||||
|
|
||||||
## Default Behavior
|
|
||||||
|
|
||||||
If you don't specify an `icon` field in your manifest:
|
|
||||||
- The plugin tab will show a default puzzle piece icon: 🧩
|
|
||||||
- This is the fallback for all plugins without custom icons
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
The icon system works as follows:
|
|
||||||
|
|
||||||
1. **Frontend reads manifest**: When plugins load, the web interface reads each plugin's `manifest.json`
|
|
||||||
2. **Icon detection**: The `getPluginIcon()` function determines icon type:
|
|
||||||
- Contains `fa-` → Font Awesome icon
|
|
||||||
- 1-4 characters → Emoji
|
|
||||||
- Starts with `http://`, `https://`, or `/` → Custom image
|
|
||||||
- Otherwise → Default puzzle piece
|
|
||||||
3. **Rendering**: Icon HTML is generated and inserted into:
|
|
||||||
- Tab button in navigation bar
|
|
||||||
- Configuration page header
|
|
||||||
|
|
||||||
## Advanced: Dynamic Icons
|
|
||||||
|
|
||||||
Want to change icons programmatically? While not officially supported, you could:
|
|
||||||
|
|
||||||
1. Store multiple icon options in your manifest
|
|
||||||
2. Use JavaScript to swap icons based on plugin state
|
|
||||||
3. Update the manifest dynamically and refresh plugins
|
|
||||||
|
|
||||||
**Example (advanced):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "status-display",
|
|
||||||
"icon": "fas fa-circle",
|
|
||||||
"icon_states": {
|
|
||||||
"active": "fas fa-check-circle",
|
|
||||||
"error": "fas fa-exclamation-circle",
|
|
||||||
"warning": "fas fa-exclamation-triangle"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Related Documentation
|
## Related Documentation
|
||||||
|
|
||||||
- [Plugin Configuration Tabs](PLUGIN_CONFIGURATION_TABS.md) - Main plugin tabs documentation
|
- [Plugin Configuration Tabs](PLUGIN_CONFIGURATION_TABS.md)
|
||||||
- [Plugin Development Guide](PLUGIN_DEVELOPMENT_GUIDE.md) - How to create plugins
|
- [Plugin Development Guide](PLUGIN_DEVELOPMENT_GUIDE.md)
|
||||||
- [Font Awesome Icons](https://fontawesome.com/icons) - Browse all available icons
|
|
||||||
- [Emoji Reference](https://unicode.org/emoji/charts/full-emoji-list.html) - All emoji options
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
Adding a custom icon to your plugin:
|
|
||||||
|
|
||||||
1. **Choose** your icon (Font Awesome, emoji, or custom image)
|
|
||||||
2. **Add** the `icon` field to `manifest.json`
|
|
||||||
3. **Test** in the web interface
|
|
||||||
|
|
||||||
That's it! Your plugin now has a professional, recognizable icon in the UI. 🎨
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ Add a `web_ui_actions` array to your plugin's `manifest.json`:
|
|||||||
"script": "path/to/script.py",
|
"script": "path/to/script.py",
|
||||||
"oauth_flow": false,
|
"oauth_flow": false,
|
||||||
"section_description": "Optional section description",
|
"section_description": "Optional section description",
|
||||||
"success_message": "Action completed successfully",
|
|
||||||
"error_message": "Action failed",
|
|
||||||
"step1_message": "Authorization URL generated",
|
|
||||||
"step2_prompt": "Please paste the full redirect URL:",
|
"step2_prompt": "Please paste the full redirect URL:",
|
||||||
"step2_button_text": "Complete Authentication"
|
"step2_button_text": "Complete Authentication"
|
||||||
}
|
}
|
||||||
@@ -52,12 +49,13 @@ Add a `web_ui_actions` array to your plugin's `manifest.json`:
|
|||||||
- **`color`**: Color theme - `"blue"`, `"green"`, `"red"`, `"yellow"`, `"purple"`, etc. (defaults to `"blue"`)
|
- **`color`**: Color theme - `"blue"`, `"green"`, `"red"`, `"yellow"`, `"purple"`, etc. (defaults to `"blue"`)
|
||||||
- **`oauth_flow`**: Set to `true` for OAuth-style two-step authentication flows
|
- **`oauth_flow`**: Set to `true` for OAuth-style two-step authentication flows
|
||||||
- **`section_description`**: Description shown at the top of the actions section
|
- **`section_description`**: Description shown at the top of the actions section
|
||||||
- **`success_message`**: Message shown on successful completion
|
|
||||||
- **`error_message`**: Message shown on failure
|
|
||||||
- **`step1_message`**: Message shown after step 1 (for OAuth flows)
|
|
||||||
- **`step2_prompt`**: Prompt text for step 2 redirect URL input
|
- **`step2_prompt`**: Prompt text for step 2 redirect URL input
|
||||||
- **`step2_button_text`**: Button text for step 2 (defaults to "Complete Authentication")
|
- **`step2_button_text`**: Button text for step 2 (defaults to "Complete Authentication")
|
||||||
|
|
||||||
|
The status messages shown after an action runs come from the action's
|
||||||
|
response (`message`), with built-in fallbacks such as "Action completed
|
||||||
|
successfully"; there are no manifest fields for them.
|
||||||
|
|
||||||
## Action Types
|
## Action Types
|
||||||
|
|
||||||
### Script Actions (`type: "script"`)
|
### Script Actions (`type: "script"`)
|
||||||
@@ -98,7 +96,6 @@ For two-step OAuth flows (e.g., Spotify):
|
|||||||
"color": "green",
|
"color": "green",
|
||||||
"script": "authenticate_spotify.py",
|
"script": "authenticate_spotify.py",
|
||||||
"oauth_flow": true,
|
"oauth_flow": true,
|
||||||
"step1_message": "Authorization URL generated",
|
|
||||||
"step2_prompt": "Please paste the full redirect URL from Spotify after authorization:",
|
"step2_prompt": "Please paste the full redirect URL from Spotify after authorization:",
|
||||||
"step2_button_text": "Complete Authentication"
|
"step2_button_text": "Complete Authentication"
|
||||||
}
|
}
|
||||||
@@ -131,9 +128,6 @@ Here's a complete example for the `ledmatrix-music` plugin:
|
|||||||
"script": "authenticate_spotify.py",
|
"script": "authenticate_spotify.py",
|
||||||
"oauth_flow": true,
|
"oauth_flow": true,
|
||||||
"section_description": "Authenticate with Spotify or YouTube Music to enable music playback display.",
|
"section_description": "Authenticate with Spotify or YouTube Music to enable music playback display.",
|
||||||
"success_message": "Spotify authentication completed successfully",
|
|
||||||
"error_message": "Spotify authentication failed",
|
|
||||||
"step1_message": "Authorization URL generated",
|
|
||||||
"step2_prompt": "Please paste the full redirect URL from Spotify after authorization:",
|
"step2_prompt": "Please paste the full redirect URL from Spotify after authorization:",
|
||||||
"step2_button_text": "Complete Authentication"
|
"step2_button_text": "Complete Authentication"
|
||||||
},
|
},
|
||||||
@@ -145,9 +139,7 @@ Here's a complete example for the `ledmatrix-music` plugin:
|
|||||||
"button_text": "Authenticate YTM",
|
"button_text": "Authenticate YTM",
|
||||||
"icon": "fab fa-youtube",
|
"icon": "fab fa-youtube",
|
||||||
"color": "red",
|
"color": "red",
|
||||||
"script": "authenticate_ytm.py",
|
"script": "authenticate_ytm.py"
|
||||||
"success_message": "YouTube Music authentication completed successfully",
|
|
||||||
"error_message": "YouTube Music authentication failed"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,9 +37,6 @@
|
|||||||
"script": "authenticate_spotify.py",
|
"script": "authenticate_spotify.py",
|
||||||
"oauth_flow": true,
|
"oauth_flow": true,
|
||||||
"section_description": "Authenticate with Spotify or YouTube Music to enable music playback display.",
|
"section_description": "Authenticate with Spotify or YouTube Music to enable music playback display.",
|
||||||
"success_message": "Spotify authentication completed successfully",
|
|
||||||
"error_message": "Spotify authentication failed",
|
|
||||||
"step1_message": "Authorization URL generated",
|
|
||||||
"step2_prompt": "Please paste the full redirect URL from Spotify after authorization:",
|
"step2_prompt": "Please paste the full redirect URL from Spotify after authorization:",
|
||||||
"step2_button_text": "Complete Authentication"
|
"step2_button_text": "Complete Authentication"
|
||||||
},
|
},
|
||||||
@@ -51,9 +48,7 @@
|
|||||||
"button_text": "Authenticate YTM",
|
"button_text": "Authenticate YTM",
|
||||||
"icon": "fab fa-youtube",
|
"icon": "fab fa-youtube",
|
||||||
"color": "red",
|
"color": "red",
|
||||||
"script": "authenticate_ytm.py",
|
"script": "authenticate_ytm.py"
|
||||||
"success_message": "YouTube Music authentication completed successfully",
|
|
||||||
"error_message": "YouTube Music authentication failed"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
|
|||||||
Reference in New Issue
Block a user