| File | Size | Format |
|---|---|---|
Wall_Display_RC2.1_PUBLIC.img.xz |
~1 GB | xz compressed raw image |
Compatible with Raspberry Pi Imager, balenaEtcher, Win32DiskImager
A ready-to-flash Armbian-based image that turns your OrangePi into a beautiful, always-on Home Assistant kiosk display — lightweight, customizable, and built as a free alternative to expensive commercial tablets.
This project was born from a simple idea: why spend hundreds of euros on a tablet just to display a Home Assistant dashboard on the wall?
The goal is to provide an optimized, ultra-lightweight and highly customizable system that anyone can flash, configure, and use as a wall-mounted smart home display — powered by open-source software and affordable ARM hardware.
⚠️ Tested hardware: OrangePi Zero 2W with a 14" HDMI display. The image should also work on OrangePi Zero 3 and similar Allwinner H618-based boards, but has not been extensively tested on other hardware.
⚠️ Known limitation: Hardware video acceleration (VAAPI/Cedrus VPU) could not be enabled due to a driver/compatibility issue. Camera streams and video are decoded in software. CPU load remains low for typical use cases.🤝 This project is open to collaboration! If you are more experienced with Armbian, Panfrost, Cedrus VPU, or Wayland and want to contribute, your help is very welcome. Feel free to open issues, pull requests, or start a discussion.
- 🚀 Auto-boot kiosk — boots directly into Home Assistant fullscreen (no desktop, no login prompt)
- 🌑 Dark mode — forced dark theme for Chromium
- 🎮 GPU accelerated UI — Panfrost OpenGL ES rendering (Mali G31)
- 🖱️ Cursor hidden — invisible cursor for a clean touch experience
- 💡 Auto screen-off — display turns off after 60s of inactivity (
swayidle) - 📲 Browser Mod integration:
- Screen state synchronized with Home Assistant
- Push notifications displayed on screen (shown over the dark/off screen without waking the display)
- Audio streaming — works as a media player device for TTS notifications and music
- 📡 MQTT monitoring — publishes CPU%, RAM%, Temperature every 10 seconds to Home Assistant
- 🔄 Remote reboot/shutdown — send commands from Home Assistant via MQTT
- 🔧 First-boot WiFi wizard — guided WiFi setup via
nmtuion first boot - 🔒 No sensitive data — all credentials replaced with placeholders, ready to configure
| Component | Details |
|---|---|
| Board | OrangePi Zero 2W ✅ tested / OrangePi Zero 3 (should work) |
| SoC | Allwinner H618 (ARM Cortex-A53) |
| GPU | Mali G31 MP2 (Panfrost driver) |
| RAM | 2GB recommended, 4GB best |
| SD Card | Minimum 8GB |
| Display | HDMI monitor touch |
| Network | WiFi (onboard) or Ethernet |
Before configuring this device, make sure you have the following installed in Home Assistant:
Settings → Add-ons → Mosquitto broker → Install & Start
Then add the MQTT integration:
Settings → Devices & Services → Add Integration → MQTT
Configure with:
- Host:
localhost(or your broker IP) - Port:
1883 - Username/Password: create a dedicated user in Mosquitto
Install via HACS (Home Assistant Community Store) Browser Mod on HACS
After installation:
Settings → Devices & Services → Browser Mod → Configure
| Component | Version/Details |
|---|---|
| OS | Armbian (Ubuntu Noble 24.04 base) |
| Compositor | Sway 1.9 (Wayland) |
| Browser | Chromium (Wayland/Ozone mode) |
| Screen timeout | swayidle |
| MQTT client | Python paho-mqtt |
| Audio | PipeWire + WirePlumber |
- Download the image:
Wall_Display_RC2.1_PUBLIC.img.xz - Open Raspberry Pi Imager → "Use custom" → select the
.img.xzfile - Select your SD card as target
- Click Write
- Insert the SD card into the OrangePi and power on
The filesystem automatically expands to fill the SD card on first boot.
| Account | Username | Password |
|---|---|---|
| Linux user | display |
admin |
| Linux root | root |
admin |
⚠️ Change these passwords after first configuration!passwd # change display password sudo passwd root # change root password
On the very first boot, before Sway starts, a setup screen will appear on the display:
╔═══════════════════════════════════════════════════════╗
║ OrangePi — Home Assistant Kiosk ║
╠═══════════════════════════════════════════════════════╣
║ FIRST BOOT — WiFi configuration required ║
║ ║
║ Instructions: ║
║ 1. Select 'Activate a connection' ║
║ 2. Choose your WiFi network ║
║ 3. Enter your password ║
║ 4. Press ESC → Quit to exit ║
╚═══════════════════════════════════════════════════════╝
- Press Enter to open
nmtui - Select your network and enter the password
- Exit — the system waits for the connection, then launches the kiosk
✅ On subsequent boots, WiFi connects automatically.
Connect via SSH:
ssh display@<orangepi-ip>Edit the Chromium launcher:
nano ~/.config/sway/launch-chromium.shReplace YOUR_HA_IP:
http://YOUR_HA_IP:8123
# e.g.: http://192.168.1.10:8123nano ~/mqtt-monitor.pyMQTT_BROKER = "192.168.1.10" # Your MQTT broker IP
MQTT_PORT = 1883
MQTT_USER = "your_mqtt_user"
MQTT_PASS = "your_mqtt_password"
MQTT_TOPIC_BASE = "home/orangepi" # Change topic if desiredRestart the MQTT service:
sudo systemctl restart mqtt-monitor.servicesudo rebootWait for the kiosk to start and open Home Assistant on the display. This is required so that Browser Mod registers the device and creates its entities.
Reconnect via SSH:
ssh display@<orangepi-ip>In Home Assistant:
Settings → Devices & Services → Browser Mod → your device
Find the screen entity, it will look like:
light.browser_mod_XXXXXXXX_XXXXXXXX_screen
Generate a Long-Lived Access Token in Home Assistant:
Profile → Security → Long-lived access tokens → Create token
🔐 Save the token in a safe place — it will NOT be shown again after creation.
echo "paste_your_token_here" > ~/.config/sway/ha-tokennano ~/.config/sway/ha-screen-off.sh
nano ~/.config/sway/ha-screen-on.shIn both files, replace:
YOUR_HA_IP→ your Home Assistant IPYOUR_BROWSER_MOD_ENTITY_screen→ the entity ID from Step 4
sudo rebootThe kiosk is now fully configured. 🎉
You can add MQTT sensors and buttons in two ways:
Settings → Devices & Services → MQTT → Configure → Add device manually
Or use the MQTT Explorer panel to discover topics automatically once the device is running.
For each sensor, add a new MQTT entity:
- CPU: topic
home/orangepi/cpu, unit% - RAM: topic
home/orangepi/ram, unit% - Temperature: topic
home/orangepi/temp, unit°C
For buttons, create automations triggered by MQTT or use Helpers → Button + a script that publishes to home/orangepi/command.
Add to your configuration.yaml:
mqtt:
sensor:
- name: "Wall Display CPU"
state_topic: "home/orangepi/cpu"
unit_of_measurement: "%"
icon: mdi:cpu-64-bit
- name: "Wall Display RAM"
state_topic: "home/orangepi/ram"
unit_of_measurement: "%"
icon: mdi:memory
- name: "Wall Display Temperature"
state_topic: "home/orangepi/temp"
unit_of_measurement: "°C"
icon: mdi:thermometer
button:
- name: "Wall Display Reboot"
command_topic: "home/orangepi/command"
payload_press: "reboot"
icon: mdi:restart
- name: "Wall Display Shutdown"
command_topic: "home/orangepi/command"
payload_press: "shutdown"
icon: mdi:powerReload after editing: Developer Tools → YAML → Reload all YAML
The display turns off automatically after 60 seconds of inactivity:
- Any touch → screen back on immediately
- State synchronized with Browser Mod light entity in HA
- Manual control via Browser Mod switch in HA
To change timeout:
nano ~/.config/sway/config
# Find the line with: exec swayidle -w timeout 60 ...
# Change 60 to your preferred value in seconds/home/display/
├── mqtt-monitor.py # MQTT publisher + command listener
├── reboot_shutdown.sh # Reboot/shutdown handler
└── .config/sway/
├── config # Sway compositor config
├── launch-chromium.sh # Chromium kiosk launcher
├── ha-screen-off.sh # Turn off screen via HA API
├── ha-screen-on.sh # Turn on screen via HA API
└── ha-token # HA long-lived access token
/etc/systemd/system/
└── mqtt-monitor.service # MQTT monitor auto-start
/usr/local/bin/
└── first-boot-wifi.sh # First-boot WiFi setup wizard
cat ~/.cache/sway.logsudo systemctl status mqtt-monitor.service
journalctl -u mqtt-monitor.service -n 30nmcli device wifi list
nmcli device wifi connect "YOUR_SSID" password "YOUR_PASSWORD"ps -eo pid,args | grep chromium | grep "gpu-process"
# Should show a process with --type=gpu-process --render-node-override=/dev/dri/renderD128- Hardware video decode (VAAPI) not working — Cedrus VPU requires
libva-v4l2-requestwhich is not available as a package for Ubuntu Noble. Video/camera streams use software decoding. CPU load remains acceptable for typical Home Assistant use. - Vulkan disabled — not supported on Panfrost + Wayland. OpenGL ES via EGL is used instead.
- Armbian — Linux for ARM boards
- Sway — Wayland compositor
- Browser Mod — by Thomas Lovén
- PiShrink — by Drew Bonasera
- Home Assistant
MIT License — free to use, modify and distribute.
💬 Found a bug? Have a suggestion? Want to contribute?
Open an issue or a pull request — all help is welcome! 🚀