Powered by Pi, rendered in Pixels.
A modern, modular, and highly customizable dashboard for Waveshare E-Ink displays. Built with Python 3.14+ using async/await patterns and a clean, testable architecture.
The easiest way to run is using Docker - it handles all dependencies and driver setup automatically.
| Todo | HackerNews |
|---|---|
![]() |
![]() |
| Quote | Poetry | Wallpaper | Year-End Summary |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
| Happy Birthday | Anniversary | Valentine's Day |
|---|---|---|
![]() |
![]() |
![]() |
| Happy New Year | Spring Festival | Mid-Autumn Festival | Christmas |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
# Pull the latest image
docker pull palemoky/paper-pi:latest
# Or use GitHub Container Registry
docker pull ghcr.io/palemoky/paper-pi:latest
# Run with docker-compose (recommended)
git clone https://github.com/palemoky/paper-pi.git
cd paper-pi
cp .env.example .env
# Edit .env with your API keys
# For dashboard/quote/wallpaper modes (default)
docker-compose up -dlinux/arm64- Raspberry Pi 3/4/5 (64-bit)
- Custom To-Do Lists - Three customizable lists (Goals/Must/Optional) with strikethrough for completed items
- HackerNews - Auto-rotating top stories with pagination and configurable display time (Live Mirror)
- Real-time Weather - OpenWeatherMap integration with icon support
- GitHub Contributions - Daily/Weekly/Monthly/Yearly stats with grid layout
- Bitcoin Price - Live BTC price with 24h change percentage
- VPS Data Usage - Monitor your server's data consumption
- Weekly Progress - Visual progress ring for the current week
- Dashboard - Main information display with time-based TODO/HN switching
- Quote - Inspirational quotes
- Poetry - Classical Chinese poetry
- Holiday Greetings - Auto-triggered on special days
- Wallpaper - Custom images
- Year-End Summary - Automatic GitHub contribution summary on Dec 31st
- Holiday Detection - Auto-displays greetings for:
- Birthdays & Anniversaries (configurable)
- Lunar New Year (Spring Festival)
- Mid-Autumn Festival
- New Year's Day & Christmas
- Time-based Switching - Configurable time slots for TODO lists vs HackerNews
- Quiet Hours - Configurable sleep period (e.g., 1 AM - 6 AM)
- Grayscale Support - 4-level grayscale for enhanced visual quality (white/light gray/dark gray/black)
- Audio Notifications - Xiaomi speaker integration for alerts and announcements
- Async/Await - Built with
asyncioandhttpxfor concurrent operations - Modular Design - 23+ focused modules following Single Responsibility Principle
- Type Safety - Full type hints with mypy validation
- Plugin System - Extensible display mode system
- Event Bus - Decoupled component communication
- Smart Caching - TTL-based caching with LRU eviction
- Unified Retry - Automatic retry with exponential backoff using
tenacity - Task Management - Async task lifecycle management
- Config Hot Reload - Runtime configuration updates with
watchdog - Graceful Shutdown - Proper SIGTERM/SIGINT handling
- Unit Tests - 90+ tests with 66% overall coverage
- Core Modules - 77%+ coverage on critical components
- CI/CD - Automated testing, type checking, and Docker builds via GitHub Actions
- Type Checking - Full mypy validation with strict mode
- Code Quality - Ruff linting and formatting
- Pre-commit Hooks - Automated code quality checks before commits
- Mock System - CLI tool for generating test images without hardware
The E-Ink Dashboard follows a modular, event-driven architecture with clear separation of concerns:
flowchart LR
%% --- Style Definition ---
classDef control fill:#e1f5fe,stroke:#01579b,stroke-width:2px;
classDef data fill:#f3e5f5,stroke:#4a148c,stroke-width:2px;
classDef render fill:#fff3e0,stroke:#e65100,stroke-width:2px;
classDef hw fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px;
classDef subBox fill:#ffffff,stroke:#90a4ae,stroke-width:1px,stroke-dasharray: 5 5;
%% --- 1. Control Layer ---
subgraph ControlLayer ["๐ฎ Core & Control"]
direction TB
Main("Main Orchestrator")
Config("Config & Hot Reload")
DisplayCtrl{{"Display Controller"}}
TaskMgr("Task Manager")
end
%% --- 2. Data Layer ---
subgraph DataLayer ["๐ก Data Acquisition"]
direction TB
Fetcher("Data Fetcher")
subgraph Providers ["Providers"]
External["External APIs<br/>(Weather, GitHub, BTC, HN)"]
Local["Local Info<br/>(Quotes, Poetry, TODO)"]
end
subgraph Storage ["State Management"]
Cache[("Cache (TTL/LRU)")]
State[("Persistence DB")]
end
end
%% --- 3. Render Layer ---
subgraph RenderLayer ["๐จ Rendering Engine"]
direction TB
ImgBuilder("Image Builder")
subgraph Strategies ["Layout Strategies"]
DashLayout["Dashboard Layout"]
ContextLayouts["Context Layouts<br/>(Holiday, Quote, Poetry)"]
end
Renderer["Primitive Renderers<br/>(Text, Icons, Shapes)"]
end
%% --- 4. Hardware Layer ---
subgraph HWLayer ["๐ฅ๏ธ Hardware Output"]
direction TB
DriverFac("Driver Factory")
EPD["E-Paper Driver"]
Mock["Mock (PNG)"]
end
%% --- Connection Logic ---
%% Control Flow
Main --> Config & TaskMgr
Main --> DisplayCtrl
Config -.-> Main
%% Data Flow
Main --"Trigger"--> Fetcher
Fetcher --> External & Local
External & Local -.-> Storage
%% Render Flow
DisplayCtrl --"Select Mode"--> ImgBuilder
ImgBuilder --"Get Data"--> Storage
ImgBuilder --> DashLayout & ContextLayouts
DashLayout & ContextLayouts --> Renderer
%% Output Flow
Renderer --> DriverFac
DriverFac --> EPD & Mock
%% --- Application Style ---
class Main,Config,DisplayCtrl,TaskMgr control
class Fetcher,External,Local,Cache,State data
class ImgBuilder,DashLayout,ContextLayouts,Renderer render
class DriverFac,EPD,Mock hw
class Providers,Storage,Strategies subBox
- Primary: Waveshare 7.5inch E-Paper HAT (V2)
- Other Models: Configurable via
EPD_MODELenv var (supports most models in the official repo) - Platform: Raspberry Pi (Zero/3/4/5) or any Linux board with SPI/GPIO
-
Antigravity for the pair programming
-
Waveshare for E-Ink display drivers
-
Chinese Poetry, LxgwWenKai, Hanyi for poetry
-
Flaticon, Weather Icons for icons
-
CoinGecko for BTC price
-
OpenWeatherMap for weather
-
Figma for UI design
-
All the open-source libraries that make this project possible













