raspiLightGUI is a lightweight and adaptable Raspberry Pi 5 control panel for an embedded system or equipment rack. It combines:
- a 128x64 SSD1306 OLED display and three navigation buttons;
- an RGB status LED for Ethernet and one primary service;
- system health and configurable systemd-service monitoring;
- confirmed restart, stop, and shutdown actions;
- one continuously supervised systemd service.
The repository also contains DisplayCTL, a minimal native helper intended to
show full-screen status icons on the same OLED during very early boot and during
shutdown or reboot, when the Python control panel is not running. Technical
implementation, compilation, initramfs integration, and validation details are
kept in AGENT.md.
The application is supplied preconfigured for a live-production rack running:
- QLC+ for lighting control;
- Oculizer as a mixing agent;
- Live Stage Assistant as an assistant service.
Services and their display order are configured in managed_services.py:
MANAGED_SERVICES = (
ServiceDefinition(
"QLC+", "QLC+", "qlcplus.service", "/usr/local/bin/qlcplus-service"
),
ServiceDefinition(
"OCULIZER", "Oculizer", "oculizer.service",
"/usr/local/bin/oculizer-service",
("QLC+",),
),
ServiceDefinition(
"ASSISTANT", "Assistant", "livestageassistant.service",
"/usr/local/bin/livestageassistant",
),
)
PRIMARY_SERVICE_KEY = "QLC+"The optional final tuple declares service dependencies. In this profile,
Oculizer requires QLC+. Trying to start or restart Oculizer while QLC+ is not
running displays Start QLC+ first and does not issue the command.
The page shows CPU temperature, input voltage, uptime, CPU/RAM/disk usage, and the active wired IPv4 address. It updates when opened and every 10 seconds while visible.
Temperature states:
| State | Temperature |
|---|---|
OK |
Below 70 C |
HIGH |
70 C to below 80 C |
CRIT |
80 C or above |
Power states:
| State | Condition |
|---|---|
OK |
4.80 V or above, without undervoltage |
LOW |
Above 4.65 V and below 4.80 V |
CRIT |
4.65 V or below, or undervoltage detected |
N/A |
Voltage information unavailable |
When inactive, the page shows the configured services. With the included rack profile, it refreshes when opened and every 10 seconds as follows:
SYSTEM
QLC+: AUTO
OCULIZER: DOWN
ASSISTANT: FAILED
...
OK = enter menu
| State | Meaning |
|---|---|
AUTO |
Running and enabled at boot |
MANUAL |
Running but not enabled at boot |
STARTING |
Starting or reloading |
STOPPING |
Stopping |
DOWN |
Stopped normally |
FAILED |
Service failure |
UNKNOWN |
State unavailable |
An automatic service that is not currently running adds AUTO to its runtime
state, for example DOWN AUTO or FAILED AUTO.
R:n appears after more than one service restart. /!\ in the title indicates
a failed service, repeated restarts, critical temperature, or critical power.
Pressing OK activates the menu. It contains one selectable entry per configured
service, followed by Reboot, Shutdown, and Back. Selecting a service opens
a contextual submenu that can:
- stop or restart the service when it is running or starting;
- start it when it is stopped, failed, or stopping;
- select
Autoto enable startup at boot, orManualto disable it.
Reboot and Shutdown remain in the main SYSTEM menu and require
confirmation. After confirmation, both hardware and simulated console interfaces
show the same wait screen: title SYSTEM, the selected action (Reboot or
Shutdown), then Please wait.... Back returns from a service submenu to
SYSTEM, then from SYSTEM to screen navigation.
Stopping a service, switching it to Manual, rebooting, and shutting down
require confirmation. Starting, restarting, and switching a service to Auto
run immediately. Every action displays a short success or failure message. The
first menu item is selected when a menu opens, while confirmation cancellation
remains selected by default.
If a service state or startup mode is unavailable, potentially unsafe actions
are omitted. Statuses stop refreshing while a menu is active, so an item cannot
move while you are selecting it. After an action, the control panel briefly
waits for the service to finish starting or stopping before updating its status
and available actions.
Red indicates board power. Blue and green alternate to provide a visible heartbeat:
| Check | Result | LED behaviour |
|---|---|---|
| Ethernet | Internet reachable | Solid blue, appearing magenta with red |
| Ethernet | IPv4 but Internet unreachable | Two short blue/magenta pulses |
| Ethernet | Link without IPv4 | Blinking blue/magenta |
| Ethernet | No link | Blue off; red only |
| Primary service | Running | Solid green, appearing yellow with red |
| Primary service | Not running | Blinking green/yellow |
Each Ethernet and primary-service phase lasts about 1.5 seconds. Internet
availability is checked immediately once an IPv4 address exists, then
approximately once per minute against Google Public DNS at 8.8.8.8. A failed
check is retried after about 10 seconds so temporary startup conditions clear
quickly. This does not verify that every Internet service is reachable. Blink
states alternate every 250 ms. In the included rack profile, the primary service
is QLC+. The LED continues working when the OLED is disconnected or asleep.
| Function | BCM GPIO | Physical pin | Connection |
|---|---|---|---|
| OLED power | 3.3 V | 1 | OLED VCC |
| RGB red anode | 3.3 V | 17 | Through 470 ohm resistor |
| OLED and button grounds | GND | 30 or 34 | OLED GND and common side of all buttons |
| RGB common cathode | GND | 14 | LED common cathode |
| OLED SDA | GPIO2 | 3 | SDA |
| OLED SCL | GPIO3 | 5 | SCL |
| Button Down / Back | GPIO13 | 33 | Other terminal to common button GND |
| Button Select / OK | GPIO6 | 31 | Other terminal to common button GND |
| Button Up / Next | GPIO5 | 29 | Other terminal to common button GND |
| RGB blue anode | GPIO27 | 13 | Through 330 ohm resistor |
| RGB green anode | GPIO22 | 15 | Through 330 ohm resistor |
Buttons use internal pull-up resistors. Never connect an LED channel without its series resistor.
There are two interactive interfaces:
- hardware mode uses the OLED and the three physical buttons;
- simulated mode displays the same interface in a terminal and uses the keyboard. It is intended for diagnosis when no OLED is connected.
Navigation is identical in both modes:
| Action | Hardware | Simulated terminal |
|---|---|---|
| Previous page or item | Up / Next | Left or Up |
| Next page or item | Down / Back | Right or Down |
| Select / confirm | OK | Enter |
| Rotate OLED 180 degrees | Hold OK for 1.5 seconds | — |
| Quit local simulation | — | q |
On information pages:
- Down / Back: next page;
- Up / Next: previous page;
The inactive SYSTEM page behaves like MONITOR: Up and Down continue
scrolling through the two screens. It shows service statuses without a selection
cursor; press OK only when you want to activate its selectable action list.
In the action list:
- Down or Up: change selection;
- OK on a service: open its contextual submenu;
- OK on an action: open its confirmation;
Backinside a service submenu: return to the mainSYSTEMmenu;- select
Backand press OK to leave the menu and return to screen navigation.
The action list remains active until Back is confirmed. The first item is
selected whenever a menu is entered.
Holding the physical OK button for 1.5 seconds rotates the OLED by 180 degrees from any screen, without activating the selected item. The selected orientation lasts until the application restarts. The first press while the OLED is asleep only wakes it, even when held.
The OLED sleeps after five minutes without input. The first button press wakes it without navigating or executing an action.
DisplayCTL is a short-lived native command that writes one full-screen icon to
the SSD1306 and exits. It is intended for boot, shutdown, reboot, panic, and
update status indications outside the normal raspiLightGUI session.
The currently available commands are:
displayctl boot
displayctl shutdown
displayctl reboot
displayctl panic
displayctl updatingThe five embedded icons have been validated on the Raspberry Pi OLED. Their artwork and exact positioning may still be refined without changing the command interface or DisplayCTL behaviour.
For compilation, static-build requirements, initramfs integration, bitmap format, and systemd hand-off details, see AGENT.md.
Install and configure the services for your chosen profile before raspiLightGUI.
For the included rack profile, QLC+ must be provided as qlcplus.service with
the qlcplus-service command from
raspi5rackSetup; Oculizer and
Live Stage Assistant must also have their service wrappers installed.
From the repository directory, run the read-only check without sudo:
./raspi_service_pack/install.sh --check --service-user piMissing software or an unavailable OLED may be reported here. The permanent installer installs supported dependencies and attempts to enable I2C.
sudo ./raspi_service_pack/install.sh --service-user piThe installer prepares Python and the required libraries, installs the service and administration command, and leaves the service disabled until you choose to start it.
Enable automatic startup and start now:
raspilightgui-service autoAvailable administration commands:
raspilightgui-service start
raspilightgui-service stop
raspilightgui-service restart
raspilightgui-service status
raspilightgui-service logs
raspilightgui-service last-state
raspilightgui-service health
raspilightgui-service noautonoauto disables startup at boot without stopping the currently running
service.
Install the project first, then stop the service before using the same GPIO from a terminal:
raspilightgui-service stop
source .venv/bin/activateAvailable modes:
python lightGUI.py
python lightGUI.py --backend hardware
python lightGUI.py --backend consoleThe first command uses automatic mode: it selects the OLED when available, the terminal interface during an interactive local run without an OLED, or the LED- only headless mode without an interactive terminal. Use the other commands only to force hardware or console mode for diagnosis.
The physical RGB LED remains active in every mode. See Navigation for the terminal controls.
If no OLED is detected, the installed service continues running the RGB LED. Check the I2C bus with:
raspilightgui-service stop
i2cdetect -y 1An SSD1306 normally appears at address 3c or 3d. If neither appears, check
3.3 V, ground, SDA on physical pin 3, and SCL on physical pin 5.
The LED behaviour was integrated from the companion raspiLed project.