Files
LEDMatrix/docs/DEVELOPER_QUICK_REFERENCE.md
ChuckandClaude Opus 5.5 2601cb4cbb chore(deprecation): remove the 35 APIs deprecated for 3.8.0 (#708)
* chore(deprecation): remove the 35 APIs deprecated for 3.8.0

The usage scan (docs/DEPRECATIONS_3.8.md, regenerated 2026-10-01 and
committed here) finds no call or override of any of them in the 46
monorepo plugins or the 8 third-party plugins plugins.json lists; the
only core callers were other deprecated methods removed alongside.

- CacheManager: 13 methods, plus the private helpers only
  has_data_changed used (_has_*_changed, _is_market_open).
- DisplayManager: 7 methods, plus WEATHER_COLORS and the private
  _draw_sun/_cloud/_rain/_snow/_storm helpers only the icon methods used.
- FontManager: 14 methods, plus size_tokens, _save_overrides and
  _clear_plugin_font_cache. font_overrides and _load_overrides stay:
  resolve_font() still applies config/font_overrides.json.
  performance_stats stays: get_font() keeps it and tests read it.
- PluginManager.get_enabled_plugins.

test_deprecation.py pins only the two 3.9.0 markers now; the scanner
tests run against a stand-in core instead of the real markers. The
memory-tier tests read stats through log_memory_cache_stats() and the
component, and the test of the removed _clear_plugin_font_cache goes.
Docs drop the removed methods' reference entries; the Deprecated APIs
table becomes "Removed in 3.8.0". CHANGELOG gains a Removed section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(deprecation): drop the test harness's copies of the removed icon methods

VisualTestDisplayManager still drew weather icons that DisplayManager no
longer has, so a plugin's visual tests could pass on calls that raise
AttributeError on the real display. Its draw_sun/draw_cloud/draw_rain/
draw_snow/draw_weather_icon/draw_text_with_icons, WEATHER_COLORS and the
private helpers go, with the tests that exercised them. The CHANGELOG's
Deprecations entries no longer say nothing is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 10:45:28 -04:00

6.5 KiB

Developer Quick Reference

One-page quick reference for common LEDMatrix development tasks.

REST API Endpoints

Most Common Endpoints

# Get installed plugins
GET /api/v3/plugins/installed

# Get plugin configuration
GET /api/v3/plugins/config?plugin_id=<plugin_id>

# Save plugin configuration
POST /api/v3/plugins/config
{"plugin_id": "my-plugin", "config": {...}}

# Start on-demand display
POST /api/v3/display/on-demand/start
{"plugin_id": "my-plugin", "duration": 30}

# Get system status
GET /api/v3/system/status

# Execute system action
POST /api/v3/system/action
{"action": "start_display"}

Base URL: http://your-pi-ip:5000/api/v3

See REST_API_REFERENCE.md for complete documentation.

Display Manager Quick Methods

# Core operations
display_manager.clear()                    # Clear display
display_manager.update_display()           # Update physical display

# Text rendering
display_manager.draw_text("Hello", x=10, y=16, color=(255, 255, 255))
display_manager.draw_text("Centered", centered=True)  # Auto-center

# Utilities
width = display_manager.get_text_width("Text", font)
height = display_manager.get_font_height(font)

# Adaptive layout (recommended for multi-size support — text and images
# that scale to any panel; see docs/ADAPTIVE_LAYOUT.md)
rows = self.layout.bounds.inset(1).split_v(3, 1, gap=1)
self.draw_fit("12:34", rows[0])                 # largest crisp font that fits
self.draw_image(logo, rows[1], mode="fill_height", crop_to_ink=True)

# Weather icons: draw_weather_icon() was removed in 3.8.0 — draw your
# own icons (the weather plugin ships WeatherIcons)

# Scrolling state
display_manager.set_scrolling_state(True)
display_manager.defer_update(lambda: self.update_cache(), priority=0)

Cache Manager Quick Methods

# Basic caching
cached = cache_manager.get("key", max_age=3600)
cache_manager.set("key", data)
cache_manager.delete("key")       # alias for clear_cache(key)

# Advanced caching
data = cache_manager.get_cached_data_with_strategy("key", data_type="weather")

# Strategy
strategy = cache_manager.get_cache_strategy("weather")

get_background_cached_data() (use get()) and get_sport_live_interval() were removed in 3.8.0. See Deprecated APIs.

Plugin Manager Quick Methods

# Get plugins
plugin = plugin_manager.get_plugin("plugin-id")
all_plugins = plugin_manager.get_all_plugins()
# get_enabled_plugins() was removed in 3.8.0 — check `enabled` on the
# entries in plugin_manager.plugins

# Get info
info = plugin_manager.get_plugin_info("plugin-id")
modes = plugin_manager.get_plugin_display_modes("plugin-id")

BasePlugin Quick Reference

class MyPlugin(BasePlugin):
    def update(self):
        # Fetch data (called based on update_interval)
        cache_key = f"{self.plugin_id}_data"
        cached = self.cache_manager.get(cache_key, max_age=3600)
        if cached:
            self.data = cached
            return
        self.data = self._fetch_from_api()
        self.cache_manager.set(cache_key, self.data)
    
    def display(self, force_clear=False):
        # Render display
        if force_clear:
            self.display_manager.clear()
        self.display_manager.draw_text("Hello", x=10, y=16)
        self.display_manager.update_display()
    
    # Optional methods
    def has_live_content(self) -> bool:
        return len(self.live_items) > 0
    
    def validate_config(self) -> bool:
        return "api_key" in self.config

Common Patterns

Caching Pattern

def update(self):
    cache_key = f"{self.plugin_id}_data"
    cached = self.cache_manager.get(cache_key, max_age=3600)
    if cached:
        self.data = cached
        return
    self.data = self._fetch_from_api()
    self.cache_manager.set(cache_key, self.data)

Error Handling Pattern

def display(self, force_clear=False):
    try:
        if not self.data:
            self._display_no_data()
            return
        self._render_content()
        self.display_manager.update_display()
    except Exception as e:
        self.logger.error(f"Display error: {e}", exc_info=True)
        self._display_error()

Scrolling Pattern

def display(self, force_clear=False):
    self.display_manager.set_scrolling_state(True)
    try:
        # Scroll content...
        for x in range(width, -text_width, -2):
            self.display_manager.clear()
            self.display_manager.draw_text(text, x=x, y=16)
            self.display_manager.update_display()
            time.sleep(0.05)
    finally:
        self.display_manager.set_scrolling_state(False)

Plugin Development Checklist

  • Plugin inherits from BasePlugin
  • Implements update() and display() methods
  • manifest.json with the required fields
  • config_schema.json for web UI (recommended)
  • README.md with documentation
  • Error handling implemented
  • Uses caching appropriately
  • Tested on Raspberry Pi hardware
  • Follows versioning best practices

Common Errors & Solutions

Error Solution
Plugin not discovered Check manifest.json exists and id matches directory name
Import errors Check requirements.txt and dependencies
Config validation fails Verify config_schema.json syntax
Display not updating Call update_display() after drawing
Cache not working Check cache directory permissions

File Locations

LEDMatrix/
├── plugin-repos/         # Installed plugins (default; plugins/ is only
│                         #   for dev symlinks via scripts/dev/dev_plugin_setup.sh)
├── config/
│   ├── config.json      # Main configuration
│   └── config_secrets.json  # API keys and secrets
├── docs/                 # Documentation
│   ├── REST_API_REFERENCE.md
│   ├── PLUGIN_API_REFERENCE.md
│   └── ...
└── src/
    ├── display_manager.py
    ├── cache_manager.py
    └── plugin_system/
        └── base_plugin.py

Tip: Bookmark this page for quick access to common methods and patterns!