Universelle Laborplattform für Lasersysteme & optische Messtechnik.
LTor ist eine industriell gestaltete Desktop-Anwendung (Electron + React + TypeScript), die heterogene Laborhardware – SPSen, Sensoren, Messgeräte – über OPC UA, MQTT und REST in einer einheitlichen Oberfläche zusammenführt, Telemetrie live darstellt, Kamera- und Mikrofon-Signale der Workstation einbindet und alle sicherheitsrelevanten Vorgänge in einem manipulationssicheren Audit-Log protokolliert.
Das Frontend ist transport-agnostisch aufgebaut: derselbe React-Code läuft sowohl in der Electron-Desktop-App (lokal, direkt am Labor-PC) als auch im Webbrowser gegen einen Remote-Backend-Server (z. B. VPS) – siehe Abschnitt Deployment-Varianten.
ltor.maazi.de · ohne Installation, ohne Anmeldung
Ein virtueller Laserplatz mit 3D-Optikbank und physikalischem Modell: fünf Lasertypen (405 nm GaN-Diode, 808 nm Hochleistungsdiode, 1550 nm DFB, 1064 nm und 532 nm DPSS) mit Schwellstrom nach T₀-Gesetz, Eigenerwärmung, Wellenlängendrift, Pumpabsorption und quadratischer Frequenzverdopplung. Linse und Messebene lassen sich im 3D-Bild verschieben – Kaustik und Strahlprofil folgen dem Gaußstrahl-Formalismus (ABCD/q-Parameter). Laserklasse, MPE, NOHD und Schutzbrillen-OD werden live berechnet. Für Auszubildende und angehende Laserfachkräfte erklärt das Labor jeden Zustand, prüft sieben Übungen automatisch und protokolliert jeden Schritt. Details: Laserlabor.
| Bereich | Kern |
|---|---|
| Plattform | Windows / macOS / Linux (Electron) |
| Protokolle | OPC UA (node-opcua), MQTT (mqtt.js), REST (axios), Laser-Simulator |
| Laserlabor | 3D-Optikbank (three.js, Blender-Modell), Laserphysik, Laserschutz, Übungen |
| Sensoren | Kamera & Mikrofon der Workstation (Web MediaDevices API) |
| UI | React + TypeScript + TailwindCSS, einklappbare Panels, modul-basiert |
| Persistenz | Verbindungen → connections.json, Audit-Log → audit.jsonl |
| Audit-Log | Append-only JSON Lines, lückenlos, exportierbar |
| Transport | Lokal: Electron-IPC (window.ltor) · Remote-fähig: WebSocket-JSON-RPC |
Aktuell liegt die App im Quellzustand vor; Binaries werden in einem späteren
Release-Schritt via electron-builder paketiert.
Lokal starten:
git clone <repo-url> LTor
cd LTor
npm install
npm run dev # öffnet das Electron-FensterHinweis:
npm run devöffnet automatisch das Electron-Fenster. Daneben startet ein Vite-Dev-Server unterhttp://localhost:5173/– das ist nur ein Asset-Server für den Renderer und in dieser Konfiguration nicht zur direkten Browser-Benutzung gedacht (außer du betreibst zusätzlich ein Backend, siehe Deployment-Varianten).
Beim allerersten Start ist die Verbindungsliste leer. Empfohlener Ablauf:
- Sidebar → Verbindungen öffnen.
- Protokolltyp wählen (OPC UA / MQTT / REST), auf Neu klicken.
- Formular ausfüllen (siehe Konfiguration pro Protokoll) und speichern.
- In der Tabelle bei der Verbindung auf Verbinden klicken.
- Telemetrie-Modul öffnen → Live-Werte erscheinen als Sparklines.
- Sensoren (Kamera/Mikrofon) und Audit-Log verhalten sich selbsterklärend.
| Modul | Inhalt |
|---|---|
| Übersicht | Stat-Cards (verbundene Geräte, aktive Kanäle, Sensoren), kompakte Verbindungs-Status-Tabelle, jüngste Warnungen. |
| Laserlabor | 3D-Laserplatz mit Simulator: Steuerung, P-I-Kennlinie, Kaustik, Strahlprofil, Laserschutz, Lernpfad & Protokoll. |
| Telemetrie | Live-Sparklines pro Kanal, Werteanzeige, Min/Max/Last, Pause-Funktion, Filter & Verbindungs-Auswahl. |
| Verbindungen | CRUD für Verbindungen, pro Verbindung Connect/Disconnect/Edit/Delete. Formular je Protokolltyp. |
| Sensoren | Bordeigene Kamera (Vorschau) und Mikrofon (RMS-Pegelmeter). Auswahl des Geräts, Start/Stopp. |
| Audit-Log | Tabelle aller Ereignisse, Filter nach Kategorie/Zeitraum/Volltext, JSONL-Export, kompletter Reset. |
Das Laserlabor ist ein virtueller Laserplatz. Hinter jedem Gerät steckt der
neue Verbindungstyp sim – ein Laser-Controller (Stromtreiber, TEC,
Schlüsselschalter, Shutter, Interlock), dessen Messwerte aus einem
physikalischen Modell (src/shared/laserPhysics.ts) stammen. Der Simulator
läuft im Backend wie jedes echte Gerät: Telemetrie, Schreibbefehle und
Audit-Log funktionieren genau wie bei OPC UA, MQTT oder REST.
Bedienen
- Interlock, Schlüsselschalter (Emission) und Shutter schalten; Diodenstrom und TEC-Temperatur über Regler oder exakte Eingabe setzen.
- Die Emission startet erst nach 3 s Emissionsverzögerung (Warnleuchte am Laserkopf), der Strom wird per Soft-Start gerampt.
- Interlock öffnen schaltet die Emission sofort ab – kein automatischer Wiederanlauf. Übertemperatur der Sperrschicht löst eine Schutzabschaltung aus, die quittiert werden muss.
- Im 3D-Bild: ziehen = drehen, Rad = Zoom, Linse und Messebene entlang der Schiene ziehen, Bauteil anklicken = Erklärung (Funktion, Physik, Praxis).
Physik (Lehrmodell, Formeln im Code dokumentiert)
| Effekt | Modell |
|---|---|
| Schwellstrom | I_th(T) = I_th,25 · exp((T − 25 °C)/T₀) |
| Ausgangsleistung (Diode) | P = η(T)·(I − I_th), darunter spontane Emission |
| Eigenerwärmung | T_j = T_TEC + R_th·(U·I − P_opt), U = U₀ + R_s·I |
| Wellenlänge | λ(T) = λ₂₅ + dλ/dT·(T − 25 °C); DPSS: atomarer Übergang (fest) |
| DPSS-Pumpabsorption | Lorentz-Linie Nd:YVO₄ bei 808,5 nm, FWHM 2,5 nm |
| Frequenzverdopplung (SHG) | P₅₃₂ = k·P₁₀₆₄² |
| Gaußstrahl | z_R = π·w₀²/(M²·λ), w(z) = w₀·√(1 + (z/z_R)²) |
| Dünne Linse | 1/q′ = 1/q − 1/f (komplexer Strahlparameter) |
| Laserschutz | AEL/Klasse, MPE, NOHD, OD nach IEC 60825-1 (vereinfacht, CW) |
npm run test:physics prüft die Formeln gegen Lehrbuchwerte.
Lernen
- Was passiert? – erklärt den aktuellen Zustand (unter/über der Schwelle, Shutter, Absorption, Temperaturgrenze …) in Klartext.
- Übungen – sieben Aufgaben, die automatisch erkannt werden: sicher einschalten, Laserschwelle finden, Temperatureinfluss, Pumpwellenlänge abstimmen (DPSS), fokussieren & vermessen, Laserklasse/Schutzbrille (Quiz), sicher ausschalten.
- Protokoll – jede Aktion und jede Gerätemeldung mit Erklärung; der Fortschritt landet zusätzlich im Audit-Log (exportierbar als JSONL).
Die Sicherheitswerte sind vereinfachte Lehrwerte. Sie ersetzen keine Gefährdungsbeurteilung durch die/den Laserschutzbeauftragte:n (TROS Laserstrahlung).
Das 3D-Modell wird reproduzierbar per Skript in Blender erzeugt:
blender --background --factory-startup --python assets/blender/build_ltor_lab.py
# → assets/blender/ltor_lab.blend + src/renderer/src/assets/ltor_lab.glb-
Endpoint:
opc.tcp://host:4840 -
Security Mode:
None,Sign,SignAndEncrypt -
Security Policy:
None,Basic256Sha256,Aes128_Sha256_RsaOaep,Aes256_Sha256_RsaPss -
Benutzer/Passwort: optional; leer = anonymous.
-
Publishing-Intervall (ms): Subscriptions-Default für alle Nodes.
-
Datenpunkte: eine Zeile pro Node im Format
nodeId|kanalNameBeispiel:
ns=2;s=Demo.Static.Scalar.Double|temperatur ns=2;s=Demo.Dynamic.Scalar.Int32|count
-
Broker-URL:
mqtt://,mqtts://oderws://…(Web-MQTT). -
Client-ID / Benutzer / Passwort: optional.
-
Topics: eine Zeile pro Subscription:
topic|kanalName|qosBeispiel:
lab/+/temperatur|temperatur|0 factory/#|allgemein|1Wildcards
+und#werden unterstützt.
-
Base-URL: z. B.
http://gateway.local:8000 -
Methode: GET / POST / PUT / PATCH / DELETE
-
Header: zeilenweise
Key: Value. -
Polling-Endpoints: zeilenweise
pfad|kanalName|intervallMs|jsonPathjsonPathist optional und bedient eine kleine Dollar-Subset-Syntax ($.path.to.value); leer = ganze Response wird verwendet.Beispiel:
/api/sensor|temperatur|1000|$.value /api/health|status|5000|
- Alle Seitenpanels (Titlebar, Sidebar, Tools-Panel, Statusbar) sind über die kleinen Chevron-Buttons einzeln ein-/ausklappbar. Eingeklappte Panels hinterlassen schmale Rand-Toggles, mit denen sie wieder geöffnet werden.
- DevTools öffnen sich standardmäßig nicht. Aktivierung wahlweise per:
- Flag:
npm run dev -- -- --devtools - Env-Variable:
LTOR_DEVTOOLS=1 - Tastenkürzel im Fenster:
F12bzw.Ctrl + Shift + I
- Flag:
- Lasermodell:
diode405,dfb1550,diode808,dpss1064,dpss532 - Telemetrie-Rate: 1 … 10 Hz, Messrauschen: 0 … 1
- Schreibbare Kanäle (
connections.write):current_set_mA,tec_set_C,emission,shutter,interlock,fault_reset - Öffnet keine Netzwerkverbindung – ideal zum Testen eigener Auswertungen ohne Hardware.
LTor schreibt in das OS-typische userData-Verzeichnis:
| OS | Pfad |
|---|---|
| Windows | %APPDATA%\LTor\ (z. B. C:\Users\<Name>\AppData\Roaming\LTor\) |
| macOS | ~/Library/Application Support/LTor/ |
| Linux | ~/.config/LTor/ |
Dateien:
connections.json– alle Verbindungen samt Konfiguration.audit.jsonl– ein JSON-Objekt pro Zeile, append-only.
Beide Dateien sind menschen-lesbar und können bei Bedarf gesichert oder versioniert werden.
- Im Browser-Tab
http://localhost:5173/ist alles leer. Das ist gewollt: der Tab ist nur Asset-Server für den Renderer. Nutze stattdessen das Electron-Fenster – oder stelle einen Remote-Backend bereit (Deployment-Varianten). - App startet mit
ERR_REQUIRE_ESM: hexy. Sicherstellen, dassnpm installdie impackage.jsonfestgeschriebene Override"hexy": "0.3.5"aufgelöst hat (gefolgt von einem frischennode_modules-Build). - OPC-UA-Verbindung schlägt mit Zertifikatsfehler fehl. Security Mode auf
Nonesetzen oder die UA-Server-Endpunkt-CA im OS-Trust-Store hinterlegen. - MQTT bleibt auf „verbindet …“ hängen. Brokerseitig prüfen, ob die
Client-ID nicht doppelt vergeben ist; bei
mqtts://Zertifikate prüfen. - Mikrofon zeigt keinen Pegel. Browser-/OS-Berechtigung erteilen, anschließend Geräte neu laden klicken.
- Electron 32, electron-vite 2 (Bundling für Main / Preload / Renderer).
- TypeScript 5 (strict).
- React 18 + Zustand (State).
- TailwindCSS 3 + eigene Design-Tokens (
tailwind.config.js,index.css). - Recharts für Sparklines.
- node-opcua 2.x (OPC UA), mqtt.js 5 (MQTT), axios 1 (REST).
- lucide-react für Icons.
src/
├── shared/ # gemeinsame Typen (Connection, AuditEntry, IPC-Konstanten)
│ ├── types.ts
│ └── laserPhysics.ts # Lasermodelle, Gaußoptik, Laserschutz (pure TS)
│
├── main/ # Electron Hauptprozess (Node)
│ ├── index.ts # Bootstrap, BrowserWindow, IPC → backend.ts
│ ├── backend.ts # RPC-Handler für Electron UND Web-Server
│ ├── audit/auditLog.ts # JSONL Audit-Log (append-only)
│ ├── store/connectionStore.ts # Persistierung der Verbindungen
│ └── protocols/
│ ├── adapter.ts # ProtocolAdapter-Interface + AdapterEmitter
│ ├── manager.ts # Orchestriert mehrere Adapter parallel
│ ├── factory.ts # alle Adapter · simFactory.ts: nur Simulator
│ ├── simAdapter.ts # Laser-Simulator (Controller + Physik)
│ ├── opcuaAdapter.ts # OPC UA (Subscriptions + Write)
│ ├── mqttAdapter.ts # MQTT (Wildcards + QoS)
│ └── restAdapter.ts # REST (Per-Endpoint-Polling + jsonPath)
│
├── preload/ # Context-Bridge
│ └── index.ts # exposeInMainWorld("ltor", api)
│
└── renderer/ # React-UI (Vite)
└── src/
├── App.tsx # Layout, Modul-Routing, Event-Abos
├── main.tsx # Entry, ReactDOM.render
├── index.css # Tailwind-Basis + Design-Tokens
├── ipc/ # Transport-Layer (Electron / WebSocket / null)
│ ├── transport.ts # LtorTransport-Interface
│ ├── electronTransport.ts
│ ├── wsTransport.ts # WebSocket-JSON-RPC-Client
│ ├── nullTransport.ts # Fallback, wenn kein Backend verfügbar
│ └── index.ts # ipc = resolveTransport()
├── store/ # Zustand-Stores (app/connections/telemetry/audit/sensors)
├── components/layout/ # TitleBar, Sidebar, StatusBar, ToolsPanel, PanelToggleBar
├── modules/ # Fachliche Module
│ ├── dashboard/
│ ├── connections/
│ ├── telemetry/
│ ├── sensors/
│ ├── laserlab/ # 3D-Szene, Diagramme, Laserschutz, Lernpfad
│ └── audit/
└── types/ipc.d.ts # window.ltor Typdeklaration (für Electron)
server/index.ts # Web-Backend (WebSocket-JSON-RPC, Demo-/Full-Modus)
assets/blender/ # Blender-Skript + .blend des 3D-Labors
deploy/ # systemd-Unit, Plesk-Anweisungen, Deploy-Skript
scripts/ # Server-Build, Physik-Selbsttest
- Node.js ≥ 20
- npm ≥ 10
- (Windows) Visual Studio Build Tools werden ggf. von
node-opcuabenötigt.
npm install # 1× nach jedem Pull
npm run dev # Watch-Mode, öffnet Electron-Fenster
npm run dev -- -- --devtools # zusätzlich DevTools öffnen
npm run typecheck # tsc -p tsconfig.node.json && tsc -p tsconfig.web.json
npm run build # Produktions-Bundles in out/{main,preload,renderer}/
npm run start # Vorschau des Production-Builds (electron-vite preview)
# Web-Version
npm run build:online # out/web (Frontend) + out/server (Backend-Bundle)
npm run serve # beides lokal: http://127.0.0.1:8646
npm run dev:web # Vite-Dev-Server :5174 (Backend separat via serve)
npm run test:physics # Physik-SelbsttestLTor folgt der klassischen Electron-3-Prozess-Trennung:
┌────────────────────────────┐ ┌───────────────────────────┐
│ Main-Prozess (Node) │ IPC ⇄ │ Preload (Context-Bridge) │
│ - ProtocolManager │ │ - exposeInMainWorld(ltor) │
│ - OPC UA / MQTT / REST │ └───────────────────────────┘
│ - AuditLog (JSONL) │ ↑ window.ltor
│ - ConnectionStore │ │
└────────────────────────────┘ │
│
┌──────────────┴───────────────────┐
│ Renderer (React, Vite, Tailwind)│
│ - Module + Layout-Shell │
│ - Zustand-Stores │
│ - ipc/* Transport-Abstraktion │
└──────────────────────────────────┘
- Sicherheit:
contextIsolation: true,nodeIntegration: false, Sandbox-konform; ausschließlich die explizit im Preload exponierteLtorApi-Oberfläche ist im Renderer sichtbar. - Live-Daten: Adapter pushen über
ProtocolManager.onSampleundonStatuszum Main-Prozess; dieser broadcastet viawebContents.sendan alle BrowserWindows.
Der Renderer redet niemals direkt mit window.ltor, sondern stets über die
Abstraktion in src/renderer/src/ipc/:
import { ipc } from "../ipc";
await ipc.connections.list();
const off = ipc.connections.onTelemetry(sample => …);ipc/index.ts löst zur Laufzeit den passenden Transport auf:
window.ltorvorhanden →ElectronTransport(Standard im Desktop-Modus).import.meta.env.VITE_LTOR_WS_URLgesetzt →WebSocketTransportzur angegebenen URL (z. B.wss://lab.example.com/ltor).- Browser ohne Vite-Dev-Port → WebSocket zu
ws[s]://<host>/ltor(Same-Host). - Sonst →
NullTransport, der alle Calls mit verständlicher Fehlermeldung ablehnt; der UI-State (Loading/Error) zeigt das sauber.
Der aktuelle Modus wird unten rechts in der Statusbar als Badge dargestellt
(Desktop, Remote, Offline).
Ein minimales JSON-RPC reicht. Ein eigenes Backend muss nur das implementieren:
Unterstützte Methoden spiegeln die LtorTransport-Schnittstelle wider
(sys.info, audit.list/append/clear,
connections.list/create/update/delete/connect/disconnect/write).
-
Konfig-Typ in
src/shared/types.tshinzufügen (type ConnectionKind, Config-Interface, Union-Erweiterung desConnection["config"]). -
Adapter in
src/main/protocols/<name>Adapter.tsanlegen, derProtocolAdapterimplementiert undAdapterEmittererweitert:export class FooAdapter extends AdapterEmitter implements ProtocolAdapter { readonly kind = "foo" as const; constructor(public readonly id: string, private cfg: FooConfig) { super(); } async connect(): Promise<void> { this.emitStatus("connecting"); // …connect… this.emitStatus("connected"); // bei jedem Sample: this.emitSample({ connectionId: this.id, channel: "x", value: 42, ts: Date.now() }); } async disconnect(): Promise<void> { this.emitStatus("disconnected"); } async write(channel: string, value: number | string | boolean): Promise<void> { … } }
-
Im ProtocolManager (
src/main/protocols/manager.ts) den neuenkindiminstantiate()-Switch registrieren. -
Im Renderer ein Formularfeld in
ConnectionForm.tsxergänzen und inConnectionsModule.tsx#endpointSummarydie Anzeige der wichtigsten Konfig-Eigenschaft. -
Optional: Default-Werte in
defaultConfig().
- Datei
src/renderer/src/modules/<name>/<Name>Module.tsxerstellen. - In
src/renderer/src/store/appStore.tsdas neueModuleIdergänzen. - In
src/renderer/src/components/layout/Sidebar.tsxeinenNAV-Eintrag. - In
src/renderer/src/App.tsxdas Modul ins Routing (activeModule === …) einbauen.
State innerhalb des Moduls → eigener Zustand-Store in store/. Datenzugriff
ausschließlich via ipc (Transport-Abstraktion) – nie direkt über
window.ltor.
audit.jsonl ist eine append-only-Datei. Jeder Eintrag:
{
"id": "01H…", // ULID (chronologisch sortierbar)
"ts": 1731585032123, // ms epoch
"category": "connection", // info | warning | alarm | sensor | connection | system
"actor": "user", // user | system
"action": "connection_created",
"details": {
/* frei strukturierbar */
},
}Schreibzugriff erfolgt ausschließlich über AuditLog.append() (oder den
IPC-Endpunkt audit:append). Manipulation an der Datei zerstört die
Lückenlosigkeits-Garantie und sollte im Produktivbetrieb durch OS-ACLs
verhindert werden.
Eine neue Kategorie:
- In
src/shared/types.tszur UnionAuditEntry["category"]hinzufügen. - Optional Filter im
AuditLogModule.tsxergänzen.
npm run build
# → out/main/, out/preload/, out/renderer/
# Verteilung als Electron-Bundle (electron-builder folgt später).server/index.ts bedient dasselbe Wire-Protokoll wie der Electron-Main und
nutzt dieselben Handler (src/main/backend.ts). Zwei Modi:
| Modus | Zweck | Verhalten |
|---|---|---|
demo (Default) |
öffentliche Demo im Netz | eigene, flüchtige Sitzung pro Browser-Tab · nur Laser-Simulator (keine ausgehenden Verbindungen → kein SSRF) · Limits & Rate-Limiting |
full |
eigener Laborserver im LAN | alle Protokolle, gemeinsamer Zustand in --data · nur hinter eigener Authentifizierung betreiben |
npm run build:online
node out/server/index.mjs --static out/web # Demo lokal: http://127.0.0.1:8646
node out/server/index.mjs --mode full --data ./ltor-data --static out/web
# full-Modus braucht zusätzlich: npm install --omit=dev (node-opcua, mqtt, axios)Optionen (Flag oder Umgebungsvariable): --port/LTOR_PORT (8646),
--host/LTOR_HOST (127.0.0.1), --mode/LTOR_MODE,
--origins/LTOR_ALLOWED_ORIGINS, --max-sessions/LTOR_MAX_SESSIONS,
--static/LTOR_STATIC_DIR. Health-Check: GET /ltor/health.
Das Demo-Bundle hat keine npm-Laufzeitabhängigkeiten – auf dem Server genügt Node.js ≥ 18.
So läuft ltor.maazi.de – übertragbar auf jeden VPS mit Plesk/Apache:
Browser ──https──▶ Apache (Plesk) ── / → Dokumentstamm (out/web)
└─ /ltor (wss) → Node 127.0.0.1:8646 (systemd)
- Subdomain in Plesk anlegen, SSL (Let's Encrypt) aktivieren, HTTP→HTTPS-Weiterleitung einschalten.
- Deployen (lokal, Git Bash):
SSH_KEY=<schlüssel> SSH_PORT=<port> deploy/deploy.sh <user>@<vps> [dokumentstamm]– baut, prüft die Physik, lädt hoch und installiert perdeploy/remote-install.sh: Backend nach/var/www/ltor, systemd-Dienstltor-backend(gehärtet, nur127.0.0.1:8646), Frontend in den Dokumentstamm. Port-Konflikte werden vorher geprüft. - Apache-Anweisungen: Inhalt von
deploy/plesk-apache-directives.confunter Apache & nginx Settings → Additional directives (HTTP und HTTPS) einfügen. Falls der WebSocket hinter Plesks nginx nicht durchkommt:deploy/plesk-nginx-directives.confverwenden. - Prüfen:
curl https://<domain>/ltor/health→{"ok":true,…}.
Sicherheit der öffentlichen Demo – wer LTor selbst online stellt, sollte diese Punkte beibehalten:
- Backend nur an
127.0.0.1binden; nach außen ausschließlich/ltorüber den Webserver freigeben (nie/auf das Backend proxien). - Modus
demo: nur der Simulator, keine ausgehenden Verbindungen (kein SSRF), Eingaben werden serverseitig validiert, Audit-Akteur wird erzwungen. - Limits: 64 KiB pro Nachricht, Rate-Limit pro Verbindung, max. Sitzungen, 6 Geräte/3 aktive pro Sitzung, Leerlauf-Abschaltung nach 60 s.
LTOR_ALLOWED_ORIGINSsetzen – fremde Webseiten können sich dann nicht mit dem WebSocket verbinden.- systemd-Härtung (
ProtectSystem=strict,NoNewPrivileges, Speicher- und CPU-Limit) ausdeploy/ltor-backend.serviceübernehmen. - Zugangsdaten (SSH-Host, Port, Schlüssel) nie ins Repository schreiben – das Deploy-Skript liest sie aus Umgebungsvariablen.
Datenschutz der Demo: keine Cookies, keine Konten, keine IP-Protokollierung.
Die Sitzung lebt nur im Arbeitsspeicher und wird 15 Minuten nach dem
Schließen des Tabs verworfen; die Sitzungs-ID liegt im sessionStorage des
Tabs.
- ✅ v0.2: Laserlabor (3D, Simulator, Laserschutz, Lernpfad), Web-Backend, öffentliche Demo.
- Phase 3: KI-Assistenzen (Anomalie-Erkennung, Wartungs-Hints).
- Phase 4: MES-/ERP-Integration, multimodale Auswertungen.
- Längerfristig: electron-builder-Paketierung (Signiert), Plugin-API für Drittprotokolle, Mehrbenutzer-Rollen, persistente Telemetrie-Aufzeichnung.
Bitte nicht als öffentliches Issue melden, sondern vertraulich über GitHub Security Advisories.
Copyright © 2026 maazi.de
LTor ist freie Software: Du kannst sie unter den Bedingungen der GNU General Public License, Version 3 (GPL-3.0), wie von der Free Software Foundation veröffentlicht, weitergeben und/oder verändern.
LTor wird in der Hoffnung verbreitet, dass es nützlich ist, aber ohne jede Gewährleistung – sogar ohne die implizite Gewährleistung der Marktreife oder der Eignung für einen bestimmten Zweck. Details stehen im vollständigen Lizenztext in LICENSE.

