Uses LibCal hours and spaces API
- Image RPi - https://www.raspberrypi.com/software/operating-systems/
- Verify timezone is set
- Install Chromium
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs git
node -v # should show e.g. v20.x
cd /home/<USER>
git clone https://github.com/rmiessle/libcal-api.git
cd libcal-api
cp .env.example .env # or create by hand
nano .env # fill LIBCAL_* creds and hours
npm init -y # creates package.json
npm install express node-fetch@2 dotenv dayjs # installs runtime dependencies
npm start
Create systemd unit /etc/systemd/system/libcal-board.service
[Unit]
Description=LibCal study‑room board
After=network.target
[Service]
User=pi
WorkingDirectory=/home/<USER>/libcal-api
Environment=NODE_ENV=production
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now libcal-board
sudo systemctl status libcal-board # should say “active (running)”
sudo raspi-config # select option A6 and revert to X11
sudo nano /home/<USER>/dpms_disable.sh
#!/bin/bash
export DISPLAY=:0
xset s noblank
xset s off
xset -dpms
chmod +x /home/USER/dpms_disable.sh
sudo nano /home/<USER>/load-kiosk.sh
#!/bin/bash
URL="http://localhost:4000"
until curl --silet --head "$URL" | grep "200 OK" > /dev/null; do
sleep 5
done
chromium --noerrdialogs --disable-infobars --incognito --no-first-start --kiosk http://localhost:4000
chmod +x /home/USER/load-kiosh.sh
sudo apt update
sudo apt install unclutter-xfixes
sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
@lxpanel --profile LXDE-pi
@pcamfm --desktop --profile LXDE-pi
@/home/<USER>/dpms_disable.sh
@unclutter-xfixes -idle 0
@sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' /home/<USER>/.config/chromium/Default/Preferences
@sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' /home/<USER>/.config/chromium/Default/Preferences
@home/<USER>/load-kiosk.sh
sudo nano ~/blank_screen.sh
#!/bin/bash
sleep 5
pkill chromium
sleep 5
export DISPLAY=:0
xhost +local:
xset +dpms
xset dpms force off
chmod +x ~/blank_screen.sh
crontab -e
###Semester hours
##reboot at 0755
55 07 * * * pkill chromium; sleep 15; sudo reboot
##turn off display at 0100
00 01 * * * /home/USER/blank_screen.sh
###Summer hours
##reboot at 0855 Monday-Friday
#55 08 * * 1-5 pkill chromium; sleep 15; sudo reboot
##turn off display at 1630 Monday-Friday
#30 16 * * 1-5 /home/<USER>/blank_screen.sh
sudo nano ~/.local/share/applications/shutdown-kiosk.desktop
[Desktop Entry]
Name=Shutdown Kiosk
Comment=Shuts down Chromium Browser Kiosk
Exec=pkill chromium
Icon=utilities-terminal
Terminal=false
Type=Application
Categories=Utility;
chmod +x ~/.local/share/applications/shutdown-kiosk.desktop
sudo nano ~/restart-kiosk.sh
#!/bin/bash
export DISPLAY=:0
xset s noblank
xset s off
xset -dpms
@unclutter-xfixes -idle 0
@sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' /home/<USER>/.config/chromium/Default/Preferences
@sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' /home/<USER>/.config/chromium/Default/Preferences
@chromium --noerrdialogs --disable-infobars --incognito --no-first-start --kiosk http://localhost:4000
chmod +x ~/restart-kiosk.sh
sudo nano ~/.local/share/applications/restart-kiosk.desktop
[Desktop Entry]
Name=Restart Kiosk
Comment=Restarts Chromium Browser Kiosk
Exec=/home/USER/restart-kiosk.sh
Icon=utilities-terminal
Terminal=false
Type=Application
Categories=Utility;
chmod +x ~/.local/share/applications/restart-kiosk.desktop
- Auto-update:
git -C /home/pi/libcal-room-board pullcron job nightly/weekly - Prevent package prompts:
sudo apt install unattended-upgradesand disable “update notifier” GUI service - Sync time: Verify with
timedatectl
- Check logs:
journalctl -u libcal-board -f - Restart service:
sudo systemctl restart libcal-board - Upgrade dependencies:
cd ~/libcal-room-board && git pull && npm ci && sudo systemctl restart libcal-board