config_cmd.py 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115
  1. # -*- coding: utf-8 -*-
  2. """
  3. Config-Tool Netzwerk-Befehle.
  4. Befehle fuer die Remote-Verwaltung laufender Trixy-Instanzen
  5. ueber das Config-Tool (TUI).
  6. """
  7. from dataclasses import dataclass, field
  8. from trixy_core.network.cmd.base import CommandMessage
  9. @dataclass
  10. class ConfigConnect(CommandMessage):
  11. """
  12. Verbindungsanfrage vom Config-Tool.
  13. Wird nach dem HELLO-Handshake gesendet, um sich
  14. als Config-Tool zu identifizieren.
  15. """
  16. tool_version: str = ""
  17. @dataclass
  18. class ConfigConnectAccepted(CommandMessage):
  19. """
  20. Verbindungsbestaetigung an das Config-Tool.
  21. Enthaelt Informationen ueber die laufende Instanz.
  22. """
  23. instance_type: str = "" # "server", "client", "standalone"
  24. instance_version: str = ""
  25. hostname: str = ""
  26. uptime_seconds: float = 0.0
  27. @dataclass
  28. class ConfigConnectDenied(CommandMessage):
  29. """
  30. Verbindungsablehnung fuer das Config-Tool.
  31. """
  32. reason: str = ""
  33. @dataclass
  34. class ConfigStatusRequest(CommandMessage):
  35. """
  36. Anfrage fuer System-Metriken.
  37. Das Config-Tool sendet diese Anfrage periodisch,
  38. um den Health-View zu aktualisieren.
  39. """
  40. include_network: bool = True
  41. include_disk: bool = True
  42. @dataclass
  43. class ConfigStatusResponse(CommandMessage):
  44. """
  45. Antwort mit System-Metriken.
  46. Enthaelt OS-, RAM-, CPU-, Disk- und Netzwerk-Informationen
  47. sowie Trixy-spezifische Daten.
  48. """
  49. # OS-Info
  50. os_name: str = ""
  51. os_version: str = ""
  52. hostname: str = ""
  53. python_version: str = ""
  54. # RAM
  55. ram_total_mb: float = 0.0
  56. ram_used_mb: float = 0.0
  57. ram_percent: float = 0.0
  58. # CPU
  59. cpu_model: str = ""
  60. cpu_count: int = 0
  61. cpu_percent: float = 0.0
  62. cpu_freq_mhz: float = 0.0
  63. # Disk
  64. disk_total_gb: float = 0.0
  65. disk_used_gb: float = 0.0
  66. disk_percent: float = 0.0
  67. # Netzwerk (aggregiert)
  68. net_bytes_sent: int = 0
  69. net_bytes_recv: int = 0
  70. net_connections: int = 0
  71. # Netzwerk pro Interface:
  72. # {name, type, is_up, bytes_sent, bytes_recv, satellites_count}
  73. # type: "wifi" | "ethernet" | "loopback" | "other"
  74. net_interfaces: list = field(default_factory=list)
  75. # Uptime
  76. uptime_seconds: float = 0.0
  77. # Trixy-spezifisch
  78. instance_type: str = ""
  79. trixy_version: str = ""
  80. satellites_connected: int = 0
  81. satellites_total: int = 0
  82. plugins_loaded: list[str] = field(default_factory=list)
  83. services_running: list[str] = field(default_factory=list)
  84. @dataclass
  85. class ConfigReadRequest(CommandMessage):
  86. """
  87. Anfrage zum Lesen einer Konfiguration.
  88. Args:
  89. config_name: Name der Konfiguration (z.B. "server", "standalone")
  90. section: Optionale Sektion (z.B. "network", "audio")
  91. """
  92. config_name: str = ""
  93. section: str = ""
  94. @dataclass
  95. class ConfigReadResponse(CommandMessage):
  96. """
  97. Antwort mit Konfigurationsdaten.
  98. Args:
  99. config_name: Name der Konfiguration
  100. section: Angeforderte Sektion
  101. data: Konfigurationsdaten als Dictionary
  102. readonly: Ob die Konfiguration schreibgeschuetzt ist
  103. """
  104. config_name: str = ""
  105. section: str = ""
  106. data: dict = field(default_factory=dict)
  107. readonly: bool = False
  108. @dataclass
  109. class ConfigWriteRequest(CommandMessage):
  110. """
  111. Anfrage zum Schreiben eines Konfigurationswerts.
  112. Args:
  113. config_name: Name der Konfiguration
  114. key_path: Punkt-separierter Pfad (z.B. "network.command_port")
  115. value: Neuer Wert
  116. """
  117. config_name: str = ""
  118. key_path: str = ""
  119. value: object = None
  120. @dataclass
  121. class ConfigWriteResponse(CommandMessage):
  122. """
  123. Antwort auf eine Schreibanfrage.
  124. Args:
  125. success: Ob das Schreiben erfolgreich war
  126. error: Fehlermeldung (falls nicht erfolgreich)
  127. requires_restart: Ob ein Neustart erforderlich ist
  128. """
  129. success: bool = False
  130. error: str = ""
  131. requires_restart: bool = False
  132. @dataclass
  133. class ConfigFieldOptionsRequest(CommandMessage):
  134. """
  135. Anfrage fuer dynamische Feld-Optionen.
  136. Fordert verfuegbare Auswahlmoeglichkeiten fuer Felder an,
  137. die dynamische Quellen verwenden (z.B. installierte Wakeword-Modelle).
  138. Args:
  139. field_sources: Liste von Quell-Bezeichnern (z.B. ["wakeword_models"])
  140. """
  141. field_sources: list[str] = field(default_factory=list)
  142. @dataclass
  143. class ConfigFieldOptionsResponse(CommandMessage):
  144. """
  145. Antwort mit dynamischen Feld-Optionen.
  146. Args:
  147. options: Dictionary von Quell-Name -> Liste von (wert, anzeige) Tupeln
  148. """
  149. options: dict[str, list[tuple[str, str]]] = field(default_factory=dict)
  150. @dataclass
  151. class ConfigSatelliteListRequest(CommandMessage):
  152. """
  153. Anfrage fuer die Liste registrierter Satellites.
  154. """
  155. pass
  156. @dataclass
  157. class SatelliteInfo:
  158. """
  159. Informationen ueber einen einzelnen Satellite.
  160. """
  161. satellite_id: str = ""
  162. alias: str = ""
  163. room_id: str = ""
  164. mac_address: str = ""
  165. ip_address: str = ""
  166. connected: bool = False
  167. version: str = ""
  168. registered_at: str = ""
  169. connected_at: str = ""
  170. has_active_conversation: bool = False
  171. @dataclass
  172. class ConfigSatelliteListResponse(CommandMessage):
  173. """
  174. Antwort mit Satellite-Liste.
  175. Args:
  176. satellites: Liste von Satellite-Informationen
  177. registration_mode: Ob der Registrierungsmodus aktiv ist
  178. permanent_mode: Ob der permanente Modus aktiv ist
  179. """
  180. satellites: list[dict] = field(default_factory=list)
  181. registration_mode: bool = False
  182. permanent_mode: bool = False
  183. @dataclass
  184. class ConfigSatelliteActionRequest(CommandMessage):
  185. """
  186. Anfrage fuer eine Satellite-Aktion.
  187. Args:
  188. action: Aktions-Typ ("enable_registration", "disable_registration",
  189. "delete", "blacklist", "unblacklist")
  190. satellite_id: Betroffener Satellite (fuer delete/blacklist)
  191. mac_address: MAC-Adresse (alternativ zu satellite_id)
  192. timeout: Optionaler Timeout fuer Registration (Sekunden)
  193. """
  194. action: str = ""
  195. satellite_id: str = ""
  196. mac_address: str = ""
  197. timeout: int = 60
  198. @dataclass
  199. class ConfigSatelliteActionResponse(CommandMessage):
  200. """
  201. Antwort auf eine Satellite-Aktion.
  202. Args:
  203. success: Ob die Aktion erfolgreich war
  204. error: Fehlermeldung (falls nicht erfolgreich)
  205. message: Erfolgsmeldung
  206. """
  207. success: bool = False
  208. error: str = ""
  209. message: str = ""
  210. @dataclass
  211. class ConfigSatelliteDetailRequest(CommandMessage):
  212. """
  213. Anfrage fuer detaillierte Satellite-Informationen.
  214. Wird fuer die Satellite Sub-Main Views benoetigt
  215. (Info, Connection, Conversation).
  216. Args:
  217. satellite_id: ID des angefragten Satellites
  218. """
  219. satellite_id: str = ""
  220. @dataclass
  221. class ConfigSatelliteDetailResponse(CommandMessage):
  222. """
  223. Antwort mit detaillierten Satellite-Informationen.
  224. Enthaelt alle Daten fuer die Satellite Sub-Main Views.
  225. """
  226. satellite_id: str = ""
  227. error: str = ""
  228. # Info (F1)
  229. alias: str = ""
  230. room_id: str = ""
  231. mac_address: str = ""
  232. ip_address: str = ""
  233. version: str = ""
  234. os_name: str = ""
  235. os_version: str = ""
  236. hostname: str = ""
  237. uptime_seconds: float = 0.0
  238. ping_ms: float = -1.0
  239. # Connection (F2) - pro Socket
  240. sockets: dict = field(default_factory=dict)
  241. # Conversation (F3)
  242. wakeword_model: str = ""
  243. wakeword_last_detection: str = ""
  244. voice_recognition_model: str = ""
  245. voice_recognition_last_speaker: str = ""
  246. has_active_conversation: bool = False
  247. last_conversation_at: str = ""
  248. last_conversation_duration: float = 0.0
  249. conversation_state: str = ""
  250. # Conversation-History (letzte abgeschlossene Sessions)
  251. conversation_history: list[dict] = field(default_factory=list)
  252. @dataclass
  253. class ConfigSatelliteConfigReadRequest(CommandMessage):
  254. """
  255. Anfrage zum Lesen der Konfiguration eines Satellites.
  256. Wird vom Config-Tool an den Server gesendet. Der Server
  257. leitet die Anfrage an den Satellite weiter.
  258. Args:
  259. satellite_id: ID des Satellites
  260. config_name: Konfigurationsname (leer = Haupt-Config)
  261. section: Optionale Sektion
  262. """
  263. satellite_id: str = ""
  264. config_name: str = ""
  265. section: str = ""
  266. @dataclass
  267. class ConfigSatelliteConfigReadResponse(CommandMessage):
  268. """
  269. Antwort mit der Konfiguration eines Satellites.
  270. Args:
  271. satellite_id: ID des Satellites
  272. data: Konfigurationsdaten als Dictionary
  273. error: Fehlermeldung (falls nicht erfolgreich)
  274. """
  275. satellite_id: str = ""
  276. data: dict = field(default_factory=dict)
  277. error: str = ""
  278. @dataclass
  279. class ConfigSatelliteConfigWriteRequest(CommandMessage):
  280. """
  281. Anfrage zum Schreiben einer Konfiguration auf einem Satellite.
  282. Wird vom Config-Tool an den Server gesendet. Der Server
  283. leitet die Anfrage an den Satellite weiter.
  284. Args:
  285. satellite_id: ID des Satellites
  286. config_name: Konfigurationsname
  287. key_path: Punkt-separierter Pfad
  288. value: Neuer Wert
  289. """
  290. satellite_id: str = ""
  291. config_name: str = ""
  292. key_path: str = ""
  293. value: object = None
  294. @dataclass
  295. class ConfigSatelliteConfigWriteResponse(CommandMessage):
  296. """
  297. Antwort auf eine Satellite-Config-Schreibanfrage.
  298. Args:
  299. satellite_id: ID des Satellites
  300. success: Ob das Schreiben erfolgreich war
  301. error: Fehlermeldung
  302. requires_restart: Ob ein Neustart erforderlich ist
  303. """
  304. satellite_id: str = ""
  305. success: bool = False
  306. error: str = ""
  307. requires_restart: bool = False
  308. # ── Plugin-Befehle ──
  309. @dataclass
  310. class ConfigPluginListRequest(CommandMessage):
  311. """
  312. Anfrage fuer die Liste aller Plugins.
  313. """
  314. pass
  315. @dataclass
  316. class ConfigPluginListResponse(CommandMessage):
  317. """
  318. Antwort mit Plugin-Liste.
  319. Args:
  320. plugins: Liste von Plugin-Informationen (dicts)
  321. """
  322. plugins: list[dict] = field(default_factory=list)
  323. @dataclass
  324. class ConfigPluginActionRequest(CommandMessage):
  325. """
  326. Anfrage fuer eine Plugin-Aktion.
  327. Args:
  328. action: Aktions-Typ ("enable", "disable", "reload", oder plugin-spezifisch)
  329. plugin_name: Name des Plugins
  330. params: Optionale Parameter fuer plugin-spezifische Aktionen
  331. """
  332. action: str = ""
  333. plugin_name: str = ""
  334. params: dict = field(default_factory=dict)
  335. @dataclass
  336. class ConfigPluginActionResponse(CommandMessage):
  337. """
  338. Antwort auf eine Plugin-Aktion.
  339. Args:
  340. success: Ob die Aktion erfolgreich war
  341. error: Fehlermeldung
  342. message: Erfolgsmeldung
  343. result_data: Optionale Rueckgabedaten (z.B. Listen, Konfigurationsdaten)
  344. """
  345. success: bool = False
  346. error: str = ""
  347. message: str = ""
  348. result_data: dict = field(default_factory=dict)
  349. @dataclass
  350. class ConfigPluginDetailRequest(CommandMessage):
  351. """
  352. Anfrage fuer detaillierte Plugin-Informationen.
  353. Args:
  354. plugin_name: Name des Plugins
  355. """
  356. plugin_name: str = ""
  357. @dataclass
  358. class ConfigPluginDetailResponse(CommandMessage):
  359. """
  360. Antwort mit detaillierten Plugin-Informationen.
  361. Args:
  362. plugin_name: Name des Plugins
  363. error: Fehlermeldung
  364. version: Plugin-Version
  365. description: Plugin-Beschreibung
  366. author: Plugin-Autor
  367. enabled: Ob das Plugin aktiviert ist
  368. loaded: Ob on_load aufgerufen wurde
  369. config: Plugin-Konfiguration als dict
  370. intents: Registrierte Intents
  371. event_handlers: Registrierte Event-Handler
  372. custom_tabs: Zusaetzliche Tabs fuer die TUI (Name -> Tab-Daten)
  373. """
  374. plugin_name: str = ""
  375. error: str = ""
  376. version: str = ""
  377. description: str = ""
  378. author: str = ""
  379. enabled: bool = False
  380. loaded: bool = False
  381. config: dict = field(default_factory=dict)
  382. intents: list[str] = field(default_factory=list)
  383. event_handlers: list[str] = field(default_factory=list)
  384. custom_tabs: list[dict] = field(default_factory=list)
  385. @dataclass
  386. class ConfigPluginConfigWriteRequest(CommandMessage):
  387. """
  388. Anfrage zum Schreiben eines Plugin-Konfigurationswerts.
  389. Args:
  390. plugin_name: Name des Plugins
  391. key_path: Punkt-separierter Pfad
  392. value: Neuer Wert
  393. """
  394. plugin_name: str = ""
  395. key_path: str = ""
  396. value: object = None
  397. @dataclass
  398. class ConfigPluginConfigWriteResponse(CommandMessage):
  399. """
  400. Antwort auf eine Plugin-Config-Schreibanfrage.
  401. Args:
  402. success: Ob das Schreiben erfolgreich war
  403. error: Fehlermeldung
  404. """
  405. success: bool = False
  406. error: str = ""
  407. @dataclass
  408. class ConfigMicTestStartRequest(CommandMessage):
  409. """
  410. Anfrage zum Starten eines Mikrofon-Tests.
  411. Der Server sendet zuerst TTS an den Satellite, dann
  412. leitet er Audio-Input-Daten an das Config-Tool weiter.
  413. Args:
  414. satellite_id: ID des Satellites
  415. """
  416. satellite_id: str = ""
  417. @dataclass
  418. class ConfigMicTestStartResponse(CommandMessage):
  419. """
  420. Antwort auf eine Mikrofon-Test-Anfrage.
  421. Args:
  422. success: Ob der Test gestartet wurde
  423. error: Fehlermeldung
  424. """
  425. success: bool = False
  426. error: str = ""
  427. @dataclass
  428. class ConfigMicTestStopRequest(CommandMessage):
  429. """
  430. Anfrage zum Stoppen eines laufenden Mikrofon-Tests.
  431. Args:
  432. satellite_id: ID des Satellites
  433. """
  434. satellite_id: str = ""
  435. @dataclass
  436. class ConfigMicTestStopResponse(CommandMessage):
  437. """
  438. Antwort auf eine Mikrofon-Test-Stop-Anfrage.
  439. Args:
  440. success: Ob der Test gestoppt wurde
  441. error: Fehlermeldung
  442. """
  443. success: bool = False
  444. error: str = ""
  445. @dataclass
  446. class ConfigMicTestAudioData(CommandMessage):
  447. """
  448. Audio-Daten vom Mikrofon-Test.
  449. Wird vom Server an das Config-Tool gesendet, waehrend
  450. der Mikrofon-Test laeuft.
  451. Args:
  452. satellite_id: ID des Satellites
  453. audio_data: Rohe Audio-Daten (16KHz, mono, 16-bit PCM)
  454. sample_rate: Abtastrate
  455. channels: Kanalanzahl
  456. """
  457. satellite_id: str = ""
  458. audio_data: bytes = b""
  459. sample_rate: int = 16000
  460. channels: int = 1
  461. # ── Schedule-Befehle ──
  462. @dataclass
  463. class ConfigScheduleListRequest(CommandMessage):
  464. """Anfrage fuer die Liste aller Schedule-Jobs."""
  465. pass
  466. @dataclass
  467. class ConfigScheduleListResponse(CommandMessage):
  468. """
  469. Antwort mit Schedule-Job-Liste.
  470. Args:
  471. jobs: Liste von Job-Informationen (dicts mit job_id, name, description,
  472. trigger_type, state, enabled, last_run, next_run, run_count)
  473. """
  474. jobs: list[dict] = field(default_factory=list)
  475. @dataclass
  476. class ConfigScheduleActionRequest(CommandMessage):
  477. """
  478. Anfrage fuer eine Schedule-Job-Aktion.
  479. Args:
  480. action: Aktions-Typ ("enable", "disable", "delete", "run_now")
  481. job_id: ID des Jobs
  482. """
  483. action: str = ""
  484. job_id: str = ""
  485. @dataclass
  486. class ConfigScheduleActionResponse(CommandMessage):
  487. """
  488. Antwort auf eine Schedule-Job-Aktion.
  489. Args:
  490. success: Ob die Aktion erfolgreich war
  491. error: Fehlermeldung
  492. message: Erfolgsmeldung
  493. """
  494. success: bool = False
  495. error: str = ""
  496. message: str = ""
  497. @dataclass
  498. class ConfigScheduleDetailRequest(CommandMessage):
  499. """
  500. Anfrage fuer detaillierte Job-Informationen.
  501. Args:
  502. job_id: ID des Jobs
  503. """
  504. job_id: str = ""
  505. @dataclass
  506. class ConfigScheduleDetailResponse(CommandMessage):
  507. """
  508. Antwort mit detaillierten Job-Informationen.
  509. Enthaelt alle Daten fuer die Schedule Sub-Views (Info, Trigger, Conditions, Actions).
  510. Args:
  511. job_id: ID des Jobs
  512. error: Fehlermeldung
  513. name: Job-Name
  514. description: Beschreibung
  515. state: Job-Status
  516. enabled: Ob aktiviert
  517. created_at: Erstellungszeitpunkt
  518. last_run: Letzte Ausfuehrung
  519. next_run: Naechste geplante Ausfuehrung
  520. run_count: Anzahl Ausfuehrungen
  521. failure_count: Anzahl Fehler
  522. trigger: Trigger-Daten als dict (type + Felder)
  523. conditions: Conditions als list[dict]
  524. actions: Actions als list[dict]
  525. config: Job-Konfiguration (max_runs, max_failures, timeout, tags, etc.)
  526. history: Letzte Ausfuehrungsergebnisse
  527. """
  528. job_id: str = ""
  529. error: str = ""
  530. name: str = ""
  531. description: str = ""
  532. state: str = ""
  533. enabled: bool = False
  534. created_at: str = ""
  535. last_run: str = ""
  536. next_run: str = ""
  537. run_count: int = 0
  538. failure_count: int = 0
  539. trigger: dict = field(default_factory=dict)
  540. conditions: list[dict] = field(default_factory=list)
  541. actions: list[dict] = field(default_factory=list)
  542. config: dict = field(default_factory=dict)
  543. history: list[dict] = field(default_factory=list)
  544. @dataclass
  545. class ConfigScheduleSaveRequest(CommandMessage):
  546. """
  547. Anfrage zum Erstellen oder Aktualisieren eines Schedule-Jobs.
  548. Enthaelt die kompletten Job-Daten. Wenn job_id leer ist,
  549. wird ein neuer Job erstellt.
  550. Args:
  551. job_id: Job-ID (leer = neuer Job)
  552. name: Job-Name
  553. description: Beschreibung
  554. trigger: Trigger-Daten als dict (type + Felder)
  555. conditions: Conditions als list[dict]
  556. actions: Actions als list[dict]
  557. config: Job-Konfiguration als dict
  558. """
  559. job_id: str = ""
  560. name: str = ""
  561. description: str = ""
  562. trigger: dict = field(default_factory=dict)
  563. conditions: list[dict] = field(default_factory=list)
  564. actions: list[dict] = field(default_factory=list)
  565. config: dict = field(default_factory=dict)
  566. @dataclass
  567. class ConfigScheduleSaveResponse(CommandMessage):
  568. """
  569. Antwort auf eine Schedule-Job-Speicheranfrage.
  570. Args:
  571. success: Ob das Speichern erfolgreich war
  572. job_id: ID des erstellten/aktualisierten Jobs
  573. error: Fehlermeldung
  574. """
  575. success: bool = False
  576. job_id: str = ""
  577. error: str = ""
  578. @dataclass
  579. class ConfigScheduleFormMetaRequest(CommandMessage):
  580. """
  581. Anfrage fuer Formular-Metadaten der Scheduler-Komponenten.
  582. Liefert die verfuegbaren Trigger/Condition/Action-Typen
  583. mit ihren Formular-Feldern fuer die TUI.
  584. """
  585. pass
  586. @dataclass
  587. class ConfigScheduleFormMetaResponse(CommandMessage):
  588. """
  589. Antwort mit Formular-Metadaten.
  590. Args:
  591. triggers: Dict von Typ-Name -> {display_name, fields: list[dict]}
  592. conditions: Dict von Typ-Name -> {display_name, fields: list[dict]}
  593. actions: Dict von Typ-Name -> {display_name, fields: list[dict]}
  594. """
  595. triggers: dict = field(default_factory=dict)
  596. conditions: dict = field(default_factory=dict)
  597. actions: dict = field(default_factory=dict)
  598. # ── Trainer-Befehle ──
  599. @dataclass
  600. class ConfigTrainerListRequest(CommandMessage):
  601. """Anfrage fuer die Liste aller verfuegbaren Trainer."""
  602. pass
  603. @dataclass
  604. class ConfigTrainerListResponse(CommandMessage):
  605. """
  606. Antwort mit Trainer-Liste.
  607. Args:
  608. trainers: Liste von Trainer-Informationen (dicts)
  609. """
  610. trainers: list[dict] = field(default_factory=list)
  611. @dataclass
  612. class ConfigTrainerDetailRequest(CommandMessage):
  613. """
  614. Anfrage fuer detaillierte Trainer-Informationen.
  615. Args:
  616. trainer_id: ID des Trainers
  617. """
  618. trainer_id: str = ""
  619. @dataclass
  620. class ConfigTrainerDetailResponse(CommandMessage):
  621. """
  622. Antwort mit detaillierten Trainer-Informationen.
  623. Enthaelt Info, Schemas, aktuelle Settings und Dataset-Info.
  624. """
  625. trainer_id: str = ""
  626. error: str = ""
  627. name: str = ""
  628. description: str = ""
  629. version: str = ""
  630. author: str = ""
  631. model_type: str = ""
  632. trainer_type: str = ""
  633. settings_schema: dict = field(default_factory=dict)
  634. dataset_schema: dict = field(default_factory=dict)
  635. optional_schema: dict | None = None
  636. settings: dict = field(default_factory=dict)
  637. dataset_info: dict = field(default_factory=dict)
  638. @dataclass
  639. class ConfigTrainerSettingsWriteRequest(CommandMessage):
  640. """
  641. Anfrage zum Schreiben von Trainer-Einstellungen.
  642. Args:
  643. trainer_id: ID des Trainers
  644. settings: Einstellungswerte als dict
  645. """
  646. trainer_id: str = ""
  647. settings: dict = field(default_factory=dict)
  648. @dataclass
  649. class ConfigTrainerSettingsWriteResponse(CommandMessage):
  650. """
  651. Antwort auf Trainer-Settings-Schreibanfrage.
  652. Args:
  653. success: Ob das Schreiben erfolgreich war
  654. error: Fehlermeldung
  655. """
  656. success: bool = False
  657. error: str = ""
  658. @dataclass
  659. class ConfigTrainerValidateRequest(CommandMessage):
  660. """
  661. Anfrage zur Validierung eines Trainers.
  662. Args:
  663. trainer_id: ID des Trainers
  664. """
  665. trainer_id: str = ""
  666. @dataclass
  667. class ConfigTrainerValidateResponse(CommandMessage):
  668. """
  669. Antwort auf eine Validierungsanfrage.
  670. Args:
  671. valid: Ob die Validierung erfolgreich war
  672. errors: Liste von Fehlermeldungen
  673. warnings: Liste von Warnungen
  674. gpu_available: Ob eine GPU verfuegbar ist
  675. gpu_name: Name der GPU
  676. gpu_memory_mb: GPU-Speicher in MB
  677. """
  678. valid: bool = False
  679. errors: list[str] = field(default_factory=list)
  680. warnings: list[str] = field(default_factory=list)
  681. gpu_available: bool = False
  682. gpu_name: str = ""
  683. gpu_memory_mb: float = 0.0
  684. @dataclass
  685. class ConfigTrainerStartRequest(CommandMessage):
  686. """
  687. Anfrage zum Starten eines Trainings.
  688. Args:
  689. trainer_id: ID des Trainers
  690. """
  691. trainer_id: str = ""
  692. @dataclass
  693. class ConfigTrainerStartResponse(CommandMessage):
  694. """
  695. Antwort auf eine Training-Start-Anfrage.
  696. Args:
  697. success: Ob das Training gestartet wurde
  698. error: Fehlermeldung
  699. """
  700. success: bool = False
  701. error: str = ""
  702. @dataclass
  703. class ConfigTrainerPauseRequest(CommandMessage):
  704. """Anfrage zum Pausieren des laufenden Trainings."""
  705. pass
  706. @dataclass
  707. class ConfigTrainerPauseResponse(CommandMessage):
  708. """Antwort auf eine Pause-Anfrage."""
  709. success: bool = False
  710. error: str = ""
  711. @dataclass
  712. class ConfigTrainerResumeRequest(CommandMessage):
  713. """Anfrage zum Fortsetzen eines pausierten Trainings."""
  714. pass
  715. @dataclass
  716. class ConfigTrainerResumeResponse(CommandMessage):
  717. """Antwort auf eine Resume-Anfrage."""
  718. success: bool = False
  719. error: str = ""
  720. @dataclass
  721. class ConfigTrainerStopRequest(CommandMessage):
  722. """Anfrage zum Stoppen des laufenden Trainings."""
  723. pass
  724. @dataclass
  725. class ConfigTrainerStopResponse(CommandMessage):
  726. """Antwort auf eine Stop-Anfrage."""
  727. success: bool = False
  728. error: str = ""
  729. @dataclass
  730. class ConfigTrainerProgressRequest(CommandMessage):
  731. """Anfrage fuer den aktuellen Trainings-Fortschritt."""
  732. pass
  733. @dataclass
  734. class ConfigTrainerProgressResponse(CommandMessage):
  735. """
  736. Antwort mit aktuellem Trainings-Fortschritt.
  737. Args:
  738. state: Trainings-Status (idle, training, paused, ...)
  739. trainer_id: ID des aktiven Trainers
  740. epoch: Aktuelle Epoche
  741. total_epochs: Gesamtzahl Epochen
  742. loss: Aktueller Training-Loss
  743. val_loss: Aktueller Validation-Loss
  744. accuracy: Aktuelle Genauigkeit
  745. learning_rate: Aktuelle Lernrate
  746. eta_seconds: Geschaetzte Restzeit
  747. vram_used_mb: GPU-Speicherverbrauch
  748. loss_history: Verlauf aller Training-Losses
  749. val_loss_history: Verlauf aller Validation-Losses
  750. message: Status-Nachricht
  751. error: Fehlermeldung
  752. """
  753. state: str = "idle"
  754. trainer_id: str = ""
  755. epoch: int = 0
  756. total_epochs: int = 0
  757. loss: float = 0.0
  758. val_loss: float = 0.0
  759. accuracy: float = 0.0
  760. learning_rate: float = 0.0
  761. eta_seconds: float = 0.0
  762. vram_used_mb: float = 0.0
  763. loss_history: list[float] = field(default_factory=list)
  764. val_loss_history: list[float] = field(default_factory=list)
  765. message: str = ""
  766. error: str = ""
  767. @dataclass
  768. class ConfigTrainerActionRequest(CommandMessage):
  769. """
  770. Anfrage zum Ausfuehren einer Trainer-Aktion.
  771. Args:
  772. trainer_id: ID des Trainers
  773. action: Name der Aktion (z.B. "generate_tts")
  774. params: Parameter fuer die Aktion
  775. """
  776. trainer_id: str = ""
  777. action: str = ""
  778. params: dict = field(default_factory=dict)
  779. @dataclass
  780. class ConfigTrainerActionResponse(CommandMessage):
  781. """
  782. Antwort auf eine Trainer-Aktion.
  783. Args:
  784. success: Ob die Aktion erfolgreich war
  785. message: Status-/Fehlermeldung
  786. data: Optionale Ergebnisdaten
  787. """
  788. success: bool = False
  789. message: str = ""
  790. data: dict = field(default_factory=dict)
  791. # ── Satellite-Audio (F6 Audio View) ──
  792. @dataclass
  793. class SatelliteAudioRequest(CommandMessage):
  794. """
  795. Audio-Anfrage zwischen Server und Satellite (interner Hop).
  796. Wird vom Server an einen Satellite weitergereicht. Der
  797. Satellite antwortet mit SatelliteAudioResponse.
  798. Args:
  799. action: "query" | "set_volume" | "set_mute" | "list_devices"
  800. | "list_pulse_sinks" | "set_speakers"
  801. | "list_pulse_sources" | "set_microphones"
  802. target: "output" | "input"
  803. volume: Zielwert in Prozent (0-100), nur bei set_volume
  804. muted: Mute-Zustand, nur bei set_mute
  805. source: "user" | "hid" — wird an VolumeHandler weitergereicht
  806. speakers: Liste von Speaker-Eintraegen fuer set_speakers,
  807. jeweils {"device": str, "enabled": bool, "volume": int}
  808. microphones: Liste von Mic-Eintraegen fuer set_microphones,
  809. jeweils {"device": str, "enabled": bool, "label": str}
  810. """
  811. action: str = "query"
  812. target: str = "output"
  813. volume: int = 0
  814. muted: bool = False
  815. source: str = "user"
  816. speakers: list = field(default_factory=list)
  817. microphones: list = field(default_factory=list)
  818. @dataclass
  819. class SatelliteAudioResponse(CommandMessage):
  820. """
  821. Audio-Antwort des Satellites an den Server.
  822. Args:
  823. success: Ob die Aktion erfolgreich war
  824. error: Fehlermeldung
  825. output_available: Ob ALSA Output verfuegbar ist
  826. output_control: Aktiver ALSA Output Mixer-Control
  827. output_volume: Aktuelle Output-Lautstaerke (0-100)
  828. output_muted: Aktueller Output-Mute-Status
  829. input_available: Ob ALSA Capture verfuegbar ist
  830. input_control: Aktiver ALSA Capture Mixer-Control
  831. input_volume: Aktuelle Capture-Lautstaerke (0-100)
  832. input_muted: Aktueller Capture-Mute-Status
  833. input_devices: Liste der Aufnahme-Geraete
  834. output_devices: Liste der Wiedergabe-Geraete
  835. """
  836. success: bool = True
  837. error: str = ""
  838. output_available: bool = False
  839. output_control: str = ""
  840. output_volume: int = 0
  841. output_muted: bool = False
  842. input_available: bool = False
  843. input_control: str = ""
  844. input_volume: int = 0
  845. input_muted: bool = False
  846. input_devices: list = field(default_factory=list)
  847. output_devices: list = field(default_factory=list)
  848. pulse_available: bool = False
  849. pulse_sinks: list = field(default_factory=list)
  850. output_speakers: list = field(default_factory=list)
  851. combined_sink_active: bool = False
  852. pulse_sources: list = field(default_factory=list)
  853. input_microphones: list = field(default_factory=list)
  854. input_mix_active: bool = False
  855. @dataclass
  856. class ConfigSatelliteAudioRequest(CommandMessage):
  857. """
  858. Audio-Anfrage vom Config-Tool an den Server.
  859. Der Server reicht die Anfrage an den genannten Satellite
  860. weiter und liefert die Antwort zurueck.
  861. Args:
  862. satellite_id: ID des Satellites
  863. action: "query" | "set_volume" | "set_mute" | "list_devices"
  864. target: "output" | "input"
  865. volume: 0-100 (bei set_volume)
  866. muted: bool (bei set_mute)
  867. """
  868. satellite_id: str = ""
  869. action: str = "query"
  870. target: str = "output"
  871. volume: int = 0
  872. muted: bool = False
  873. speakers: list = field(default_factory=list)
  874. microphones: list = field(default_factory=list)
  875. @dataclass
  876. class ConfigSatelliteAudioResponse(CommandMessage):
  877. """
  878. Audio-Antwort vom Server an das Config-Tool.
  879. Spiegelt SatelliteAudioResponse plus satellite_id.
  880. """
  881. satellite_id: str = ""
  882. success: bool = True
  883. error: str = ""
  884. output_available: bool = False
  885. output_control: str = ""
  886. output_volume: int = 0
  887. output_muted: bool = False
  888. input_available: bool = False
  889. input_control: str = ""
  890. input_volume: int = 0
  891. input_muted: bool = False
  892. input_devices: list = field(default_factory=list)
  893. output_devices: list = field(default_factory=list)
  894. pulse_available: bool = False
  895. pulse_sinks: list = field(default_factory=list)
  896. output_speakers: list = field(default_factory=list)
  897. combined_sink_active: bool = False
  898. pulse_sources: list = field(default_factory=list)
  899. input_microphones: list = field(default_factory=list)
  900. input_mix_active: bool = False