mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
* 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>
426 lines
12 KiB
Markdown
426 lines
12 KiB
Markdown
# On-Demand Display - Quick Start Guide
|
||
|
||
## 🎯 What Is It?
|
||
|
||
On-Demand Display lets users **manually trigger** specific plugins to show on the LED matrix - perfect for "Show Now" buttons in your web interface!
|
||
|
||
> **2025 update:** The LEDMatrix web interface now ships with first-class on-demand controls. You can trigger plugins directly from the Plugin Management page or by calling the new `/api/v3/display/on-demand/*` endpoints described below. The legacy quick-start steps are still documented for bespoke integrations.
|
||
|
||
## ✅ Built-In Controls
|
||
|
||
### Web Interface (no-code)
|
||
|
||
- Navigate to **Settings → Plugin Management**.
|
||
- Each installed plugin now exposes a **Run On-Demand** button:
|
||
- Choose the display mode (when a plugin exposes multiple views).
|
||
- Optionally set a fixed duration (leave blank to use the plugin default or `0` to run until you stop it).
|
||
- Pin the plugin so rotation stays paused.
|
||
- The dashboard shows real-time status and lets you stop the session. **Shift+click** the stop button to stop the display service after clearing the plugin.
|
||
- The status card refreshes automatically and indicates whether the display service is running.
|
||
|
||
### REST Endpoints
|
||
|
||
All endpoints live under `/api/v3/display/on-demand`.
|
||
|
||
| Endpoint | Method | Description |
|
||
|----------|--------|-------------|
|
||
| `/status` | GET | Returns the current on-demand state plus display service health. |
|
||
| `/start` | POST | Requests a plugin/mode to run. Automatically starts the display service (unless `start_service: false`). |
|
||
| `/stop` | POST | Clears on-demand mode. Include `{"stop_service": true}` to stop the systemd service. |
|
||
|
||
Example `curl` calls:
|
||
|
||
```bash
|
||
# Start the default mode for football-scoreboard for 45 seconds
|
||
curl -X POST http://localhost:5000/api/v3/display/on-demand/start \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"plugin_id": "football-scoreboard",
|
||
"duration": 45,
|
||
"pinned": true
|
||
}'
|
||
|
||
# Start by mode name (plugin id inferred automatically)
|
||
curl -X POST http://localhost:5000/api/v3/display/on-demand/start \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "mode": "football_live" }'
|
||
|
||
# Stop on-demand and shut down the display service
|
||
curl -X POST http://localhost:5000/api/v3/display/on-demand/stop \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "stop_service": true }'
|
||
|
||
# Check current status
|
||
curl http://localhost:5000/api/v3/display/on-demand/status | jq
|
||
```
|
||
|
||
**Notes**
|
||
|
||
- The display controller will honour the plugin’s configured `display_duration` when no duration is provided.
|
||
- When you pass `duration: 0` (or omit it) and `pinned: true`, the plugin stays active until you issue `/stop`.
|
||
- The service automatically resumes normal rotation after the on-demand session expires or is cleared.
|
||
|
||
## 🚀 Quick Implementation (3 Steps)
|
||
|
||
> The steps below describe a lightweight custom implementation that predates the built-in API. You generally no longer need this unless you are integrating with a separate control surface.
|
||
|
||
### Step 1: Add API Endpoint
|
||
|
||
```python
|
||
# In web_interface/blueprints/api_v3.py
|
||
|
||
@api_v3.route('/display/show', methods=['POST'])
|
||
def show_on_demand():
|
||
data = request.json
|
||
mode = data.get('mode')
|
||
duration = data.get('duration', 30) # Default 30 seconds
|
||
|
||
# Get display controller (implementation depends on your setup)
|
||
controller = get_display_controller()
|
||
|
||
success = controller.show_on_demand(mode, duration=duration)
|
||
|
||
return jsonify({'success': success})
|
||
|
||
@api_v3.route('/display/clear', methods=['POST'])
|
||
def clear_on_demand():
|
||
controller = get_display_controller()
|
||
controller.clear_on_demand()
|
||
return jsonify({'success': True})
|
||
```
|
||
|
||
### Step 2: Add UI Button
|
||
|
||
```html
|
||
<!-- Show weather button -->
|
||
<button onclick="showWeather()">Show Weather Now</button>
|
||
|
||
<script>
|
||
async function showWeather() {
|
||
await fetch('/api/v3/display/show', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
mode: 'weather',
|
||
duration: 30 // Show for 30 seconds
|
||
})
|
||
});
|
||
}
|
||
</script>
|
||
```
|
||
|
||
### Step 3: Done! 🎉
|
||
|
||
Users can now click the button to show weather immediately!
|
||
|
||
## 📋 Complete Web UI Example
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>Display Control</title>
|
||
<style>
|
||
.plugin-card {
|
||
border: 1px solid #ccc;
|
||
padding: 15px;
|
||
margin: 10px;
|
||
border-radius: 5px;
|
||
}
|
||
.show-now-btn {
|
||
background: #4CAF50;
|
||
color: white;
|
||
padding: 10px 20px;
|
||
border: none;
|
||
border-radius: 5px;
|
||
cursor: pointer;
|
||
}
|
||
.pin-btn {
|
||
background: #2196F3;
|
||
color: white;
|
||
padding: 10px 20px;
|
||
border: none;
|
||
border-radius: 5px;
|
||
cursor: pointer;
|
||
}
|
||
.clear-btn {
|
||
background: #f44336;
|
||
color: white;
|
||
padding: 10px 20px;
|
||
border: none;
|
||
border-radius: 5px;
|
||
cursor: pointer;
|
||
}
|
||
#status-bar {
|
||
background: #ff9800;
|
||
color: white;
|
||
padding: 15px;
|
||
text-align: center;
|
||
display: none;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<!-- Status bar (shown when on-demand is active) -->
|
||
<div id="status-bar">
|
||
<span id="status-text"></span>
|
||
<button class="clear-btn" onclick="clearOnDemand()">
|
||
Return to Rotation
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Plugin controls -->
|
||
<div class="plugin-grid">
|
||
<div class="plugin-card">
|
||
<h3>⛅ Weather</h3>
|
||
<button class="show-now-btn" onclick="showPlugin('weather', 30)">
|
||
Show for 30s
|
||
</button>
|
||
<button class="pin-btn" onclick="pinPlugin('weather')">
|
||
Pin Weather
|
||
</button>
|
||
</div>
|
||
|
||
<div class="plugin-card">
|
||
<h3>🏒 Hockey</h3>
|
||
<button class="show-now-btn" onclick="showPlugin('hockey_live', 45)">
|
||
Show Live Game
|
||
</button>
|
||
<button class="pin-btn" onclick="pinPlugin('hockey_live')">
|
||
Pin Game
|
||
</button>
|
||
</div>
|
||
|
||
<div class="plugin-card">
|
||
<h3>🎵 Music</h3>
|
||
<button class="show-now-btn" onclick="showPlugin('music', 20)">
|
||
Show Now Playing
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// Show plugin for specific duration
|
||
async function showPlugin(mode, duration) {
|
||
const response = await fetch('/api/v3/display/show', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ mode, duration })
|
||
});
|
||
|
||
const data = await response.json();
|
||
if (data.success) {
|
||
updateStatus();
|
||
} else {
|
||
alert('Failed to show plugin');
|
||
}
|
||
}
|
||
|
||
// Pin plugin (stays until cleared)
|
||
async function pinPlugin(mode) {
|
||
const response = await fetch('/api/v3/display/show', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
mode,
|
||
pinned: true
|
||
})
|
||
});
|
||
|
||
const data = await response.json();
|
||
if (data.success) {
|
||
updateStatus();
|
||
}
|
||
}
|
||
|
||
// Clear on-demand and return to rotation
|
||
async function clearOnDemand() {
|
||
await fetch('/api/v3/display/clear', { method: 'POST' });
|
||
updateStatus();
|
||
}
|
||
|
||
// Update status display
|
||
async function updateStatus() {
|
||
const response = await fetch('/api/v3/display/on-demand-info');
|
||
const info = await response.json();
|
||
|
||
const statusBar = document.getElementById('status-bar');
|
||
const statusText = document.getElementById('status-text');
|
||
|
||
if (info.active) {
|
||
let text = `Showing: ${info.mode}`;
|
||
if (info.remaining) {
|
||
text += ` (${Math.ceil(info.remaining)}s remaining)`;
|
||
} else if (info.pinned) {
|
||
text += ' (pinned)';
|
||
}
|
||
statusText.textContent = text;
|
||
statusBar.style.display = 'block';
|
||
} else {
|
||
statusBar.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
// Poll for status updates every second
|
||
setInterval(updateStatus, 1000);
|
||
|
||
// Initial status check
|
||
updateStatus();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
## ⚡ Usage Patterns
|
||
|
||
### Pattern 1: Timed Preview
|
||
```javascript
|
||
// Show for 30 seconds then return to rotation
|
||
showPlugin('weather', 30);
|
||
```
|
||
|
||
### Pattern 2: Pinned Display
|
||
```javascript
|
||
// Stay on this plugin until manually cleared
|
||
pinPlugin('hockey_live');
|
||
```
|
||
|
||
### Pattern 3: Quick Check
|
||
```javascript
|
||
// Show for 10 seconds
|
||
showPlugin('clock', 10);
|
||
```
|
||
|
||
### Pattern 4: Indefinite Display
|
||
```javascript
|
||
// Show until cleared (duration=0)
|
||
fetch('/api/v3/display/show', {
|
||
method: 'POST',
|
||
body: JSON.stringify({ mode: 'weather', duration: 0 })
|
||
});
|
||
```
|
||
|
||
## 📊 Priority Order
|
||
|
||
```
|
||
User clicks "Show Weather" button
|
||
↓
|
||
1. On-Demand (Highest) ← Shows immediately
|
||
2. Live Priority ← Overridden
|
||
3. Normal Rotation ← Paused
|
||
```
|
||
|
||
On-demand has **highest priority** - it overrides everything!
|
||
|
||
## 🎮 Common Use Cases
|
||
|
||
### Quick Weather Check
|
||
```html
|
||
<button onclick="showPlugin('weather', 20)">
|
||
Check Weather
|
||
</button>
|
||
```
|
||
|
||
### Monitor Live Game
|
||
```html
|
||
<button onclick="pinPlugin('hockey_live')">
|
||
Watch Game
|
||
</button>
|
||
```
|
||
|
||
### Test Plugin Configuration
|
||
```html
|
||
<button onclick="showPlugin('my-plugin', 15)">
|
||
Preview Plugin
|
||
</button>
|
||
```
|
||
|
||
### Emergency Message
|
||
```html
|
||
<button onclick="pinPlugin('text-display')">
|
||
Show Alert
|
||
</button>
|
||
```
|
||
|
||
## 🔧 Duration Options
|
||
|
||
| Value | Behavior | Example |
|
||
|-------|----------|---------|
|
||
| `30` | Show for 30s then return | Quick preview |
|
||
| `0` | Show until cleared | Extended viewing |
|
||
| `null` | Use plugin's default | Let plugin decide |
|
||
| `pinned: true` | Stay until unpinned | Monitor mode |
|
||
|
||
## ❓ FAQ
|
||
|
||
### Q: What happens when duration expires?
|
||
**A:** Display automatically returns to normal rotation (or live priority if active).
|
||
|
||
### Q: Can I show multiple modes at once?
|
||
**A:** No, only one mode at a time. Last request wins.
|
||
|
||
### Q: Does it override live games?
|
||
**A:** Yes! On-demand has highest priority, even over live priority.
|
||
|
||
### Q: How do I go back to normal rotation?
|
||
**A:** Either wait for duration to expire, or call `clearOnDemand()`.
|
||
|
||
### Q: What if the mode doesn't exist?
|
||
**A:** API returns `success: false` and logs a warning.
|
||
|
||
## 🐛 Testing
|
||
|
||
### Test 1: Show for 30 seconds
|
||
```bash
|
||
curl -X POST http://pi-ip:5001/api/v3/display/show \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"mode": "weather", "duration": 30}'
|
||
```
|
||
|
||
### Test 2: Pin mode
|
||
```bash
|
||
curl -X POST http://pi-ip:5001/api/v3/display/show \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"mode": "hockey_live", "pinned": true}'
|
||
```
|
||
|
||
### Test 3: Clear on-demand
|
||
```bash
|
||
curl -X POST http://pi-ip:5001/api/v3/display/clear
|
||
```
|
||
|
||
### Test 4: Check status
|
||
```bash
|
||
curl http://pi-ip:5001/api/v3/display/on-demand-info
|
||
```
|
||
|
||
## 📝 Implementation Checklist
|
||
|
||
- [ ] Add API endpoints to web interface
|
||
- [ ] Add "Show Now" buttons to plugin cards
|
||
- [ ] Add status bar showing current on-demand mode
|
||
- [ ] Add "Clear" button when on-demand active
|
||
- [ ] Add authentication to API endpoints
|
||
- [ ] Test with multiple plugins
|
||
- [ ] Test duration expiration
|
||
- [ ] Test pinned mode
|
||
|
||
## 📚 Full Documentation
|
||
|
||
See `ON_DEMAND_DISPLAY_API.md` for:
|
||
- Complete API reference
|
||
- Security best practices
|
||
- Troubleshooting guide
|
||
- Advanced examples
|
||
|
||
## 🎯 Key Points
|
||
|
||
1. **User-triggered** - Manual control from web UI
|
||
2. **Highest priority** - Overrides everything
|
||
3. **Auto-clear** - Returns to rotation after duration
|
||
4. **Pin mode** - Stay on mode until manually cleared
|
||
5. **Simple API** - Just 3 endpoints needed
|
||
|
||
That's it! Your users can now control what shows on the display! 🚀
|
||
|