mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
The .cursor/ directory holds the dev-side helper docs that Cursor and
contributors using AI tooling rely on to bootstrap plugin development.
Several of them had the same bug patterns as the user-facing docs.
.cursor/plugin_templates/QUICK_START.md
- "Adding Image Rendering" section showed
display_manager.draw_image(image, x=0, y=0). That method doesn't
exist on DisplayManager (same bug as PLUGIN_API_REFERENCE.md and
PLUGIN_DEVELOPMENT_GUIDE.md). Replaced with the canonical
display_manager.image.paste((x,y)) pattern, including the
transparency-mask form.
.cursor/plugins_guide.md
- 10 occurrences of ./dev_plugin_setup.sh — the script lives at
scripts/dev/dev_plugin_setup.sh, so anyone copy-pasting these
examples gets "command not found". Bulk fixed via sed.
- "Test with emulator: python run.py --emulator" — there's no
--emulator flag. Replaced with the real options:
EMULATOR=true python3 run.py for the full display, or
scripts/dev_server.py for the dev preview.
- Secrets management section showed a fictional
"config_secrets": { "api_key": "my-plugin.api_key" } reference
field. Verified in src/config_manager.py:162-172 that secrets are
loaded by deep-merging config_secrets.json into the main config.
There is no separate reference field — just put the secret under
the same plugin namespace and read it from the merged config.
Rewrote the section with the real pattern.
- "ssh pi@raspberrypi" -> "ssh ledpi@your-pi-ip" (consistent with
the rest of LEDMatrix docs which use ledpi as the default user)
.cursor/README.md
- Same ./dev_plugin_setup.sh -> ./scripts/dev/dev_plugin_setup.sh
fix (×6 occurrences via replace_all).
- Same "python run.py --emulator" -> "EMULATOR=true python3 run.py"
fix. Also added a pointer to scripts/dev_server.py for previewing
plugins without running the full display.
- "Example Plugins: plugins/hockey-scoreboard/" — the canonical
source is the ledmatrix-plugins repo. Installed copies land in
plugin-repos/ or plugins/. Updated the line to point at the
ledmatrix-plugins repo and explain both local locations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
248 lines
5.3 KiB
Markdown
248 lines
5.3 KiB
Markdown
# Quick Start: Creating a New Plugin
|
|
|
|
This guide will help you create a new plugin using the templates in `.cursor/plugin_templates/`.
|
|
|
|
## Step 1: Create Plugin Directory
|
|
|
|
```bash
|
|
cd /path/to/LEDMatrix
|
|
mkdir -p plugins/my-plugin
|
|
cd plugins/my-plugin
|
|
```
|
|
|
|
## Step 2: Copy Templates
|
|
|
|
```bash
|
|
# Copy all template files
|
|
cp ../../.cursor/plugin_templates/manifest.json.template ./manifest.json
|
|
cp ../../.cursor/plugin_templates/manager.py.template ./manager.py
|
|
cp ../../.cursor/plugin_templates/config_schema.json.template ./config_schema.json
|
|
cp ../../.cursor/plugin_templates/README.md.template ./README.md
|
|
cp ../../.cursor/plugin_templates/requirements.txt.template ./requirements.txt
|
|
```
|
|
|
|
## Step 3: Customize Files
|
|
|
|
### manifest.json
|
|
|
|
Replace placeholders:
|
|
- `PLUGIN_ID` → `my-plugin` (lowercase, use hyphens)
|
|
- `Plugin Name` → Your plugin's display name
|
|
- `PluginClassName` → `MyPlugin` (PascalCase)
|
|
- Update description, author, homepage, etc.
|
|
|
|
### manager.py
|
|
|
|
Replace placeholders:
|
|
- `PluginClassName` → `MyPlugin` (must match manifest)
|
|
- Implement `_fetch_data()` method
|
|
- Implement `_render_content()` method
|
|
- Add any custom validation in `validate_config()`
|
|
|
|
### config_schema.json
|
|
|
|
Customize:
|
|
- Update description
|
|
- Add/remove configuration properties
|
|
- Set default values
|
|
- Add validation rules
|
|
|
|
### README.md
|
|
|
|
Replace placeholders:
|
|
- `PLUGIN_ID` → `my-plugin`
|
|
- `Plugin Name` → Your plugin's name
|
|
- Fill in features, installation, configuration sections
|
|
|
|
### requirements.txt
|
|
|
|
Add your plugin's dependencies:
|
|
```txt
|
|
requests>=2.28.0
|
|
pillow>=9.0.0
|
|
```
|
|
|
|
## Step 4: Enable Plugin
|
|
|
|
Edit `config/config.json`:
|
|
|
|
```json
|
|
{
|
|
"my-plugin": {
|
|
"enabled": true,
|
|
"display_duration": 15
|
|
}
|
|
}
|
|
```
|
|
|
|
## Step 5: Test Plugin
|
|
|
|
### Test with Emulator
|
|
|
|
```bash
|
|
cd /path/to/LEDMatrix
|
|
python run.py --emulator
|
|
```
|
|
|
|
### Check Plugin Loading
|
|
|
|
Look for logs like:
|
|
```
|
|
[INFO] Discovered 1 plugin(s)
|
|
[INFO] Loaded plugin: my-plugin v1.0.0
|
|
[INFO] Added plugin mode: my-plugin
|
|
```
|
|
|
|
### Test Plugin Display
|
|
|
|
The plugin should appear in the display rotation. Check logs for any errors.
|
|
|
|
## Step 6: Develop and Iterate
|
|
|
|
1. Edit `manager.py` to implement your plugin logic
|
|
2. Test with emulator: `python run.py --emulator`
|
|
3. Check logs for errors
|
|
4. Iterate until working correctly
|
|
|
|
## Step 7: Test on Hardware (Optional)
|
|
|
|
When ready, test on Raspberry Pi:
|
|
|
|
```bash
|
|
# Deploy to Pi
|
|
rsync -avz plugins/my-plugin/ pi@raspberrypi:/path/to/LEDMatrix/plugins/my-plugin/
|
|
|
|
# Or if using git
|
|
ssh pi@raspberrypi "cd /path/to/LEDMatrix/plugins/my-plugin && git pull"
|
|
|
|
# Restart service
|
|
ssh pi@raspberrypi "sudo systemctl restart ledmatrix"
|
|
```
|
|
|
|
## Common Customizations
|
|
|
|
### Adding API Integration
|
|
|
|
1. Add API key to `config_schema.json`:
|
|
```json
|
|
{
|
|
"api_key": {
|
|
"type": "string",
|
|
"description": "API key for service"
|
|
}
|
|
}
|
|
```
|
|
|
|
2. Implement API call in `_fetch_data()`:
|
|
```python
|
|
import requests
|
|
|
|
def _fetch_data(self):
|
|
response = requests.get(
|
|
"https://api.example.com/data",
|
|
headers={"Authorization": f"Bearer {self.api_key}"}
|
|
)
|
|
return response.json()
|
|
```
|
|
|
|
3. Store API key in `config/config_secrets.json`:
|
|
```json
|
|
{
|
|
"my-plugin": {
|
|
"api_key": "your-secret-key"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Adding Image Rendering
|
|
|
|
There is no `draw_image()` helper on `DisplayManager`. To render an
|
|
image, paste it directly onto the underlying PIL `Image`
|
|
(`display_manager.image`) and then call `update_display()`:
|
|
|
|
```python
|
|
def _render_content(self):
|
|
# Load and paste image onto the display canvas
|
|
image = Image.open("assets/logo.png").convert("RGB")
|
|
self.display_manager.image.paste(image, (0, 0))
|
|
|
|
# Draw text overlay
|
|
self.display_manager.draw_text(
|
|
"Text",
|
|
x=10, y=20,
|
|
color=(255, 255, 255)
|
|
)
|
|
|
|
self.display_manager.update_display()
|
|
```
|
|
|
|
For transparency, paste with a mask:
|
|
|
|
```python
|
|
icon = Image.open("assets/icon.png").convert("RGBA")
|
|
self.display_manager.image.paste(icon, (5, 5), icon)
|
|
```
|
|
|
|
|
|
### Adding Live Priority
|
|
|
|
1. Enable in config:
|
|
```json
|
|
{
|
|
"my-plugin": {
|
|
"live_priority": true
|
|
}
|
|
}
|
|
```
|
|
|
|
2. Implement `has_live_content()`:
|
|
```python
|
|
def has_live_content(self) -> bool:
|
|
return self.data and self.data.get("is_live", False)
|
|
```
|
|
|
|
3. Override `get_live_modes()` if needed:
|
|
```python
|
|
def get_live_modes(self) -> list:
|
|
return ["my_plugin_live_mode"]
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Plugin Not Loading
|
|
|
|
- Check `manifest.json` syntax (must be valid JSON)
|
|
- Verify `entry_point` file exists
|
|
- Ensure `class_name` matches class name in manager.py
|
|
- Check for import errors in logs
|
|
|
|
### Configuration Errors
|
|
|
|
- Validate config against `config_schema.json`
|
|
- Check required fields are present
|
|
- Verify data types match schema
|
|
|
|
### Display Issues
|
|
|
|
- Check display dimensions: `display_manager.width`, `display_manager.height`
|
|
- Verify coordinates are within bounds
|
|
- Ensure `update_display()` is called
|
|
- Test with emulator first
|
|
|
|
## Next Steps
|
|
|
|
- Review existing plugins for patterns:
|
|
- `plugins/hockey-scoreboard/` - Sports scoreboard example
|
|
- `plugins/ledmatrix-music/` - Real-time data example
|
|
- `plugins/ledmatrix-stocks/` - Data display example
|
|
|
|
- Read full documentation:
|
|
- `.cursor/plugins_guide.md` - Comprehensive guide
|
|
- `docs/PLUGIN_ARCHITECTURE_SPEC.md` - Architecture details
|
|
- `.cursorrules` - Development rules
|
|
|
|
- Check plugin system code:
|
|
- `src/plugin_system/base_plugin.py` - Base class
|
|
- `src/plugin_system/plugin_manager.py` - Plugin manager
|
|
|