Files
LEDMatrix/docs/archive/VEGAS_SCROLL_MODE.md
Chuck ddd300a117 Docs/consolidate documentation (#217)
* docs: rename FONT_MANAGER_USAGE.md to FONT_MANAGER.md

Renamed for clearer naming convention.
Part of documentation consolidation effort.

* docs: consolidate Plugin Store guides (2→1)

Merged:
- PLUGIN_STORE_USER_GUIDE.md
- PLUGIN_STORE_QUICK_REFERENCE.md

Into: PLUGIN_STORE_GUIDE.md

- Unified writing style to professional technical
- Added Quick Reference section at top for easy access
- Removed duplicate content
- Added cross-references to related documentation
- Updated formatting to match style guidelines

* docs: create user-focused Web Interface Guide

Created WEB_INTERFACE_GUIDE.md consolidating:
- V3_INTERFACE_README.md (technical details)
- User-facing interface documentation

- Focused on end-user tasks and navigation
- Removed technical implementation details
- Added common tasks section
- Included troubleshooting
- Professional technical writing style

* docs: consolidate WiFi setup guides (4→1)

Merged:
- WIFI_SETUP.md
- OPTIMAL_WIFI_AP_FAILOVER_SETUP.md
- AP_MODE_MANUAL_ENABLE.md
- WIFI_ETHERNET_AP_MODE_FIX.md (behavior documentation)

Into: WIFI_NETWORK_SETUP.md

- Comprehensive coverage of WiFi setup and configuration
- Clear explanation of AP mode failover and grace period
- Configuration scenarios and best practices
- Troubleshooting section combining all sources
- Professional technical writing style
- Added quick reference table for behavior

* docs: consolidate troubleshooting guides (4→1)

Merged:
- TROUBLESHOOTING_QUICK_START.md
- WEB_INTERFACE_TROUBLESHOOTING.md
- CAPTIVE_PORTAL_TROUBLESHOOTING.md
- WEATHER_TROUBLESHOOTING.md

Into: TROUBLESHOOTING.md

- Organized by issue category (web, WiFi, plugins)
- Comprehensive diagnostic commands reference
- Quick diagnosis steps at the top
- Service file template preserved
- Complete diagnostic script included
- Professional technical writing style

* docs: create consolidated Advanced Features guide

Merged:
- VEGAS_SCROLL_MODE.md
- ON_DEMAND_DISPLAY_QUICK_START.md
- ON_DEMAND_DISPLAY_API.md
- ON_DEMAND_CACHE_MANAGEMENT.md
- BACKGROUND_SERVICE_README.md
- PERMISSION_MANAGEMENT_GUIDE.md

Into: ADVANCED_FEATURES.md

- Comprehensive guide covering all advanced features
- Vegas scroll mode with integration examples
- On-demand display with API reference
- Cache management troubleshooting
- Background service documentation
- Permission management patterns
- Professional technical writing style

* docs: create Getting Started guide for first-time users

Created GETTING_STARTED.md:
- Quick start guide (5 minutes)
- Initial configuration walkthrough
- Common first-time issues and solutions
- Next steps and quick reference
- User-friendly tone for beginners
- Links to detailed documentation

* docs: archive consolidated source files and ephemeral docs

Archived files that have been consolidated:
- Plugin Store guides (2 files → PLUGIN_STORE_GUIDE.md)
- Web Interface guide (V3_INTERFACE_README.md → WEB_INTERFACE_GUIDE.md)
- WiFi Setup guides (4 files → WIFI_NETWORK_SETUP.md)
- Troubleshooting guides (4 files → TROUBLESHOOTING.md)
- Advanced Features (6 files → ADVANCED_FEATURES.md)

Archived ephemeral/debug documentation:
- DEBUG_WEB_ISSUE.md
- BROWSER_ERRORS_EXPLANATION.md
- FORM_VALIDATION_FIXES.md
- WEB_UI_RELIABILITY_IMPROVEMENTS.md
- CAPTIVE_PORTAL_TESTING.md
- NEXT_STEPS_COMMANDS.md
- STATIC_IMAGE_MULTI_UPLOAD_PLAN.md
- RECONNECT_AFTER_CAPTIVE_PORTAL_TESTING.md

Archived implementation summaries:
- PLUGIN_CONFIG_TABS_SUMMARY.md
- PLUGIN_CONFIG_SYSTEM_VERIFICATION.md
- PLUGIN_SCHEMA_AUDIT_SUMMARY.md
- STARTUP_OPTIMIZATION_SUMMARY.md
- PLUGIN_DISPATCH_IMPLEMENTATION.md
- NESTED_SCHEMA_IMPLEMENTATION.md
- AP_MODE_MANUAL_ENABLE_CHANGES.md
- PLUGIN_CONFIG_SYSTEM_EXPLANATION.md

Total archived: 27 files
Preserves git history while cleaning up main docs directory

* docs: rename API_REFERENCE.md to REST_API_REFERENCE.md

Renamed for clarity - this is specifically the REST API reference
for the web interface, not a general API reference.

* docs: update README.md to reflect consolidated documentation structure

Updated documentation index:
- Reflects new consolidated guides (51 → 16-17 files)
- Updated Quick Start sections with new file names
- Added consolidation history (January 2026)
- Updated file references (API_REFERENCE → REST_API_REFERENCE)
- Documented archival of 33 files
- Added benefits of consolidation
- Updated statistics and highlights
- Removed outdated references
- Professional writing style maintained throughout

* docs: add Vegas scroll mode system architecture documentation

Added comprehensive internal architecture section for Vegas mode:
- Component overview with diagram
- VegasModeCoordinator responsibilities and main loop
- StreamManager buffering strategy and content flow
- PluginAdapter integration and fallback behavior
- RenderPipeline 125 FPS rendering process
- Component interaction flows
- Thread safety patterns
- Performance characteristics

Covers:
- How the four components work together
- Initialization and render loop flows
- Config update handling
- Frame rate management and optimization
- Memory usage and CPU characteristics

---------

Co-authored-by: Chuck <chuck@example.com>
2026-01-29 10:32:00 -05:00

11 KiB
Raw Blame History

Vegas Scroll Mode - Plugin Developer Guide

Vegas scroll mode displays content from multiple plugins in a continuous horizontal scroll, similar to the news tickers seen in Las Vegas casinos. This guide explains how to integrate your plugin with Vegas mode.

Overview

When Vegas mode is enabled, the display controller composes content from all enabled plugins into a single continuous scroll. Each plugin can control how its content appears in the scroll using one of three display modes:

Mode Behavior Best For
SCROLL Content scrolls continuously within the stream Multi-item plugins (sports scores, odds, news)
FIXED_SEGMENT Fixed-width block that scrolls by Static info (clock, weather, current temp)
STATIC Scroll pauses, plugin displays for duration, then resumes Important alerts, detailed views

Quick Start

Minimal Integration (Zero Code Changes)

If you do nothing, your plugin will work with Vegas mode using these defaults:

  • Plugins with get_vegas_content_type() == 'multi' use SCROLL mode
  • Plugins with get_vegas_content_type() == 'static' use FIXED_SEGMENT mode
  • Content is captured by calling your plugin's display() method

Basic Integration

To provide optimized Vegas content, implement get_vegas_content():

from PIL import Image

class MyPlugin(BasePlugin):
    def get_vegas_content(self):
        """Return content for Vegas scroll mode."""
        # Return a single image for fixed content
        return self._render_current_view()

        # OR return multiple images for multi-item content
        # return [self._render_item(item) for item in self.items]

Full Integration

For complete control over Vegas behavior, implement these methods:

from src.plugin_system.base_plugin import BasePlugin, VegasDisplayMode

class MyPlugin(BasePlugin):
    def get_vegas_content_type(self) -> str:
        """Legacy method - determines default mode mapping."""
        return 'multi'  # or 'static' or 'none'

    def get_vegas_display_mode(self) -> VegasDisplayMode:
        """Specify how this plugin behaves in Vegas scroll."""
        return VegasDisplayMode.SCROLL

    def get_supported_vegas_modes(self) -> list:
        """Return list of modes users can configure."""
        return [VegasDisplayMode.SCROLL, VegasDisplayMode.FIXED_SEGMENT]

    def get_vegas_content(self):
        """Return PIL Image(s) for the scroll."""
        return [self._render_game(g) for g in self.games]

    def get_vegas_segment_width(self) -> int:
        """For FIXED_SEGMENT: width in panels (optional)."""
        return 2  # Use 2 panels width

Display Modes Explained

SCROLL Mode

Content scrolls continuously within the Vegas stream. Best for plugins with multiple items.

def get_vegas_display_mode(self):
    return VegasDisplayMode.SCROLL

def get_vegas_content(self):
    # Return list of images - each scrolls individually
    images = []
    for game in self.games:
        img = Image.new('RGB', (200, 32))
        # ... render game info ...
        images.append(img)
    return images

When to use:

  • Sports scores with multiple games
  • Stock/odds tickers with multiple items
  • News feeds with multiple headlines

FIXED_SEGMENT Mode

Content is rendered as a fixed-width block that scrolls by with other content.

def get_vegas_display_mode(self):
    return VegasDisplayMode.FIXED_SEGMENT

def get_vegas_content(self):
    # Return single image at your preferred width
    img = Image.new('RGB', (128, 32))  # 2 panels wide
    # ... render clock/weather/etc ...
    return img

def get_vegas_segment_width(self):
    # Optional: specify width in panels
    return 2

When to use:

  • Clock display
  • Current weather/temperature
  • System status indicators
  • Any "at a glance" information

STATIC Mode

Scroll pauses completely, your plugin displays using its normal display() method for its configured duration, then scroll resumes.

def get_vegas_display_mode(self):
    return VegasDisplayMode.STATIC

def get_display_duration(self):
    # How long to pause and show this plugin
    return 10.0  # 10 seconds

When to use:

  • Important alerts that need attention
  • Detailed information that's hard to read while scrolling
  • Interactive or animated content
  • Content that requires the full display

User Configuration

Users can override the default display mode per-plugin in their config:

{
  "my_plugin": {
    "enabled": true,
    "vegas_mode": "static",       // Override: "scroll", "fixed", or "static"
    "vegas_panel_count": 2,       // Width in panels for fixed mode
    "display_duration": 10        // Duration for static mode
  }
}

The get_vegas_display_mode() method checks config first, then falls back to your implementation.

Content Rendering Guidelines

Image Dimensions

  • Height: Must match display height (typically 32 pixels)
  • Width:
    • SCROLL: Any width, content will scroll
    • FIXED_SEGMENT: panels × single_panel_width (e.g., 2 × 64 = 128px)

Color Mode

Always use RGB mode for images:

img = Image.new('RGB', (width, 32), color=(0, 0, 0))

Performance Tips

  1. Cache rendered images - Don't re-render on every call
  2. Pre-render on update() - Render images when data changes, not when Vegas requests them
  3. Keep images small - Memory adds up with multiple plugins
class MyPlugin(BasePlugin):
    def __init__(self, ...):
        super().__init__(...)
        self._cached_vegas_images = None
        self._cache_valid = False

    def update(self):
        # Fetch new data
        self.data = self._fetch_data()
        # Invalidate cache so next Vegas request re-renders
        self._cache_valid = False

    def get_vegas_content(self):
        if not self._cache_valid:
            self._cached_vegas_images = self._render_all_items()
            self._cache_valid = True
        return self._cached_vegas_images

Fallback Behavior

If your plugin doesn't implement get_vegas_content(), Vegas mode will:

  1. Create a temporary canvas matching display dimensions
  2. Call your display() method
  3. Capture the resulting image
  4. Use that image in the scroll

This works but is less efficient than providing native Vegas content.

Excluding from Vegas Mode

To exclude your plugin from Vegas scroll entirely:

def get_vegas_content_type(self):
    return 'none'

Or users can exclude via config:

{
  "display": {
    "vegas_scroll": {
      "excluded_plugins": ["my_plugin"]
    }
  }
}

Complete Example

Here's a complete example of a weather plugin with full Vegas integration:

from PIL import Image, ImageDraw
from src.plugin_system.base_plugin import BasePlugin, VegasDisplayMode

class WeatherPlugin(BasePlugin):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.temperature = None
        self.conditions = None
        self._vegas_image = None

    def update(self):
        """Fetch weather data."""
        data = self._fetch_weather_api()
        self.temperature = data['temp']
        self.conditions = data['conditions']
        self._vegas_image = None  # Invalidate cache

    def display(self, force_clear=False):
        """Standard display for normal rotation."""
        if force_clear:
            self.display_manager.clear()

        # Full weather display with details
        self.display_manager.draw_text(
            f"{self.temperature}°F",
            x=10, y=8, color=(255, 255, 255)
        )
        self.display_manager.draw_text(
            self.conditions,
            x=10, y=20, color=(200, 200, 200)
        )
        self.display_manager.update_display()

    # --- Vegas Mode Integration ---

    def get_vegas_content_type(self):
        """Legacy compatibility."""
        return 'static'

    def get_vegas_display_mode(self):
        """Use FIXED_SEGMENT for compact weather display."""
        # Allow user override via config
        return super().get_vegas_display_mode()

    def get_supported_vegas_modes(self):
        """Weather can work as fixed or static."""
        return [VegasDisplayMode.FIXED_SEGMENT, VegasDisplayMode.STATIC]

    def get_vegas_segment_width(self):
        """Weather needs 2 panels to show clearly."""
        return self.config.get('vegas_panel_count', 2)

    def get_vegas_content(self):
        """Render compact weather for Vegas scroll."""
        if self._vegas_image is not None:
            return self._vegas_image

        # Create compact display (2 panels = 128px typical)
        panel_width = 64  # From display.hardware.cols
        panels = self.get_vegas_segment_width() or 2
        width = panel_width * panels
        height = 32

        img = Image.new('RGB', (width, height), color=(0, 0, 40))
        draw = ImageDraw.Draw(img)

        # Draw compact weather
        temp_text = f"{self.temperature}°"
        draw.text((10, 8), temp_text, fill=(255, 255, 255))
        draw.text((60, 8), self.conditions[:10], fill=(200, 200, 200))

        self._vegas_image = img
        return img

API Reference

VegasDisplayMode Enum

from src.plugin_system.base_plugin import VegasDisplayMode

VegasDisplayMode.SCROLL        # "scroll" - continuous scrolling
VegasDisplayMode.FIXED_SEGMENT # "fixed" - fixed block in scroll
VegasDisplayMode.STATIC        # "static" - pause scroll to display

BasePlugin Vegas Methods

Method Returns Description
get_vegas_content() Image or List[Image] or None Content for Vegas scroll
get_vegas_content_type() str Legacy: 'multi', 'static', or 'none'
get_vegas_display_mode() VegasDisplayMode How plugin behaves in Vegas
get_supported_vegas_modes() List[VegasDisplayMode] Modes available for user config
get_vegas_segment_width() int or None Width in panels for FIXED_SEGMENT

Configuration Options

Per-plugin config:

{
  "plugin_id": {
    "vegas_mode": "scroll|fixed|static",
    "vegas_panel_count": 2,
    "display_duration": 15
  }
}

Global Vegas config:

{
  "display": {
    "vegas_scroll": {
      "enabled": true,
      "scroll_speed": 50,
      "separator_width": 32,
      "plugin_order": ["clock", "weather", "sports"],
      "excluded_plugins": ["debug_plugin"],
      "target_fps": 125,
      "buffer_ahead": 2
    }
  }
}

Troubleshooting

Plugin not appearing in Vegas scroll

  1. Check get_vegas_content_type() doesn't return 'none'
  2. Verify plugin is not in excluded_plugins list
  3. Ensure plugin is enabled

Content looks wrong in scroll

  1. Verify image height matches display height (32px typical)
  2. Check image mode is 'RGB'
  3. Test with get_vegas_content() returning a simple test image

STATIC mode not pausing

  1. Verify get_vegas_display_mode() returns VegasDisplayMode.STATIC
  2. Check user hasn't overridden with vegas_mode in config
  3. Ensure display() method works correctly

Performance issues

  1. Implement image caching in get_vegas_content()
  2. Pre-render images in update() instead of on-demand
  3. Reduce image dimensions if possible