Event handling is a fundamental concept in Home Assistant. The event bus is the central nervous system that allows components to communicate asynchronously. Understanding how to work with events efficiently is crucial for building responsive integrations.
Understanding the Event Bus
The event bus (EventBus) allows firing and listening for events throughout Home Assistant. Every state change, service call, and custom integration action can be represented as an event.
Key Event Types
Home Assistant Core defines several built-in event types:
EVENT_STATE_CHANGED - Fired when an entity’s state changes
EVENT_STATE_REPORTED - Fired when state is updated but unchanged
EVENT_HOMEASSISTANT_START - Fired when Home Assistant starts
EVENT_HOMEASSISTANT_STARTED - Fired after all components are loaded
EVENT_HOMEASSISTANT_STOP - Fired when Home Assistant begins shutdown
EVENT_SERVICE_REGISTERED - Fired when a service is registered
EVENT_CALL_SERVICE - Fired when a service is called
Reference: homeassistant/const.py
Listening to Events
Basic Event Listener
Use async_listen to subscribe to events. This method must be run in the event loop:
Reference: homeassistant/core.py:1565
Event Filters
Event filters allow you to pre-filter events before your handler is called, improving performance:
Reference: homeassistant/core.py:1569
Event filters must be decorated with @callback to ensure they run synchronously in the event loop.
Tracking State Changes
Track State Change Events
For entity-specific state tracking, use the optimized async_track_state_change_event helper:
Reference: homeassistant/helpers/event.py:309
Track by Domain
Track when entities are added to specific domains:
Reference: homeassistant/helpers/event.py:653
Advanced Tracking Patterns
Filtered State Change Tracking
Use async_track_state_change_filtered for dynamic entity tracking:
Reference: homeassistant/helpers/event.py:867
Template Tracking
Track template results and react to changes:
Reference: homeassistant/helpers/event.py:1343
Time-Based Event Tracking
Track Point in Time
Schedule a callback at a specific time:
Reference: homeassistant/helpers/event.py:1544
Firing Events
Fire Internal Events
For internal core use, fire events directly without extra validation:
Reference: homeassistant/core.py:1492
Fire Public Events
For integration events that may be consumed externally:
Reference: homeassistant/core.py:1470
Event Dispatching Optimization
The event system uses several optimizations:
- Entity ID Indexing: State change events are indexed by entity_id for fast routing
- Event Filters: Pre-filtering prevents unnecessary job creation
- Call Soon: Events are dispatched with
call_soon to ensure proper event loop iteration
- Job Types: Callbacks are executed directly, coroutines are scheduled efficiently
Reference: homeassistant/helpers/event.py:340-367
Best Practices
Use @callback Decorator
Always decorate synchronous event handlers with @callback:
Async Handlers
For async operations, use coroutine functions:
Clean Up Listeners
Always remove listeners when they’re no longer needed:
Avoid Long-Running Operations
Event handlers should be fast. For long operations, create a task:
- Use specific tracking helpers -
async_track_state_change_event is more efficient than manual filtering
- Implement event filters - Pre-filter events to avoid unnecessary processing
- Index by entity_id - The event system automatically optimizes entity-specific tracking
- Batch updates - When possible, batch multiple state changes together
Common Pitfalls
- Don’t block the event loop in event handlers
- Always clean up listeners to prevent memory leaks
- Don’t modify event data directly (it may be shared)
- Use
@callback for synchronous handlers to avoid thread issues