1
0

install.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. #!/bin/bash
  2. # Dune Weaver Touch - One-Command Installer
  3. # This script sets up everything needed to run Dune Weaver Touch on boot
  4. set -e
  5. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  6. ACTUAL_USER="${SUDO_USER:-$USER}"
  7. USER_HOME=$(eval echo ~$ACTUAL_USER)
  8. echo "🎯 Dune Weaver Touch - Complete Installation"
  9. echo "============================================="
  10. echo "App directory: $SCRIPT_DIR"
  11. echo "User: $ACTUAL_USER"
  12. echo ""
  13. # Check if running as root
  14. if [ "$EUID" -ne 0 ]; then
  15. echo "❌ This installer must be run with sudo privileges"
  16. echo ""
  17. echo "Usage: sudo ./install.sh"
  18. echo ""
  19. exit 1
  20. fi
  21. echo "🔧 Installing system components..."
  22. echo ""
  23. # Function to install system scripts
  24. install_scripts() {
  25. echo "📄 Installing system scripts..."
  26. local scripts=("screen-on" "screen-off" "touch-monitor")
  27. for script in "${scripts[@]}"; do
  28. local source_path="$SCRIPT_DIR/scripts/$script"
  29. local target_path="/usr/local/bin/$script"
  30. if [ -f "$source_path" ]; then
  31. cp "$source_path" "$target_path"
  32. chmod 755 "$target_path"
  33. chown root:root "$target_path"
  34. echo " ✅ $script → $target_path"
  35. else
  36. echo " ⚠️ $script not found at $source_path"
  37. fi
  38. done
  39. echo " 📄 System scripts installed"
  40. }
  41. # Function to setup systemd service
  42. setup_systemd() {
  43. echo "🚀 Setting up systemd service..."
  44. # Update paths in the service file
  45. sed "s|/home/pi/dune-weaver-touch|$SCRIPT_DIR|g" "$SCRIPT_DIR/dune-weaver-touch.service" > /tmp/dune-weaver-touch.service
  46. sed -i "s|User=pi|User=$ACTUAL_USER|g" /tmp/dune-weaver-touch.service
  47. sed -i "s|Group=pi|Group=$ACTUAL_USER|g" /tmp/dune-weaver-touch.service
  48. # Copy service file
  49. cp /tmp/dune-weaver-touch.service /etc/systemd/system/
  50. # Enable service
  51. systemctl daemon-reload
  52. systemctl enable dune-weaver-touch.service
  53. echo " 🚀 Systemd service installed and enabled"
  54. }
  55. # Function to configure boot settings for DSI display
  56. configure_boot_settings() {
  57. echo "🖥️ Configuring boot settings for DSI display..."
  58. local CONFIG_FILE="/boot/firmware/config.txt"
  59. # Fallback to old path if new path doesn't exist
  60. [ ! -f "$CONFIG_FILE" ] && CONFIG_FILE="/boot/config.txt"
  61. if [ ! -f "$CONFIG_FILE" ]; then
  62. echo " ⚠️ config.txt not found, skipping boot configuration"
  63. return
  64. fi
  65. # Backup config.txt
  66. cp "$CONFIG_FILE" "${CONFIG_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
  67. echo " ✅ Backed up config.txt"
  68. # Remove old/conflicting KMS settings
  69. sed -i '/dtoverlay=vc4-fkms-v3d/d' "$CONFIG_FILE"
  70. sed -i '/dtoverlay=vc4-xfkms-v3d/d' "$CONFIG_FILE"
  71. # Add full KMS if not present
  72. if ! grep -q "dtoverlay=vc4-kms-v3d" "$CONFIG_FILE"; then
  73. # Find [all] section or add at end
  74. if grep -q "^\[all\]" "$CONFIG_FILE"; then
  75. sed -i '/^\[all\]/a dtoverlay=vc4-kms-v3d' "$CONFIG_FILE"
  76. else
  77. echo -e "\n[all]\ndtoverlay=vc4-kms-v3d" >> "$CONFIG_FILE"
  78. fi
  79. echo " ✅ Enabled full KMS (vc4-kms-v3d) for eglfs support"
  80. else
  81. echo " ℹ️ Full KMS already enabled"
  82. fi
  83. # Add GPU memory if not present
  84. if ! grep -q "gpu_mem=" "$CONFIG_FILE"; then
  85. echo "gpu_mem=128" >> "$CONFIG_FILE"
  86. echo " ✅ Set GPU memory to 128MB"
  87. else
  88. echo " ℹ️ GPU memory already configured"
  89. fi
  90. # Disable splash screens for cleaner boot
  91. if ! grep -q "disable_splash=1" "$CONFIG_FILE"; then
  92. echo "disable_splash=1" >> "$CONFIG_FILE"
  93. echo " ✅ Disabled rainbow splash"
  94. else
  95. echo " ℹ️ Rainbow splash already disabled"
  96. fi
  97. echo " 🖥️ Boot configuration updated for eglfs"
  98. }
  99. # Function to setup touch rotation via udev rule
  100. setup_touch_rotation() {
  101. echo "👆 Setting up touchscreen rotation..."
  102. local UDEV_RULE_FILE="/etc/udev/rules.d/99-ft5x06-rotate.rules"
  103. # Create udev rule for FT5x06 touch controller (180° rotation)
  104. cat > "$UDEV_RULE_FILE" << 'EOF'
  105. # Rotate FT5x06 touchscreen 180 degrees using libinput calibration matrix
  106. # Matrix format: a b c d e f 0 0 1
  107. # For 180° rotation: -1 0 1 0 -1 1 0 0 1
  108. # This inverts both X and Y axes (equivalent to 180° rotation)
  109. SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="*generic ft5x06*", \
  110. ENV{LIBINPUT_CALIBRATION_MATRIX}="-1 0 1 0 -1 1 0 0 1"
  111. EOF
  112. chmod 644 "$UDEV_RULE_FILE"
  113. echo " ✅ Touch rotation udev rule created: $UDEV_RULE_FILE"
  114. # Reload udev rules
  115. udevadm control --reload-rules
  116. udevadm trigger
  117. echo " ✅ Udev rules reloaded"
  118. echo " 👆 Touch rotation configured (180°)"
  119. }
  120. # Function to hide mouse cursor
  121. hide_mouse_cursor() {
  122. echo "🖱️ Configuring mouse cursor hiding..."
  123. # Install unclutter for hiding mouse cursor when idle
  124. echo " 📦 Installing unclutter..."
  125. apt install -y unclutter > /dev/null 2>&1
  126. # Create autostart directory if it doesn't exist
  127. local AUTOSTART_DIR="$USER_HOME/.config/autostart"
  128. mkdir -p "$AUTOSTART_DIR"
  129. chown -R "$ACTUAL_USER:$ACTUAL_USER" "$USER_HOME/.config"
  130. # Create unclutter autostart entry
  131. cat > "$AUTOSTART_DIR/unclutter.desktop" << 'EOF'
  132. [Desktop Entry]
  133. Type=Application
  134. Name=Unclutter
  135. Comment=Hide mouse cursor when idle
  136. Exec=unclutter -idle 0.1 -root
  137. Hidden=false
  138. NoDisplay=false
  139. X-GNOME-Autostart-enabled=true
  140. EOF
  141. chown "$ACTUAL_USER:$ACTUAL_USER" "$AUTOSTART_DIR/unclutter.desktop"
  142. echo " 🖱️ Mouse cursor hiding configured"
  143. }
  144. # Function to setup kiosk optimizations
  145. setup_kiosk_optimizations() {
  146. echo "🖥️ Setting up kiosk optimizations..."
  147. local CMDLINE_FILE="/boot/firmware/cmdline.txt"
  148. [ ! -f "$CMDLINE_FILE" ] && CMDLINE_FILE="/boot/cmdline.txt"
  149. # Configure cmdline.txt for display and boot
  150. if [ -f "$CMDLINE_FILE" ]; then
  151. cp "$CMDLINE_FILE" "${CMDLINE_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
  152. # Add video parameter for DSI display with rotation
  153. if ! grep -q "video=DSI-1:800x480@60,rotate=180" "$CMDLINE_FILE"; then
  154. sed -i 's/$/ video=DSI-1:800x480@60,rotate=180/' "$CMDLINE_FILE"
  155. echo " ✅ DSI display configuration added (800x480@60, rotated 180°)"
  156. else
  157. echo " ℹ️ DSI display configuration already present"
  158. fi
  159. # Add quiet splash for cleaner boot
  160. if ! grep -q "quiet splash" "$CMDLINE_FILE"; then
  161. sed -i 's/$/ quiet splash/' "$CMDLINE_FILE"
  162. echo " ✅ Boot splash enabled"
  163. else
  164. echo " ℹ️ Boot splash already enabled"
  165. fi
  166. fi
  167. # Note about auto-login - let user configure manually
  168. echo " ℹ️ Auto-login configuration skipped (manual setup recommended)"
  169. echo " 🖥️ Kiosk optimizations applied"
  170. }
  171. # Function to setup Python virtual environment and install dependencies
  172. setup_python_environment() {
  173. echo "🐍 Setting up Python virtual environment..."
  174. # Install system Qt6 and PySide6 packages for full eglfs support
  175. echo " 📦 Installing system Qt6 and PySide6 packages..."
  176. apt update
  177. apt install -y \
  178. python3-pyside6.qtcore \
  179. python3-pyside6.qtgui \
  180. python3-pyside6.qtqml \
  181. python3-pyside6.qtquick \
  182. python3-pyside6.qtquickcontrols2 \
  183. python3-pyside6.qtquickwidgets \
  184. python3-pyside6.qtwebsockets \
  185. python3-pyside6.qtnetwork \
  186. qml6-module-qtquick \
  187. qml6-module-qtquick-controls \
  188. qml6-module-qtquick-layouts \
  189. qml6-module-qtquick-window \
  190. qml6-module-qtquick-dialogs \
  191. qml6-module-qt-labs-qmlmodels \
  192. qt6-virtualkeyboard-plugin \
  193. qml6-module-qtquick-virtualkeyboard \
  194. qt6-base-dev \
  195. qt6-declarative-dev \
  196. libqt6opengl6 \
  197. libqt6core5compat6 \
  198. libqt6network6 \
  199. libqt6websockets6 > /dev/null 2>&1
  200. echo " ✅ System Qt6/PySide6 packages installed"
  201. # Create virtual environment with system site packages
  202. if [ ! -d "$SCRIPT_DIR/venv" ]; then
  203. echo " 📦 Creating virtual environment with system site packages..."
  204. python3 -m venv --system-site-packages "$SCRIPT_DIR/venv" || {
  205. echo " ⚠️ Could not create virtual environment. Installing python3-venv..."
  206. apt install -y python3-venv python3-full
  207. python3 -m venv --system-site-packages "$SCRIPT_DIR/venv"
  208. }
  209. else
  210. echo " ℹ️ Virtual environment already exists"
  211. fi
  212. # Install non-Qt dependencies
  213. echo " 📦 Installing Python dependencies (qasync, aiohttp, Pillow)..."
  214. "$SCRIPT_DIR/venv/bin/python" -m pip install --upgrade pip > /dev/null 2>&1
  215. "$SCRIPT_DIR/venv/bin/pip" install \
  216. qasync>=0.27.0 \
  217. aiohttp>=3.9.0 \
  218. Pillow>=10.0.0 > /dev/null 2>&1
  219. # Change ownership to the actual user (not root)
  220. chown -R "$ACTUAL_USER:$ACTUAL_USER" "$SCRIPT_DIR/venv"
  221. echo " 🐍 Python virtual environment ready"
  222. }
  223. # Main installation process
  224. echo "Starting complete installation..."
  225. echo ""
  226. # Install everything
  227. setup_python_environment
  228. install_scripts
  229. setup_systemd
  230. configure_boot_settings
  231. setup_touch_rotation
  232. hide_mouse_cursor
  233. setup_kiosk_optimizations
  234. echo ""
  235. echo "🎉 Installation Complete!"
  236. echo "========================"
  237. echo ""
  238. echo "✅ Python virtual environment created at: $SCRIPT_DIR/venv"
  239. echo "✅ System scripts installed in /usr/local/bin/"
  240. echo "✅ Systemd service configured for auto-start"
  241. echo "✅ Mouse cursor hiding configured (Qt + unclutter)"
  242. echo "✅ Kiosk optimizations applied"
  243. echo ""
  244. echo "🔧 Service Management:"
  245. echo " Start now: sudo systemctl start dune-weaver-touch"
  246. echo " Stop: sudo systemctl stop dune-weaver-touch"
  247. echo " Status: sudo systemctl status dune-weaver-touch"
  248. echo " Logs: sudo journalctl -u dune-weaver-touch -f"
  249. echo ""
  250. echo "🚀 Next Steps:"
  251. echo " 1. ${YELLOW}⚠️ REBOOT REQUIRED${NC} for config.txt changes (vc4-kms-v3d) to take effect"
  252. echo " 2. Configure auto-login (recommended for kiosk mode):"
  253. echo " sudo ./setup-autologin.sh (automated setup)"
  254. echo " OR manually: sudo raspi-config → System Options → Boot/Auto Login → Desktop Autologin"
  255. echo " 3. After reboot, the app will start automatically on boot via systemd service"
  256. echo " 4. Check the logs if you encounter any issues: sudo journalctl -u dune-weaver-touch -f"
  257. echo ""
  258. echo "💡 To start the service now without rebooting:"
  259. echo " sudo systemctl start dune-weaver-touch"
  260. echo ""
  261. echo "🛠️ For development/testing (run manually):"
  262. echo " cd $SCRIPT_DIR"
  263. echo " ./run.sh"
  264. echo ""
  265. echo "⚙️ To change boot/login settings later:"
  266. echo " sudo ./configure-boot.sh"
  267. echo ""
  268. # Ask if user wants to start now
  269. read -p "🤔 Would you like to start the service now? (y/N): " -n 1 -r
  270. echo
  271. if [[ $REPLY =~ ^[Yy]$ ]]; then
  272. echo "🚀 Starting Dune Weaver Touch service..."
  273. systemctl start dune-weaver-touch
  274. sleep 2
  275. systemctl status dune-weaver-touch --no-pager -l
  276. echo ""
  277. echo "✅ Service started! Check the status above."
  278. fi
  279. echo ""
  280. echo "🎯 Installation completed successfully!"