Files
LEDMatrix/docs/archive/STATIC_IMAGE_MULTI_UPLOAD_PLAN.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

379 lines
11 KiB
Markdown

# Static Image Plugin - Multi-Image Upload & Rotation Implementation Plan
## Overview
Enhance the static-image plugin to support:
1. **Multiple image uploads** via web UI
2. **Image rotation** (sequential, random, time-based, date-based)
3. **Robust asset management** (storage, validation, cleanup)
4. **Future-proof architecture** for advanced rotation logic
## Architecture Design
### 1. Configuration Schema Enhancement
#### Current Schema
```json
{
"image_path": "assets/static_images/default.png"
}
```
#### Enhanced Schema (Backward Compatible)
```json
{
"image_config": {
"mode": "single" | "multiple",
"rotation_mode": "sequential" | "random" | "time_based" | "date_based",
"images": [
{
"id": "uuid-or-hash",
"path": "assets/plugins/static-image/uploads/image_1234567890.png",
"uploaded_at": "2025-01-15T10:30:00Z",
"display_order": 0,
"schedule": null // Future: {"start_time": "08:00", "end_time": "18:00", "days": [1,2,3,4,5]}
}
]
},
// Legacy support - maps to single image mode
"image_path": "assets/static_images/default.png",
// Rotation settings
"rotation_settings": {
"sequential_loop": true,
"random_seed": null, // null = use time, or fixed seed for reproducible rotation
"time_intervals": {
"enabled": false,
"interval_seconds": 3600 // Change image every hour
},
"date_ranges": [] // Future: [{"start": "2025-12-01", "end": "2025-12-25", "image_id": "..."}]
}
}
```
### 2. Asset Storage Structure
```text
assets/
├── plugins/
│ └── static-image/
│ └── uploads/
│ ├── image_1705312200_abc123.png
│ ├── image_1705312400_def456.jpg
│ └── .metadata.json // Maps IDs to filenames
```
**Storage Strategy:**
- Files stored in `assets/plugins/static-image/uploads/`
- Filenames: `image_{timestamp}_{hash}.{ext}` (prevents collisions)
- Metadata JSON tracks: ID → filename mapping, upload dates, file sizes
- Cleanup: Remove files not referenced in config
### 3. Backend API Endpoints
#### POST `/api/v3/plugins/assets/upload`
**Purpose:** Upload image files for a specific plugin
**Request:**
- `multipart/form-data`
- `plugin_id`: string (required)
- `files`: File[] (multiple files supported)
- `rotation_mode`: string (optional, default: "sequential")
**Response:**
```json
{
"status": "success",
"uploaded_files": [
{
"id": "uuid-here",
"filename": "image_1705312200_abc123.png",
"path": "assets/plugins/static-image/uploads/image_1705312200_abc123.png",
"size": 45678,
"uploaded_at": "2025-01-15T10:30:00Z"
}
]
}
```
**Validation:**
- File type: PNG, JPG, JPEG, BMP, GIF
- Max file size: 5MB per file
- Max files per upload: 10
- Total storage limit: 50MB per plugin
#### DELETE `/api/v3/plugins/assets/delete`
**Purpose:** Delete uploaded image
**Request:**
- `plugin_id`: string
- `image_id`: string (from upload response)
**Response:**
```json
{
"status": "success",
"deleted_file": "image_1705312200_abc123.png"
}
```
#### GET `/api/v3/plugins/assets/list`
**Purpose:** List all uploaded images for a plugin
**Response:**
```json
{
"status": "success",
"images": [
{
"id": "uuid-here",
"filename": "image_1705312200_abc123.png",
"path": "assets/plugins/static-image/uploads/image_1705312200_abc123.png",
"size": 45678,
"uploaded_at": "2025-01-15T10:30:00Z"
}
]
}
```
### 4. Frontend Form Generator Enhancement
#### Schema Format for File Upload
```json
{
"type": "object",
"properties": {
"images": {
"type": "array",
"x-widget": "file-upload",
"x-upload-config": {
"endpoint": "/api/v3/plugins/assets/upload",
"plugin_id_field": "plugin_id",
"max_files": 10,
"allowed_types": ["image/png", "image/jpeg", "image/bmp", "image/gif"],
"max_size_mb": 5
},
"items": {
"type": "object",
"properties": {
"id": {"type": "string"},
"path": {"type": "string"},
"uploaded_at": {"type": "string", "format": "date-time"}
}
},
"description": "Upload images to display. Multiple images will rotate based on rotation mode."
},
"rotation_mode": {
"type": "string",
"enum": ["sequential", "random", "time_based", "date_based"],
"default": "sequential",
"description": "How to rotate through images"
}
}
}
```
#### UI Components
1. **File Upload Widget:**
- Drag-and-drop zone
- File list with thumbnails
- Remove button per file
- Upload progress indicator
- Image preview before upload
2. **Rotation Mode Selector:**
- Dropdown with rotation options
- Settings panel per mode:
- Sequential: Loop option
- Random: Seed option
- Time-based: Interval input
- Date-based: Calendar picker (future)
### 5. Plugin Manager Updates
#### Rotation Logic in `manager.py`
```python
class StaticImagePlugin(BasePlugin):
def __init__(self, ...):
# ... existing code ...
# Enhanced image handling
self.image_config = config.get('image_config', {})
self.rotation_mode = self.image_config.get('rotation_mode', 'sequential')
self.rotation_settings = config.get('rotation_settings', {})
self.images_list = self.image_config.get('images', [])
self.current_image_index = 0
self.last_rotation_time = time.time()
# Initialize rotation
self._setup_rotation()
def _setup_rotation(self):
"""Initialize rotation based on mode"""
if self.rotation_mode == 'random':
import random
seed = self.rotation_settings.get('random_seed')
if seed:
random.seed(seed)
if not self.images_list:
# Fallback to legacy image_path
if self.image_path:
self.images_list = [{'path': self.image_path}]
def _get_next_image(self) -> Optional[str]:
"""Get next image path based on rotation mode"""
if not self.images_list:
return None
if self.rotation_mode == 'sequential':
path = self.images_list[self.current_image_index]['path']
self.current_image_index = (self.current_image_index + 1) % len(self.images_list)
return path
elif self.rotation_mode == 'random':
import random
return random.choice(self.images_list)['path']
elif self.rotation_mode == 'time_based':
interval = self.rotation_settings.get('time_intervals', {}).get('interval_seconds', 3600)
now = time.time()
if now - self.last_rotation_time >= interval:
self.current_image_index = (self.current_image_index + 1) % len(self.images_list)
self.last_rotation_time = now
return self.images_list[self.current_image_index]['path']
elif self.rotation_mode == 'date_based':
# Future implementation
return self._get_date_based_image()
return self.images_list[0]['path']
def display(self, force_clear: bool = False):
"""Display current image based on rotation"""
image_path = self._get_next_image()
if not image_path or not os.path.exists(image_path):
self._display_error()
return
self.image_path = image_path # For compatibility
self._load_image()
# ... rest of display logic ...
```
### 6. Asset Management System
#### File Operations
- **Upload:** Save to `assets/plugins/{plugin_id}/uploads/`
- **Validation:** Check file type, size, dimensions
- **Metadata:** Track in `.metadata.json`
- **Cleanup:** Remove orphaned files on config save
- **Permissions:** Ensure writable by web service
#### Security
- Validate file extensions (whitelist)
- Check file content (magic bytes, not just extension)
- Limit file sizes
- Sanitize filenames
- Prevent path traversal
### 7. Migration Strategy
#### Backward Compatibility
1. **Legacy Support:**
- If `image_path` exists but no `image_config`, auto-convert
- Create `image_config` with single image from `image_path`
2. **Config Migration:**
```python
def _migrate_legacy_config(self, config):
"""Migrate legacy image_path to new image_config format"""
if 'image_path' in config and 'image_config' not in config:
config['image_config'] = {
'mode': 'single',
'rotation_mode': 'sequential',
'images': [{
'id': str(uuid.uuid4()),
'path': config['image_path'],
'uploaded_at': datetime.now().isoformat(),
'display_order': 0
}]
}
return config
```
## Implementation Phases
### Phase 1: Core Upload System
1. ✅ Enhanced config schema
2. ✅ Backend upload endpoint
3. ✅ Asset storage structure
4. ✅ File validation
### Phase 2: Frontend Integration
5. ✅ File upload widget in form generator
6. ✅ Image preview/management UI
7. ✅ Rotation mode selector
### Phase 3: Plugin Rotation Logic
8. ✅ Update plugin manager with rotation
9. ✅ Sequential rotation
10. ✅ Random rotation
### Phase 4: Advanced Features
11. ✅ Time-based rotation
12. ✅ Date-based rotation (future)
13. ✅ Cleanup/orphan removal
## File Structure Changes
```text
plugins/static-image/
├── manager.py # Enhanced with rotation logic
├── config_schema.json # Updated with upload/rotation fields
├── manifest.json # No changes
└── README.md # Update documentation
web_interface/
├── blueprints/
│ └── api_v3.py # Add upload/delete/list endpoints
└── templates/v3/
└── partials/
└── plugins.html # File upload widget
assets/
└── plugins/
└── static-image/
└── uploads/ # NEW - user uploaded images
└── .metadata.json
```
## Testing Checklist
- [ ] Single image upload works
- [ ] Multiple image upload works
- [ ] File validation (type, size)
- [ ] Sequential rotation cycles correctly
- [ ] Random rotation works
- [ ] Time-based rotation changes at intervals
- [ ] Legacy config migration preserves existing images
- [ ] Orphaned file cleanup on config save
- [ ] Web UI displays upload widget correctly
- [ ] Image preview shows before upload
- [ ] Delete removes file and updates config
- [ ] Error handling for missing/invalid files
## Future Enhancements
1. **Date-based rotation:** Display different images on specific dates
2. **Time-of-day rotation:** Show images based on time ranges
3. **Transition effects:** Fade between images
4. **Image filters:** Apply effects (brightness, contrast)
5. **Bulk operations:** Select multiple images for deletion
6. **Image organization:** Folders/tags for images
7. **Remote images:** Support URLs (with caching)