├── .bash_profile ├── .gitignore ├── .hushlogin ├── .xinitrc ├── README.MD ├── install.sh ├── rpi-hdmi.sh ├── scripts ├── restartgui.sh └── showserial.sh ├── splash.png ├── splashscreen.service └── uninstall.sh /.bash_profile: -------------------------------------------------------------------------------- 1 | if [ -z "$DISPLAY" ] && [ -n "$XDG_VTNR" ] && [ "$XDG_VTNR" -eq 1 ]; then 2 | exec startx -- -nocursor >/dev/null 2>&1 3 | fi 4 | 5 | if [ -f ~/.bashrc ]; then 6 | source ~/.bashrc 7 | fi 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bertramt/pikiosk/82abcbe8e2b6f04c5adeeb1cef9afbaaf309a380/.gitignore -------------------------------------------------------------------------------- /.hushlogin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bertramt/pikiosk/82abcbe8e2b6f04c5adeeb1cef9afbaaf309a380/.hushlogin -------------------------------------------------------------------------------- /.xinitrc: -------------------------------------------------------------------------------- 1 | export DISPLAY=:0.0 2 | #Normal 3 | xrandr -s 1920x1080 4 | 5 | #Pi 7" Touchsceen 6 | #xrandr -s 800x480 7 | #xrandr --output DSI-1 --rotate inverted 8 | #xinput set-prop 6 "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1 9 | 10 | #Rotated HD Touchscreen 11 | #xrandr -s 1080x1920 12 | #xrandr --output HDMI-1 --rotate left 13 | #xinput set-prop 6 "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1 14 | #xinput set-prop 7 "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1 15 | #xinput set-prop 8 "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1 16 | #xinput set-prop 9 "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1 17 | #xinput set-prop 10 "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1 18 | 19 | #Enable second screen 20 | #xrandr --output HDMI-2 --auto --right-of HDMI-1 21 | 22 | xset s off 23 | xset -dpms 24 | xset s noblank 25 | numlockx on 26 | 27 | #Attempts to extend SD life 28 | sudo swapoff --all 29 | rm -fr /home/pi/.cache/chromium 30 | mkdir -p /run/user/1000/chromium/ 31 | ln -s /run/user/1000/chromium/ /home/pi/.cache/ 32 | 33 | #Cleanup Some files 34 | sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' ~/.config/chromium/'Local State' 35 | sed -i 's/"exited_cleanly":false/"exited_cleanly":true/; s/"exit_type":"[^"]\+"/"exit_type":"Normal"/' ~/.config/chromium/Default/Preferences 36 | 37 | #If urllist.txt that doesn't exist then assuming first run and open up tab revolver install 38 | if ! test -f /home/pi/urllist.txt; then 39 | chromium-browser https://chrome.google.com/webstore/detail/revolver-tabs/dlknooajieciikpedpldejhhijacnbda 40 | fi 41 | 42 | touch urllist.txt 43 | URL_LIST=`cat urllist.txt` 44 | 45 | 46 | #chromium-browser --window-size=1920,1080 --window-position=0,0 --kiosk --no-default-browser-check --no-first-run --disable-infobars --disable-session-crashed-bubble --simulate-outdated-no-au='Tue, 31 Dec 2099 23:59:59 GMT' --disable-component-update "https://google.com" 47 | 48 | #Normal TV/Monitor 49 | chromium-browser --window-size=1920,1080 --kiosk --no-default-browser-check --no-first-run --disable-infobars --disable-session-crashed-bubble --simulate-outdated-no-au='Tue, 31 Dec 2099 23:59:59 GMT' --disable-component-update $URL_LIST 50 | 51 | #Vertical Touchscreen 52 | #chromium-browser --window-size=1080,1920 --kiosk --no-default-browser-check --no-first-run --disable-infobars --disable-session-crashed-bubble --simulate-outdated-no-au='Tue, 31 Dec 2099 23:59:59 GMT' --disable-component-update $URL_LIST 53 | 54 | #Dual Browsers 55 | #chromium-browser --kiosk --new-window --user-data-dir="~/.config/chromium/Default/Preferences" --window-position=0,0 --window-size=1920,1080 --no-default-browser-check --no-first-run --disable-infobars --disable-session-crashed-bubble --simulate-outdated-no-au='Tue, 31 Dec 2099 23:59:59 GMT' --disable-component-update $URL_LIST & 56 | #chromium-browser --kiosk --new-window --user-data-dir="~/.config/chromium/Default2/Preferences" --window-position=1921,0 --window-size=1920,1080 --no-default-browser-check --no-first-run --disable-infobars --disable-session-crashed-bubble --simulate-outdated-no-au='Tue, 31 Dec 2099 23:59:59 GMT' --disable-component-update $URL_LIST -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # Raspberry Pi Kiosk (guide and scripts) 2 | This is a guide and scripts to create a kiosk with a Raspberry Pi. This can be used with a TV or with the Raspberry Pi touchscreen. 3 | 4 | ## Getting Started 5 | 6 | These instructions will get you up and going from a fresh install. They may need some adaption for your use case. 7 | 8 | ### Prerequisites 9 | 10 | To start you need a Raspberry Pi and an Micro SD with Raspian Lite. If your SD card came preinstalled with [NOOBS](https://www.raspberrypi.org/downloads/noobs/) you can use that to install Raspian Lite. If you are staring with a empty SD card you can install NOOBS Lite for doing a network install of Raspian Lite. Alternatively you could choose to directly write the [Raspian Lite](https://www.raspberrypi.org/downloads/raspbian/) image to the SD card with [etcher](https://www.balena.io/etcher/) 11 | 12 | 13 | ### Installing OS 14 | 15 | Install Raspbian Lite via NOOBS or writing the image to the SD card. Use of NOOBS has been discontinued current recommended method is to use the Raspberry Pi Imager and use the "Raspberry Pi OS Lite (64bit)" or "Raspberry Pi OS Lite (32bit)". If you need to configure hostname, wifi, password and ssh you can now do that in the Raspberry Pi Imager. 16 | 17 | 18 | ### First Boot (Basic OS Setup) 19 | 20 | Here are some of the most common items that need to be configured on a fresh install. 21 | 22 | #### 23 | Install Updates (If you need to configure Wi-fi skip this step and come back after running raspi-config) 24 | ``` 25 | sudo apt update && sudo apt install -y raspi-config 26 | ``` 27 | 28 | #### 29 | Raspberry Pi Config (raspi-config) is a tool used to configure your Raspberry Pi. Most of these settings can be set from the Raspberry Pi Imager but you can also adjust them at any time with raspi-config. 30 | 31 | New Versions 32 | ``` 33 | sudo raspi-config 34 | * System Options > Password 35 | * System Options > Hostname 36 | * System Options > Boot / Auto Login > Console Autologin (NOT Desktop!!) 37 | * System Options > Wireless LAN (optional) 38 | * Localization Options > Locale > Enable 'en_US.UTF-8 UTF-8' 39 | * Localization Options > Timezone > US > Central 40 | * Localization Options > WLAN Country 41 | * Interface Options > SSH > Enable (optional) 42 | ``` 43 | 44 | Old Versions (Not really relevant anymore) 45 | ``` 46 | sudo raspi-config 47 | * Change Password 48 | * Network Options > Change Hostname 49 | * Network Options > Wi-fi (optional) 50 | * Boot Options > Desktop/CLI > Console Autologin (NOT Desktop!!) 51 | * Localization Options > Change Locale > Enable 'en_US.UTF-8 UTF-8' 52 | * Localization Options > Time Zone > US > Central 53 | * Interfacing Options > SSH > Enable (optional) 54 | 55 | ``` 56 | ## Optional Enhancements for Power and Touchscreen 57 | While setting up several of these for AIO kiosks with 7" touchscreens and an inline POE adapter several tweaks were added. The key option is the lcd_rotate that may be required if your using a touchscreen and not a TV. The other options mostly apply mostly reducing the power use on a Raspberry Pi 3 because of the POE adapter that was being used. I used a POE splitter verses a POE shield because it was the easiest way to power the screen and Pi via POE. The case I used for the touchscreen and POE splitter will not work with a Raspberry Pi 4 or newer devices. 58 | 59 | For those wondering here is the equipment I used for the 7" AIO Kiosks. 60 | . Raspberry Pi 3 61 | . [Touchscreen](https://www.amazon.com/dp/B0153R2A9I) 62 | . [Touchscreen Case](https://www.amazon.com/dp/B01GQFUWIC) 63 | . [POE Splitter](https://www.amazon.com/dp/B019BLMWY0) 64 | 65 | Here are the /boot/config.txt options I added to rotate the screen and slightly reduce the power usage. 66 | ``` 67 | lcd_rotate=2 68 | dtparam=act_led_trigger=none 69 | dtparam=act_led_activelow=off 70 | dtparam=pwr_led_trigger=none 71 | dtparam=pwr_led_activelow=off 72 | dtoverlay=pi3-disable-wifi 73 | dtoverlay=pi3-disable-bt 74 | ``` 75 | 76 | ## Kiosk Browser Installation 77 | ### Install git 78 | ``` 79 | sudo apt update && sudo apt install -y git 80 | ``` 81 | 82 | ### Download and change folder 83 | ``` 84 | cd ~ 85 | git clone https://github.com/bertramt/pikiosk.git 86 | 87 | cd pikiosk 88 | ``` 89 | ### Run install 90 | ``` 91 | ./install.sh 92 | ``` 93 | 94 | ## Finishing Details 95 | 96 | Head on over to the raspberry pi docs for more details on the [config.txt](https://www.raspberrypi.org/documentation/configuration/config-txt/). 97 | 98 | ### /boot/config.txt 99 | 100 | #### Limit to 1080p 101 | Some of my TVs are 4K and I really don't need to display at 4K 102 | ``` 103 | framebuffer_width=1920 104 | framebuffer_height=1080 105 | 106 | hdmi_group=1 107 | hdmi_mode=16 108 | 109 | disable_splash=1 110 | ``` 111 | 112 | ### /boot/cmdline.txt 113 | 114 | #### Quiet Down Boot 115 | Adding or changing these options should quiet down the booting process. This is done automatically with the install script. 116 | ``` 117 | ADD: loglevel=3 consoleblank=0 quiet splash vt.global_cursor_default=0 logo.nologo plymouth.ignore-serial-consoles 118 | CHANGE: console=tty1 to console=tty3 119 | ``` 120 | 121 | ### Boot Splash Screen 122 | This should be done automatically via the install script. 123 | ``` 124 | sudo ln splash.png /opt/splash.png 125 | sudo ln splashscreen.service /etc/systemd/system/splashscreen.service 126 | sudo systemctl enable splashscreen 127 | ``` 128 | 129 | ### Changing default URL(s) 130 | This section needs to be cleaned up 131 | ``` 132 | edit chromium-browser add urls at end 133 | ``` 134 | 135 | ### Tab Revolver (optional) 136 | This section needs to be cleaned up 137 | ``` 138 | edit .xinitrc and remove --kiosk 139 | https://chrome.google.com/webstore/detail/revolver-tabs/dlknooajieciikpedpldejhhijacnbda 140 | more tools > extensions > detail > enable allow in incognito 141 | Revolver Tabs Options 142 | - Autostart 143 | - Reload 144 | - Rotate only when inactive 145 | edit .xinitrc and add --kiosk to 146 | ``` 147 | 148 | ## Uninstallation 149 | 150 | ### Change to dotfiles folder 151 | ``` 152 | cd ~/pikiosk 153 | ``` 154 | 155 | ### Run uninstaller 156 | ``` 157 | ./uninstall.sh 158 | ``` 159 | 160 | ## TODO 161 | - ADD SMARTS to uninstall 162 | - Install firewall 163 | - Add a cleaner way to enable/disable kiosk mode 164 | - Add a cleaner way to add/edit urls 165 | 166 | 167 | 168 | ## Helpful Links 169 | https://raspberrypi.stackexchange.com/questions/59310/remove-boot-messages-all-text-in-jessie 170 | https://yingtongli.me/blog/2016/12/21/splash.html -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This install script is using some code from https://github.com/flipsidecreations/dotfiles 3 | 4 | # Check if vim-addon installed, if not, install it automatically 5 | #if hash vim-addon 2>/dev/null; then 6 | #echo "vim-addon (vim-scripts) installed" 7 | #else 8 | #echo "vim-addon (vim-scripts) not installed, installing" 9 | #sudo apt update && sudo apt -y install vim-scripts 10 | #fi 11 | 12 | # Install Updates and other required packages 13 | sudo apt update && sudo apt upgrade -y 14 | sudo apt install -y xinit xserver-xorg chromium-browser htop numlockx tmux fbi cec-utils xinput 15 | 16 | #Check if rpimonitor is installed and offer to install it. 17 | if [ $(dpkg-query -W -f='${Status}' rpimonitor 2>/dev/null | grep -c "ok installed") -eq 0 ]; 18 | then 19 | while true; do 20 | read -p "Do you wish to install extra RPi-Mon package?" yn 21 | case $yn in 22 | [Yy]* ) sudo wget http://goo.gl/vewCLL -O /etc/apt/sources.list.d/rpimonitor.list; sudo apt install -y dirmngr;sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 2C0D3C0F;sudo apt update && sudo apt install -y rpimonitor;sudo /etc/init.d/rpimonitor update;break;; 23 | [Nn]* ) break;; 24 | * ) echo "Please answer yes or no.";; 25 | esac 26 | done 27 | else 28 | echo "" 29 | echo "rpimonitor already installed" 30 | fi 31 | 32 | echo "" 33 | echo "Apt installs complete" 34 | echo "" 35 | 36 | # Find all dot files then if the original file exists, create a backup 37 | # Once backed up to {file}.dtbak symlink the new dotfile in place 38 | for file in $(find . -maxdepth 1 -name ".*" -type f -printf "%f\n" ); do 39 | if [ -e ~/$file ]; then 40 | mv -f ~/$file{,.dtbak} 41 | fi 42 | ln -s $PWD/$file ~/$file 43 | done 44 | 45 | #Link the splash image to /opt dir 46 | SPLASHIMAGE=/opt/splash.png 47 | if [ -f "$SPLASHIMAGE" ]; then 48 | echo "$SPLASHIMAGE exists" 49 | else 50 | echo "$SPLASHIMAGE does not exist" 51 | sudo ln splash.png /opt/splash.png 52 | fi 53 | 54 | #Link to service file for the splash screen 55 | SPLASHSERVICE=/etc/systemd/system/splashscreen.service 56 | if [ -f "$SPLASHSERVICE" ]; then 57 | echo "$SPLASHSERVICE exists" 58 | else 59 | echo "$SPLASHSERVICE does not exist" 60 | sudo ln splashscreen.service /etc/systemd/system/splashscreen.service 61 | fi 62 | 63 | #Enable Splash Screen 64 | sudo systemctl enable splashscreen 65 | 66 | echo "" 67 | echo "Current cmdline.txt:" 68 | cat /boot/cmdline.txt 69 | #Move Console output to tty3 70 | sudo sed -i 's/console=tty1/console=tty3/g' /boot/cmdline.txt 71 | 72 | if grep -iq "loglevel=" /boot/cmdline.txt; then 73 | echo "loglevel already set in /boot/cmdline.txt" 74 | else 75 | echo "set /boot/cmdline.txt > loglevel=3" 76 | sudo sed -in 's/$/ loglevel=3/' /boot/cmdline.txt 77 | fi 78 | 79 | if grep -iq "consoleblank=" /boot/cmdline.txt; then 80 | echo "consoleblank already set in /boot/cmdline.txt" 81 | else 82 | echo "set /boot/cmdline.txt > consoleblank=0" 83 | sudo sed -in 's/$/ consoleblank=0/' /boot/cmdline.txt 84 | fi 85 | 86 | if grep -iq "quiet" /boot/cmdline.txt; then 87 | echo "quiet already set in /boot/cmdline.txt" 88 | else 89 | echo "set /boot/cmdline.txt > quiet" 90 | sudo sed -in 's/$/ quiet/' /boot/cmdline.txt 91 | fi 92 | 93 | if grep -iq "splash" /boot/cmdline.txt; then 94 | echo "splash already set in /boot/cmdline.txt" 95 | else 96 | echo "set /boot/cmdline.txt > splash" 97 | sudo sed -in 's/$/ splash/' /boot/cmdline.txt 98 | fi 99 | 100 | if grep -iq "vt.global_cursor_default=" /boot/cmdline.txt; then 101 | echo "vt.global_cursor_default already set in /boot/cmdline.txt" 102 | else 103 | echo "set /boot/cmdline.txt > vt.global_cursor_default=0" 104 | sudo sed -in 's/$/ vt.global_cursor_default=0/' /boot/cmdline.txt 105 | fi 106 | 107 | if grep -iq "logo.nologo" /boot/cmdline.txt; then 108 | echo "logo.nologo already set in /boot/cmdline.txt" 109 | else 110 | echo "set /boot/cmdline.txt > logo.nologo" 111 | sudo sed -in 's/$/ logo.nologo/' /boot/cmdline.txt 112 | fi 113 | 114 | if grep -iq "plymouth.ignore-serial-consoles" /boot/cmdline.txt; then 115 | echo "plymouth.ignore-serial-consoles already set in /boot/cmdline.txt" 116 | else 117 | echo "set /boot/cmdline.txt > plymouth.ignore-serial-consoles" 118 | sudo sed -in 's/$/ plymouth.ignore-serial-consoles/' /boot/cmdline.txt 119 | fi 120 | 121 | echo "" 122 | echo "New cmdline.txt:" 123 | cat /boot/cmdline.txt 124 | 125 | echo "" 126 | echo "Installed Please Reboot" -------------------------------------------------------------------------------- /rpi-hdmi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Enable and disable HDMI output on the Raspberry Pi 4 | # sudo apt install cec-utils 5 | 6 | is_off () 7 | { 8 | #tvservice -s | grep "TV is off" >/dev/null 9 | echo "pow 0" | cec-client -s -d 1 | grep "power status: standby" >/dev/null 10 | } 11 | 12 | case $1 in 13 | off) 14 | #tvservice -o 15 | echo "as" | cec-client -s -d 1 16 | echo "standby 0" | cec-client -s -d 1 >/dev/null 17 | ;; 18 | on) 19 | if is_off 20 | then 21 | #tvservice -p 22 | #curr_vt=`fgconsole` 23 | #if [ "$curr_vt" = "1" ] 24 | #then 25 | # chvt 2 26 | # chvt 1 27 | #else 28 | # chvt 1 29 | # chvt "$curr_vt" 30 | #fi 31 | echo "on 0" | cec-client -s -d 1 >/dev/null 32 | echo "as" | cec-client -s -d 1 33 | fi 34 | ;; 35 | status) 36 | if is_off 37 | then 38 | echo off 39 | else 40 | echo on 41 | fi 42 | ;; 43 | *) 44 | echo "Usage: $0 on|off|status" >&2 45 | exit 2 46 | ;; 47 | esac 48 | 49 | exit 0 50 | -------------------------------------------------------------------------------- /scripts/restartgui.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | killall "/usr/lib/chromium-browser/chromium-browser-v7" -------------------------------------------------------------------------------- /scripts/showserial.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cat /dev/ttyUSB0 -------------------------------------------------------------------------------- /splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bertramt/pikiosk/82abcbe8e2b6f04c5adeeb1cef9afbaaf309a380/splash.png -------------------------------------------------------------------------------- /splashscreen.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Splash screen 3 | DefaultDependencies=no 4 | After=local-fs.target 5 | 6 | [Service] 7 | ExecStart=/usr/bin/fbi -d /dev/fb0 --noverbose -a /opt/splash.png 8 | StandardInput=tty 9 | StandardOutput=tty 10 | 11 | [Install] 12 | WantedBy=sysinit.target -------------------------------------------------------------------------------- /uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Loop through all the dotfiles, if the file is a symlink then remove it 4 | # Then if the backup file exists, restore it to it's original location 5 | for file in $(find . -maxdepth 1 -name ".*" -type f -printf "%f\n" ); do 6 | if [ -h ~/$file ]; then 7 | rm -f ~/$file 8 | fi 9 | if [ -e ~/${file}.dtbak ]; then 10 | mv -f ~/$file{.dtbak,} 11 | fi 12 | done 13 | 14 | echo "Uninstalled" --------------------------------------------------------------------------------