config.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. # -*- coding: utf-8 -*-
  2. """
  3. Installer-Konfiguration als Dataclass.
  4. Speichert alle Einstellungen die der Benutzer
  5. in der TUI vornimmt.
  6. """
  7. from __future__ import annotations
  8. from dataclasses import dataclass, field
  9. @dataclass
  10. class InstallerConfig:
  11. """Alle Installer-Einstellungen."""
  12. # Modus und Version (von CLI gesetzt)
  13. mode: str = "server"
  14. version: str = "1.0.0"
  15. source_archive: str = ""
  16. # System (F1)
  17. hostname: str = "trixyone"
  18. username: str = "pi"
  19. install_path: str = "/home/pi/trixy"
  20. autostart: bool = True
  21. install_service: bool = True
  22. auto_regist: bool = True
  23. # Netzwerk (F2) — Server
  24. wifi_enabled: bool = True
  25. wifi_ssid: str = "trixyone_srv"
  26. wifi_password: str = "trixy2026!"
  27. wifi_channel: int = 6
  28. ap_ip: str = "10.10.10.1"
  29. dhcp_range_start: str = "10.10.10.10"
  30. dhcp_range_end: str = "10.10.10.50"
  31. # Netzwerk (F2) — Client/Standalone WLAN
  32. wifi_connect: bool = False # WLAN umkonfigurieren
  33. wifi_connect_ssid: str = "" # Bevorzugte SSID (z.B. Trixy-Server-Hotspot)
  34. wifi_connect_password: str = "" # Passwort fuer bevorzugte SSID
  35. # Fallback-WLAN (optional — wird genutzt wenn primaeres Netz nicht erreichbar)
  36. wifi_fallback_enabled: bool = False
  37. wifi_fallback_ssid: str = ""
  38. wifi_fallback_password: str = ""
  39. # Auto-Rueckwechsel: Wenn aktiv, wechselt der Client automatisch zurueck
  40. # zum primaeren Netz sobald es wieder erreichbar ist.
  41. wifi_auto_switchback: bool = True
  42. wifi_switchback_interval: int = 30 # Pruefintervall in Sekunden
  43. # Netzwerk (F2) — Client
  44. server_host: str = "10.10.10.1"
  45. server_port: int = 2101
  46. room: str = ""
  47. alias: str = ""
  48. # Plugins (F3)
  49. selected_plugins: list[str] = field(default_factory=list)
  50. # NLP Backend (nur relevant wenn nlp_llm in selected_plugins)
  51. nlp_backend: str = "llama_cpp" # "llama_cpp", "ollama" oder "ollama_remote"
  52. ollama_host: str = "http://localhost:11434"
  53. # Modelle
  54. download_models: bool = False
  55. # Vereinbarung (F5)
  56. agreement_accepted: bool = False
  57. @property
  58. def venv_path(self) -> str:
  59. """Pfad zum Python venv."""
  60. return f"{self.install_path}/venv"
  61. @property
  62. def source_path(self) -> str:
  63. """Pfad zum entpackten Quellcode."""
  64. return f"{self.install_path}/source"
  65. def validate(self) -> list[tuple[str, str]]:
  66. """
  67. Validiert die Konfiguration.
  68. Returns:
  69. Liste von (view_id, fehlermeldung) Tupeln.
  70. """
  71. errors: list[tuple[str, str]] = []
  72. # System
  73. if not self.hostname.strip():
  74. errors.append(("system", "Hostname darf nicht leer sein"))
  75. if not self.username.strip():
  76. errors.append(("system", "Benutzername darf nicht leer sein"))
  77. if not self.install_path.strip():
  78. errors.append(("system", "Installationspfad darf nicht leer sein"))
  79. # Netzwerk — Server
  80. if self.mode == "server" and self.wifi_enabled:
  81. if not self.wifi_ssid.strip():
  82. errors.append(("network", "WiFi SSID darf nicht leer sein"))
  83. if len(self.wifi_password) < 8:
  84. errors.append(("network", "WiFi Passwort muss mindestens 8 Zeichen haben"))
  85. # Netzwerk — Client
  86. if self.mode == "client":
  87. if not self.server_host.strip():
  88. errors.append(("network", "Server-Host darf nicht leer sein"))
  89. if not self.room.strip():
  90. errors.append(("network", "Raum darf nicht leer sein"))
  91. if not self.alias.strip():
  92. errors.append(("network", "Alias darf nicht leer sein"))
  93. # Netzwerk — WLAN-Verbindung (Client/Standalone)
  94. if self.wifi_connect:
  95. if not self.wifi_connect_ssid.strip():
  96. errors.append(("network", "Primaere WLAN-SSID darf nicht leer sein"))
  97. if not self.wifi_connect_password:
  98. errors.append(("network", "Primaeres WLAN-Passwort darf nicht leer sein"))
  99. if self.wifi_fallback_enabled:
  100. if not self.wifi_fallback_ssid.strip():
  101. errors.append(("network", "Fallback-WLAN-SSID darf nicht leer sein"))
  102. if not self.wifi_fallback_password:
  103. errors.append(("network", "Fallback-WLAN-Passwort darf nicht leer sein"))
  104. if self.wifi_fallback_ssid.strip() == self.wifi_connect_ssid.strip():
  105. errors.append(("network", "Fallback- und Primaere SSID muessen unterschiedlich sein"))
  106. if self.wifi_switchback_interval < 10:
  107. errors.append(("network", "Switchback-Intervall muss mindestens 10 Sekunden sein"))
  108. # Vereinbarung
  109. if not self.agreement_accepted:
  110. errors.append(("agreement", "Nutzungsbedingungen muessen akzeptiert werden"))
  111. # Quellarchiv
  112. if not self.source_archive:
  113. errors.append(("install", "Kein Quellarchiv angegeben"))
  114. return errors