I need to setup a Raspberry Pi to start and open a browser with a specific URL in fullscreen mode. I have been using Ubuntu Mate and Firefox to do that, but I would like to know if there is a better way to achieve this goal?
I learned about
nodm today from this answer, to a question that is only a slight variation on this one. "Nodm" sounds clever and likely works on almost any distro; I notice the Arch linux wiki has a page about it with some additional useful information -- most significantly the point about disabling (other) display managers (this is not a recommendation to use Arch, but because they have better documentation than most other distros, and most of that information is about software that is used on other distros as well, such as systemd, which is mentioned in that article with regard to disabling the normal display manager).
Display managers (DMs) are the programs that present a graphical login. They are a distinct entity from desktop environments (DEs), since different users of the same machine may choose to use different DEs (and in fact, you can have simulataneous logins of different users running different DEs; the sessions run on separate virtual consoles and can be switched between using CtrlAltF-[1-6+]), but the login is always the same DM. Last I checked, the display manager used on Raspbian was
lightdm, but there are others -- it doesn't really matter which one is in play as long as you know what it is because again, all you want to do is disable it.
I mention all that for a couple of reasons:
On a distro with a default GUI, the DM is going to get in your way, because you want a GUI, but you don't want a DM, but the way things are configured on such a system, the DM is run as an init service. You need to circumvent or supplant this service via the init system (which is usually systemd).
To do that so you can still work with the GUI effectively you need to understand how the the GUI stack works. Like any software stack, it is composed of layers:
- The first, most fundamental layer, common to the vast majority of GNU/Linux systems, is the Xorg server. You need this.
- The second layer normally is a window manager (WM). You may want this. Note the more elaborate diagram of the GUI stack in that wikipedia article.
- The third layer, normally, is a DE. On Raspbian this is by default PIXEL, a recent fork of LXDE. You almost certainly don't want this.
Personally, I would start with a distro with no GUI (such as Raspbian lite), and add components to get what I want, rather than starting with a desktop system and modifying it to create a kiosk. However, that is just an opinion, and I can't say it will be easier unless you understand what you are doing, which is why I am painting a big picture here and including a lot of links to other reading.
Working this way, the goal can be broken into two:
Create an init service that is going to do what a DM usually does, namely, start the Xorg server at boot and run an application on top of it, possibly with the aid of a WM. Something to be aware of here is that you probably do not want the X session to be a root session, hence autologins are sometimes used for kiosks. Another option is to simply downgrade privileges, since the root user can start something as someone else. However, there is a serious weakness in that if someone is able to stop whatever and return to a root login, so you would want to do that with no login, which is how init services work.
As tjohnson notes in a comment below,
nodmis probably a perfect way to deal with these issues.
Get your application to run inside X the way you want it. This is really the easy part, since it is mostly just a matter of telling X what command(s) to run. Normally that's a DM or DE, but it can be a standalone application such as a web browser.
I use Arch Linux + Openbox + Crontab + Surf + OMXPlayer.
In my case (video-advertising installed inside gyms, shops, ..) I have customers ads spots running over an HTML page used as background with news, weather info and date-time.
Automated Power On Steps:
- wifi connection
- start Openbox
- start surf (browser) in fullscreen mode
- run omxplayer daemon with video playlist (https://github.com/subogero/omxd)
Automated Checks and Commands:
- TV power on/off (CEC technology, LG tvs don't accept "poweroff" command)
- restart services (surf, omxplayer, ..) if they crashed
- reboot during night
If you intersted and you need more details, I can update this answer with step-by-step commands and configurations required.
1. Following tutorial is not complete, you have to use it as guideline. I suggest you to read it all once, to read something on linked sources and manipulate it as you need.
2. My project is based on the RaspberryPi 3 computer with ARM architecture. Some instructions are direclty related to it, they have a triple comment symbol (###).
3. TV management via CEC technology is available only for the RaspberryPi and a few other devices. You can buy an adapter for all others computers. Have a look to the vendor compatibility to know which TV to use/buy. !!!
1 - Arch Linux Installation ARM. You can use a 32/64bit version as well: archlinux-arm-rpi3 ###
2 - Installing packages (from root):
# xorg, xorg-xinit: for desktop-environment and drivers # netctl, net-tools, dialog, wpa_supplicant: for wifi connections # wpa_actiond: for auto managed wifi connections # openbox: desktop-environment # surf: light browser web # cronie: tasks scheduler # libcec: tv manager over CEC technology pacman -S xorg xorg-xinit netctl net-tools dialog wpa_supplicant wpa_actiond openbox surf cronie libcec
3 - [Optional] Create new user and delete the default one (from root): source
useradd -m -g users -G storage,video,audio,power -s /bin/bash USERNAME userdel -r alarm ###
4 - Autologin (from root): source
# move into login services folder cd /etc/systemd/system/getty.target.wants/ # create a copy of current login service and edit it cp firstname.lastname@example.org email@example.com # edit one line in firstname.lastname@example.org # from: ExecStart=-/sbin/agetty --noclear %I $TERM # to: ExecStart=-/sbin/agetty -a USERNAME %I 38400 # -a parameter passed is the abbreviation of --autologin # disable current login service and enable the new one systemctl disable email@example.com systemctl enable firstname.lastname@example.org reboot
5 - Auto startx (from user): source
# if .bash_profile doesn't exist into user's home cp /etc/skel/.bash_profile ~/.bash_profile # append following lines to .bash_profile to autorun startx at login #if [[ -z $DISPLAY ]] && [ -n "$XDG_VTNR" ] && [ "$XDG_VTNR" -eq 1 ]; then # exec startx #fi # copy new .xinitrc file into the user's home and edit it, to run openbox with startx command cp /etc/X11/xinit/xinitrc ~/.xinitrc # comment last lines (from 'twm &') and add following line exec openbox-session
6 - Enable the task scheduler and auto managed wifi connection
6.1 - enable task scheduler service to run on boot: source
systemctl enable cronie
6.2 - enable and set auto managed wifi connection: source
# get wifi adapter name iwconfig # enable the wifi manager systemctl enable netctl-auto@WIFIADAPTERNAME reboot
7 - Run software you want after autologin (from user): source
# example: run a webpage in fullscreen # 1. copy openbox configuration files into user's home # cp -R /etc/xdg/openbox ~/.config/ # 2. edit autostart to run the browser, add following lines # surf -F ~/index.html # or surf -F http://google.it
8 - Set periodic checks (from user):
8.1 - TV on/off check: ### source
# create a .sh script to get TV power status and decide if to power on/off # you have to filter the result with cut or awk, I can't give you now the correct script > #!/bin/bash > # get TV status > # usage: ./tvstatus.sh > # status: on > # standby > # unknown > echo 'pow 0' | cec-client -s -d 1
8.2 - software/services checker
# create a .sh script to check if a process is running > #!/bin/bash > # retrieve if given process is running or not > # usage: ./isrunning.sh PROCESSNAME > # example: ./isrunning.sh surf > if [ "`ps -C $1 | grep $1`" != "" ]; then echo 1; else echo 0; fi # create a .sh script to run once a command checking if related process is not running > #!/bin/bash > # run once a command if related process is not running > # usage: ./runonce.sh PROCESSNAME COMMAND > # usage: ./runonce.sh surf "surf -F ~/index.html" > if [ `./isrunning.sh $1` = 0 ]; then bash -c "$2"; fi # 6.3 - set the task scheduler with checks to run # create a temp crontab config file (or edit it directly with 'crontab -e') > * * * * * /home/USERNAME/main.sh # assign new configuration crontab CRONTABCONFIGFILE rm CRONTABCONFIGFILE # inside main.sh you can write all checks/commands you need (in this case, they are runned each minute. Have a look to the source if you are not familiar with crontab)
There a lot of stuff/checks to run, you can scheduling the TV power on/off using libcec and a json file (read it with JQ) or get temperature from rpi using vcgencmd. I can't give you all information because mine is a commercial project. If you need more help, I'm here, sorry for the late answer. I suggest you to have a look to all sources (if you don't already know) to understand better all steps and to know how to expand them with new features.