# Home Automation API Client Wiederverwendbare JavaScript-API-Client-Bibliothek für das Home Automation UI. ## Installation Füge die folgenden Script-Tags in deine HTML-Seiten ein: ```html ``` ## Konfiguration Der API-Client nutzt `window.API_BASE`, das vom Backend gesetzt wird: ```javascript window.API_BASE = '{{ api_base }}'; // Jinja2 template ``` ## Verwendung ### Globale Instanz Der API-Client erstellt automatisch eine globale Instanz `window.apiClient`: ```javascript // Layout abrufen const layout = await window.apiClient.getLayout(); // Geräte abrufen const devices = await window.apiClient.getDevices(); // Gerätestatus abrufen const state = await window.apiClient.getDeviceState('kitchen_light'); // Gerätesteuerung await window.apiClient.setDeviceState('kitchen_light', 'light', { power: true, brightness: 80 }); ``` ### Verfügbare Methoden #### `getLayout(): Promise` Lädt die Layout-Daten (Räume und ihre Geräte). ```javascript const layout = await window.apiClient.getLayout(); // { rooms: [{name: "Küche", devices: ["kitchen_light", ...]}, ...] } ``` #### `getDevices(): Promise` Lädt alle Geräte mit ihren Features. ```javascript const devices = await window.apiClient.getDevices(); // [{device_id: "...", name: "...", type: "light", features: {...}}, ...] ``` #### `getDeviceState(deviceId): Promise` Lädt den aktuellen Status eines Geräts. ```javascript const state = await window.apiClient.getDeviceState('kitchen_light'); // {power: true, brightness: 80, ...} ``` #### `getAllStates(): Promise` Lädt alle Gerätestatus auf einmal. ```javascript const states = await window.apiClient.getAllStates(); // {"kitchen_light": {power: true, ...}, "thermostat_1": {...}, ...} ``` #### `setDeviceState(deviceId, type, payload): Promise` Sendet einen Befehl an ein Gerät. ```javascript // Licht einschalten await window.apiClient.setDeviceState('kitchen_light', 'light', { power: true, brightness: 80 }); // Thermostat einstellen await window.apiClient.setDeviceState('thermostat_1', 'thermostat', { target_temp: 22.5 }); // Rollladen steuern await window.apiClient.setDeviceState('cover_1', 'cover', { position: 50 }); ``` #### `getDeviceRoom(deviceId): Promise<{room: string}>` Ermittelt den Raum eines Geräts. ```javascript const { room } = await window.apiClient.getDeviceRoom('kitchen_light'); // {room: "Küche"} ``` #### `getScenes(): Promise` Lädt alle verfügbaren Szenen. ```javascript const scenes = await window.apiClient.getScenes(); ``` #### `activateScene(sceneId): Promise` Aktiviert eine Szene. ```javascript await window.apiClient.activateScene('evening'); ``` ### Realtime-Updates (SSE) #### `connectRealtime(onEvent, onError): EventSource` Verbindet sich mit dem SSE-Stream für Live-Updates. ```javascript window.apiClient.connectRealtime( (event) => { console.log('Update:', event.device_id, event.state); // event = {device_id: "...", type: "state", state: {...}} }, (error) => { console.error('Connection error:', error); } ); ``` #### `onDeviceUpdate(deviceId, callback): Function` Registriert einen Listener für spezifische Geräte-Updates. ```javascript // Für ein bestimmtes Gerät const unsubscribe = window.apiClient.onDeviceUpdate('kitchen_light', (event) => { console.log('Kitchen light changed:', event.state); updateUI(event.state); }); // Für alle Geräte const unsubscribeAll = window.apiClient.onDeviceUpdate(null, (event) => { console.log('Any device changed:', event.device_id, event.state); }); // Später: Listener entfernen unsubscribe(); ``` #### `disconnectRealtime(): void` Trennt die SSE-Verbindung und entfernt alle Listener. ```javascript window.apiClient.disconnectRealtime(); ``` ### Helper-Methoden #### `findDevice(devices, deviceId): Device|null` Findet ein Gerät in einem Array. ```javascript const devices = await window.apiClient.getDevices(); const device = window.apiClient.findDevice(devices, 'kitchen_light'); ``` #### `findRoom(layout, roomName): Room|null` Findet einen Raum im Layout. ```javascript const layout = await window.apiClient.getLayout(); const room = window.apiClient.findRoom(layout, 'Küche'); ``` #### `getDevicesForRoom(layout, devices, roomName): Device[]` Gibt alle Geräte eines Raums zurück. ```javascript const layout = await window.apiClient.getLayout(); const devices = await window.apiClient.getDevices(); const kitchenDevices = window.apiClient.getDevicesForRoom(layout, devices, 'Küche'); ``` #### `api(path): string` Konstruiert eine vollständige API-URL. ```javascript const url = window.apiClient.api('/devices'); // "http://172.19.1.11:8001/devices" ``` ### Backward Compatibility Die globale `api()` Funktion ist weiterhin verfügbar: ```javascript function api(url) { return window.apiClient.api(url); } ``` ## Typen (JSDoc) Die Datei `types.js` enthält JSDoc-Definitionen für alle API-Typen: - `Room` - Raum mit Geräten - `Layout` - Layout-Struktur - `Device` - Gerätedaten - `DeviceFeatures` - Geräte-Features - `DeviceState` - Gerätestatus (Light, Thermostat, Contact, etc.) - `RealtimeEvent` - SSE-Event-Format - `Scene` - Szenen-Definition - `*Payload` - Command-Payloads für verschiedene Gerätetypen Diese ermöglichen IDE-Autocomplete und Type-Checking in modernen Editoren (VS Code, WebStorm). ## Beispiel: Vollständige Seite ```html My Page
``` ## Error Handling Alle API-Methoden werfen Exceptions bei Fehlern: ```javascript try { const state = await window.apiClient.getDeviceState('invalid_id'); } catch (error) { console.error('API error:', error); showErrorMessage(error.message); } ``` ## Auto-Reconnect Der SSE-Client versucht automatisch, nach 5 Sekunden wieder zu verbinden, wenn die Verbindung abbricht. ## Verwendete Technologien - **Fetch API** - Für HTTP-Requests - **EventSource** - Für Server-Sent Events - **JSDoc** - Für Type Definitions - **ES6+** - Modern JavaScript (Class, async/await, etc.)