mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +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>
5.3 KiB
5.3 KiB
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
cd /path/to/LEDMatrix
mkdir -p plugins/my-plugin
cd plugins/my-plugin
Step 2: Copy Templates
# 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 namePluginClassName→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-pluginPlugin Name→ Your plugin's name- Fill in features, installation, configuration sections
requirements.txt
Add your plugin's dependencies:
requests>=2.28.0
pillow>=9.0.0
Step 4: Enable Plugin
Edit config/config.json:
{
"my-plugin": {
"enabled": true,
"display_duration": 15
}
}
Step 5: Test Plugin
Test with Emulator
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
- Edit
manager.pyto implement your plugin logic - Test with emulator:
python run.py --emulator - Check logs for errors
- Iterate until working correctly
Step 7: Test on Hardware (Optional)
When ready, test on Raspberry Pi:
# 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
- Add API key to
config_schema.json:
{
"api_key": {
"type": "string",
"description": "API key for service"
}
}
- Implement API call in
_fetch_data():
import requests
def _fetch_data(self):
response = requests.get(
"https://api.example.com/data",
headers={"Authorization": f"Bearer {self.api_key}"}
)
return response.json()
- Store API key in
config/config_secrets.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():
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:
icon = Image.open("assets/icon.png").convert("RGBA")
self.display_manager.image.paste(icon, (5, 5), icon)
Adding Live Priority
- Enable in config:
{
"my-plugin": {
"live_priority": true
}
}
- Implement
has_live_content():
def has_live_content(self) -> bool:
return self.data and self.data.get("is_live", False)
- Override
get_live_modes()if needed:
def get_live_modes(self) -> list:
return ["my_plugin_live_mode"]
Troubleshooting
Plugin Not Loading
- Check
manifest.jsonsyntax (must be valid JSON) - Verify
entry_pointfile exists - Ensure
class_namematches 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 exampleplugins/ledmatrix-music/- Real-time data exampleplugins/ledmatrix-stocks/- Data display example
-
Read full documentation:
.cursor/plugins_guide.md- Comprehensive guidedocs/PLUGIN_ARCHITECTURE_SPEC.md- Architecture details.cursorrules- Development rules
-
Check plugin system code:
src/plugin_system/base_plugin.py- Base classsrc/plugin_system/plugin_manager.py- Plugin manager