#!/bin/sh INTERACTIVE=True ASK_TO_REBOOT=0 CONFIG=/boot/config.txt RED='\033[0;31m' GREEN='\033[0;32m' BOLD='\e[1m' NC='\033[0m' is_pi () { ARCH=$(dpkg --print-architecture) if [ "$ARCH" = "armhf" ] || [ "$ARCH" = "arm64" ] ; then return 0 else return 1 fi } is_pione() { if grep -q "^Revision\s*:\s*00[0-9a-fA-F][0-9a-fA-F]$" /proc/cpuinfo; then return 0 elif grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]0[0-36][0-9a-fA-F]$" /proc/cpuinfo ; then return 0 else return 1 fi } is_pitwo() { grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]04[0-9a-fA-F]$" /proc/cpuinfo return $? } is_pizero() { grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]0[9cC][0-9a-fA-F]$" /proc/cpuinfo return $? } is_pifour() { grep -q "^Revision\s*:\s*[ 123][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]11[0-9a-fA-F]$" /proc/cpuinfo return $? } get_pi_type() { if is_pione; then echo 1 elif is_pitwo; then echo 2 else echo 0 fi } is_live() { grep -q "boot=live" $CMDLINE return $? } is_ssh() { if pstree -p | egrep --quiet --extended-regexp ".*sshd.*\($$\)"; then return 0 else return 1 fi } is_fkms() { if grep -q okay /proc/device-tree/soc/v3d@7ec00000/status 2> /dev/null || grep -q okay /proc/device-tree/soc/firmwarekms@7e600000/status 2> /dev/null ; then return 0 else return 1 fi } is_installed() { if [ "$(dpkg -l "$1" 2> /dev/null | tail -n 1 | cut -d ' ' -f 1)" != "ii" ]; then return 1 else return 0 fi } deb_ver () { ver=`cat /etc/debian_version | cut -d . -f 1` echo $ver } calc_wt_size() { # NOTE: it's tempting to redirect stderr to /dev/null, so supress error # output from tput. However in this case, tput detects neither stdout or # stderr is a tty and so only gives default 80, 24 values WT_HEIGHT=17 WT_WIDTH=$(tput cols) if [ -z "$WT_WIDTH" ] || [ "$WT_WIDTH" -lt 60 ]; then WT_WIDTH=80 fi if [ "$WT_WIDTH" -gt 178 ]; then WT_WIDTH=120 fi WT_MENU_HEIGHT=$(($WT_HEIGHT-7)) } set_config_var() { lua - "$1" "$2" "$3" < "$3.bak" local key=assert(arg[1]) local value=assert(arg[2]) local fn=assert(arg[3]) local file=assert(io.open(fn)) local made_change=false for line in file:lines() do if line:match("^#?%s*"..key.."=.*$") then line=key.."="..value made_change=true end print(line) end if not made_change then print(key.."="..value) end EOF mv "$3.bak" "$3" } get_web_addresses() { IP=$(hostname -I) printf " ${BOLD}*${NC} ${GREEN}$1://$(hostname).local:$2$3${NC}\n" for ip in $IP; do if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then printf " ${BOLD}*${NC} ${GREEN}$1://$ip:$2$3${NC}\n" else printf " ${BOLD}*${NC} ${GREEN}$1://[$ip]:$2$3${NC}\n" fi done } get_ip_and_port() { IP=$(hostname -I) printf " ${BOLD}*${NC} ${GREEN}$(hostname).local:$1$2${NC}\n" for ip in $IP; do if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then printf " ${BOLD}*${NC} ${GREEN}$ip:$1$2${NC}\n" else printf " ${BOLD}*${NC} ${GREEN}[$ip]:$1$2${NC}\n" fi done } do_finish() { if [ $ASK_TO_REBOOT -eq 1 ]; then whiptail --yesno "Would you like to reboot now?" 20 60 2 if [ $? -eq 0 ]; then # yes sync reboot fi fi exit 0 } do_stop_services() { systemctl stop homebridge } do_start_services() { systemctl start homebridge } do_restart_services() { whiptail --yesno "Would you like to restart Homebridge now?" 10 60 2 RET=$? if [ $RET -eq 0 ]; then printf "Restarting Homebridge...\n" systemctl restart homebridge fi } do_homebridge_update() { printf "Updating Homebridge, please wait...\n" npm install -g --unsafe-perm homebridge@latest homebridge-config-ui-x@latest whiptail --msgbox "Homebridge is up-to-date." 10 60 1 do_restart_services } do_nodejs_update() { printf "Updating Node.js to LTS, please wait...\n" INDEX=$(curl -s https://nodejs.org/dist/index.json) LTS=$(echo $INDEX | jq -r 'map(select(.lts))[0].version') CURRENT=$(node -v || echo "0.0.0") echo "Installed: $CURRENT" echo "Current Node.js LTS: $LTS" if [ $LTS != $CURRENT ]; then echo "Updating Node.js to $LTS..." PREFIX=$(npm -g prefix || echo "/usr/local") tempDir=$(mktemp -d) echo "Downloading to $tempDir/node-$LTS-linux-armv6l.tar.gz ..." curl -Lf# -o "$tempDir/node-$LTS-linux-armv6l.tar.gz" "https://unofficial-builds.nodejs.org/download/release/$LTS/node-$LTS-linux-armv6l.tar.gz" if [ $? -ne 0 ]; then echo "Failed to download node-$LTS-linux-armv6l.tar.gz. See logs above." exit 1 fi echo "Cleaning up old version of npm..." sudo rm -rf "$PREFIX/lib/node_modules/npm" echo "Extracting node-$LTS-linux-armv6l.tar.gz to $PREFIX ..." sudo tar xz -f "$tempDir/node-$LTS-linux-armv6l.tar.gz" -C /usr/local --strip-components=1 --no-same-owner echo "Removing $tempDir/node-$LTS-linux-armv6l.tar.gz ..." sudo rm -rf "$tempDir/node-$LTS-linux-armv6l.tar.gz" echo "Node.js $(node -v)" echo "npm $(npm -v)" echo "Node.js updated to $LTS" echo "Rebuilding modules..." cd "$PREFIX/lib/node_modules" sudo npm --unsafe-perm rebuild whiptail --msgbox "Node.js upgraded from $CURRENT to $LTS." 10 60 1 do_restart_services else whiptail --msgbox "Node.js $CURRENT is already up-to-date" 10 60 1 fi } do_restore_config() { whiptail --yesno "This will remove all custom Homebridge config and restore it to the factory default. You will need to manually remove any existing connections to this instance in the iOS Home app.\n\nAre you sure you want to proceed?" 20 60 2 RET=$? if [ $RET -eq 0 ]; then do_stop_services rm -rf /var/lib/homebridge/persist rm -rf /var/lib/homebridge/accessories rm -rf /var/lib/homebridge/config.json do_start_services fi } do_install_pihole() { whiptail --title "Warning" --yesno "Please make sure you are NOT attempting to run this command from the Homebridge UI web terminal.\n\nFor a successful installation of Pi-Hole you must be logged in using SSH (see wiki for instructions).\n\nIf you are already connected via SSH, you can proceed with the installation." 20 60 1 --no-button "Cancel" --yes-button "Continue" if [ $? -ne 0 ]; then return; fi whiptail --title "Warning" --yesno "Installing Pi-Hole will prevent you from accessing the Homebridge UI on port 80.\n\nYou will still be able to access the Homebridge UI on port $(cat /etc/hb-ui-port) and via:\n\n* http://homebridge.local:$(cat /etc/hb-ui-port)\n* https://homebridge.local\n\nWARNING: Failing to configure Pi-Hole correctly or attempting to uninstall Pi-Hole may result in Homebridge not working correctly. You should take a backup of your Homebridge instance via the UI before proceeding.\n\nAre you sure you want to continue?" 20 60 1 RET=$? if [ $RET -eq 0 ]; then if [ -f /etc/nginx/sites-available/homebridge.local ]; then sed -i "/listen 80;/c\ # listen 80; # http IPv4 - disabled by Pi-Hole installer" /etc/nginx/sites-available/homebridge.local sed -i "/listen \[::\]:80;/c\ # listen \[::\]:80; # http IPv6 - disabled by Pi-Hole installer" /etc/nginx/sites-available/homebridge.local if systemctl is-active --quiet nginx.service; then echo "Restarting Nginx..." systemctl restart nginx fi fi printf "Starting Pi-hole installer...\n" curl -sSL https://install.pi-hole.net | bash printf "\n${BOLD}Pi-hole has been installed${NC}\n" printf "Access Pi-hole in your browser by going to:\n" get_web_addresses http 80 /admin printf "\nYou can still access the Homebridge UI by going to:\n" get_web_addresses http $(cat /etc/hb-ui-port) get_web_addresses https 443 printf "\n" exit 0 fi } do_install_nodered() { whiptail --title "Warning" --yesno "This will install Node-RED on your system as a service running on port 1880.\n\nAre you sure you want to continue?" 20 60 1 RET=$? if [ $RET -eq 0 ]; then npm install -g --unsafe-perm node-red node-red-node-pi-gpio node-red-node-random node-red-node-ping node-red-contrib-play-audio node-red-node-smooth node-red-node-serialport node-red-contrib-homebridge-automation # add helper shortcuts if curl -f https://raw.githubusercontent.com/node-red/linux-installers/master/resources/node-red-icon.svg >/dev/null 2>&1; then sudo curl -sL -o /usr/share/icons/hicolor/scalable/apps/node-red-icon.svg https://raw.githubusercontent.com/node-red/linux-installers/master/resources/node-red-icon.svg 2>&1 | sudo tee -a /var/log/nodered-install.log >>/dev/null sudo curl -sL -o /usr/share/applications/Node-RED.desktop https://raw.githubusercontent.com/node-red/linux-installers/master/resources/Node-RED.desktop 2>&1 | sudo tee -a /var/log/nodered-install.log >>/dev/null sudo curl -sL -o /usr/bin/node-red-start https://raw.githubusercontent.com/node-red/linux-installers/master/resources/node-red-start 2>&1 | sudo tee -a /var/log/nodered-install.log >>/dev/null sudo curl -sL -o /usr/bin/node-red-stop https://raw.githubusercontent.com/node-red/linux-installers/master/resources/node-red-stop 2>&1 | sudo tee -a /var/log/nodered-install.log >>/dev/null sudo curl -sL -o /usr/bin/node-red-restart https://raw.githubusercontent.com/node-red/linux-installers/master/resources/node-red-restart 2>&1 | sudo tee -a /var/log/nodered-install.log >>/dev/null sudo curl -sL -o /usr/bin/node-red-reload https://raw.githubusercontent.com/node-red/linux-installers/master/resources/node-red-reload 2>&1 | sudo tee -a /var/log/nodered-install.log >>/dev/null sudo curl -sL -o /usr/bin/node-red-log https://raw.githubusercontent.com/node-red/linux-installers/master/resources/node-red-log 2>&1 | sudo tee -a /var/log/nodered-install.log >>/dev/null sudo curl -sL -o /etc/logrotate.d/nodered https://raw.githubusercontent.com/node-red/linux-installers/master/resources/nodered.rotate 2>&1 | sudo tee -a /var/log/nodered-install.log >>/dev/null sudo chmod +x /usr/bin/node-red-start sudo chmod +x /usr/bin/node-red-stop sudo chmod +x /usr/bin/node-red-restart sudo chmod +x /usr/bin/node-red-reload sudo chmod +x /usr/bin/node-red-log printf "Added shortcut commands\r\n" else printf "Could not add shortcut commands\r\n" fi cat > /etc/systemd/system/nodered.service <&1 1>&2 2>&3) RET=$? if [ $RET -eq 1 ]; then return 0 elif [ $RET -eq 0 ]; then case "$FUN" in C1\ *) do_conbee_setup ;; C2\ *) do_raspbee_setup ;; C3\ *) do_raspbee2_setup ;; *) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;; esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1 fi # Import Phoscon public key wget -O - http://phoscon.de/apt/deconz.pub.key | sudo apt-key add - # Configure the APT repository for deCONZ # remove -beta when https://forum.phoscon.de/t/please-create-a-repo-for-debian-11-bullseye/432 is resolved sudo sh -c "echo 'deb http://phoscon.de/apt/deconz \ $(lsb_release -cs)-beta main' > \ /etc/apt/sources.list.d/deconz.list" # Update APT package list apt update --allow-releaseinfo-change # Install deCONZ apt install -y deconz # Add override service mkdir -p /etc/systemd/system/deconz.service.d cat > /etc/systemd/system/deconz.service.d/override.conf < /etc/systemd/system/vncserver-pi.service < /dev/null 2>&1 ExecStart=/usr/bin/vncserver -depth 24 -geometry 1280x800 :12 ExecStop=/usr/bin/vncserver -kill :12 [Install] WantedBy=multi-user.target EOL systemctl enable vncserver-x11-serviced.service && systemctl start vncserver-x11-serviced.service && systemctl enable vncserver-pi.service && systemctl start vncserver-pi.service && STATUS=enabled else return 1 fi elif [ $RET -eq 1 ]; then if is_installed realvnc-vnc-server; then systemctl disable vncserver-x11-serviced.service systemctl stop vncserver-x11-serviced.service systemctl disable vncserver-pi.service systemctl stop vncserver-pi.service fi STATUS=disabled else return $RET fi if [ "$STATUS" = "disabled" ]; then whiptail --title "Success" --msgbox "The VNC Server and virtual desktop have been disabled." 20 60 1 else # Complete VNC_ACCESS_URI=$(get_ip_and_port 5912 | sed 's/\x1b\[[0-9;]*m//g') whiptail --title "Success" --msgbox "The VNC Server and virtual desktop have been configured.\n\nYou can connect to the virtual desktop using the RealVNC Viewer on port 5912:\n\n$VNC_ACCESS_URI\n\nDownload RealVNC Viewer:\n\n * https://www.realvnc.com/download/viewer/" 20 60 1 fi } do_vnc } do_extra_packages() { FUN=$(whiptail --title "Homebridge Raspbian Configuration Tool (hb-config)" --menu "Advanced Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Back --ok-button Select \ "A0 AdGuard Home" "Install / Uninstall AdGuard Home" \ "A1 Pi-hole" "Install / Reconfigure Pi-hole" \ "A2 Node-RED" "Install / Update Node-RED" \ "A3 deCONZ / Phoscon" "Install / Update to manage your ConBee or RaspBee device" \ "A4 RealVNC Server" "Enable / Disable desktop access over VNC" \ 3>&1 1>&2 2>&3) RET=$? if [ $RET -eq 1 ]; then return 0 elif [ $RET -eq 0 ]; then case "$FUN" in A0\ *) do_install_adguard_home ;; A1\ *) do_install_pihole ;; A2\ *) do_install_nodered ;; A3\ *) do_install_deconz ;; A4\ *) do_install_desktop_and_vnc ;; *) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;; esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1 fi } do_configure_nginx() { whiptail --title "Warning" --yesno "Using this tool will overwrite any manual changes you may have made to the Homebridge Nginx config file.\n\nAre you sure you wish to continue?" 20 60 1 RET=$? tempDir=$(mktemp -d) if [ $RET -eq 0 ]; then whiptail --title "Homebridge Raspbian Configuration Tool (hb-config)" --separate-output --checklist "\nNGINX Options:" 20 80 5 --cancel-button Cancel --ok-button Save \ "1" "Listen on port 80 - http:// " 1 \ "2" "Listen on port 443 - https:// " 1 \ "3" "Redirect http:// to https:// " 0 2>$tempDir/results if [ $? -eq 0 ]; then LISTEN_ON_PORT_80=false LISTEN_ON_PORT_443=false REDIRECT_HTTP_TO_HTTPS=false while read choice do case "$choice" in 1) LISTEN_ON_PORT_80=true ;; 2) LISTEN_ON_PORT_443=true ;; 3) REDIRECT_HTTP_TO_HTTPS=true ;; *) ;; esac done < $tempDir/results NGINX_PORT_80_CONFIG="" if [ "$LISTEN_ON_PORT_80" = "true" ]; then NGINX_PORT_80_CONFIG="# http://\n listen 80; # http IPv4\n listen [::]:80; # http IPv6\n" fi NGINX_PORT_443_CONFIG="" if [ "$LISTEN_ON_PORT_443" = "true" ]; then NGINX_PORT_443_CONFIG="# https://\n listen 443 ssl http2; # https IPv4\n listen [::]:443 ssl http2; # https IPv6\n" fi NGINX_REDIRECT_HTTP_TO_HTTPS="" if [ "$REDIRECT_HTTP_TO_HTTPS" = "true" ] && [ "$LISTEN_ON_PORT_80" = "true" ]; then NGINX_PORT_80_CONFIG="" NGINX_REDIRECT_HTTP_TO_HTTPS=" server { listen 80; # http IPv4 listen [::]:80; # http IPv6 # replace the _ with your domain name if required # eg. # server_name example.com; server_name _; return 302 https://\$host\$request_uri; }" fi NGINX_TEMPLATE="# this file was generated using the hb-config tool server { $NGINX_PORT_80_CONFIG $NGINX_PORT_443_CONFIG # replace the _ with your domain name if required # eg. # server_name example.com; server_name _; # replace with your domain # path to ssl certificate file # If using Let's Encrypt replace this path with the location of the fullchain.pem file for your domain # eg. # ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate /etc/nginx/ssl/homebridge.local.crt; # path to ssl private key file # If using Let's Encrypt replace this path with the location of the privkey.pem file for your domain # eg. # ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_certificate_key /etc/nginx/ssl/homebridge.local.key; ssl_session_cache builtin:1000 shared:SSL:10m; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; # ssl_stapling on; # ssl_stapling_verify on; # large upload size to allow for uploading 3rd party backup files client_max_body_size 2G; error_page 502 /custom_502.html; location /startup-status.json { alias /usr/share/nginx/html/status.json; } location / { proxy_pass http://127.0.0.1:$(cat /etc/hb-ui-port); proxy_http_version 1.1; proxy_buffering off; proxy_set_header Host \$host; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection \"Upgrade\"; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forward-For \$proxy_add_x_forwarded_for; } location = /custom_502.html { root /usr/share/nginx/html; internal; } } $NGINX_REDIRECT_HTTP_TO_HTTPS " echo "$NGINX_TEMPLATE" > /etc/nginx/sites-available/homebridge.local /usr/local/sbin/nginx-homebridge-self-signed-cert systemctl enable nginx if systemctl is-active --quiet nginx.service; then echo "Restarting Nginx..." systemctl restart nginx else echo "Starting Nginx..." systemctl start nginx fi if [ $? -eq 0 ]; then whiptail --title "Success" --msgbox "NGINX has been configured successfully." 20 60 1 else whiptail --title "Error" --msgbox "An error occured while attempting to reload the NGINX config." 20 60 1 fi fi fi } do_configure_raspbian() { raspi-config } do_update() { tempDir=$(mktemp -d) scriptUrl=https://raw.githubusercontent.com/homebridge/homebridge-raspbian-image/latest/stage3_homebridge/01-homebridge/files/hb-config # download the update to a temporary directory scriptUrl=$scriptUrl?$(date --iso-8601) printf "Downloading hb-config update...\n$scriptUrl\n" curl -fL# $scriptUrl > $tempDir/hb-config # check the download was a success RET=$? if [ $RET -ne 0 ]; then whiptail --title "Error" --msgbox "An error occured while attempting to update the hb-config tool." 20 60 1 else # syntax check the script is a valid bash script if bash -n $tempDir/hb-config; then chmod +x $tempDir/hb-config mv $tempDir/hb-config /usr/local/sbin/hb-config whiptail --title "Success" --msgbox "The hb-config tool has been updated and will now exit.\n\nIf you like the Homebridge Raspberry Pi image please show your support by starring the project on GitHub:\n\nhttps://github.com/homebridge/homebridge-raspbian-image" 20 60 1 exit 0 else whiptail --title "Error" --msgbox "The downloaded script was corrupted and did not pass the syntax check." 20 60 1 fi fi } do_about() { IMAGE_VERSION=$(cat /etc/hb-release) whiptail --title "About" --msgbox "\ This tool provides a straight-forward way of managing Homebridge on a Raspberry Pi. Although it can be run at any time, some of the options may have difficulties if you have heavily customised your installation. Image Version: $IMAGE_VERSION Homebridge - @nfarina https://github.com/homebridge/homebridge Homebridge Config UI X - @oznu https://github.com/oznu/homebridge-config-ui-x Homebridge Raspbian Image - @oznu https://github.com/homebridge/homebridge-raspbian-image \ " 20 80 1 } # Everything else needs to be run as root if [ $(id -u) -ne 0 ]; then printf "Script must be run as root. Try 'sudo hb-config'\n" exit 1 fi # # Interactive use loop # if [ "$INTERACTIVE" = True ]; then [ -e $CONFIG ] || touch $CONFIG calc_wt_size while true; do if is_pi ; then FUN=$(whiptail --title "Homebridge Raspbian Configuration Tool (hb-config)" --backtitle "$(cat /proc/device-tree/model)" --menu "Setup Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Finish --ok-button Select \ "1 Upgrade Node.js" "Upgrade Node.js to the latest LTS version" \ "2 Update Homebridge" "Update Homebridge to the latest version" \ "3 Restore Config" "Restores the Homebridge config to the factory default" \ "4 Extra Packages" "Optional packages, eg. Pi-Hole, Node-RED, UniFi Controller" \ "5 Nginx Options" "Configure Homebridge Nginx settings" \ "6 Configure OS" "Open the Raspbian Configuration Tool" \ "7 Networking" "Open the NetworkManager UI" \ "8 Update" "Update this tool to the latest version" \ "9 About" "Information about this configuration tool" \ 3>&1 1>&2 2>&3) else FUN=$(whiptail --title "Homebridge Raspbian Configuration Tool (hb-config)" --menu "Setup Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT --cancel-button Finish --ok-button Select \ "1 Upgrade Node.js" "Upgrade Node.js to the latest LTS version" \ "2 Update Homebridge" "Update Homebridge to the latest version" \ "3 Restore Config" "Restores the Homebridge config to the factory default" \ "4 Extra Packages" "Optional packages, eg. Pi-Hole, Node-RED, UniFi Controller" \ "5 Nginx Options" "Configure Homebridge Nginx settings" \ "6 Configure OS" "Open the Raspbian Configuration Tool" \ "7 Networking" "Open the NetworkManager UI" \ "8 Update" "Update this tool to the latest version" \ "9 About" "Information about this configuration tool" \ 3>&1 1>&2 2>&3) fi RET=$? if [ $RET -eq 1 ]; then do_finish elif [ $RET -eq 0 ]; then if is_pi ; then case "$FUN" in 1\ *) do_nodejs_update ;; 2\ *) do_homebridge_update ;; 3\ *) do_restore_config ;; 4\ *) do_extra_packages ;; 5\ *) do_configure_nginx ;; 6\ *) do_configure_raspbian ;; 7\ *) nmtui ;; 8\ *) do_update ;; 9\ *) do_about ;; *) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;; esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1 else case "$FUN" in 1\ *) do_nodejs_update ;; 2\ *) do_homebridge_update ;; 3\ *) do_restore_config ;; 4\ *) do_extra_packages ;; 5\ *) do_configure_nginx ;; 6\ *) do_configure_raspbian ;; 7\ *) nmtui ;; 8\ *) do_update ;; 9\ *) do_about ;; *) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;; esac || whiptail --msgbox "There was an error running option $FUN" 20 60 1 fi else exit 1 fi done fi