This repository contains the Raspberry Pi client component of the PiSignage project, a digital signage system consisting of a desktop application and a Raspberry Pi display client.
Main project repository:
https://github.com/mischlox/pisignage
Related repositories:
- Host / Desktop App: https://github.com/mischlox/pisignage-host
- Raspberry Pi Client: https://github.com/mischlox/pisignage-raspberry
A lightweight Raspberry Pi digital signage client that synchronizes images from a remote server and displays them as a fullscreen slideshow. The system automatically downloads new content, removes outdated files, and updates the display configuration remotely.
The client is designed to run reliably on low-power devices such as the Raspberry Pi Zero 2 W and operate unattended with minimal maintenance.
It supports:
- Automatic content synchronization
- Remote configuration updates
- Scheduled display operation
- Offline resilience on unstable networks
- Headless deployment via cloud-init
- Secure connectivity using Tailscale + Funnel
This repository contains the device-side client responsible for:
- Connecting to a remote server
- Fetching a content manifest
- Downloading missing images
- Removing outdated files
- Applying remote display configuration
- Running a fullscreen slideshow on the Pi display
The client periodically polls the server and ensures the device stays synchronized.
Tested OS: Raspberry Pi OS Lite (64-bit)
Required system packages:
xserver-xorg
xinit
x11-xserver-utils
feh
unclutter
network-manager
avahi-daemon
watchdog
python3-venv
python3-pip
These are automatically installed during the cloud-init setup.
.
├── app
│ ├── controller.py
│ ├── config.py
│ ├── sync_service.py
│ ├── display_manager.py
│
├── configs/
│ └── system configuration snippets
│
├── main.py
├── requirements.txt
├── .env
│
├── user-data # cloud-init configuration
├── deploy_to_sd.sh # SD card deployment script
The client uses a .env file.
Example:
HOST_URL=https://your-server.ts.net
PI_NAME=StoreDisplay01
LOCAL_STORAGE=/home/pi/pisignage/display
API_KEY=your_api_key_here (enter same one in host application)
POLL_INTERVAL_SECONDS=60
TIMEOUT_CONNECT_SEC=15
TIMEOUT_READ_SEC=60
MAX_RETRIES=10
BACKOFF_FACTOR=2.0Download:
https://www.raspberrypi.com/software/
Flash using:
Raspberry Pi Imager
Recommended settings:
- hostname:
pi - enable SSH
- configure WiFi
- set username/password
This repository includes a deployment script that prepares the SD card.
Edit the SD path in deploy_to_sd.sh:
SD_PATH="D:/"
Run:
bash deploy_to_sd.shThe script will:
- copy the repository
- copy cloud-init configuration
- append system configs
- enable watchdog
- configure HDMI behavior
Once complete:
- Safely eject SD card
- Insert into Raspberry Pi
- Boot device
On first boot the Pi will:
- install packages
- create a Python virtual environment
- install dependencies
- enable system services
- reboot automatically
The system runs automatically via a systemd service.
Manual run:
cd /home/pi/pisignage
source venv/bin/activate
python main.py
The slideshow uses:
feh
Example command used internally:
feh --fullscreen --auto-zoom --hide-pointer --slideshow-delay 5 ./display