Skip to content

# 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
2. Always include authentication tokens
3. Implement token refresh mechanisms

4. Handle authentication errors gracefully

5. Error Handling

6. Implement progressive retry logic
7. Log connection issues

8. Notify users of connection status

9. Resource Management

10. Close EventSource connections when not needed
11. Limit the number of concurrent connections

12. Use filtered subscriptions when possible

13. Performance

14. Process events efficiently
15. Batch UI updates
16. 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
        };
    }, []);

## Related Resources

- API Overview
- Core Functions
- WebSocket API
- Troubleshooting

February 5, 2025
February 5, 2025
Was this page helpful?
Thanks for your feedback!
Thanks for your feedback! Please consider creating an issue to help us improve.

#### Cookie consent

We use cookies to recognize your repeated visits and preferences, as well as to measure the effectiveness of our documentation and whether users find what they're searching for. With your consent, you're helping us to make our documentation better.

- Google Analytics
- GitHub

Manage settings