# Raspberry Pi Kiosk Setup Guide for Liveposter

Complete guide for setting up a Raspberry Pi as a fullscreen kiosk display for Liveposter animations.

## Table of Contents

- [Hardware Requirements](#hardware-requirements)
- [Quick Start (Automated)](#quick-start-automated)
- [Manual Setup](#manual-setup)
- [Troubleshooting](#troubleshooting)
- [Advanced Configuration](#advanced-configuration)

## Hardware Requirements

### Recommended Setup (Optimal Performance)

- **Raspberry Pi 5 (4GB)** - ~$60
  - Best performance for 4K@60Hz
  - Hardware video decode acceleration
  - PCIe Gen 2 for faster storage

- **Power Supply (27W USB-C)** - ~$12
  - Official Raspberry Pi power supply recommended
  - 5.1V 5A for stable operation

- **microSD Card (32GB+ UHS-I)** - ~$15
  - SanDisk Extreme or Samsung EVO Plus recommended
  - Faster cards improve loading times

- **HDMI Cable (Micro HDMI to HDMI)** - ~$8
  - 4K@60Hz capable
  - Raspberry Pi 5 uses micro HDMI ports

**Total Cost: ~$95**

### Minimum Setup (Budget Option)

- **Raspberry Pi 4 (2GB)** - ~$35
  - Can handle 4K@30Hz or 1080p@60Hz
  - May struggle with complex animations

- All other components same as recommended

**Total Cost: ~$70**

### Optional Accessories

- **Active Cooling Fan** - ~$5 (recommended for 24/7 operation)
- **Case with ventilation** - ~$10
- **Real-time clock (RTC) module** - ~$5 (for accurate timekeeping without internet)

## Quick Start (Automated)

The easiest way to set up kiosk mode is using the automated setup script.

### Step 1: Install Raspberry Pi OS

1. Download [Raspberry Pi Imager](https://www.raspberrypi.com/software/)
2. Insert microSD card into your computer
3. Open Raspberry Pi Imager
4. Choose OS: **Raspberry Pi OS (64-bit)** (recommended) or Lite version
5. Choose Storage: Your microSD card
6. Click settings gear icon (⚙️):
   - Set hostname: `liveposter-kiosk`
   - Enable SSH (optional, for remote access)
   - Set username/password
   - Configure WiFi (if not using ethernet)
7. Click **Write** and wait for completion

### Step 2: Initial Boot

1. Insert microSD card into Raspberry Pi
2. Connect HDMI cable to display
3. Connect keyboard and mouse (for initial setup)
4. Connect power supply
5. Wait for first boot (1-2 minutes)
6. Complete initial setup wizard if prompted

### Step 3: Run Automated Setup

Transfer the `kiosk-setup.sh` file to your Raspberry Pi, then:

```bash
chmod +x kiosk-setup.sh
./kiosk-setup.sh
```

The script will:
- Install Chromium browser with GPU acceleration
- Configure 4K@60Hz HDMI output
- Setup auto-boot to fullscreen kiosk mode
- Hide cursor and UI elements
- Disable screen blanking
- Create default test page

### Step 4: Add Your Content

```bash
# For custom HTML/CSS/JS
cp your-content.html /home/pi/kiosk/index.html
cp -r assets /home/pi/kiosk/

# For Liveposter animations (from your development machine)
npx liveposter build poster-list.json --output ./pi-output
# Then copy pi-output/* to /home/pi/kiosk/
```

### Step 5: Reboot

```bash
sudo reboot
```

Your Pi will now boot directly into fullscreen kiosk mode!

## Manual Setup

If you prefer to understand each step or need to customize the setup, follow this manual guide.

### 1. Update System

```bash
sudo apt-get update
sudo apt-get upgrade -y
```

### 2. Install Required Packages

```bash
sudo apt-get install -y \
    chromium-browser \
    xdotool \
    unclutter \
    sed \
    x11-xserver-utils
```

**Package Purposes:**
- `chromium-browser` - Web browser for displaying content
- `xdotool` - Simulate keyboard/mouse input (useful for automation)
- `unclutter` - Hides mouse cursor when idle
- `x11-xserver-utils` - X11 utilities (includes `xset` for screen blanking)

### 3. Configure HDMI Output

Edit `/boot/firmware/config.txt`:

```bash
sudo nano /boot/firmware/config.txt
```

Add these lines at the end:

```ini
# Liveposter Kiosk - 4K@60Hz Configuration
hdmi_group=2
hdmi_mode=87
hdmi_cvt=3840 2160 60 3 0 0 0
hdmi_drive=2
max_framebuffer_width=3840
max_framebuffer_height=2160

# GPU Memory (critical for smooth rendering)
gpu_mem=256

# Disable screen blanking
hdmi_blanking=1
```

**Configuration Explained:**
- `hdmi_group=2` - DMT (computer monitor) mode
- `hdmi_mode=87` - Custom CVT mode
- `hdmi_cvt=3840 2160 60 3 0 0 0` - 4K@60Hz timings
- `gpu_mem=256` - Allocate 256MB to GPU (minimum for 4K)
- `hdmi_blanking=1` - Prevent HDMI power saving

**For 1080p displays**, use instead:
```ini
hdmi_group=2
hdmi_mode=82  # 1080p@60Hz
gpu_mem=128   # Less memory needed
```

Save and exit (Ctrl+X, Y, Enter)

### 4. Create Kiosk Directory

```bash
mkdir -p /home/pi/kiosk
```

This is where your HTML/CSS/JS files will live.

### 5. Configure Auto-Login

```bash
sudo raspi-config
```

Navigate: **System Options → Boot / Auto Login → Desktop Autologin**

Or manually edit `/etc/lightdm/lightdm.conf`:

```bash
sudo nano /etc/lightdm/lightdm.conf
```

Add/modify under `[Seat:*]`:

```ini
[Seat:*]
autologin-user=pi
autologin-user-timeout=0
user-session=LXDE-pi
```

### 6. Configure Autostart

Create/edit autostart file:

```bash
mkdir -p /home/pi/.config/lxsession/LXDE-pi
nano /home/pi/.config/lxsession/LXDE-pi/autostart
```

Add this content:

```bash
# Disable screen blanking and power management
@xset s off
@xset s noblank
@xset -dpms

# Hide mouse cursor after 0.1 seconds of inactivity
@unclutter -idle 0.1 -root

# Launch Chromium in kiosk mode
@chromium-browser \
    --kiosk \
    --noerrdialogs \
    --disable-infobars \
    --disable-session-crashed-bubble \
    --disable-translate \
    --disable-save-password-bubble \
    --disable-features=TranslateUI \
    --disable-component-update \
    --no-first-run \
    --fast \
    --fast-start \
    --disable-features=TouchpadOverscrollHistoryNavigation \
    --overscroll-history-navigation=0 \
    --enable-features=VaapiVideoDecoder \
    --use-gl=egl \
    --enable-accelerated-video-decode \
    --enable-gpu-rasterization \
    --enable-zero-copy \
    --ignore-gpu-blocklist \
    --disk-cache-size=104857600 \
    file:///home/pi/kiosk/index.html
```

**Key Chromium Flags Explained:**
- `--kiosk` - Fullscreen mode, no browser UI
- `--noerrdialogs` - Suppress error dialogs
- `--disable-infobars` - No "Chrome is being controlled" banner
- `--enable-features=VaapiVideoDecoder` - Hardware video decode
- `--use-gl=egl` - Use EGL for better GPU performance
- `--enable-gpu-rasterization` - GPU-accelerated rendering
- `--disk-cache-size=104857600` - 100MB cache (adjust as needed)

### 7. Reboot

```bash
sudo reboot
```

## Liveposter Integration

### Option 1: Build Static Site

On your development machine:

```bash
# Create poster list JSON
cat > poster-list.json <<EOF
{
  "buildConfig": {
    "template": "sequential",
    "title": "My Kiosk Display",
    "displayMode": "contain",
    "aspectRatio": "16/9"
  },
  "posters": [
    { "configPath": "specs/poster1.json", "name": "First Poster" },
    { "configPath": "specs/poster2.json", "name": "Second Poster" }
  ]
}
EOF

# Build static site
npx liveposter build poster-list.json --output ./kiosk-output

# Transfer to Raspberry Pi
scp -r kiosk-output/* pi@liveposter-kiosk.local:/home/pi/kiosk/
```

### Option 2: Run Liveposter Server on Pi

Install Node.js on Raspberry Pi:

```bash
# Install Node.js 20 (LTS)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

# Install Liveposter
npm install -g @liveposter/demo-server
```

Modify autostart to run server instead:

```bash
@chromium-browser \
    --kiosk \
    [... other flags ...] \
    http://localhost:3000
```

Add server startup before Chromium:

```bash
@bash -c "cd /home/pi/liveposter && liveposter poster-list.json &"
```

**Note:** Static site (Option 1) is recommended for better performance and reliability.

## Troubleshooting

### Display Issues

**Black screen on boot:**
```bash
# Check HDMI config
sudo cat /boot/firmware/config.txt | grep hdmi

# Try safe HDMI mode
hdmi_safe=1  # Add to config.txt

# Force HDMI output
hdmi_force_hotplug=1
```

**Wrong resolution:**
```bash
# Check current resolution
xrandr

# List supported modes
tvservice -m CEA
tvservice -m DMT

# For 1080p instead of 4K
hdmi_mode=82  # In config.txt
```

**Screen tearing:**
```bash
# Enable V-Sync (add to /boot/firmware/config.txt)
disable_overscan=1

# In Chromium flags, ensure:
--disable-gpu-vsync=0
```

### Performance Issues

**Slow animations:**
```bash
# Increase GPU memory (in /boot/firmware/config.txt)
gpu_mem=512  # Maximum for 4GB model

# Check CPU throttling
vcgencmd measure_temp
vcgencmd get_throttled

# If throttled (0x50000 or higher), improve cooling
```

**High CPU usage:**
```bash
# Check processes
htop

# Reduce Chromium cache
--disk-cache-size=52428800  # 50MB

# Use lighter animations (fewer overlays, simpler effects)
```

**Memory issues:**
```bash
# Check memory usage
free -h

# Reduce resolution or use sequential template
# Sequential loads one poster at a time
```

### Kiosk Mode Issues

**Browser UI showing:**
```bash
# Verify autostart file
cat /home/pi/.config/lxsession/LXDE-pi/autostart

# Check for typos in --kiosk flag
# Ensure no spaces in file:/// path
```

**Cursor visible:**
```bash
# Check unclutter is installed
which unclutter

# Reinstall if needed
sudo apt-get install --reinstall unclutter

# Or use alternate method in autostart:
@xdotool mousemove 5000 5000
```

**Screen blanking:**
```bash
# Verify xset commands in autostart
@xset s off
@xset s noblank
@xset -dpms

# Also check /boot/firmware/config.txt
hdmi_blanking=1
```

### Network Issues

**Can't reach Pi via SSH:**
```bash
# Find Pi's IP address (on Pi with keyboard/monitor)
hostname -I

# Enable SSH if not enabled
sudo raspi-config
# Interface Options → SSH → Enable

# Check SSH service
sudo systemctl status ssh
```

**No internet connection:**
```bash
# Check WiFi config
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

# Or use raspi-config
sudo raspi-config
# System Options → Wireless LAN
```

## Advanced Configuration

### Remote Management

**Enable SSH:**
```bash
sudo systemctl enable ssh
sudo systemctl start ssh
```

**Install VNC for remote desktop:**
```bash
sudo apt-get install -y realvnc-vnc-server
sudo systemctl enable vncserver-x11-serviced
sudo systemctl start vncserver-x11-serviced
```

### Automatic Content Updates

Create update script `/home/pi/update-kiosk.sh`:

```bash
#!/bin/bash
cd /home/pi/kiosk
git pull origin main  # If using git
# Or use rsync, scp, etc.
```

Add to crontab:
```bash
crontab -e
# Add line:
0 */4 * * * /home/pi/update-kiosk.sh  # Update every 4 hours
```

### Watchdog for Auto-Restart

Install watchdog to auto-restart if Pi freezes:

```bash
sudo apt-get install -y watchdog
sudo nano /etc/watchdog.conf
```

Uncomment:
```ini
watchdog-device = /dev/watchdog
max-load-1 = 24
```

Enable:
```bash
sudo systemctl enable watchdog
sudo systemctl start watchdog
```

### Hardware RTC for Offline Operation

If kiosk runs without internet (can't sync time):

```bash
# Install RTC module (DS3231 recommended)
# Connect via I2C pins

# Enable I2C
sudo raspi-config
# Interface Options → I2C → Enable

# Detect RTC
sudo i2cdetect -y 1

# Configure RTC
sudo nano /boot/firmware/config.txt
# Add: dtoverlay=i2c-rtc,ds3231

sudo reboot

# Disable fake-hwclock, enable RTC
sudo apt-get remove -y fake-hwclock
sudo update-rc.d -f fake-hwclock remove
sudo systemctl disable fake-hwclock

# Set time and save to RTC
sudo date -s "2025-01-15 10:30:00"
sudo hwclock -w

# Time will persist across reboots
```

### Temperature Monitoring

```bash
# Check temperature
vcgencmd measure_temp

# Create monitoring script
cat > /home/pi/temp-monitor.sh <<'EOF'
#!/bin/bash
TEMP=$(vcgencmd measure_temp | cut -d= -f2 | cut -d\' -f1)
if (( $(echo "$TEMP > 70" | bc -l) )); then
    echo "WARNING: Temperature high: $TEMP°C" | logger
fi
EOF

chmod +x /home/pi/temp-monitor.sh

# Run every 5 minutes
crontab -e
# Add: */5 * * * * /home/pi/temp-monitor.sh
```

### Read-Only Filesystem (for SD card longevity)

For 24/7 kiosks, make filesystem read-only to prevent SD card wear:

```bash
# Use overlay filesystem
sudo raspi-config
# Performance Options → Overlay File System → Enable

# Or manually:
sudo apt-get install -y overlayroot
sudo nano /etc/overlayroot.conf
# Set: overlayroot="tmpfs"
```

**Note:** Changes won't persist across reboots. Use `sudo overlayroot-chroot` to make permanent changes.

## Best Practices

### For 24/7 Operation

1. **Use active cooling** - Fan or heatsink case
2. **Enable watchdog** - Auto-restart on freeze
3. **Monitor temperature** - Alert if >70°C
4. **Use quality power supply** - Official PSI recommended
5. **Consider read-only filesystem** - Extends SD card life
6. **Regular updates** - Security patches via `apt-get update`

### For Power Outages

1. **UPS (Uninterruptible Power Supply)** - ~$50, provides graceful shutdown
2. **Automatic restart** - Already configured via autostart
3. **No need for RTC** - If internet available, time syncs automatically

### For Multiple Displays

1. **Clone SD card** - Use same setup for all kiosks
2. **Central content server** - All kiosks pull from same source
3. **Use static IPs** - Easier management
4. **Ansible/SSH scripts** - Update all kiosks simultaneously

## Support

For Liveposter-specific issues:
- Documentation: https://github.com/iplanwebsites/liveposter
- Issues: https://github.com/iplanwebsites/liveposter/issues

For Raspberry Pi issues:
- Official docs: https://www.raspberrypi.com/documentation/
- Forums: https://forums.raspberrypi.com/

## License

This guide is part of the Liveposter project and is licensed under MIT.
