Initial import: clean snapshot from /home/olafn/infoscreen-dev (2025-10-25)
This commit is contained in:
612
README.md
Normal file
612
README.md
Normal file
@@ -0,0 +1,612 @@
|
||||
# Infoscreen Client - Display Manager
|
||||
|
||||
Digital signage system for Raspberry Pi that displays presentations, videos, and web content in kiosk mode. Centrally managed via MQTT with automatic client discovery and heartbeat monitoring.
|
||||
|
||||
## 🎯 Key Features
|
||||
|
||||
- **Automatic Presentation Display** - PPTX files converted to PDF and displayed with Impressive
|
||||
- **Auto-Advance Slideshows** - Configurable timing for automatic slide progression
|
||||
- **Loop Mode** - Presentations can loop infinitely or quit after last slide
|
||||
- **MQTT Integration** - Real-time event management from central server
|
||||
- **Group Management** - Organize clients into groups for targeted content
|
||||
- **Heartbeat Monitoring** - Regular status updates and screenshot dashboard
|
||||
- **Multi-Content Support** - Presentations, videos, and web pages
|
||||
- **Kiosk Mode** - Full-screen display with automatic startup
|
||||
|
||||
## 📋 System Requirements
|
||||
|
||||
### Hardware
|
||||
- Raspberry Pi 4/5 (or compatible)
|
||||
- HDMI display
|
||||
- Network connectivity (WiFi or Ethernet)
|
||||
- SSD storage recommended
|
||||
|
||||
### Software
|
||||
- Raspberry Pi OS (Bookworm or newer)
|
||||
- Python 3.x
|
||||
- LibreOffice (for PPTX→PDF conversion)
|
||||
- Impressive (PDF presenter with auto-advance)
|
||||
- Chromium browser (for web content)
|
||||
- VLC or MPV (for video playback)
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### 1. Installation
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
cd ~/
|
||||
git clone <repository-url> infoscreen-dev
|
||||
cd infoscreen-dev
|
||||
|
||||
# Install system dependencies
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
python3 python3-pip python3-venv \
|
||||
libreoffice impressive \
|
||||
chromium-browser vlc
|
||||
|
||||
# Create Python virtual environment
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Install Python dependencies
|
||||
pip install -r src/requirements.txt
|
||||
```
|
||||
|
||||
### 2. Configuration
|
||||
|
||||
Create `.env` file in project root:
|
||||
|
||||
```bash
|
||||
# Environment
|
||||
ENV=production
|
||||
LOG_LEVEL=INFO
|
||||
|
||||
# MQTT Configuration
|
||||
MQTT_BROKER=192.168.1.100
|
||||
MQTT_PORT=1883
|
||||
MQTT_BROKER_FALLBACKS=192.168.1.101,192.168.1.102
|
||||
|
||||
# Timing (seconds)
|
||||
HEARTBEAT_INTERVAL=30
|
||||
SCREENSHOT_INTERVAL=60
|
||||
DISPLAY_CHECK_INTERVAL=5
|
||||
|
||||
# File/API Server (used to download presentation files)
|
||||
# Defaults to the same host as MQTT_BROKER, port 8000, scheme http.
|
||||
# If incoming event URLs use host 'server' (or are host-less), simclient rewrites them to this server.
|
||||
FILE_SERVER_HOST= # optional; if empty, defaults to MQTT_BROKER
|
||||
FILE_SERVER_PORT=8000 # default API port
|
||||
# http or https
|
||||
FILE_SERVER_SCHEME=http
|
||||
# FILE_SERVER_BASE_URL= # optional full override, e.g., http://192.168.1.100:8000
|
||||
```
|
||||
|
||||
### 3. Start Services
|
||||
|
||||
```bash
|
||||
# Start MQTT client (handles events, heartbeat, discovery)
|
||||
cd ~/infoscreen-dev/src
|
||||
python3 simclient.py
|
||||
|
||||
# In another terminal: Start Display Manager
|
||||
cd ~/infoscreen-dev/src
|
||||
python3 display_manager.py
|
||||
```
|
||||
|
||||
Or use the startup script:
|
||||
```bash
|
||||
./scripts/start-display-manager.sh
|
||||
```
|
||||
|
||||
## 📊 Presentation System
|
||||
|
||||
### How It Works
|
||||
|
||||
The system uses **Impressive** as the PDF presenter with native auto-advance and loop support:
|
||||
|
||||
1. **PPTX files** are automatically converted to PDF using LibreOffice headless
|
||||
2. **PDF files** are displayed directly with Impressive
|
||||
3. **Auto-advance** uses Impressive's built-in `--auto` parameter
|
||||
4. **Loop mode** uses Impressive's `--wrap` parameter (infinite loop)
|
||||
5. **Auto-quit** uses Impressive's `--autoquit` parameter (exit after last slide)
|
||||
|
||||
### Event JSON Format
|
||||
|
||||
#### Looping Presentation (Typical for Events)
|
||||
```json
|
||||
{
|
||||
"id": "event_123",
|
||||
"start": "2025-10-01 14:00:00",
|
||||
"end": "2025-10-01 16:00:00",
|
||||
"presentation": {
|
||||
"files": [
|
||||
{
|
||||
"name": "slides.pptx",
|
||||
"url": "https://server/files/slides.pptx"
|
||||
}
|
||||
],
|
||||
"auto_advance": true,
|
||||
"slide_interval": 10,
|
||||
"loop": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Result:** Slides advance every 10 seconds, presentation loops infinitely until event ends.
|
||||
|
||||
#### Single Playthrough
|
||||
```json
|
||||
{
|
||||
"presentation": {
|
||||
"files": [{"name": "welcome.pptx"}],
|
||||
"auto_advance": true,
|
||||
"slide_interval": 5,
|
||||
"loop": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Result:** Slides advance every 5 seconds, exits after last slide.
|
||||
|
||||
### Presentation Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `auto_advance` | boolean | `false` | Enable automatic slide advancement |
|
||||
| `slide_interval` | integer | `10` | Seconds between slides |
|
||||
| `loop` | boolean | `false` | Loop presentation vs. quit after last slide |
|
||||
|
||||
### Scheduler-Specific Fields
|
||||
|
||||
The scheduler may send additional fields that are preserved in `current_event.json`:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `page_progress` | boolean | Show overall progress bar in presentation (Impressive `--page-progress`). Can be provided at `presentation.page_progress` (preferred) or top-level. |
|
||||
| `auto_progress` | boolean | Show per-page auto-advance countdown (Impressive `--auto-progress`). Can be provided at `presentation.auto_progress` (preferred) or top-level. |
|
||||
| `occurrence_of_id` | integer | Original event ID for recurring events |
|
||||
| `recurrence_rule` | string | iCal recurrence rule (RRULE format) |
|
||||
| `recurrence_end` | string | End date for recurring events |
|
||||
|
||||
**Note:** All fields from the scheduler are automatically preserved when events are stored in `current_event.json`. The client does not filter or modify scheduler-specific metadata.
|
||||
|
||||
#### Progress Bar Display
|
||||
|
||||
When using Impressive PDF presenter:
|
||||
- `page_progress: true` - Shows a progress bar at the bottom indicating position in the presentation
|
||||
- `auto_progress: true` - Shows a countdown progress bar for each slide during auto-advance
|
||||
- Both options can be enabled simultaneously for maximum visual feedback
|
||||
|
||||
## 🎥 Video Events
|
||||
|
||||
```json
|
||||
{
|
||||
"video": {
|
||||
"url": "https://server/videos/intro.mp4",
|
||||
"loop": true,
|
||||
"autoplay": true,
|
||||
"volume": 0.8
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
- The Display Manager prefers `python-vlc` (libvlc) when available. This gives programmatic control over playback (autoplay, loop, volume) and ensures the player is cleanly stopped and released when events end.
|
||||
- Supported video event fields:
|
||||
- `url` (string): HTTP/HTTPS or streaming URL. URLs using the placeholder host `server` are rewritten to the configured file server (see File/API Server configuration).
|
||||
- `autoplay` (boolean): start playback automatically when the event becomes active (default: true).
|
||||
- `loop` (boolean): loop playback indefinitely.
|
||||
- `volume` (float): 0.0–1.0 (mapped internally to VLC's 0–100 volume scale).
|
||||
- If `python-vlc` is not installed, the Display Manager will fall back to launching the external `vlc` binary.
|
||||
- The manager attempts to make the player window fullscreen and remove window decorations. For a truly panel-free fullscreen (no taskbar), run the Display Manager inside a minimal kiosk X session or a dedicated user session without a desktop panel (see the kiosk notes below).
|
||||
|
||||
## 🌐 Web Events
|
||||
|
||||
```json
|
||||
{
|
||||
"web": {
|
||||
"url": "https://dashboard.example.com"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Opens webpage in Chromium kiosk mode (fullscreen, no UI).
|
||||
|
||||
## 🗂️ Project Structure
|
||||
|
||||
```
|
||||
infoscreen-dev/
|
||||
├── .env # Environment configuration
|
||||
├── README.md # This file
|
||||
├── IMPRESSIVE_INTEGRATION.md # Detailed presentation system docs
|
||||
├── src/
|
||||
│ ├── simclient.py # MQTT client (events, heartbeat, discovery)
|
||||
│ ├── display_manager.py # Display controller (manages applications)
|
||||
│ ├── requirements.txt # Python dependencies
|
||||
│ ├── current_event.json # Current active event (runtime)
|
||||
│ ├── config/ # Persistent client data
|
||||
│ │ ├── client_uuid.txt
|
||||
│ │ └── last_group_id.txt
|
||||
│ ├── presentation/ # Downloaded presentation files
|
||||
│ └── screenshots/ # Dashboard screenshots
|
||||
├── scripts/
|
||||
│ ├── start-dev.sh # Start development client
|
||||
│ ├── start-display-manager.sh # Start Display Manager
|
||||
│ ├── test-display-manager.sh # Interactive testing
|
||||
│ ├── test-impressive.sh # Test Impressive (auto-quit mode)
|
||||
│ ├── test-impressive-loop.sh # Test Impressive (loop mode)
|
||||
│ ├── test-mqtt.sh # Test MQTT connectivity
|
||||
│ ├── test-screenshot.sh # Test screenshot capture
|
||||
│ ├── test-utc-timestamps.sh # Test event timing
|
||||
│ └── present-pdf-auto-advance.sh # PDF presentation wrapper
|
||||
└── logs/ # Application logs
|
||||
```
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
### Test Display Manager
|
||||
|
||||
```bash
|
||||
./scripts/test-display-manager.sh
|
||||
```
|
||||
|
||||
Interactive menu for testing:
|
||||
- Check Display Manager status
|
||||
- Create test events (presentation, video, webpage)
|
||||
- View active processes
|
||||
- Cycle through different event types
|
||||
|
||||
### Test Impressive Presentation
|
||||
|
||||
**Single playthrough (auto-quit):**
|
||||
```bash
|
||||
./scripts/test-impressive.sh
|
||||
```
|
||||
|
||||
**Loop mode (infinite):**
|
||||
```bash
|
||||
./scripts/test-impressive-loop.sh
|
||||
```
|
||||
|
||||
### Test MQTT Communication
|
||||
|
||||
```bash
|
||||
./scripts/test-mqtt.sh
|
||||
```
|
||||
|
||||
Verifies MQTT broker connectivity and topics.
|
||||
|
||||
### Test Screenshot Capture
|
||||
|
||||
```bash
|
||||
./scripts/test-screenshot.sh
|
||||
```
|
||||
|
||||
Captures test screenshot for dashboard monitoring.
|
||||
|
||||
## 🔧 Configuration Details
|
||||
|
||||
### Environment Variables
|
||||
|
||||
#### Environment
|
||||
- `ENV` - `development` or `production`
|
||||
- `DEBUG_MODE` - Enable debug output (1=on, 0=off)
|
||||
- `LOG_LEVEL` - `DEBUG`, `INFO`, `WARNING`, `ERROR`
|
||||
|
||||
#### MQTT
|
||||
- `MQTT_BROKER` - Primary MQTT broker IP/hostname
|
||||
- `MQTT_PORT` - MQTT port (default: 1883)
|
||||
- `MQTT_BROKER_FALLBACKS` - Comma-separated fallback brokers
|
||||
- `MQTT_USERNAME` - Optional authentication
|
||||
- `MQTT_PASSWORD` - Optional authentication
|
||||
|
||||
#### Timing
|
||||
- `HEARTBEAT_INTERVAL` - Status update frequency (seconds)
|
||||
- `SCREENSHOT_INTERVAL` - Dashboard screenshot frequency (seconds)
|
||||
- `DISPLAY_CHECK_INTERVAL` - Event check frequency (seconds)
|
||||
|
||||
#### File/API Server
|
||||
- `FILE_SERVER_HOST` - Host/IP of the file server; defaults to `MQTT_BROKER` when empty
|
||||
- `FILE_SERVER_PORT` - Port of the file server (default: 8000)
|
||||
- `FILE_SERVER_SCHEME` - `http` or `https` (default: http)
|
||||
- `FILE_SERVER_BASE_URL` - Optional full override, e.g., `https://api.example.com:443`
|
||||
|
||||
### File Server URL Resolution
|
||||
- The MQTT client (`src/simclient.py`) downloads presentation files listed in events.
|
||||
- If an event contains URLs with host `server` (e.g., `http://server:8000/...`) or a missing host, the client rewrites them to the configured file server.
|
||||
- By default, the file server host is the same as `MQTT_BROKER`, with port `8000` and scheme `http`.
|
||||
- You can override this behavior using the `.env` variables above; `FILE_SERVER_BASE_URL` takes precedence over the individual host/port/scheme.
|
||||
- Tip: When editing `.env`, keep comments after a space and `#` so values stay clean.
|
||||
|
||||
### MQTT Topics
|
||||
|
||||
#### Client → Server
|
||||
- `infoscreen/discovery` - Initial client announcement
|
||||
- `infoscreen/{client_id}/heartbeat` - Regular status updates
|
||||
- `infoscreen/{client_id}/dashboard` - Screenshot images (base64)
|
||||
|
||||
#### Server → Client
|
||||
- `infoscreen/{client_id}/discovery_ack` - Server response with client ID
|
||||
- `infoscreen/{client_id}/group_id` - Group assignment
|
||||
- `infoscreen/events/{group_id}` - Event commands for group
|
||||
|
||||
### Client Identification
|
||||
|
||||
**Hardware Token:** SHA256 hash of:
|
||||
- CPU serial number
|
||||
- MAC addresses (all network interfaces)
|
||||
|
||||
**Persistent UUID:** Stored in `src/config/client_uuid.txt`
|
||||
|
||||
**Group Membership:** Stored in `src/config/last_group_id.txt`
|
||||
|
||||
## 🔍 Troubleshooting
|
||||
|
||||
### Display Manager doesn't start presentations
|
||||
|
||||
**Check Impressive installation:**
|
||||
```bash
|
||||
which impressive
|
||||
# If not found: sudo apt-get install impressive
|
||||
```
|
||||
|
||||
**Check LibreOffice installation:**
|
||||
```bash
|
||||
which libreoffice
|
||||
# If not found: sudo apt-get install libreoffice
|
||||
```
|
||||
|
||||
**Check logs:**
|
||||
```bash
|
||||
tail -f logs/display_manager.log
|
||||
```
|
||||
|
||||
### Presentations don't convert from PPTX
|
||||
|
||||
**Verify LibreOffice headless:**
|
||||
```bash
|
||||
libreoffice --headless --convert-to pdf --outdir /tmp presentation.pptx
|
||||
ls -l /tmp/*.pdf
|
||||
```
|
||||
|
||||
**Check disk space:**
|
||||
```bash
|
||||
df -h
|
||||
```
|
||||
|
||||
### Slides don't auto-advance
|
||||
|
||||
**Verify event JSON:**
|
||||
- `auto_advance: true` is set
|
||||
- `slide_interval` is specified (default: 10)
|
||||
|
||||
**Test Impressive directly:**
|
||||
```bash
|
||||
./scripts/test-impressive.sh
|
||||
```
|
||||
|
||||
### Presentation doesn't loop
|
||||
|
||||
**Verify event JSON:**
|
||||
- `loop: true` is set
|
||||
|
||||
**Test loop mode:**
|
||||
```bash
|
||||
./scripts/test-impressive-loop.sh
|
||||
```
|
||||
|
||||
### File downloads fail
|
||||
|
||||
Symptoms:
|
||||
- `Failed to resolve 'server'` or `NameResolutionError` when downloading files
|
||||
- `Invalid URL 'http # http or https://...'` in `logs/simclient.log`
|
||||
|
||||
What to check:
|
||||
- Look for lines like `Lade Datei herunter von:` in `logs/simclient.log` to see the effective URL used
|
||||
- Ensure the URL host is the MQTT broker IP (or your configured file server), not `server`
|
||||
- Verify `.env` values don’t include inline comments as part of the value (e.g., keep `FILE_SERVER_SCHEME=http` on its own line)
|
||||
|
||||
Fixes:
|
||||
- If your API is on the same host as the broker: leave `FILE_SERVER_HOST` empty (defaults to `MQTT_BROKER`), keep `FILE_SERVER_PORT=8000`, and set `FILE_SERVER_SCHEME=http` or `https`
|
||||
- To override fully, set `FILE_SERVER_BASE_URL` (e.g., `http://192.168.1.100:8000`); this takes precedence over host/port/scheme
|
||||
- After changing `.env`, restart the simclient process
|
||||
|
||||
Expected healthy log sequence:
|
||||
- `Lade Datei herunter von: http://<broker-ip>:8000/...`
|
||||
- Followed by `"GET /... HTTP/1.1" 200` and `Datei erfolgreich heruntergeladen:`
|
||||
|
||||
### VLC hardware decode / renderer issues
|
||||
|
||||
If you see messages like:
|
||||
|
||||
```
|
||||
[h264_v4l2m2m @ ...] Could not find a valid device
|
||||
[h264_v4l2m2m @ ...] can't configure decoder
|
||||
[... ] avcodec decoder error: cannot start codec (h264_v4l2m2m)
|
||||
```
|
||||
|
||||
that indicates libVLC / ffmpeg attempted to use the platform V4L2 M2M hardware decoder but the kernel/device isn't available. Options to resolve:
|
||||
|
||||
- Enable the V4L2 M2M codec driver on the system (platform-specific; on Raspberry Pi ensure correct kernel/firmware and codec modules are loaded). Check `v4l2-ctl --list-devices` and `ls /dev/video*` after installing `v4l-utils`.
|
||||
- Disable hardware decoding so libVLC/ffmpeg uses software decoding (reliable but higher CPU). You can test this by launching the `vlc` binary with:
|
||||
|
||||
```bash
|
||||
vlc --avcodec-hw=none 'http://<your-video-url>'
|
||||
```
|
||||
|
||||
Or modify `src/display_manager.py` to create the libVLC instance with software-decoding forced:
|
||||
|
||||
```python
|
||||
instance = vlc.Instance('--avcodec-hw=none', '--no-video-title-show', '--no-video-deco')
|
||||
```
|
||||
|
||||
This is the fastest workaround if hardware decode is not required or not available on the device.
|
||||
|
||||
### MQTT connection issues
|
||||
|
||||
**Test broker connectivity:**
|
||||
```bash
|
||||
./scripts/test-mqtt.sh
|
||||
```
|
||||
|
||||
**Check broker status:**
|
||||
```bash
|
||||
# On server
|
||||
sudo systemctl status mosquitto
|
||||
```
|
||||
|
||||
**Try fallback brokers:**
|
||||
Edit `.env` and add `MQTT_BROKER_FALLBACKS`
|
||||
|
||||
### Screenshots not uploading
|
||||
|
||||
**Test screenshot capture:**
|
||||
```bash
|
||||
./scripts/test-screenshot.sh
|
||||
ls -l screenshots/
|
||||
```
|
||||
|
||||
**Check DISPLAY variable:**
|
||||
```bash
|
||||
echo $DISPLAY # Should be :0
|
||||
```
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- **IMPRESSIVE_INTEGRATION.md** - Detailed presentation system documentation
|
||||
- **src/DISPLAY_MANAGER.md** - Display Manager architecture
|
||||
- **src/IMPLEMENTATION_SUMMARY.md** - Implementation overview
|
||||
- **src/README.md** - MQTT client documentation
|
||||
|
||||
## 🔐 Security
|
||||
|
||||
- Hardware-based client identification (non-spoofable)
|
||||
- Configurable MQTT authentication
|
||||
- Local-only file storage
|
||||
- No sensitive data in logs
|
||||
|
||||
## 🚢 Production Deployment
|
||||
|
||||
### Systemd Service
|
||||
|
||||
Create `/etc/systemd/system/infoscreen-display.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Infoscreen Display Manager
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=olafn
|
||||
WorkingDirectory=/home/olafn/infoscreen-dev/src
|
||||
Environment="DISPLAY=:0"
|
||||
Environment="XAUTHORITY=/home/olafn/.Xauthority"
|
||||
ExecStart=/home/olafn/infoscreen-dev/venv/bin/python3 /home/olafn/infoscreen-dev/src/display_manager.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Enable and start:
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable infoscreen-display
|
||||
sudo systemctl start infoscreen-display
|
||||
sudo systemctl status infoscreen-display
|
||||
```
|
||||
|
||||
### Auto-start on Boot
|
||||
|
||||
Both services (simclient.py and display_manager.py) should start automatically:
|
||||
|
||||
1. **simclient.py** - MQTT communication, event management
|
||||
2. **display_manager.py** - Display application controller
|
||||
|
||||
Create similar systemd service for simclient.py.
|
||||
|
||||
### Docker Deployment (Alternative)
|
||||
|
||||
```bash
|
||||
docker-compose -f src/docker-compose.production.yml up -d
|
||||
```
|
||||
|
||||
See `src/CONTAINER_TRANSITION.md` for details.
|
||||
|
||||
## 📝 Development
|
||||
|
||||
### Development Mode
|
||||
|
||||
Set in `.env`:
|
||||
```bash
|
||||
ENV=development
|
||||
DEBUG_MODE=1
|
||||
LOG_LEVEL=DEBUG
|
||||
HEARTBEAT_INTERVAL=10
|
||||
```
|
||||
|
||||
### Start Development Client
|
||||
|
||||
```bash
|
||||
./scripts/start-dev.sh
|
||||
```
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
# Display Manager
|
||||
tail -f logs/display_manager.log
|
||||
|
||||
# MQTT Client
|
||||
tail -f logs/simclient.log
|
||||
|
||||
# Both
|
||||
tail -f logs/*.log
|
||||
```
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
1. Test changes with `./scripts/test-display-manager.sh`
|
||||
2. Verify MQTT communication with `./scripts/test-mqtt.sh`
|
||||
3. Update documentation
|
||||
4. Submit pull request
|
||||
|
||||
## 📄 License
|
||||
|
||||
[Add your license here]
|
||||
|
||||
## 🆘 Support
|
||||
|
||||
For issues or questions:
|
||||
1. Check logs in `logs/` directory
|
||||
2. Review troubleshooting section
|
||||
3. Test individual components with test scripts
|
||||
4. Check MQTT broker connectivity
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** October 2025
|
||||
**Status:** ✅ Production Ready
|
||||
**Tested On:** Raspberry Pi 5, Raspberry Pi OS (Bookworm)
|
||||
|
||||
## Recent changes (Oct 2025)
|
||||
|
||||
The following notable changes were added after the previous release and are included in this branch:
|
||||
|
||||
- Event handling: support for scheduler-provided `event_type` values (new types: `presentation`, `webuntis`, `webpage`, `website`). The display manager now prefers `event_type` when selecting which renderer to start.
|
||||
- Web display: Chromium is launched in kiosk mode for web events. `website` events (scheduler) and legacy `web` keys are both supported and normalized.
|
||||
- Auto-scroll feature: automatic scrolling for long websites implemented. Two mechanisms are available:
|
||||
- CDP injection: The display manager attempts to inject a small auto-scroll script via Chrome DevTools Protocol (DevTools websocket) when possible (uses `websocket-client` and `requests`). Default injection duration: 60s.
|
||||
- Extension fallback: When DevTools websocket handshakes are blocked (403), a tiny local Chrome extension (`src/chrome_autoscroll`) is loaded via `--load-extension` to run a content script that performs the auto-scroll reliably.
|
||||
- Autoscroll enabled only for scheduler events with `event_type: "website"` (not for general `web` or `webpage`). The extension and CDP injection are only used when autoscroll is requested for that event type.
|
||||
- New test utilities:
|
||||
- `scripts/test_cdp.py` — quick DevTools JSON listing + Runtime.evaluate tester
|
||||
- `scripts/test_cdp_origins.py` — tries several Origin headers to diagnose 403 handshakes
|
||||
- Dependencies: `src/requirements.txt` updated to include `websocket-client` (used by the CDP injector).
|
||||
- Small refactors and improved logging in `src/display_manager.py` to make event dispatch and browser injection more robust.
|
||||
|
||||
If you rely on autoscroll in production, review the security considerations around `--remote-debugging-port` (DevTools) and prefer the extension fallback if your Chromium build enforces strict websocket Origin policies.
|
||||
Reference in New Issue
Block a user