# Spectra Display random Unsplash photos on an Inky Impression e-paper display, with a web interface for uploading your own images. ## Features - Fetches random high-resolution photos from Unsplash (cached to gallery) - Upload your own images via the web interface (drag-and-drop, multi-file) - Centres and scales images to fit the display resolution - Colour saturation tuning for e-paper - Web dashboard with preview, gallery, rotation queue, and config editor - MQTT integration for remote commands and status reporting - Simulation mode for testing without hardware (configurable resolution) - systemd integration for automatic updates on a schedule - Randomised update intervals to avoid predictable refreshes - Config hot-reload — no service restart needed for setting changes ## Requirements - Raspberry Pi (any model with GPIO) - [Pimoroni Inky Impression](https://shop.pimoroni.com/products/inky-impression) (4.0", 7.3", or 13.3") - Python 3.9+ - [Unsplash API access key](https://unsplash.com/developers) ## Installation Run the installer on a Raspberry Pi: ```bash ./install.sh ``` The installer will: 1. Install the Pimoroni Inky library (skipped if not a Raspberry Pi) 2. Install Python dependencies (including web server and MQTT) 3. Install the `spectra` package 4. Copy the default config to `/etc/spectra/config.yaml` 5. Install and enable both the display and web interface systemd services ### Manual installation ```bash pip install -r requirements.txt pip install -e . ``` ## Configuration Edit `/etc/spectra/config.yaml` (or `~/.config/spectra/config.yaml` or `config.yaml` in the current directory): ```yaml unsplash: access_key: "your_access_key_here" query: "nature" orientation: "landscape" collections: "" display: saturation: 0.5 # resolution: # width: 800 # height: 480 schedule: interval_hours: 1 random_delay_seconds: 300 mqtt: enabled: false broker: localhost port: 1883 topic_prefix: spectra client_id: spectra-display username: "" password: "" paths: cache: /var/cache/spectra ``` ## Usage ### Display loop ```bash # Run once and exit spectra --once # Run once in simulation mode spectra --once --simulate # Simulate at a specific resolution spectra --once --simulate --width 800 --height 480 # Run with a custom config spectra -c /path/to/config.yaml # Run continuously spectra ``` ### Web interface ```bash # Start the web interface (default: http://0.0.0.0:5000) spectra web # With custom host/port spectra web --host 0.0.0.0 --port 5000 # Verbose logging spectra web -v ``` The web interface provides: - **Dashboard** — display status, schedule info, quick actions (refresh, clear) - **Gallery** — browse all uploaded and cached Unsplash images, trigger "show now" - **Upload** — drag-and-drop multiple image files with progress tracking - **Settings** — live-edit Unsplash, display, schedule, and MQTT configuration ### MQTT When MQTT is enabled in the config, the display loop subscribes to commands and publishes status. See [MQTT integration docs](docs/mqtt.md) for details. ## systemd services Two systemd services are installed: - `spectra.service` — the display loop (fetches Unsplash, processes triggers) - `spectra-web.service` — the web interface (Flask + htmx) ```bash sudo systemctl start spectra sudo systemctl stop spectra-web sudo systemctl status spectra-web # View logs journalctl -u spectra -f journalctl -u spectra-web -f ``` ## Project structure ``` spectra/ ├── config.yaml # Example configuration ├── install.sh # Installer script ├── pyproject.toml # Package metadata ├── requirements.txt # Python dependencies ├── spectra/ │ ├── __init__.py │ ├── __main__.py # python -m spectra entry point │ ├── cli.py # CLI argument parsing and main loop │ ├── config.py # Configuration loader │ ├── config_manager.py # Config read/write with YAML write-back │ ├── display.py # Inky display abstraction and image processing │ ├── fetcher.py # Unsplash API client │ ├── library.py # Unsplash image caching to SQLite library │ ├── mqtt.py # MQTT client (commands + status) │ ├── trigger.py # Shared trigger file (web server → display loop) │ └── web/ │ ├── server.py # Flask app factory and API routes │ ├── models.py # SQLAlchemy models │ ├── templates/ # Jinja2 templates (6 pages) │ ├── static/ # CSS and JS │ └── __init__.py ├── systemd/ │ ├── spectra.service # Display loop systemd unit │ └── spectra-web.service # Web interface systemd unit └── docs/ ├── web-interface.md # Web interface documentation └── mqtt.md # MQTT integration documentation ```