Files
homeassistant-mcp/docs/api/sse.md
jango-blockchained 53a041921b docs: enhance documentation with comprehensive API, architecture, and installation guides
- Add detailed API documentation for core functions, SSE, and WebSocket APIs
- Create comprehensive architecture overview with system design diagrams
- Develop in-depth installation and quick start guides
- Improve troubleshooting documentation with advanced debugging techniques
- Update site navigation and markdown configuration
2025-02-05 02:44:30 +01:00

6.1 KiB

layout, title, parent, nav_order
layout title parent nav_order
default SSE API API Reference 2

Server-Sent Events (SSE) API 📡

The SSE API provides real-time updates about device states and events from your Home Assistant setup. This guide covers how to use and implement SSE connections in your applications.

Overview

Server-Sent Events (SSE) is a standard that enables servers to push real-time updates to clients over HTTP connections. MCP Server uses SSE to provide:

  • Real-time device state updates
  • Event notifications
  • System status changes
  • Command execution results

Basic Usage

Establishing a Connection

Create an EventSource connection to receive updates:

const eventSource = new EventSource('http://localhost:3000/subscribe_events?token=YOUR_JWT_TOKEN');

eventSource.onmessage = (event) => {
    const data = JSON.parse(event.data);
    console.log('Received update:', data);
};

Connection States

Handle different connection states:

eventSource.onopen = () => {
    console.log('Connection established');
};

eventSource.onerror = (error) => {
    console.error('Connection error:', error);
    // Implement reconnection logic if needed
};

Event Types

Device State Events

Subscribe to all device state changes:

const stateEvents = new EventSource('http://localhost:3000/subscribe_events?type=state');

stateEvents.onmessage = (event) => {
    const state = JSON.parse(event.data);
    console.log('Device state changed:', state);
};

Example state event:

{
  "type": "state_changed",
  "entity_id": "light.living_room",
  "state": "on",
  "attributes": {
    "brightness": 255,
    "color_temp": 370
  },
  "timestamp": "2024-01-20T15:30:00Z"
}

Filtered Subscriptions

By Domain

Subscribe to specific device types:

// Subscribe to only light events
const lightEvents = new EventSource('http://localhost:3000/subscribe_events?domain=light');

// Subscribe to multiple domains
const multiEvents = new EventSource('http://localhost:3000/subscribe_events?domain=light,switch,sensor');

By Entity ID

Subscribe to specific devices:

// Single entity
const livingRoomLight = new EventSource(
    'http://localhost:3000/subscribe_events?entity_id=light.living_room'
);

// Multiple entities
const kitchenDevices = new EventSource(
    'http://localhost:3000/subscribe_events?entity_id=light.kitchen,switch.coffee_maker'
);

Advanced Usage

Connection Management

Implement robust connection handling:

class SSEManager {
    constructor(url, options = {}) {
        this.url = url;
        this.options = {
            maxRetries: 3,
            retryDelay: 1000,
            ...options
        };
        this.retryCount = 0;
        this.connect();
    }

    connect() {
        this.eventSource = new EventSource(this.url);
        
        this.eventSource.onopen = () => {
            this.retryCount = 0;
            console.log('Connected to SSE stream');
        };

        this.eventSource.onerror = (error) => {
            this.handleError(error);
        };

        this.eventSource.onmessage = (event) => {
            this.handleMessage(event);
        };
    }

    handleError(error) {
        console.error('SSE Error:', error);
        this.eventSource.close();

        if (this.retryCount < this.options.maxRetries) {
            this.retryCount++;
            setTimeout(() => {
                console.log(`Retrying connection (${this.retryCount}/${this.options.maxRetries})`);
                this.connect();
            }, this.options.retryDelay * this.retryCount);
        }
    }

    handleMessage(event) {
        try {
            const data = JSON.parse(event.data);
            // Handle the event data
            console.log('Received:', data);
        } catch (error) {
            console.error('Error parsing SSE data:', error);
        }
    }

    disconnect() {
        if (this.eventSource) {
            this.eventSource.close();
        }
    }
}

// Usage
const sseManager = new SSEManager('http://localhost:3000/subscribe_events?token=YOUR_TOKEN');

Event Filtering

Filter events on the client side:

class EventFilter {
    constructor(conditions) {
        this.conditions = conditions;
    }

    matches(event) {
        return Object.entries(this.conditions).every(([key, value]) => {
            if (Array.isArray(value)) {
                return value.includes(event[key]);
            }
            return event[key] === value;
        });
    }
}

// Usage
const filter = new EventFilter({
    domain: ['light', 'switch'],
    state: 'on'
});

eventSource.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (filter.matches(data)) {
        console.log('Matched event:', data);
    }
};

Best Practices

  1. Authentication

    • Always include authentication tokens
    • Implement token refresh mechanisms
    • Handle authentication errors gracefully
  2. Error Handling

    • Implement progressive retry logic
    • Log connection issues
    • Notify users of connection status
  3. Resource Management

    • Close EventSource connections when not needed
    • Limit the number of concurrent connections
    • Use filtered subscriptions when possible
  4. Performance

    • Process events efficiently
    • Batch UI updates
    • Consider debouncing frequent updates

Common Issues

Connection Drops

If the connection drops, the EventSource will automatically attempt to reconnect. You can customize this behavior:

eventSource.addEventListener('error', (error) => {
    if (eventSource.readyState === EventSource.CLOSED) {
        // Connection closed, implement custom retry logic
    }
});

Memory Leaks

Always clean up EventSource connections:

// In a React component
useEffect(() => {
    const eventSource = new EventSource('http://localhost:3000/subscribe_events');
    
    return () => {
        eventSource.close(); // Cleanup on unmount
    };
}, []);