| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- #!/bin/bash
- #############################################
- # Dune Weaver Touch - Kiosk Mode Setup Script
- # For Raspberry Pi with Freenove 5" DSI Display
- # Author: Dune Weaver Team
- # Version: 1.0
- #############################################
- set -e # Exit on error
- # Color codes for output
- RED='\033[0;31m'
- GREEN='\033[0;32m'
- YELLOW='\033[1;33m'
- NC='\033[0m' # No Color
- # Configuration variables
- SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
- USER_NAME=$(whoami)
- HOME_DIR="/home/$USER_NAME"
- APP_DIR="$SCRIPT_DIR"
- SERVICE_NAME="dune-weaver-kiosk"
- VENV_PATH="$APP_DIR/bin/activate"
- # Display banner
- echo -e "${GREEN}"
- echo "================================================"
- echo " Dune Weaver Touch - Kiosk Setup"
- echo " Freenove 5\" DSI Display (800x480)"
- echo "================================================"
- echo -e "${NC}"
- # Function to detect Raspberry Pi model
- detect_pi_model() {
- local model=$(cat /proc/cpuinfo | grep "Model" | cut -d ':' -f 2 | sed 's/^ *//')
- if [[ $model == *"Pi 3"* ]]; then
- echo "3"
- elif [[ $model == *"Pi 4"* ]]; then
- echo "4"
- elif [[ $model == *"Pi 5"* ]]; then
- echo "5"
- else
- echo "unknown"
- fi
- }
- # Function to backup files
- backup_file() {
- local file=$1
- if [ -f "$file" ]; then
- cp "$file" "${file}.backup.$(date +%Y%m%d_%H%M%S)"
- echo -e "${YELLOW}Backed up: $file${NC}"
- fi
- }
- # Function to setup boot configuration
- setup_boot_config() {
- echo -e "${GREEN}Configuring boot settings for DSI display...${NC}"
-
- backup_file "/boot/config.txt"
-
- local pi_model=$(detect_pi_model)
- echo -e "${GREEN}Detected Raspberry Pi Model: $pi_model${NC}"
-
- # Remove conflicting HDMI settings if they exist
- sudo sed -i '/hdmi_force_hotplug/d' /boot/config.txt
- sudo sed -i '/hdmi_group/d' /boot/config.txt
- sudo sed -i '/hdmi_mode/d' /boot/config.txt
- sudo sed -i '/hdmi_cvt/d' /boot/config.txt
- sudo sed -i '/hdmi_drive/d' /boot/config.txt
- sudo sed -i '/config_hdmi_boost/d' /boot/config.txt
- sudo sed -i '/dtoverlay=ads7846/d' /boot/config.txt
-
- # Remove old overlays
- sudo sed -i '/dtoverlay=vc4-fkms-v3d/d' /boot/config.txt
- sudo sed -i '/dtoverlay=vc4-kms-v3d/d' /boot/config.txt
-
- # Add proper configuration based on Pi model
- if [ "$pi_model" == "3" ]; then
- # Pi 3 configuration
- echo -e "${GREEN}Configuring for Pi 3...${NC}"
- cat << EOF | sudo tee -a /boot/config.txt > /dev/null
- # Dune Weaver Kiosk - DSI Display Configuration (Pi 3)
- dtoverlay=vc4-fkms-v3d
- gpu_mem=128
- max_framebuffers=2
- display_auto_detect=1
- disable_overscan=1
- EOF
- else
- # Pi 4/5 configuration
- echo -e "${GREEN}Configuring for Pi 4/5...${NC}"
- cat << EOF | sudo tee -a /boot/config.txt > /dev/null
- # Dune Weaver Kiosk - DSI Display Configuration (Pi 4/5)
- dtoverlay=vc4-kms-v3d
- gpu_mem=128
- max_framebuffers=2
- display_auto_detect=1
- disable_overscan=1
- EOF
- fi
-
- # Add common settings
- cat << EOF | sudo tee -a /boot/config.txt > /dev/null
- # Common settings
- dtparam=i2c_arm=on
- dtparam=spi=on
- enable_uart=1
- max_usb_current=1
- # Disable splash screens for faster boot
- disable_splash=1
- EOF
-
- echo -e "${GREEN}Boot configuration updated${NC}"
- }
- # Function to install dependencies
- install_dependencies() {
- echo -e "${GREEN}Installing required dependencies...${NC}"
-
- sudo apt-get update
- sudo apt-get install -y \
- libgles2-mesa \
- libgles2-mesa-dev \
- libgbm-dev \
- libdrm-dev \
- libinput-dev \
- libudev-dev \
- libxkbcommon-dev \
- fbset \
- evtest \
- qtvirtualkeyboard-plugin \
- qml-module-qtquick-virtualkeyboard \
- qt6-virtualkeyboard-plugin \
- qml6-module-qt-labs-qmlmodels || {
- echo -e "${YELLOW}Some packages may not be available, continuing...${NC}"
- }
-
- echo -e "${GREEN}Dependencies installed${NC}"
- }
- # Function to create startup script
- create_startup_script() {
- echo -e "${GREEN}Creating startup script...${NC}"
-
- local pi_model=$(detect_pi_model)
- local START_SCRIPT="$APP_DIR/start_kiosk.sh"
-
- cat << 'EOF' > "$START_SCRIPT"
- #!/bin/bash
- # Dune Weaver Touch Kiosk Startup Script
- # Auto-generated by setup_kiosk.sh
- # Wait for system to fully boot
- sleep 10
- # Log file
- LOG_FILE="/tmp/dune-weaver-kiosk.log"
- exec &> >(tee -a "$LOG_FILE")
- echo "========================================="
- echo "Starting Dune Weaver Touch Kiosk"
- echo "Date: $(date)"
- echo "========================================="
- # Detect Pi model for platform selection
- PI_MODEL=$(cat /proc/cpuinfo | grep "Model" | cut -d ':' -f 2)
- # Set working directory
- cd "$(dirname "$0")"
- # Check if virtual environment exists
- if [ ! -f "bin/activate" ]; then
- echo "ERROR: Virtual environment not found!"
- exit 1
- fi
- # Activate virtual environment
- source bin/activate
- # Function to run with LinuxFB (Pi 3 with DSI)
- run_linuxfb() {
- export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0
- export QT_QPA_FONTDIR=/usr/share/fonts/truetype
- export QT_QPA_FB_HIDECURSOR=1
- export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event0:rotate=0
-
- # Enable Virtual Keyboard
- export QT_IM_MODULE=qtvirtualkeyboard
- export QT_VIRTUALKEYBOARD_STYLE=default
- export QT_VIRTUALKEYBOARD_LAYOUT_PATH=/usr/share/qt5/qtvirtualkeyboard/layouts
-
- echo "Starting with LinuxFB platform and virtual keyboard..."
- python main.py
- }
- # Function to run with EGLFS (Pi 4/5 with DSI)
- run_eglfs() {
- export QT_QPA_PLATFORM=eglfs
- export QT_QPA_EGLFS_WIDTH=800
- export QT_QPA_EGLFS_HEIGHT=480
- export QT_QPA_EGLFS_INTEGRATION=eglfs_kms
- export QT_QPA_EGLFS_KMS_ATOMIC=1
- export QT_QPA_EGLFS_HIDECURSOR=1
- export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event0:rotate=0
-
- # Enable Virtual Keyboard
- export QT_IM_MODULE=qtvirtualkeyboard
- export QT_VIRTUALKEYBOARD_STYLE=default
- export QT_VIRTUALKEYBOARD_LAYOUT_PATH=/usr/share/qt5/qtvirtualkeyboard/layouts
-
- echo "Starting with EGLFS platform and virtual keyboard..."
- python main.py
- }
- # Check for DRM device (needed for EGLFS)
- if [ -e /dev/dri/card0 ] || [ -e /dev/dri/card1 ]; then
- echo "DRM device found, using EGLFS"
- run_eglfs
- else
- echo "No DRM device, using LinuxFB"
- run_linuxfb
- fi
- echo "Application exited at $(date)"
- EOF
-
- chmod +x "$START_SCRIPT"
- echo -e "${GREEN}Startup script created: $START_SCRIPT${NC}"
- }
- # Function to create systemd service
- create_systemd_service() {
- echo -e "${GREEN}Creating systemd service...${NC}"
-
- local SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
-
- cat << EOF | sudo tee "$SERVICE_FILE" > /dev/null
- [Unit]
- Description=Dune Weaver Touch Kiosk Mode
- After=multi-user.target graphical.target
- Wants=network-online.target
- After=network-online.target
- [Service]
- Type=simple
- User=$USER_NAME
- Group=$USER_NAME
- WorkingDirectory=$APP_DIR
- # Auto-restart on failure
- Restart=always
- RestartSec=10
- # Start script
- ExecStart=$APP_DIR/start_kiosk.sh
- # Stop timeout
- TimeoutStopSec=10
- # Logging
- StandardOutput=journal
- StandardError=journal
- [Install]
- WantedBy=multi-user.target
- EOF
-
- # Reload systemd and enable service
- sudo systemctl daemon-reload
- sudo systemctl enable "${SERVICE_NAME}.service"
-
- echo -e "${GREEN}Systemd service created and enabled${NC}"
- }
- # Function to create uninstall script
- create_uninstall_script() {
- echo -e "${GREEN}Creating uninstall script...${NC}"
-
- cat << 'EOF' > "$APP_DIR/uninstall_kiosk.sh"
- #!/bin/bash
- # Dune Weaver Touch - Kiosk Mode Uninstall Script
- set -e
- RED='\033[0;31m'
- GREEN='\033[0;32m'
- YELLOW='\033[1;33m'
- NC='\033[0m'
- SERVICE_NAME="dune-weaver-kiosk"
- echo -e "${YELLOW}Uninstalling Dune Weaver Kiosk Mode...${NC}"
- # Stop and disable service
- if systemctl list-units --full -all | grep -Fq "${SERVICE_NAME}.service"; then
- echo "Stopping and disabling service..."
- sudo systemctl stop "${SERVICE_NAME}.service" 2>/dev/null || true
- sudo systemctl disable "${SERVICE_NAME}.service" 2>/dev/null || true
- sudo rm -f "/etc/systemd/system/${SERVICE_NAME}.service"
- sudo systemctl daemon-reload
- echo -e "${GREEN}Service removed${NC}"
- fi
- # Remove startup script
- if [ -f "start_kiosk.sh" ]; then
- rm -f "start_kiosk.sh"
- echo -e "${GREEN}Startup script removed${NC}"
- fi
- # Restore boot config if backup exists
- LATEST_BACKUP=$(ls -t /boot/config.txt.backup.* 2>/dev/null | head -n1)
- if [ -n "$LATEST_BACKUP" ]; then
- echo -e "${YELLOW}Found backup: $LATEST_BACKUP${NC}"
- read -p "Restore boot configuration from backup? (y/n): " -n 1 -r
- echo
- if [[ $REPLY =~ ^[Yy]$ ]]; then
- sudo cp "$LATEST_BACKUP" /boot/config.txt
- echo -e "${GREEN}Boot configuration restored${NC}"
- echo -e "${YELLOW}Reboot required for changes to take effect${NC}"
- fi
- fi
- echo -e "${GREEN}Kiosk mode uninstalled successfully${NC}"
- echo -e "${YELLOW}You may want to reboot your Raspberry Pi${NC}"
- EOF
-
- chmod +x "$APP_DIR/uninstall_kiosk.sh"
- echo -e "${GREEN}Uninstall script created: $APP_DIR/uninstall_kiosk.sh${NC}"
- }
- # Function to test the display
- test_display() {
- echo -e "${GREEN}Testing display configuration...${NC}"
-
- # Check framebuffer
- if [ -e /dev/fb0 ]; then
- echo -e "${GREEN}✓ Framebuffer device found${NC}"
- fbset -i | head -5
- else
- echo -e "${RED}✗ No framebuffer device found${NC}"
- fi
-
- # Check for DRM device
- if [ -e /dev/dri/card0 ] || [ -e /dev/dri/card1 ]; then
- echo -e "${GREEN}✓ DRM device found${NC}"
- ls -la /dev/dri/
- else
- echo -e "${YELLOW}! No DRM device (normal for Pi 3)${NC}"
- fi
-
- # Check touch input
- echo -e "${GREEN}Available input devices:${NC}"
- ls -la /dev/input/event* 2>/dev/null || echo "No input devices found"
- }
- # Main installation function
- install_kiosk() {
- echo -e "${GREEN}Starting Kiosk Mode Installation...${NC}"
-
- # Check if running on Raspberry Pi
- if ! grep -q "Raspberry Pi" /proc/cpuinfo; then
- echo -e "${YELLOW}Warning: This doesn't appear to be a Raspberry Pi${NC}"
- read -p "Continue anyway? (y/n): " -n 1 -r
- echo
- if [[ ! $REPLY =~ ^[Yy]$ ]]; then
- exit 1
- fi
- fi
-
- # Check if virtual environment exists
- if [ ! -f "$VENV_PATH" ]; then
- echo -e "${RED}Error: Virtual environment not found at $VENV_PATH${NC}"
- echo "Please run this script from the dune-weaver-touch directory"
- exit 1
- fi
-
- # Install steps
- install_dependencies
- setup_boot_config
- create_startup_script
- create_systemd_service
- create_uninstall_script
- test_display
-
- echo -e "${GREEN}"
- echo "================================================"
- echo " Installation Complete!"
- echo "================================================"
- echo -e "${NC}"
- echo
- echo "Next steps:"
- echo "1. Reboot your Raspberry Pi:"
- echo " ${GREEN}sudo reboot${NC}"
- echo
- echo "2. The kiosk will start automatically after reboot"
- echo
- echo "3. To manually control the service:"
- echo " Start: ${GREEN}sudo systemctl start ${SERVICE_NAME}${NC}"
- echo " Stop: ${GREEN}sudo systemctl stop ${SERVICE_NAME}${NC}"
- echo " Status: ${GREEN}sudo systemctl status ${SERVICE_NAME}${NC}"
- echo " Logs: ${GREEN}journalctl -u ${SERVICE_NAME} -f${NC}"
- echo
- echo "4. To uninstall:"
- echo " ${GREEN}./uninstall_kiosk.sh${NC}"
- echo
-
- read -p "Reboot now? (y/n): " -n 1 -r
- echo
- if [[ $REPLY =~ ^[Yy]$ ]]; then
- sudo reboot
- fi
- }
- # Parse command line arguments
- case "${1:-}" in
- uninstall)
- if [ -f "$APP_DIR/uninstall_kiosk.sh" ]; then
- "$APP_DIR/uninstall_kiosk.sh"
- else
- echo -e "${RED}Uninstall script not found${NC}"
- exit 1
- fi
- ;;
- test)
- test_display
- ;;
- status)
- sudo systemctl status "${SERVICE_NAME}.service"
- ;;
- *)
- install_kiosk
- ;;
- esac
|