From 18353675600a1bae3e7f72406af980cd053367bb Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Wed, 4 Jun 2025 14:24:57 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9A=20Improved=20X11=20framebuffer=20s?= =?UTF-8?q?cript=20and=20related=20files=20=F0=9F=96=B1=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/models.cpython-313.pyc | Bin 0 -> 84646 bytes database/myp.db-shm | Bin 32768 -> 32768 bytes fix-x11-framebuffer.sh | 237 ++++++++++++++++++++++ logs/app/app.log | 20 ++ setup.sh | 309 +++++++++++++++++++++++++++++ 5 files changed, 566 insertions(+) create mode 100644 __pycache__/models.cpython-313.pyc create mode 100644 fix-x11-framebuffer.sh diff --git a/__pycache__/models.cpython-313.pyc b/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f0762d7fff3b9a5c0aa5e45882ddc6e6f7a80715 GIT binary patch literal 84646 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 ysp^47fdReYnHg9%3Vvl}WZfvpY7PLeS1eut delta 18 ZcmZo@U}|V!VwQNMyK!Nx)5Z-8Yym%+2VMXG diff --git a/fix-x11-framebuffer.sh b/fix-x11-framebuffer.sh new file mode 100644 index 0000000..c3fc3c4 --- /dev/null +++ b/fix-x11-framebuffer.sh @@ -0,0 +1,237 @@ +#!/bin/bash + +# =================================================================== +# MYP X11 Framebuffer-Fix für Raspberry Pi +# Behebt den "Cannot run in framebuffer mode" Fehler +# =================================================================== + +set -euo pipefail + +# Farben für Ausgabe +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +log() { + echo -e "${GREEN}[$(date '+%H:%M:%S')] $1${NC}" +} + +warning() { + echo -e "${YELLOW}[WARNUNG] $1${NC}" +} + +error() { + echo -e "${RED}[FEHLER] $1${NC}" + exit 1 +} + +info() { + echo -e "${BLUE}[INFO] $1${NC}" +} + +# Prüfe root-Berechtigung +if [ "$EUID" -ne 0 ]; then + error "Dieses Skript muss als Root ausgeführt werden: sudo $0" +fi + +log "=== X11 FRAMEBUFFER-FIX FÜR RASPBERRY PI ===" + +# Stoppe laufende X-Server +log "Stoppe laufende X-Server..." +pkill -f "X :0" 2>/dev/null || true +pkill -f "Xorg" 2>/dev/null || true +pkill -f "xinit" 2>/dev/null || true +pkill -f "chromium" 2>/dev/null || true +sleep 2 + +# Erstelle X11-Konfigurationsverzeichnis +log "Erstelle X11-Konfiguration..." +mkdir -p /etc/X11/xorg.conf.d + +# Erstelle Framebuffer-Fix-Konfiguration +cat > /etc/X11/xorg.conf.d/99-fbdev.conf << 'EOF' +# X11 Konfiguration für Raspberry Pi - behebt Framebuffer-Fehler +Section "Device" + Identifier "Raspberry Pi FBDEV" + Driver "fbdev" + Option "fbdev" "/dev/fb0" + Option "SwapbuffersWait" "true" +EndSection + +Section "Screen" + Identifier "Primary Screen" + Device "Raspberry Pi FBDEV" + DefaultDepth 24 + SubSection "Display" + Depth 24 + Modes "1920x1080" "1680x1050" "1600x900" "1280x1024" "1280x800" "1024x768" + EndSubSection +EndSection + +Section "ServerLayout" + Identifier "Default Layout" + Screen "Primary Screen" +EndSection + +Section "ServerFlags" + Option "BlankTime" "0" + Option "StandbyTime" "0" + Option "SuspendTime" "0" + Option "OffTime" "0" + Option "DPMS" "false" +EndSection +EOF + +# Alternative Modesetting-Konfiguration +cat > /etc/X11/xorg.conf.d/20-modesetting.conf << 'EOF' +# Alternative Modesetting-Konfiguration +Section "Device" + Identifier "Raspberry Pi Modesetting" + Driver "modesetting" + Option "AccelMethod" "none" +EndSection +EOF + +# Installiere fehlende Video-Treiber +log "Installiere Video-Treiber..." +apt-get update +apt-get install -y xserver-xorg-video-fbturbo 2>/dev/null || { + # Fallback zu Standard-Treibern + apt-get install -y xserver-xorg-video-all 2>/dev/null || true +} + +# Erstelle X11-Start-Wrapper +log "Erstelle X11-Start-Wrapper..." +cat > /usr/local/bin/start-x11-kiosk << 'EOF' +#!/bin/bash + +# X11 Kiosk-Start-Wrapper für Raspberry Pi +export DISPLAY=:0 +export XAUTHORITY=/home/kiosk/.Xauthority + +# Erstelle .Xauthority +if [ ! -f "$XAUTHORITY" ]; then + touch "$XAUTHORITY" + chown kiosk:kiosk "$XAUTHORITY" + chmod 600 "$XAUTHORITY" +fi + +# Stoppe alte X-Server +pkill -f "X :0" 2>/dev/null || true +pkill -f "Xorg" 2>/dev/null || true +sleep 2 + +echo "Starte X-Server..." + +# Versuche verschiedene Start-Methoden +if ! xinit /home/kiosk/.xinitrc -- :0 vt7 -novtswitch -nolisten tcp -dpi 96 2>/tmp/x11-error.log; then + echo "Methode 1 fehlgeschlagen, versuche Alternative..." + + if ! xinit /home/kiosk/.xinitrc -- :0 vt7 -config /etc/X11/xorg.conf.d/99-fbdev.conf -ignoreABI 2>>/tmp/x11-error.log; then + echo "Methode 2 fehlgeschlagen, versuche Fallback..." + xinit /home/kiosk/.xinitrc -- :0 2>>/tmp/x11-error.log + fi +fi + +if [ -f /tmp/x11-error.log ]; then + echo "X11 Fehler-Log:" + tail -20 /tmp/x11-error.log +fi +EOF + +chmod +x /usr/local/bin/start-x11-kiosk + +# Erstelle einfaches .xinitrc für kiosk +log "Erstelle korrigiertes .xinitrc..." +cat > /home/kiosk/.xinitrc << 'EOF' +#!/bin/bash + +# Fehlerlog +exec 2>/tmp/xinitrc-error.log + +# X11 Einstellungen +xset s off +xset s noblank +xset -dpms + +# Window Manager +openbox-session & +sleep 2 + +# Browser starten +BROWSER="" +if command -v chromium >/dev/null 2>&1; then + BROWSER="chromium" +elif command -v chromium-browser >/dev/null 2>&1; then + BROWSER="chromium-browser" +else + BROWSER="firefox-esr" +fi + +# Starte Browser mit GPU-Deaktivierung +exec $BROWSER \ + --kiosk \ + --no-sandbox \ + --disable-gpu \ + --disable-software-rasterizer \ + --disable-dev-shm-usage \ + --no-first-run \ + --start-fullscreen \ + http://localhost:5000 +EOF + +chmod +x /home/kiosk/.xinitrc +chown kiosk:kiosk /home/kiosk/.xinitrc + +# Konfiguriere Raspberry Pi Boot-Einstellungen +if [ -f /boot/config.txt ]; then + log "Konfiguriere Raspberry Pi GPU-Einstellungen..." + + # Backup + cp /boot/config.txt /boot/config.txt.backup + + # GPU-Einstellungen + if ! grep -q "^gpu_mem=" /boot/config.txt; then + echo "gpu_mem=128" >> /boot/config.txt + fi + + if ! grep -q "^hdmi_force_hotplug=" /boot/config.txt; then + cat >> /boot/config.txt << 'EOF' + +# X11 Kiosk-Modus Optimierungen +hdmi_force_hotplug=1 +hdmi_drive=2 +config_hdmi_boost=4 +disable_overscan=1 +framebuffer_width=1920 +framebuffer_height=1080 +framebuffer_depth=32 +framebuffer_ignore_alpha=1 +EOF + fi +fi + +log "✅ X11 Framebuffer-Fix installiert!" +info "" +info "📋 Was wurde konfiguriert:" +info " - X11 fbdev-Konfiguration erstellt" +info " - Video-Treiber installiert" +info " - X11-Start-Wrapper erstellt: /usr/local/bin/start-x11-kiosk" +info " - GPU-Einstellungen optimiert" +info "" +info "🔧 Nächste Schritte:" +info " 1. System neustarten: sudo reboot" +info " 2. Als kiosk-User einloggen" +info " 3. X11 wird automatisch mit den Fixes starten" +info "" +info "💡 Manueller Test:" +info " su - kiosk" +info " /usr/local/bin/start-x11-kiosk" +info "" + +# Prüfe ob Neustart erforderlich +if [ -f /boot/config.txt.backup ]; then + warning "⚠️ Boot-Konfiguration geändert - Neustart erforderlich!" +fi \ No newline at end of file diff --git a/logs/app/app.log b/logs/app/app.log index 37ee5cc..8bd6fe8 100644 --- a/logs/app/app.log +++ b/logs/app/app.log @@ -3930,3 +3930,23 @@ WHERE jobs.status = ?) AS anon_1] 2025-06-04 09:27:18 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O) 2025-06-04 09:38:42 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O) 2025-06-04 09:38:44 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O) +2025-06-04 14:24:38 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\manage-your-printer\database\myp.db +2025-06-04 14:24:42 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O) +2025-06-04 14:24:42 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen +2025-06-04 14:24:42 - [app] app - [INFO] INFO - 📋 Standard-Konfiguration verwendet +2025-06-04 14:24:42 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert +2025-06-04 14:24:42 - [app] app - [INFO] INFO - ✅ Error-Recovery-Monitoring gestartet +2025-06-04 14:24:42 - [app] app - [INFO] INFO - ✅ System-Control-Manager initialisiert +2025-06-04 14:24:42 - [app] app - [WARNING] WARNING - ⚠️ Kiosk-Service nicht gefunden - Kiosk-Funktionen eventuell eingeschränkt +2025-06-04 14:24:42 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen... +2025-06-04 14:24:42 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert +2025-06-04 14:24:42 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden +2025-06-04 14:24:42 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt. +2025-06-04 14:24:42 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen +2025-06-04 14:24:42 - [app] app - [INFO] INFO - 📋 Standard-Konfiguration aktiv (keine Optimierungen) +2025-06-04 14:24:42 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung... +2025-06-04 14:24:42 - [app] app - [INFO] INFO - ℹ️ Keine Drucker zur Initialisierung gefunden +2025-06-04 14:24:42 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung +2025-06-04 14:24:42 - [app] app - [INFO] INFO - Job-Scheduler gestartet +2025-06-04 14:24:42 - [app] app - [INFO] INFO - 🔧 Starte Debug-Server auf 0.0.0.0:5000 (HTTP) +2025-06-04 14:24:42 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert diff --git a/setup.sh b/setup.sh index 5d2ecc0..869541f 100644 --- a/setup.sh +++ b/setup.sh @@ -1241,6 +1241,209 @@ install_minimal_x11() { log "✅ Minimale X11-Umgebung installiert" } +# =========================== X11 KONFIGURATION FÜR RASPBERRY PI =========================== +configure_x11_for_raspberry_pi() { + log "=== KONFIGURIERE X11 FÜR RASPBERRY PI ===" + + progress "Erstelle X11-Konfiguration für Raspberry Pi..." + + # Erstelle xorg.conf.d Verzeichnis + mkdir -p /etc/X11/xorg.conf.d + + # Erstelle 99-fbdev.conf um Framebuffer-Fehler zu beheben + cat > /etc/X11/xorg.conf.d/99-fbdev.conf << 'XORGEOF' +# X11 Konfiguration für Raspberry Pi - behebt Framebuffer-Fehler +Section "Device" + Identifier "Raspberry Pi FBDEV" + Driver "fbdev" + Option "fbdev" "/dev/fb0" + Option "SwapbuffersWait" "true" +EndSection + +Section "Screen" + Identifier "Primary Screen" + Device "Raspberry Pi FBDEV" + DefaultDepth 24 + SubSection "Display" + Depth 24 + Modes "1920x1080" "1680x1050" "1600x900" "1280x1024" "1280x800" "1024x768" + EndSubSection +EndSection + +Section "ServerLayout" + Identifier "Default Layout" + Screen "Primary Screen" +EndSection + +Section "ServerFlags" + Option "BlankTime" "0" + Option "StandbyTime" "0" + Option "SuspendTime" "0" + Option "OffTime" "0" + Option "DPMS" "false" +EndSection +XORGEOF + + # Alternative: Verwende modesetting Treiber statt fbdev + cat > /etc/X11/xorg.conf.d/20-modesetting.conf << 'MODESETEOF' +# Alternative Modesetting-Konfiguration +Section "Device" + Identifier "Raspberry Pi Modesetting" + Driver "modesetting" + Option "AccelMethod" "none" +EndSection +MODESETEOF + + # Erstelle Wrapper-Skript für X11-Start mit korrekten Parametern + cat > /usr/local/bin/start-x11-kiosk << 'KIOSKSTARTEOF' +#!/bin/bash + +# X11 Kiosk-Start-Wrapper für Raspberry Pi +# Behebt Framebuffer und Permission-Probleme + +export DISPLAY=:0 +export XAUTHORITY=/home/kiosk/.Xauthority + +# Erstelle .Xauthority falls nicht vorhanden +if [ ! -f "$XAUTHORITY" ]; then + touch "$XAUTHORITY" + chown kiosk:kiosk "$XAUTHORITY" + chmod 600 "$XAUTHORITY" +fi + +# Stoppe eventuell laufende X-Server +pkill -f "X :0" 2>/dev/null || true +pkill -f "Xorg" 2>/dev/null || true +sleep 2 + +# Versuche verschiedene X-Server Start-Methoden +echo "Starte X-Server für Kiosk-Modus..." + +# Methode 1: Mit vt und novtswitch (empfohlen für Raspberry Pi) +if ! xinit /home/kiosk/.xinitrc -- :0 vt7 -novtswitch -nolisten tcp -dpi 96 2>/tmp/x11-error.log; then + echo "Methode 1 fehlgeschlagen, versuche Alternative..." + + # Methode 2: Mit config und ignoreABI + if ! xinit /home/kiosk/.xinitrc -- :0 vt7 -config /etc/X11/xorg.conf.d/99-fbdev.conf -ignoreABI 2>>/tmp/x11-error.log; then + echo "Methode 2 fehlgeschlagen, versuche Fallback..." + + # Methode 3: Minimaler Start + xinit /home/kiosk/.xinitrc -- :0 2>>/tmp/x11-error.log + fi +fi + +# Fehlerlog anzeigen bei Problem +if [ -f /tmp/x11-error.log ]; then + echo "X11 Fehler-Log:" + tail -20 /tmp/x11-error.log +fi +KIOSKSTARTEOF + + chmod +x /usr/local/bin/start-x11-kiosk + + # Installiere fehlende Video-Treiber + progress "Installiere Video-Treiber für Raspberry Pi..." + apt-get install -y xserver-xorg-video-fbturbo 2>/dev/null || { + # Fallback zu Standard-Treibern + apt-get install -y xserver-xorg-video-all 2>/dev/null || true + } + + # Raspberry Pi spezifische Video-Treiber + if [ -f /boot/config.txt ]; then + progress "Konfiguriere Raspberry Pi GPU-Einstellungen..." + + # Backup config.txt + cp /boot/config.txt /boot/config.txt.backup + + # GPU-Speicher erhöhen für bessere Grafik-Performance + if ! grep -q "^gpu_mem=" /boot/config.txt; then + echo "gpu_mem=128" >> /boot/config.txt + fi + + # HDMI-Einstellungen für bessere Kompatibilität + if ! grep -q "^hdmi_force_hotplug=" /boot/config.txt; then + cat >> /boot/config.txt << 'BOOTEOF' + +# X11 Kiosk-Modus Optimierungen +hdmi_force_hotplug=1 +hdmi_drive=2 +config_hdmi_boost=4 +disable_overscan=1 +framebuffer_width=1920 +framebuffer_height=1080 +framebuffer_depth=32 +framebuffer_ignore_alpha=1 +BOOTEOF + fi + fi + + # Erstelle alternatives .xinitrc für kiosk User + cat > /home/kiosk/.xinitrc-fixed << 'XINITRCEOF' +#!/bin/bash + +# Fehlerbehandlung +set -e +exec 2>/tmp/xinitrc-error.log + +# X11 Einstellungen +xset s off +xset s noblank +xset -dpms + +# Mauszeiger verstecken +unclutter -idle 0.1 -root -noevents & + +# Window Manager starten (lightweight) +openbox-session & + +# Warte kurz +sleep 2 + +# Browser starten +if command -v chromium >/dev/null 2>&1; then + BROWSER="chromium" +elif command -v chromium-browser >/dev/null 2>&1; then + BROWSER="chromium-browser" +else + BROWSER="firefox-esr" +fi + +# Starte Browser im Kiosk-Modus +exec $BROWSER \ + --kiosk \ + --no-sandbox \ + --disable-gpu-sandbox \ + --disable-software-rasterizer \ + --disable-dev-shm-usage \ + --disable-setuid-sandbox \ + --disable-gpu \ + --no-first-run \ + --noerrdialogs \ + --disable-infobars \ + --start-fullscreen \ + http://localhost:5000 +XINITRCEOF + + chmod +x /home/kiosk/.xinitrc-fixed + chown kiosk:kiosk /home/kiosk/.xinitrc-fixed + + # Aktualisiere die .bashrc für den alternativen Start + cat > /home/kiosk/.bashrc-kiosk << 'BASHRCEOF4' +# Kiosk-Autostart mit X11-Fixes +if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then + echo "Starte Kiosk-Modus mit X11-Fixes..." + + # Verwende das neue Start-Skript + exec /usr/local/bin/start-x11-kiosk +fi +BASHRCEOF4 + + log "✅ X11-Konfiguration für Raspberry Pi erstellt" + info " 📁 Konfiguration: /etc/X11/xorg.conf.d/" + info " 🚀 Start-Skript: /usr/local/bin/start-x11-kiosk" + info " 🔧 Alternative .xinitrc: /home/kiosk/.xinitrc-fixed" +} + # =========================== KIOSK-BENUTZER MANAGEMENT =========================== create_kiosk_user() { log "=== KIOSK-BENUTZER SETUP ===" @@ -1495,6 +1698,111 @@ EOF log "✅ Automatischer Kiosk-Start konfiguriert" info "Der Kiosk-Modus startet automatisch beim Login des $KIOSK_USER" + + # Wenn X11-Konfiguration für Raspberry Pi vorhanden ist, verwende sie + if [ -f /usr/local/bin/start-x11-kiosk ]; then + progress "Aktualisiere .bashrc für X11-Fix-Integration..." + + # Backup der aktuellen .bashrc + cp "$kiosk_home/.bashrc" "$kiosk_home/.bashrc.backup" + + # Verwende die korrigierte Version + cat > "$kiosk_home/.bashrc" << 'BASHRCFIXED' +# Automatischer Kiosk-Start beim Login mit X11-Fixes +if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then + echo "Starte Kiosk-Modus mit X11-Fixes..." + + # Verwende das X11-Fix Start-Skript wenn vorhanden + if [ -x /usr/local/bin/start-x11-kiosk ]; then + exec /usr/local/bin/start-x11-kiosk + else + # Fallback zum normalen Start + startx /home/kiosk/.xinitrc -- :0 vt1 & + sleep 5 + export DISPLAY=:0 + + # Warte auf HTTP-Backend + echo "Warte auf HTTP-Backend..." + for i in {1..60}; do + if curl -s http://localhost:5000 >/dev/null 2>&1; then + echo "HTTP-Backend erreichbar" + break + fi + echo "Warte... ($i/60)" + sleep 2 + done + + # Bildschirmschoner deaktivieren + xset s off + xset s noblank + xset -dpms + + # Mauszeiger verstecken + unclutter -idle 0.1 -root -noevents & + + # Browser im Kiosk-Modus starten + if command -v chromium >/dev/null 2>&1; then + BROWSER="chromium" + elif command -v chromium-browser >/dev/null 2>&1; then + BROWSER="chromium-browser" + else + BROWSER="firefox-esr" + fi + + echo "Starte $BROWSER im Kiosk-Modus..." + + if [[ "$BROWSER" == "chromium"* ]]; then + exec $BROWSER \ + --kiosk \ + --no-sandbox \ + --disable-infobars \ + --disable-session-crashed-bubble \ + --disable-restore-session-state \ + --disable-features=TranslateUI \ + --disable-extensions \ + --disable-plugins \ + --disable-popup-blocking \ + --disable-prompt-on-repost \ + --disable-sync \ + --disable-translate \ + --noerrdialogs \ + --no-first-run \ + --no-default-browser-check \ + --autoplay-policy=no-user-gesture-required \ + --start-fullscreen \ + --start-maximized \ + --user-data-dir=/home/kiosk/.chromium-kiosk \ + --disable-background-mode \ + --force-device-scale-factor=1.0 \ + --disable-pinch \ + --overscroll-history-navigation=0 \ + --disable-dev-shm-usage \ + --memory-pressure-off \ + --max_old_space_size=512 \ + --disable-background-timer-throttling \ + --disable-backgrounding-occluded-windows \ + --disable-renderer-backgrounding \ + --disable-features=VizDisplayCompositor \ + --enable-features=OverlayScrollbar \ + --hide-scrollbars \ + --ignore-certificate-errors \ + --ignore-ssl-errors \ + --ignore-certificate-errors-spki-list \ + --disable-web-security \ + --allow-running-insecure-content \ + http://localhost:5000 + else + exec firefox-esr \ + --kiosk \ + http://localhost:5000 + fi + fi +fi +BASHRCFIXED + + chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.bashrc" + log "✅ .bashrc für X11-Fix-Integration aktualisiert" + fi } # =========================== ROBUSTE SSL-ZERTIFIKATE INSTALLATION =========================== @@ -2955,6 +3263,7 @@ install_full_production_system() { # Desktop-Environments entfernen und minimale X11 installieren remove_desktop_environments install_minimal_x11 + configure_x11_for_raspberry_pi # Performance-Optimierungen für Raspberry Pi Webapp optimize_webapp_performance