- 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
266 lines
6.1 KiB
Markdown
266 lines
6.1 KiB
Markdown
---
|
|
layout: default
|
|
title: SSE API
|
|
parent: API Reference
|
|
nav_order: 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:
|
|
|
|
```javascript
|
|
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:
|
|
|
|
```javascript
|
|
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:
|
|
|
|
```javascript
|
|
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:
|
|
```json
|
|
{
|
|
"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:
|
|
|
|
```javascript
|
|
// 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:
|
|
|
|
```javascript
|
|
// 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:
|
|
|
|
```javascript
|
|
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:
|
|
|
|
```javascript
|
|
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:
|
|
|
|
```javascript
|
|
eventSource.addEventListener('error', (error) => {
|
|
if (eventSource.readyState === EventSource.CLOSED) {
|
|
// Connection closed, implement custom retry logic
|
|
}
|
|
});
|
|
```
|
|
|
|
### Memory Leaks
|
|
Always clean up EventSource connections:
|
|
|
|
```javascript
|
|
// In a React component
|
|
useEffect(() => {
|
|
const eventSource = new EventSource('http://localhost:3000/subscribe_events');
|
|
|
|
return () => {
|
|
eventSource.close(); // Cleanup on unmount
|
|
};
|
|
}, []);
|
|
```
|
|
|
|
## Related Resources
|
|
|
|
- [API Overview](index.md)
|
|
- [Core Functions](core.md)
|
|
- [WebSocket API](index.md#websocket-api)
|
|
- [Troubleshooting](../troubleshooting.md) |