Initial scaffold: README, project layout, and headless-chromium render loop sketch

This commit is contained in:
Padreug 2026-05-16 12:17:27 +02:00
commit 51f5ffcd66
8 changed files with 243 additions and 0 deletions

107
README.md Normal file
View file

@ -0,0 +1,107 @@
# InkyImpression
Display server for a 13.3" Pimoroni Inky Impression on a Raspberry Pi Zero 2 W.
## Hardware
- **Display**: [Inky Impression 13.3"](https://shop.pimoroni.com/products/inky-impression) — 1600×1200, 6 colors (Spectra 6: red/green/blue/yellow/black/white), ~12s refresh (real-world 2035s).
- **Host**: Raspberry Pi Zero 2 W (quad-core ARMv7, 512 MB RAM — enough for headless Chromium on a single page).
- **Buttons**: 4 tactile buttons on the back. For the 13.3" variant they map to BCM GPIO **5, 6, 25, 24** (note: 25, not 16 — see `reference/inky/examples/spectra6/buttons.py`).
- **Mounting**: Pi Zero plugs straight into the socket header on the back. USB ports face down; text on Pi and Inky reads the same way up. **Power off before attaching/removing.**
## What this project does
Drives the Inky Impression to cycle through display "scenes":
1. **Tasks** — pulled from the webapp tasks module (`~/dev/webapp/src/modules/tasks`).
2. **Restaurant menu** — shown during the lunch window (12:0013:00).
3. **Announcements / events** — cycled via the 4 hardware buttons.
## Architecture
**Current strategy (this branch): headless Chromium on the Pi.**
The webapp already renders the scenes we want (`tasks.ariege.io`, etc.), so the Pi runs `chromium --headless --screenshot` against the live URL, then pushes the PNG through PIL into the `inky` library. E-ink refresh is 2035 s anyway, so a 515 s screenshot is comfortably within budget. Inky's `set_image()` handles dithering to the 6-color Spectra 6 palette.
Other strategies we may try on branches later:
- **Webapp JSON → PIL**: lighter, no browser, but layouts have to be redrawn by hand.
- **External render service**: only worth it if multiple Pis share renders, or if Chromium-on-Pi proves too slow/flaky.
## Initial Pi setup
Flash **Raspberry Pi OS Bookworm or later** (the "with desktop" image is recommended by Pimoroni — pulls in the dependencies, but Lite works if you install them manually).
On first boot:
```bash
sudo raspi-config
# Interfacing Options → enable SPI and I2C
sudo apt update && sudo apt upgrade -y
sudo apt install -y git python3-venv python3-pip chromium-browser
```
Install the Inky library via Pimoroni's installer (creates `~/.virtualenvs/pimoroni`):
```bash
git clone https://github.com/pimoroni/inky
cd inky
./install.sh
source ~/.virtualenvs/pimoroni/bin/activate
```
Verify the display is detected:
```bash
python3 -c "from inky.auto import auto; i = auto(verbose=True); print(i.resolution, i.colour)"
```
Quick smoke test using the bundled example:
```bash
cd ~/inky/examples/spectra6
python3 image.py --file images/spectra6-1600x1200.png
```
Then clone this repo on the Pi and install into the same venv:
```bash
git clone <this-repo-url> ~/InkyImpression
cd ~/InkyImpression
pip install -e .
inky-impression # runs the main loop
```
## Project layout
```
.
├── README.md
├── pyproject.toml
├── src/inky_impression/
│ ├── __init__.py
│ ├── __main__.py # `python -m inky_impression`
│ ├── main.py # scheduler loop
│ ├── render.py # chromium screenshot → PIL → Inky
│ └── scenes.py # which URL to show at what time
└── reference/inky/ # cloned Pimoroni library (gitignored)
```
## Reference
- Pimoroni library (cloned for reference): `reference/inky/`
- `inky/inky_el133uf1.py` — driver for the 13.3" Spectra 6 panel
- `examples/spectra6/image.py` — minimal "draw an image" example
- `examples/spectra6/buttons.py` — button GPIO setup (remember: SW_C = 25 for 13.3")
- [Pimoroni getting-started article](https://learn.pimoroni.com/article/getting-started-with-inky-impression)
- Webapp tasks module: `~/dev/webapp/src/modules/tasks`
## Version control
This repo uses [jj](https://github.com/martinvonz/jj) (colocated with git):
```bash
jj st # status
jj describe # set commit message for working copy
jj new # start a new change
```