Skip to content

Repository files navigation

Statusberry

Statusberry banner

License: CC BY-ND 4.0 Raspberry Pi 4 Python 3.10+ ST7735 SPI 160x128 landscape systemd

Statusberry is a lightweight, always-on system status display application designed for Raspberry Pi-class devices equipped with small SPI-connected LCDs (e.g. 160x128 ST7735).

Overview

Statusberry displays critical system information at a glance with a boot-fast, resilient, and themeable interface. It supports headless operation and can be fully previewed on non-RPi systems like WSL/Linux laptops - and on Windows.

Who this is for

Statusberry was built for a specific situation: the Pi sits somewhere you can't access at will, and the people who can enter aren't technical. The box reaches the network on its own (via Tailscale in my case) and works as a remote USB host for attached equipment. The screen answers the only question that matters at a glance - is it up, is it on ethernet or Wi-Fi, and what's its IP - so anyone nearby can just look and tell you. No SSH session, no monitor, no dashboard to open.

Key Features

  • CPU utilization percent - total load, core-count independent, with core count shown and a fixed 3-minute scrolling graph (0-100 % scale)
  • Per-interface network cards - state-colored icon (connected / no link / down), interface name, and IP address; up to 3 interfaces, ethernet first
  • Memory meter - used/total, percent, and a full-width usage bar; turns orange above 85 %, red above 95 %
  • Hostname and uptime on the bottom line
  • Themeable interface - YAML theme sources compiled to runtime artifacts
  • Boot screen - splash with hostname and progress bar while the Pi boots, then automatic switch to the status screen (no restart)
  • Headless operation - no user interaction
  • Development friendly - pixel-exact window emulator on Linux, WSL, macOS and Windows
  • SPI LCD backend - ST7735-class panels via the Pimoroni st7735 driver (pip), running landscape (160x128)

Screenshots

Simulated frames rendered by scripts/dev_screenshots.py (no real host data): the boot splash, normal operation, and a high-load state showing the warning colors.

Boot screen  Normal status  High load

Target Platforms

Runtime

  • Raspberry Pi 4
  • Raspberry Pi OS (systemd-based)
  • SPI LCD (ST7735-compatible)
  • Python 3 (system-wide installation, no venv)

The display side targets the ubiquitous ST7735 / ST7735S controller family - the 1.77" and 1.8" 160x128 SPI boards sold under many names (Pimoroni, Waveshare, Adafruit, and generic boards all use the same chip and wiring). If your panel is a 160x128 SPI TFT, it is most likely one of these.

Development

  • Windows, Linux, WSL2, macOS (best-effort)
  • Python 3 + venv
  • Window-based display emulator

Installation

All three installers cover both setups: a local dev install (emulator) and a deployment to a Raspberry Pi over SSH. Deploying needs the OpenSSH client (built into Windows 10+ and every Linux), SSH access to the Pi, and sudo rights on it. The first connection asks to accept the Pi's host key; the remote run may ask for the Pi's sudo password.

Windows (PowerShell)

# Local dev install (emulator):
powershell -ExecutionPolicy Bypass -File scripts\install.ps1
.venv\Scripts\python statusberry.py --preview

# Deploy to a Raspberry Pi over SSH:
powershell -ExecutionPolicy Bypass -File scripts\install.ps1 -PiHost pi@192.168.1.50

Linux / WSL / macOS

./scripts/install.sh                  # local dev install (or: make install)
make preview

# Deploy to a Raspberry Pi over SSH:
./scripts/install.sh --pi pi@192.168.1.50

Raspberry Pi (in situ)

Copy the project to the Pi and run the installer as root:

sudo ./scripts/install-pi.sh

Both deploy modes and the in-situ installer do the same thing on the Pi: install the system packages, copy the project to /opt/statusberry, compile the themes, install the systemd unit (bound to the invoking user) and enable the service. Override the target directory with INSTALL_DIR=/path.

SPI display (Raspberry Pi + ST7735-class panel)

  1. Enable SPI: sudo raspi-config → Interfacing Options → SPI, reboot.

  2. Wire the panel (the usual 1.77" 8-pin board). Physical pin numbers per the official Pi pinout - config values (dc_pin, reset_pin) are BCM GPIO numbers:

    Board pin Signal Jumper Pi physical pin Pi GPIO
    1 GND black 6 Ground
    2 VCC red 1 3V3
    3 SCK white 23 GPIO11 (SCLK)
    4 SDA yellow 19 GPIO10 (MOSI)
    5 RES green 13 GPIO27
    6 RS purple 22 GPIO25
    7 CS brown 24 GPIO8 (CE0)
    8 LEDA orange 17 3V3 (backlight on)

    Touch pins (GT_*) and the second LED anode are unused.

  3. Set display.backend: spi in config.yaml. The app renders in landscape (160x128 logical); the spi backend maps the panel's native portrait memory automatically. The display.spi block holds the knobs: dc_pin/reset_pin as GPIO labels (GPIO25, GPIO27 - plain numbers also work), rotation (0/90/180/270 degrees; switch 90 to 270 if the image is upside down), offset_left/offset_top (keep 0 for this panel), bgr (flip if red and blue look swapped), invert (flip if colors look negative), and spi_speed_hz (lower to 16 MHz or 8 MHz if the panel glitches).

Raspberry Pi (manual)

  1. Install system packages (the file lists Debian package names, not pip packages):
    sudo apt install $(grep -v '^#' requirements-runtime.txt)
  2. Copy the project to /opt/statusberry and build the theme there:
    cd /opt/statusberry && python3 builder/theme_builder.py
  3. Install and start the service (edit User=/paths in the unit first):
    sudo cp systemd/statusberry.service /etc/systemd/system/
    sudo systemctl daemon-reload
    sudo systemctl enable --now statusberry

Command Reference

python statusberry.py                          # emulator preview (default)
python statusberry.py --preview                # same, explicit
python statusberry.py --build-theme            # compile all theme sources
python statusberry.py --build-theme default    # compile one theme
python statusberry.py --screenshot frame.png   # render one frame headlessly
python builder/theme_builder.py [THEME...]     # theme compiler directly

Or via make (Linux/WSL): make install, make dev, make build, make preview, make screenshot, make clean.

Themes

A theme lives in themes/<name>/:

  • theme.yaml - colors (hex), font sizes (small/medium/large), icon declarations
  • layout.yaml - screen geometry (see below)
  • assets/svg/ - icon sources on a 16x16 viewBox

builder/theme_builder.py validates everything (fail fast with clear errors), rasterizes the SVGs with a built-in Pillow-only renderer at 8x supersampling, recolors each icon per state, and writes compiled_themes/<name>/theme.json plus the PNG icons. The runtime reads only the compiled artifact - after editing any theme source, rebuild with make build.

Key layout parameters (themes/default/layout.yaml):

Parameter Meaning
width display width in pixels
columns.right x where the CPU column starts
network.max_rows interface cards shown (ethernet first, then wifi)
network.block_h, ip_dy card height and IP line offset
network.ip_medium_max IPs up to this length render in the bigger font
name_max, hostname_max truncation limits
cpu.graph_h CPU graph height (window is 3 minutes at 1 fps)
memory.bar_h RAM bar thickness (always full screen width)

Configuration

config.yaml:

app:
  fps: 1

display:
  width: 160
  height: 128
  scale: 3            # emulator only
  backend: emulator   # emulator | spi

theme:
  name: default

Project Structure

statusberry/
├── statusberry.py          # Application entry point (preview/build/screenshot)
├── config.yaml             # Global configuration
├── engine/                 # Runtime logic
│   ├── system/             # Data collection (psutil)
│   ├── screens/            # Screen composition -> semantic draw commands
│   ├── display/            # Theme loader, frame renderer, display backends
│   └── util/               # Shared helpers
├── themes/                 # Theme sources
│   └── default/
│       ├── theme.yaml      # Colors, fonts, icon declarations
│       ├── layout.yaml     # Semantic layout rules
│       └── assets/svg/     # Icon sources
├── compiled_themes/        # Compiled theme artifacts (build output)
├── builder/                # Theme compiler (SVG -> PNG, theme.json)
├── docs/                   # Banner and README screenshots
├── scripts/                # Installation automation (Windows/Linux/Pi), dev tools
└── systemd/                # Service files

License

Statusberry is licensed under a Creative Commons Attribution-NoDerivatives 4.0 International License.

About

Lightweight always-on system status display for Raspberry Pi SPI LCDs (ST7735, landscape 160x128) with boot screen, themes, and a pixel-exact emulator.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages