Hindsight: I should have documented this better the first time…
When we built our magic mirror, I remember thinking: “I really should document this” but I didn’t. Today, the micro-SD card that was running the Magic Mirror died, it wouldn’t boot, we couldn’t mount it, nothing. I couldn’t even find the blog posts that I had followed when we built it originally. Hanging my head in shame all I could think of was “I fucking knew this was gonna happen”. So, learn from me, make sure you document your projects, you never know when you might need to rebuild.
Supplies
- Raspberry Pi (version depends on your needs)
- A display with HDMI input
- Micro-SD card reader (for installing OS on the RPi)
Decide now: Chromium or Iceweasel?
Depending on your choice of browser, that will dictate which version of the operating system you’ll use. The current version of Rhaspian (Buster), does not support Chromium but the previous version (Stretch) does.
Chromium has an execute flag --app
that will hide the address bar and border and easily provide you a full-screen experience. Iceweasel on the other hand, is a little more involved. Chromium is not currently supported in Rhaspian Buster (Debian 10), though you might be able to find some workarounds. We spent a few hours trying to image some micro-SD cards with Rhaspbian Stretch but kept running into issues with the filesystem: some would fail verification, some would have the root console locked. I decided that I just didn’t care enough to dig deeper; I went with the Raspberry Pi Imager and burned Buster to a spare micro-SD card and read up on how to use Iceweasel.
Regardless of your path, something I learned in the last few months, you can set up SSH and WPA supplicant before you even insert the card into the pi. Simply mount the boot volume of the micro-SD card on your system and run:
touch ssh
An empty file named ssh
is all that is needed to enable SSH on your Raspberry Pi right from the gate! No need to dig around the basement for an old monitor and keyboard to configure, it’s remotely accessible. Speaking of remote access, write a file to the boot volume named wpa_supplicant.conf
with content:
country=US # Your 2-digit country code ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev network={ ssid="YOUR_NETWORK_NAME" psk="YOUR_PASSWORD" key_mgmt=WPA-PSK }
Replace YOUR_NETWORK_NAME
with your SSID and YOUR_PASSWORD
with the WiFi password for that network. Once your Raspberry Pi boots, it will automatically connect to your WiFi network and have SSH access with user pi
and password raspberry
. Now it’s time to configure it for your kiosk display.
First, get the preferred resolution and display modw using the tvservice
command:
tvservice -d /tmp/edid_info
edidparser /tmp/edid_info | grep 'preferred mode'
This will provide you with the preferred display settings for the display connected to your Raspberry Pi. Take this information and edit /boot/config.txt
:
# Always force HDMI display over DVI
hdmi_group=2
# HDMI mode as reported by the display
hdmi_mode=16
The X-Server
It’s highly recommended you create a new user for running the display as root
or pi
have too broad an attack vector, make sure you provide the user with a sufficiently complex password and a home directory, as it will be used by the browsers to store profile information.
adduser kiosk
Now you need access to the graphics cards, input devices, and displays in order to run your choice of browser: the X server. Install the appropriate X server for your system, along with the xinit helper package:
apt update
apt install -y xorg xinit xserver-xorg-legacy
Modify the /etc/X11/Xwrapper.config which facilitates launching the X server with or without a user with sudo privileges:
# Xwrapper.config (Debian X Window System server wrapper configuration file)
#
# This file was generated by the post-installation script of the
# xserver-xorg-legacy package using values from the debconf database.
#
# See the Xwrapper.config(5) manual page for more information.
#
# This file is automatically updated on upgrades of the xserver-xorg-legacy
# package *only* if it has not been modified since the last upgrade of that
# package.
#
# If you have edited this file but would like it to be automatically updated
# again, run the following command as root:
# dpkg-reconfigure xserver-xorg-legacy
needs_root_rights=yes
allowed_users=anybody
As we are building a kiosk display, we want the X server to start up without power management to prevent it from sleeping. Create a file, .xserverrc, with execute permissions in your kiosk user’s home directory:
#!/bin/sh
# Disable power management on a new X server process to prevent the display from sleeping along with ignoring tcp-based connections to it
exec /usr/bin/X -s 0 -dpms -nolisten tcp "$@"
Iceweasel Setup
Install the official iceweasel package:
apt install -y iceweasel
We will want the browser to always launch full-screen, so modify the width and height values to the values associated with the preferred display mode above and write to /home/kiosk/.mozilla/firefox/XXXXX.default-esr/xulstore.json
:
{
"chrome://browser/content/browser.xul": {
"navigator-toolbox": {
"iconsize": "small"
},
"main-window": {
"width": "1080",
"height": "1900",
"screenX": "0",
"screenY": "0",
"sizemode": "fullscreen"
}
}
}
To make the browser consume all of the screen real-estate, modify the browser’s CSS /home/kiosk/.mozilla/firefox/XXXXX.default-esr/chrome/userChrome.css
– create the path and file if either does not exist:
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
#content browser {
margin-right: -18px !important;
overflow-y: scroll;
overflow-x: hidden;
}
#content browser {
margin-bottom: -18px !important;
overflow-y: scroll;
overflow-x: hidden;
}
#content browser {
margin-left: -2px !important;
}
#content browser {
margin-top: -5px !important;
}
When the X server starts up, it will look to execute the .xsession
located in the user’s home directory. This is where you will launch the browser and load the appropriate URL for your needs:
#!/bin/sh
exec /usr/bin/iceweasel --profile /home/kiosk/.mozilla/firefox/XXXXX.default-esr https://www.your.domain
Create your your_kiosk.service
file in /etc/systemd/system/ and enable it via systemctl enable your_kiosk.service
so that it is invoked on system startup:
[Unit]
Description=Kiosk Display
After=network-online.target
Before=multi-user.target
DefaultDependencies=no
[Service]
User=kiosk
ExecStart=/usr/bin/startx -- /usr/lib/xorg/Xorg.wrap -nocursor
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
And finally…
Make an image of your rhaspian system so you don’t have to do this again!