# Home Assistant Integration & Automation **Meta-Description:** Smart Home Automation mit Home Assistant. WebSocket API, Node-RED Integration, Custom Automations und YAML-Konfiguration. **Keywords:** Home Assistant, Smart Home, Automation, Node-RED, WebSocket API, YAML, IoT Platform --- ## Einführung **Home Assistant** ist die führende Open-Source Smart Home Plattform. Mit über 2.800 Integrations, lokaler Kontrolle und einer aktiven Community bietet sie die perfekte Grundlage für jedes Smart Home Projekt. --- ## Home Assistant Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ HOME ASSISTANT ARCHITECTURE │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Frontend │ │ Core │ │ Supervisor │ │ │ │ (React) │←──→│ (Python) │←──→│ (Docker) │ │ │ └─────────────┘ └──────┬──────┘ └─────────────┘ │ │ │ │ │ ┌─────────────────────────┼─────────────────────────┐ │ │ │ Integrations │ │ │ ├─────────────────────────┼─────────────────────────┤ │ │ │ ┌────────┐ ┌────────┐ │ ┌────────┐ ┌────────┐ │ │ │ │ │ Zigbee │ │ Z-Wave │ │ │ MQTT │ │ HTTP │ │ │ │ │ └────────┘ └────────┘ │ └────────┘ └────────┘ │ │ │ │ ┌────────┐ ┌────────┐ │ ┌────────┐ ┌────────┐ │ │ │ │ │ Thread │ │ Matter │ │ │Bluetooth│ │ Cloud │ │ │ │ │ └────────┘ └────────┘ │ └────────┘ └────────┘ │ │ │ └───────────────────────────────────────────────────┘ │ │ │ │ Protocols: WebSocket, REST API, MQTT │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Installation & Setup ```bash # Docker Installation docker run -d \ --name homeassistant \ --privileged \ --restart=unless-stopped \ -e TZ=Europe/Berlin \ -v /path/to/config:/config \ -v /run/dbus:/run/dbus:ro \ --network=host \ ghcr.io/home-assistant/home-assistant:stable # Oder mit Docker Compose # docker-compose.yml version: '3' services: homeassistant: container_name: homeassistant image: "ghcr.io/home-assistant/home-assistant:stable" volumes: - ./config:/config - /etc/localtime:/etc/localtime:ro - /run/dbus:/run/dbus:ro restart: unless-stopped privileged: true network_mode: host ``` --- ## WebSocket API Integration ```typescript // lib/homeassistant-client.ts import WebSocket from 'ws'; interface HAMessage { id?: number; type: string; [key: string]: any; } interface HAState { entity_id: string; state: string; attributes: Record; last_changed: string; last_updated: string; } class HomeAssistantClient { private ws: WebSocket | null = null; private messageId = 1; private pendingRequests: Map void; reject: (error: Error) => void; }> = new Map(); private eventSubscribers: Map void>> = new Map(); constructor( private url: string, private token: string ) {} async connect(): Promise { return new Promise((resolve, reject) => { this.ws = new WebSocket(this.url); this.ws.on('open', () => { console.log('Connected to Home Assistant'); }); this.ws.on('message', async (data) => { const message = JSON.parse(data.toString()); await this.handleMessage(message, resolve); }); this.ws.on('error', (error) => { console.error('WebSocket error:', error); reject(error); }); this.ws.on('close', () => { console.log('Connection closed'); this.reconnect(); }); }); } private async handleMessage(message: any, onAuth?: (value: void) => void) { switch (message.type) { case 'auth_required': this.send({ type: 'auth', access_token: this.token }); break; case 'auth_ok': console.log('Authenticated with Home Assistant'); onAuth?.(); break; case 'auth_invalid': throw new Error('Invalid authentication'); case 'result': const pending = this.pendingRequests.get(message.id); if (pending) { if (message.success) { pending.resolve(message.result); } else { pending.reject(new Error(message.error?.message)); } this.pendingRequests.delete(message.id); } break; case 'event': this.handleEvent(message.event); break; } } private handleEvent(event: any) { const eventType = event.event_type; const subscribers = this.eventSubscribers.get(eventType); if (subscribers) { subscribers.forEach(callback => callback(event.data)); } // Wildcard subscribers const allSubscribers = this.eventSubscribers.get('*'); if (allSubscribers) { allSubscribers.forEach(callback => callback(event)); } } private send(message: HAMessage) { if (this.ws?.readyState === WebSocket.OPEN) { this.ws.send(JSON.stringify(message)); } } private async sendCommand(message: Omit): Promise { return new Promise((resolve, reject) => { const id = this.messageId++; this.pendingRequests.set(id, { resolve, reject }); this.send({ ...message, id }); // Timeout nach 30 Sekunden setTimeout(() => { if (this.pendingRequests.has(id)) { this.pendingRequests.delete(id); reject(new Error('Request timeout')); } }, 30000); }); } // States abrufen async getStates(): Promise { return this.sendCommand({ type: 'get_states' }); } async getState(entityId: string): Promise { const states = await this.getStates(); return states.find(s => s.entity_id === entityId); } // Services aufrufen async callService( domain: string, service: string, serviceData?: Record, target?: { entity_id?: string | string[] } ): Promise { await this.sendCommand({ type: 'call_service', domain, service, service_data: serviceData, target }); } // Events abonnieren async subscribeEvents( eventType: string, callback: (data: any) => void ): Promise<() => void> { if (!this.eventSubscribers.has(eventType)) { this.eventSubscribers.set(eventType, new Set()); // Bei HA registrieren await this.sendCommand({ type: 'subscribe_events', event_type: eventType === '*' ? undefined : eventType }); } this.eventSubscribers.get(eventType)!.add(callback); // Unsubscribe Function return () => { this.eventSubscribers.get(eventType)?.delete(callback); }; } // Trigger State Change async subscribeStateChanges( entityId: string, callback: (newState: HAState, oldState: HAState) => void ): Promise<() => void> { return this.subscribeEvents('state_changed', (data) => { if (data.entity_id === entityId) { callback(data.new_state, data.old_state); } }); } private reconnect() { setTimeout(() => { console.log('Reconnecting...'); this.connect(); }, 5000); } disconnect() { this.ws?.close(); } } // Verwendung const ha = new HomeAssistantClient( 'ws://homeassistant.local:8123/api/websocket', process.env.HA_TOKEN! ); await ha.connect(); // Alle States abrufen const states = await ha.getStates(); console.log(`${states.length} entities found`); // Licht einschalten await ha.callService('light', 'turn_on', { brightness: 255, color_temp: 300 }, { entity_id: 'light.wohnzimmer' }); // State Changes beobachten ha.subscribeStateChanges('sensor.temperature', (newState, oldState) => { console.log(`Temperature changed: ${oldState.state} → ${newState.state}`); }); ``` --- ## REST API Integration ```typescript // lib/homeassistant-rest.ts interface HARestConfig { baseUrl: string; token: string; } class HomeAssistantREST { private baseUrl: string; private headers: HeadersInit; constructor(config: HARestConfig) { this.baseUrl = config.baseUrl.replace(/\/$/, ''); this.headers = { 'Authorization': `Bearer ${config.token}`, 'Content-Type': 'application/json' }; } private async request( method: string, endpoint: string, body?: any ): Promise { const response = await fetch(`${this.baseUrl}/api${endpoint}`, { method, headers: this.headers, body: body ? JSON.stringify(body) : undefined }); if (!response.ok) { throw new Error(`HA API Error: ${response.status}`); } return response.json(); } // API Status async getApiStatus(): Promise<{ message: string }> { return this.request('GET', '/'); } // Config async getConfig(): Promise { return this.request('GET', '/config'); } // States async getStates(): Promise { return this.request('GET', '/states'); } async getState(entityId: string): Promise { return this.request('GET', `/states/${entityId}`); } async setState(entityId: string, state: string, attributes?: Record): Promise { return this.request('POST', `/states/${entityId}`, { state, attributes }); } // Services async getServices(): Promise> { return this.request('GET', '/services'); } async callService( domain: string, service: string, data?: Record ): Promise { return this.request('POST', `/services/${domain}/${service}`, data); } // History async getHistory( entityId: string, startTime?: Date, endTime?: Date ): Promise { const params = new URLSearchParams(); if (startTime) params.set('start_time', startTime.toISOString()); if (endTime) params.set('end_time', endTime.toISOString()); params.set('filter_entity_id', entityId); return this.request('GET', `/history/period?${params}`); } // Logbook async getLogbook( entityId?: string, startTime?: Date, endTime?: Date ): Promise { const params = new URLSearchParams(); if (entityId) params.set('entity', entityId); if (startTime) params.set('start_time', startTime.toISOString()); if (endTime) params.set('end_time', endTime.toISOString()); return this.request('GET', `/logbook?${params}`); } // Template Rendering async renderTemplate(template: string): Promise { const result = await this.request<{ result: string }>('POST', '/template', { template }); return result.result; } } // API Route für Next.js // app/api/home/lights/route.ts import { NextRequest, NextResponse } from 'next/server'; const ha = new HomeAssistantREST({ baseUrl: process.env.HA_URL!, token: process.env.HA_TOKEN! }); export async function GET() { const states = await ha.getStates(); const lights = states.filter(s => s.entity_id.startsWith('light.')); return NextResponse.json(lights.map(light => ({ id: light.entity_id, name: light.attributes.friendly_name, state: light.state, brightness: light.attributes.brightness, color_temp: light.attributes.color_temp }))); } export async function POST(request: NextRequest) { const { entityId, action, ...params } = await request.json(); await ha.callService('light', action, { entity_id: entityId, ...params }); return NextResponse.json({ success: true }); } ``` --- ## YAML Automations ```yaml # automations.yaml # Licht bei Bewegung einschalten - id: 'motion_light_on' alias: 'Flur Licht bei Bewegung' description: 'Schaltet das Flur-Licht bei Bewegung ein' trigger: - platform: state entity_id: binary_sensor.flur_motion to: 'on' condition: - condition: state entity_id: sun.sun state: 'below_horizon' - condition: state entity_id: input_boolean.guest_mode state: 'off' action: - service: light.turn_on target: entity_id: light.flur data: brightness_pct: 80 transition: 2 - delay: '00:05:00' - service: light.turn_off target: entity_id: light.flur data: transition: 5 mode: restart # Temperatur-basierte Heizungssteuerung - id: 'heating_control' alias: 'Heizung Temperatur Kontrolle' trigger: - platform: numeric_state entity_id: sensor.wohnzimmer_temperature below: 20 condition: - condition: state entity_id: input_boolean.heating_enabled state: 'on' - condition: time after: '06:00:00' before: '22:00:00' action: - service: climate.set_temperature target: entity_id: climate.wohnzimmer data: temperature: 22 hvac_mode: heat # Guten Morgen Routine - id: 'morning_routine' alias: 'Guten Morgen Routine' trigger: - platform: time at: input_datetime.wakeup_time condition: - condition: state entity_id: input_boolean.alarm_enabled state: 'on' - condition: state entity_id: person.user state: 'home' action: - service: light.turn_on target: entity_id: light.schlafzimmer data: brightness_pct: 10 color_temp: 500 - delay: '00:05:00' - service: light.turn_on data: brightness_pct: 50 color_temp: 370 transition: 300 - service: media_player.play_media target: entity_id: media_player.schlafzimmer_speaker data: media_content_type: music media_content_id: 'spotify:playlist:morning' - service: notify.mobile_app data: message: "Guten Morgen! Es sind {{ states('sensor.outside_temperature') }}°C draußen." ``` --- ## Node-RED Integration ```json // Node-RED Flow für Home Assistant [ { "id": "ha-server", "type": "server", "name": "Home Assistant", "addon": true }, { "id": "motion-trigger", "type": "server-state-changed", "name": "Motion Detected", "server": "ha-server", "entityId": "binary_sensor.motion", "entityIdType": "exact", "outputInitially": false, "stateType": "str", "ifState": "on", "ifStateType": "str", "outputOnlyOnStateChange": true, "wires": [["check-conditions"]] }, { "id": "check-conditions", "type": "api-current-state", "name": "Check Sun State", "server": "ha-server", "entityId": "sun.sun", "outputProperties": [ { "property": "payload", "propertyType": "msg", "value": "", "valueType": "entityState" } ], "wires": [["filter-night"]] }, { "id": "filter-night", "type": "switch", "name": "Night Only", "property": "payload", "rules": [ { "t": "eq", "v": "below_horizon", "vt": "str" } ], "wires": [["turn-on-light"]] }, { "id": "turn-on-light", "type": "api-call-service", "name": "Turn On Light", "server": "ha-server", "service_domain": "light", "service": "turn_on", "entityId": "light.hallway", "data": "{\"brightness_pct\": 80, \"transition\": 2}", "wires": [[]] } ] ``` ```typescript // Custom Node-RED Node import { Red, Node, NodeProperties } from 'node-red'; interface SmartLightConfig extends NodeProperties { server: string; entityId: string; brightness: number; colorTemp: number; } module.exports = function(RED: Red) { function SmartLightNode(this: Node, config: SmartLightConfig) { RED.nodes.createNode(this, config); const server = RED.nodes.getNode(config.server) as any; this.on('input', async (msg: any) => { try { const brightness = msg.brightness || config.brightness; const colorTemp = msg.colorTemp || config.colorTemp; await server.websocket.callService('light', 'turn_on', { entity_id: config.entityId, brightness_pct: brightness, color_temp: colorTemp }); this.status({ fill: 'green', shape: 'dot', text: 'Light on' }); this.send({ ...msg, payload: { success: true } }); } catch (error) { this.status({ fill: 'red', shape: 'ring', text: 'Error' }); this.error(error); } }); } RED.nodes.registerType('smart-light', SmartLightNode); }; ``` --- ## Custom Integration Development ```python # custom_components/my_sensor/sensor.py """Custom sensor integration for Home Assistant.""" from homeassistant.components.sensor import ( SensorEntity, SensorDeviceClass, SensorStateClass, ) from homeassistant.const import UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.entity_platform import AddEntitiesCallback async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the sensor platform.""" async_add_entities([ MySensor(config_entry), ]) class MySensor(SensorEntity): """Representation of a custom sensor.""" _attr_name = "My Custom Sensor" _attr_device_class = SensorDeviceClass.TEMPERATURE _attr_state_class = SensorStateClass.MEASUREMENT _attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS def __init__(self, config_entry: ConfigEntry) -> None: """Initialize the sensor.""" self._attr_unique_id = f"{config_entry.entry_id}_temperature" self._attr_native_value = None async def async_update(self) -> None: """Fetch new state data for the sensor.""" # API Call oder Sensor-Abfrage self._attr_native_value = await self._fetch_temperature() async def _fetch_temperature(self) -> float: """Fetch temperature from external source.""" # Implementierung return 21.5 ``` --- ## Dashboard Configuration ```yaml # ui-lovelace.yaml title: Smart Home views: - title: Übersicht path: overview icon: mdi:home cards: - type: weather-forecast entity: weather.home - type: grid columns: 3 cards: - type: button entity: light.wohnzimmer name: Wohnzimmer icon: mdi:sofa tap_action: action: toggle - type: button entity: light.schlafzimmer name: Schlafzimmer icon: mdi:bed - type: button entity: script.movie_mode name: Kino Modus icon: mdi:movie - type: entities title: Temperaturen entities: - entity: sensor.wohnzimmer_temperature - entity: sensor.schlafzimmer_temperature - entity: sensor.aussen_temperature - type: history-graph title: Temperaturverlauf hours_to_show: 24 entities: - entity: sensor.wohnzimmer_temperature - entity: sensor.aussen_temperature ``` --- ## Fazit Home Assistant bietet: 1. **Lokale Kontrolle**: Keine Cloud-Abhängigkeit 2. **2800+ Integrations**: Alle Smart Home Protokolle 3. **Flexible APIs**: WebSocket, REST, MQTT 4. **Node-RED**: Visual Automation Flows Die perfekte Plattform für Smart Home Projekte. --- ## Bildprompts 1. "Smart home dashboard with device controls, Home Assistant interface" 2. "Automation flow connecting sensors and actuators, Node-RED visual programming" 3. "Home network diagram with IoT devices, local smart home server" --- ## Quellen - [Home Assistant Documentation](https://www.home-assistant.io/) - [Home Assistant 2026.1 Release](https://www.home-assistant.io/blog/2026/01/07/release-20261) - [Node-RED Home Assistant](https://flows.nodered.org/node/node-red-contrib-home-assistant) - [Home Assistant WebSocket API](https://developers.home-assistant.io/docs/api/websocket)