Raspberry Pi Wall Display

Last updated 10/31/2026

Overview

The TV Dashboard is a web page, so anything with a modern browser can show it. A Raspberry Pi is the cheapest reliable way to drive a clubhouse screen: it boots straight into the display, restarts the browser if it ever crashes, turns the screen off at night and back on in the morning, and reboots itself once a day so it stays fresh for months without anyone touching it.

This guide takes about twenty minutes. You flash an SD card, boot the Pi once, paste in a setup script, and answer five questions.

What You Need

  • A Raspberry Pi 4 (2 GB or more) or a Raspberry Pi 5, with its power supply and a micro-HDMI cable. Older models are too slow for the display.
  • A microSD card of 16 GB or more.
  • A TV or monitor. A TV is better: it supports HDMI-CEC, which lets the Pi switch it fully off and on. A computer monitor goes to sleep when the Pi cuts the HDMI signal, which works too.
  • Wi-Fi or Ethernet at the clubhouse.
  • A keyboard and mouse for the first boot only.
  • Your club's Display URL from Setup → Data & Features → TV Dashboard.

Step 1: Flash the SD Card

  1. Install Raspberry Pi Imager on your computer.
  2. Choose your Pi model, then choose Raspberry Pi OS (64-bit) — the full desktop version, not "Lite".
  3. When Imager asks whether to apply OS customisation settings, choose Edit settings and fill in:
    • Hostname: something like clubhouse-tv.
    • Username and password: pick a username and a password you'll remember. The setup script needs to run as this user.
    • Wireless LAN: your clubhouse Wi-Fi name and password, unless you'll use an Ethernet cable.
    • Locale settings: set the time zone. The on/off schedule follows the Pi's clock.
    • On the Services tab, enable SSH if you'd like to manage the Pi from your laptop later.
  4. Write the card. Put it in the Pi, connect the screen, keyboard and mouse, and power it on.

Step 2: Run the Setup Script

The Pi boots to the desktop. Open a terminal (the black icon in the top bar, or Ctrl+Alt+T), then:

  1. Type nano ~/setup-tv.sh and press Enter.
  2. Copy the entire script below and paste it into the terminal (Ctrl+Shift+V, or right-click → Paste).
  3. Press Ctrl+O, Enter to save, then Ctrl+X to exit.
  4. Type bash ~/setup-tv.sh and press Enter.

The script asks for the Display URL, the screen type, the on and off hours, and the nightly reboot hour. It installs what it needs, sets the Pi to log in and open the display automatically, disables the desktop's own screen blanking, and writes the schedule. At the end it offers to reboot.

#!/usr/bin/env bash
# Centerline TV Dashboard - Raspberry Pi setup
# For Raspberry Pi OS (64-bit) with the desktop, on a Pi 4 or Pi 5.
# Re-run at any time to change the URL, screen type or schedule.
set -euo pipefail

if [ "$(id -u)" -eq 0 ]; then
  echo "Run this as your normal user, not with sudo. It asks for sudo when it needs it."
  exit 1
fi

ask() { # ask VARIABLE "question" "default"
  local value
  read -r -p "$2 [$3]: " value </dev/tty || true
  printf -v "$1" '%s' "${value:-$3}"
}
is_hour() { [[ "$1" =~ ^[0-9]{1,2}$ ]] && [ "$1" -le 23 ]; }

echo
echo "Centerline TV Dashboard - Raspberry Pi setup"
echo "--------------------------------------------"
ask DISPLAY_URL "Display URL (Setup > Data & Features > TV Dashboard)" ""
case "$DISPLAY_URL" in
  https://*/tv/*) ;;
  *) echo "That doesn't look like a Centerline display URL (https://.../tv/...)."; exit 1 ;;
esac

ask POWER "Screen type: tv (switch off with HDMI-CEC), monitor (cut the HDMI signal) or none" "tv"
case "$POWER" in tv|monitor|none) ;; *) echo "Please answer tv, monitor or none."; exit 1 ;; esac

ON_HOUR=7; OFF_HOUR=22
if [ "$POWER" != none ]; then
  ask ON_HOUR  "Turn the screen on at (hour, 0-23)" "7"
  ask OFF_HOUR "Turn the screen off at (hour, 0-23)" "22"
  is_hour "$ON_HOUR" && is_hour "$OFF_HOUR" || { echo "Hours must be 0-23."; exit 1; }
fi
ask REBOOT_HOUR "Reboot the Pi every night at (hour, 0-23, or 'never')" "4"
[ "$REBOOT_HOUR" = never ] || is_hour "$REBOOT_HOUR" || { echo "Hour must be 0-23 or never."; exit 1; }

CHROMIUM="$(command -v chromium || command -v chromium-browser || true)"
if [ -z "$CHROMIUM" ]; then
  echo "Chromium isn't installed. Use Raspberry Pi OS with the desktop, not the Lite version."
  exit 1
fi

echo
echo "Installing packages..."
PKGS="curl wlr-randr"
[ "$POWER" = tv ] && PKGS="$PKGS cec-utils"
sudo apt-get update -qq
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $PKGS

echo "Setting desktop auto-login and disabling screen blanking..."
sudo raspi-config nonint do_boot_behaviour B4
sudo raspi-config nonint do_blanking 1

DIR="$HOME/centerline-tv"
mkdir -p "$DIR" "$HOME/.config/labwc"

# A tiny local page that waits for the network, then opens the display.
# Without it, Chromium would show "no internet" forever if it started before Wi-Fi was up.
cat > "$DIR/launch.html" <<'EOF'
<!doctype html>
<meta charset="utf-8">
<title>Centerline</title>
<style>
  html, body { height: 100%; margin: 0; background: #ffffff;
    font: 4vmin system-ui, sans-serif; display: flex; align-items: center; justify-content: center; }
</style>
<body>Connecting to Centerline...
<script>
  var url = "__DISPLAY_URL__";
  function tryConnect() {
    fetch(url, { mode: "no-cors", cache: "no-store" })
      .then(function () { location.replace(url); })
      .catch(function () { setTimeout(tryConnect, 5000); });
  }
  tryConnect();
</script>
EOF
sed -i "s|__DISPLAY_URL__|${DISPLAY_URL//&/\\&}|" "$DIR/launch.html"

# Keeps Chromium running in kiosk mode; relaunches it if it ever exits.
cat > "$DIR/start.sh" <<EOF
#!/usr/bin/env bash
# Wait until the desktop has brought the screen up. Chromium started too early
# under labwc paints a blank white or gray window and never recovers.
for _ in \$(seq 1 60); do
  wlr-randr 2>/dev/null | grep -q "Enabled: yes" && break
  sleep 1
done
sleep 10
while true; do
  "$CHROMIUM" --kiosk --incognito --noerrdialogs --disable-infobars --no-first-run \\
    --password-store=basic --enable-features=OverlayScrollbar \\
    "file://$DIR/launch.html"
  sleep 2
done
EOF

if [ "$POWER" = tv ]; then
  cat > "$DIR/display-off.sh" <<'EOF'
#!/usr/bin/env bash
echo "standby 0" | cec-client -s -d 1 >/dev/null
EOF
  cat > "$DIR/display-on.sh" <<'EOF'
#!/usr/bin/env bash
echo "on 0" | cec-client -s -d 1 >/dev/null
sleep 5
echo "as" | cec-client -s -d 1 >/dev/null   # make the TV switch to the Pi's input
EOF
  CRON_USER=root
elif [ "$POWER" = monitor ]; then
  cat > "$DIR/display-off.sh" <<'EOF'
#!/usr/bin/env bash
export WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR="/run/user/$(id -u)"
OUT="$(wlr-randr | awk '/^[A-Za-z]/ { print $1; exit }')"
wlr-randr --output "${OUT:-HDMI-A-1}" --off
EOF
  cat > "$DIR/display-on.sh" <<'EOF'
#!/usr/bin/env bash
export WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR="/run/user/$(id -u)"
OUT="$(wlr-randr | awk '/^[A-Za-z]/ { print $1; exit }')"
wlr-randr --output "${OUT:-HDMI-A-1}" --on
sleep 3
pkill -f -- "--kiosk" || true   # relaunch Chromium so it fills the screen again
EOF
  CRON_USER="$USER"
fi
chmod +x "$DIR"/*.sh

# Start the display when the desktop logs in.
AUTOSTART="$HOME/.config/labwc/autostart"
touch "$AUTOSTART"
sed -i '/centerline-tv/d' "$AUTOSTART"
echo "$DIR/start.sh &" >> "$AUTOSTART"

# The schedule. Edit this file later to change the hours, or re-run this script.
{
  echo "# Centerline TV display schedule - written by setup-tv.sh"
  echo "SHELL=/bin/bash"
  if [ "$POWER" != none ]; then
    echo "0 $ON_HOUR  * * * $CRON_USER $DIR/display-on.sh"
    echo "0 $OFF_HOUR * * * $CRON_USER $DIR/display-off.sh"
  fi
  if [ "$REBOOT_HOUR" != never ]; then
    echo "0 $REBOOT_HOUR  * * * root /sbin/shutdown -r now"
  fi
} | sudo tee /etc/cron.d/centerline-tv >/dev/null
sudo chmod 644 /etc/cron.d/centerline-tv

echo
echo "Done."
echo "  Display URL : $DISPLAY_URL"
[ "$POWER" = none ] || echo "  Screen      : $POWER, on at ${ON_HOUR}:00, off at ${OFF_HOUR}:00"
[ "$REBOOT_HOUR" = never ] || echo "  Reboot      : nightly at ${REBOOT_HOUR}:00"
echo "  Time zone   : $(timedatectl show -p Timezone --value) (change with: sudo raspi-config)"
echo "  Files       : $DIR and /etc/cron.d/centerline-tv"
echo
ask REBOOT_NOW "Reboot now to start the display? (y/n)" "y"
if [ "$REBOOT_NOW" = y ]; then sudo reboot; fi

Step 3: Check It

After the reboot the Pi should log in on its own, show "Connecting to Centerline..." for a moment, and then the display. Unplug the keyboard and mouse. If the screen looks wrong, see Troubleshooting below.

To test the schedule without waiting for night, run the scripts by hand from a terminal:

sudo ~/centerline-tv/display-off.sh    # TV: use sudo. Monitor: leave sudo off.
sudo ~/centerline-tv/display-on.sh

For a TV, make sure HDMI-CEC is switched on in the TV's settings. Every brand names it differently: Anynet+ (Samsung), Bravia Sync (Sony), Simplink (LG), Viera Link (Panasonic), EasyLink (Philips), CEC (Vizio, TCL, Hisense). The Pi can't switch the TV off until it is on.

Changing the Schedule Later

The on, off and reboot hours live in one file on the Pi, /etc/cron.d/centerline-tv, in standard cron format. Edit it with sudo nano /etc/cron.d/centerline-tv, or simply run the setup script again and answer the questions with the new values. Re-running the script is also how you point the Pi at a new Display URL after replacing it in Setup.

Removing the Setup

To turn the Pi back into an ordinary desktop, run these from a terminal (Ctrl+Alt+T, or SSH in). They stop the display, remove its files and schedule, and undo the auto-login and screen-blanking changes:

pkill -f centerline-tv; pkill chromium
sed -i '/centerline-tv/d' ~/.config/labwc/autostart
rm -rf ~/centerline-tv ~/setup-tv.sh
sudo rm -f /etc/cron.d/centerline-tv
sudo raspi-config nonint do_boot_behaviour B3   # desktop, ask for a password at login
sudo raspi-config nonint do_blanking 0          # screen blanking back on
sudo reboot

The packages the script installed (cec-utils, wlr-randr, curl) are harmless to leave in place. To remove them anyway, run sudo apt remove cec-utils wlr-randr.

To reuse the Pi as a wall display later, run the setup script again from Step 2. If you'd rather wipe it completely, reflash the SD card with Raspberry Pi Imager.

Troubleshooting

  • "Connecting to Centerline..." never goes away. The Pi can't reach the internet. Check the Wi-Fi name and password in the desktop's network menu, or plug in Ethernet. The page keeps retrying every few seconds and opens the display on its own once the network is back.
  • The display shows "not found". The Display URL was replaced or turned off in Setup. Re-run the setup script with the current URL.
  • The TV doesn't turn off or on. HDMI-CEC is off in the TV's menu (see Step 3), or the TV is on an HDMI input that doesn't carry CEC. Some TVs only support CEC on HDMI 1. A TV that ignores CEC can still be put to sleep by choosing monitor as the screen type, so it sees no signal and sleeps on its own.
  • The display is unstyled or looks broken. Make sure the Pi is on a current Raspberry Pi OS. The dashboard needs a browser from 2023 or newer, and a Pi OS release older than that ships an older Chromium. Run sudo apt full-upgrade from a terminal.
  • The screen comes back on with the display in a small window. This can happen on a monitor after the signal is cut and restored. The morning script restarts the browser to handle it. If it still happens, reboot the Pi.
  • A plain white or gray screen, no "Connecting to Centerline..." and no display. Chromium started before the desktop had finished bringing the screen up, which leaves it with a blank window it never repaints. The start script waits for the screen before launching, so this shouldn't happen on a fresh setup. If it does, open a terminal (Ctrl+Alt+T, or SSH in) and run pkill -f centerline-tv; pkill chromium; ~/centerline-tv/start.sh &. If the display appears, the Pi just needed longer: edit ~/centerline-tv/start.sh and raise the sleep 10 to sleep 30.
  • The screen goes blank after ten minutes. The desktop's own screen blanking is still on. Run sudo raspi-config, choose Display Options → Screen Blanking, and answer No.
  • The Pi shows a desktop instead of the display. The start script didn't run. Check that ~/.config/labwc/autostart contains the line /home/YOUR-USER/centerline-tv/start.sh &, and that you ran the setup script as that user rather than with sudo.
  • Managing the Pi without a trip to the airport. Enable SSH in Imager (Step 1), or install Raspberry Pi Connect, which gives you a terminal and a view of the screen from any browser.