Jesse A. Green / notebook

Home Assistant Core — Administrator & Developer Guide

Generated May 2026 from home-assistant/core at 277daf2

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

1. Architecture Overview

Home Assistant Core is an open-source Python home automation platform built on an asynchronous, event-driven architecture. It provides a unified system for device control, state management, automation, and data recording, with over 2,000 integrations connecting to virtually every smart home protocol and service.

System Architecture

                    ┌─────────────────────────────────┐
                    │         Web Browser / App        │
                    └──────────┬──────────┬────────────┘
                               │ HTTP/WS  │ WebRTC
                    ┌──────────▼──────────▼────────────┐
                    │       Frontend (Lovelace)         │
                    ├──────────────────────────────────┤
                    │         HTTP Server (aiohttp)     │
                    │     REST API    │   WebSocket API  │
                    ├──────────────────────────────────┤
                    │           Core Event Bus          │
                    │     State Machine  │  Service Reg  │
                    ├──────────────────────────────────┤
                    │         Integration Layer         │
                    │  ┌─────┐ ┌──────┐ ┌───────────┐  │
                    │  │MQTT │ │Alexa │ │Automation │  │
                    │  └─────┘ └──────┘ └───────────┘  │
                    │  ┌─────┐ ┌──────┐ ┌───────────┐  │
                    │  │SSDP │ │go2rtc│ │ Recorder  │  │
                    │  └─────┘ └──────┘ └───────────┘  │
                    │  ┌─────┐ ┌──────┐ ┌───────────┐  │
                    │  │Hue  │ │ MCP  │ │ Template  │  │
                    │  └─────┘ └──────┘ └───────────┘  │
                    │       + 2,000 more integrations   │
                    ├──────────────────────────────────┤
                    │      Registries & Helpers         │
                    │  Area│Device│Entity│Floor│Label   │
                    ├──────────────────────────────────┤
                    │   Auth (JWT + MFA + Permissions)  │
                    ├──────────────────────────────────┤
                    │     Recorder (SQLAlchemy/SQLite)  │
                    └──────────────────────────────────┘

Component Inventory

Component Path Role
Core homeassistant/core.py Event bus, state machine, service registry, HomeAssistant class
Bootstrap homeassistant/bootstrap.py Staged startup, integration loading, recovery mode
Configuration homeassistant/config.py YAML parsing, validation, package merging, safe mode
Authentication homeassistant/auth/ JWT tokens, MFA, user/group management, permission policies
Helpers homeassistant/helpers/ 74 utility modules — registries, HTTP client, templates, entity management
Utilities homeassistant/util/ 38 low-level modules — slugify, color, datetime, throttle, async
Components homeassistant/components/ 2,000+ integration packages
Generated homeassistant/generated/ 17 auto-generated files (discovery matchers, config flows, locales)
Scripts script/ Development tools (hassfest, translations, scaffold, version_bump)
Tests tests/ Comprehensive test suite

Technology Stack

Layer Technology
Language Python 3.13+
Async Runtime asyncio with eager_start tasks
HTTP Server aiohttp 3.13.x
Database SQLAlchemy 2.0.x + SQLite (WAL mode, FK enforcement)
Template Engine Jinja2 3.1.x
Config Validation voluptuous 0.15.x
JSON orjson 3.11.x (high-performance)
Date/Time ciso8601 (fast ISO 8601 parsing)
Crypto PyJWT 2.12.x (HS256), bcrypt 5.0.x, cryptography 46.x
DNS aiodns 4.0.x with async mDNS resolver
Media ha-ffmpeg 3.2.x, PyTurboJPEG 2.2.x, Pillow 12.2.x
Voice hassil 3.5.x (intent recognition), pymicro-vad (voice activity), pyspeex-noise
Discovery zeroconf 0.148.x, async-upnp-client, home-assistant-bluetooth 2.0.x
Cloud hass-nabucasa 2.2.x
Backup securetar 2026.4.x (encrypted tar archives)
Package Mgmt uv 0.11.x (replaces pip for dependency resolution)

Core Data Flow

State change propagation:

1. Integration detects device change (push or poll)
2. Integration calls hass.states.async_set(entity_id, new_state, attributes)
3. State machine fires EVENT_STATE_CHANGED on the event bus
4. Listeners react:
   - Automation engine evaluates triggers
   - Recorder persists to database
   - Frontend pushes WebSocket update to connected clients
   - Template entities re-evaluate
   - Any registered state change callbacks fire

Service call flow:

1. User/API/Automation calls hass.services.async_call(domain, service, data)
2. Service registry looks up registered handler
3. Handler validates data against service schema
4. Handler executes the action (device control, state change, etc.)
5. Results propagate via state changes and events

Note

The event bus is the central nervous system. All inter-component communication flows through events. The state machine, service registry, and component lifecycle are all coordinated via event subscriptions.


2. System Requirements

Hardware Requirements

Tier CPU RAM Storage Use Case
Minimum 1 GHz ARMv7+ 2 GB 32 GB SD/eMMC Small setup (<20 devices)
Recommended 1.5 GHz quad-core 4 GB 64 GB SSD Typical home (20-100 devices)
Large 2+ GHz quad-core 8 GB+ 128 GB+ SSD Power user (100+ devices, extensive history)

Software Requirements

Requirement Version
Python 3.13+
Operating System Linux (any distribution), macOS, Windows via WSL
Database SQLite 3.31+ (bundled), MySQL 8+, MariaDB 10.3+, PostgreSQL 12+ (optional)
Container Runtime Docker 20.10+ (for container installs)

Network Requirements

Protocol Port Purpose
HTTP 8123 Web UI and REST API
SSDP 1900/UDP UPnP device discovery (multicast)
mDNS 5353/UDP Zeroconf device discovery (multicast)
MQTT 1883/8883 MQTT broker (if using MQTT)
RTSP 18554/TCP go2rtc RTSP proxy (localhost only)
WebRTC 18555/TCP go2rtc WebRTC signaling
go2rtc API 11984 go2rtc management API (localhost only)

Core Dependencies

Package Version Purpose
aiohttp 3.13.5 Async HTTP server and client
SQLAlchemy 2.0.49 Database ORM for recorder
voluptuous 0.15.2 Configuration schema validation
Jinja2 3.1.6 Template engine
orjson 3.11.8 High-performance JSON serialization
PyJWT 2.12.1 JWT token handling
bcrypt 5.0.0 Password hashing
cryptography 46.0.7 TLS and cryptographic operations
PyYAML 6.0.3 YAML configuration parsing
annotatedyaml 1.0.2 YAML parsing with annotations
ciso8601 2.3.3 Fast ISO 8601 datetime parsing
zeroconf 0.148.0 mDNS/DNS-SD device discovery
requests 2.33.1 Synchronous HTTP client (legacy integrations)
httpx 0.28.1 Modern async HTTP client
Pillow 12.2.0 Image processing
securetar 2026.4.1 Encrypted backup archives
uv 0.11.6 Fast Python package installer

3. Configuration Reference

Configuration Files

File Format Location Purpose
configuration.yaml YAML Config dir root Primary configuration
automations.yaml YAML Config dir root UI-managed automation definitions
scripts.yaml YAML Config dir root UI-managed script definitions
scenes.yaml YAML Config dir root UI-managed scene definitions
secrets.yaml YAML Config dir root Secret values (excluded from backups by design intent)
customize.yaml YAML Config dir root Entity customization overrides
.HA_VERSION Text Config dir root Installed version marker
.safe_mode File Config dir root Presence triggers safe mode on next boot
.HA_RESTORE JSON Config dir root Backup restore instruction (consumed on boot)
.HA_RESTORE_RESULT JSON Config dir root Result of last restore attempt
home-assistant.log Text Config dir root Application log (rotatable)
home-assistant.log.fault Text Config dir root Fault handler output (crash traces)

Environment Variables

Variable Type Default Description Required?
SUPERVISOR_TOKEN string — Authentication token for Supervisor API communication Only in HAOS/Supervised
SOFT_FILE_LIMIT integer — Override the soft file descriptor limit for the process No
CI boolean — Indicates CI environment (affects hassfest behavior) Dev only
AZURE_BRANCH string — Branch name for Azure DevOps translation uploads Dev only
LOKALISE_TOKEN string — API token for Lokalise translation management Dev only

CLI Flags

Flag Type Default Description
--version action — Display version and exit
-c, --config string ~/.homeassistant Configuration directory path
--recovery-mode boolean false Start in recovery mode
--debug boolean false Enable debug mode
--open-ui boolean false Open web UI in browser on start
--skip-pip boolean false Skip all pip installs on startup
--skip-pip-packages string [] Comma-separated packages to skip
-v, --verbose boolean false Enable verbose file logging
--log-rotate-days integer None Days to keep rotated logs
--log-file string CONFIG/home-assistant.log Custom log file path
--log-no-color boolean false Disable colored log output
--script string — Run an embedded script
--ignore-os-check boolean false Skip OS validation

Important

--skip-pip and --skip-pip-packages are mutually exclusive. Using --skip-pip in non-containerized environments will cause integrations with uninstalled dependencies to fail.

Core Configuration Schema

The homeassistant: section in configuration.yaml:

Key Type Default Description
name string "Home" Instance name
latitude float 0 Home latitude (WGS84)
longitude float 0 Home longitude (WGS84)
elevation integer 0 Elevation above sea level (meters)
unit_system string "metric" metric or us_customary
currency string "USD" ISO 4217 currency code
country string — ISO 3166 country code
time_zone string "UTC" IANA timezone identifier
internal_url string — URL for internal network access
external_url string — URL for external access
customize dict — Entity customization
customize_domain dict — Domain-wide customization
customize_glob dict — Glob-pattern entity customization
allowlist_external_dirs list [] Directories integrations can access
allowlist_external_urls list [] URLs integrations can access
packages dict — Configuration packages
auth_providers list [homeassistant] Authentication provider chain
auth_mfa_modules list [] Multi-factor authentication modules

MQTT Integration Configuration

Key Type Default Description
broker string — MQTT broker hostname or IP
port integer 1883 MQTT broker port
username string — MQTT username
password string — MQTT password
keepalive integer 60 MQTT keepalive interval (seconds)
discovery boolean true Enable MQTT auto-discovery
discovery_prefix string "homeassistant" MQTT discovery topic prefix
birth_message dict — Message sent on broker connect
will_message dict — Last will and testament message
certificate string — CA certificate path for TLS
client_cert string — Client certificate path
client_key string — Client key path
tls_insecure boolean false Allow insecure TLS connections
transport string "tcp" tcp or websockets
ws_path string — WebSocket path (for WS transport)
ws_headers dict — WebSocket headers (for WS transport)
qos integer 0 Default QoS level (0, 1, or 2)
retain boolean false Default retain flag

Emulated Hue Configuration

Key Type Default Description
host_ip string auto-detect IP address to bind the Hue bridge to
listen_port integer 8300 HTTP API listen port
advertise_ip string host_ip IP advertised in UPnP/SSDP discovery
advertise_port integer listen_port Port advertised in discovery
upnp_bind_multicast boolean true Bind to SSDP multicast group
off_maps_to_on_domains list [script, scene] Domains where "off" triggers "on"
expose_by_default boolean true Expose all entities by default
exposed_domains list [switch, light, group, input_boolean, media_player, fan] Domains exposed by default
type string "google_home" alexa or google_home
lights_all_dimmable boolean false Report all lights as dimmable
entities dict — Per-entity name/hidden overrides

Alexa Smart Home Configuration

Key Type Default Description
smart_home.endpoint string — Alexa event gateway URL (US/EU/FE regional endpoints)
smart_home.client_id string — Login with Amazon OAuth client ID
smart_home.client_secret string — Login with Amazon OAuth client secret
smart_home.locale string "en-US" Alexa locale
smart_home.filter dict — Entity filter (include/exclude domains/entities)
smart_home.entity_config dict — Per-entity name, description, display categories
flash_briefings.password string — API password for flash briefing endpoint

go2rtc Configuration

Key Type Default Description
url string — External go2rtc server URL (mutually exclusive with debug_ui)
debug_ui boolean false Enable go2rtc web debug interface
username string — Basic auth username (required when debug_ui is true)
password string — Basic auth password (required when debug_ui is true)

Note

In Docker/HAOS, go2rtc runs as a managed subprocess with auto-generated credentials. Communication uses a Unix socket for security. The RTSP proxy listens on 127.0.0.1:18554 and WebRTC on :18555/tcp.

Automation Configuration Schema

Key Type Default Description
id string — Unique automation identifier
alias string — Human-readable name
description string — Automation description
trigger / triggers list — List of trigger definitions
condition / conditions list [] List of condition definitions
action / actions list — List of action definitions
mode string "single" Execution mode: single, restart, queued, parallel
max integer 10 Max concurrent/queued runs (for queued/parallel modes)
max_exceeded string "WARNING" Log level when max is exceeded: SILENT, WARNING, ERROR
variables dict — Variables available in templates
trace dict — Trace configuration
initial_state boolean — Initial enabled state on startup
use_blueprint dict — Blueprint reference with inputs

Script Configuration Schema

Key Type Default Description
alias string — Human-readable name
description string — Script description
icon string — MDI icon identifier
mode string "single" Execution mode: single, restart, queued, parallel
max integer 10 Max concurrent/queued runs
max_exceeded string "WARNING" Log level when max is exceeded
sequence list — Ordered list of actions
variables dict — Script-level variables
fields dict — Service call field definitions (for UI)

4. Deployment & Scaling

Deployment Options

Method Supervisor Add-ons OS Control Best For
Home Assistant OS Yes Yes Full Dedicated hardware, beginners
Supervised Yes Yes No Existing Debian servers
Container No No No Docker-savvy users, NAS devices
Core No No No Developers, custom environments

Container Deployment

# docker-compose.yml
version: '3'
services:
  homeassistant:
    container_name: homeassistant
    image: ghcr.io/home-assistant/home-assistant:stable
    volumes:
      - /path/to/config:/config
      - /run/dbus:/run/dbus:ro
    environment:
      - TZ=America/New_York
    restart: unless-stopped
    privileged: true
    network_mode: host

Important

network_mode: host is strongly recommended for device discovery. Bridge networking breaks SSDP, mDNS, and other multicast-based discovery protocols. The privileged flag enables USB device access for Zigbee/Z-Wave controllers.

Reverse Proxy Configuration

Home Assistant runs behind a reverse proxy for SSL termination and domain routing:

# configuration.yaml
http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.16.0.0/12
    - 10.0.0.0/8

Warning

Always configure trusted_proxies when using a reverse proxy. Without it, Home Assistant cannot correctly identify client IP addresses, which affects rate limiting and logging.

Supervisor Integration

In HAOS/Supervised installations, the hassio integration provides:

  • Add-on management — install, start, stop, update add-ons via services
  • Host control — reboot, shutdown, network configuration
  • OS updates — update the underlying operating system
  • Hardware detection — auto-detects board type (Raspberry Pi 2-5, ODROID variants, Green, Yellow) and installs hardware-specific integrations
  • Backup management — create, restore, download backups with encryption support
  • Ingress — secure reverse proxy for add-on web UIs

The integration creates a system user (Home Assistant) in the Administrators group for Supervisor API authentication using the SUPERVISOR_TOKEN environment variable.

Note

The Supervisor integration overrides the homeassistant.restart and homeassistant.stop services to route through the Supervisor API, ensuring proper container lifecycle management.

Database Backend Configuration

The recorder supports multiple database backends:

Backend Connection URI Notes
SQLite (default) sqlite:///config/home-assistant_v2.db WAL mode, FK enforcement
MySQL/MariaDB mysql+pymysql://user:pass@host/db Optimizer: slow_range_in_select (MariaDB MDEV-25020)
PostgreSQL postgresql://user:pass@host/db Optimizer: slow_range_in_select (loose indexscan)

Warning

MySQL 8.x has a known optimizer issue (slow_dependent_subquery) causing file-sort operations on certain statistics queries. The recorder automatically applies workarounds when it detects MySQL 8.


5. Operations

Startup Sequence

Home Assistant follows a staged bootstrap process:

1. Validate Python version (3.13+) and OS (Linux/macOS/WSL)
2. Parse CLI arguments
3. Check for backup restore instruction (.HA_RESTORE)
4. Ensure config directory and deps/ exist
5. Acquire single-instance lock (one instance per config dir)
6. Check safe mode flag
7. Create HomeAssistant instance
8. Enable fault handler (writes crash traces to .log.fault)
9. Load base functionality (registries, config entries, templates, translations)
10. Stage 0: Core integrations (logging, HTTP, frontend, recorder, zeroconf)
11. Stage 1: Discovery services (bluetooth, dhcp, ssdp, usb, cloud, hassio) — 120s timeout
12. Stage 2: All remaining user integrations — 300s timeout
13. Fire EVENT_HOMEASSISTANT_STARTED

Default integrations loaded automatically (~50) include: automation, cloud, config, conversation, counter, default_config, dhcp, energy, frontend, group, history, homeassistant, input_*, logbook, logger, media_source, mobile_app, mqtt, person, recorder, scene, schedule, script, ssdp, sun, system_log, tag, timer, usb, webhook, websocket_api, zeroconf.

Tip

Pre-imported frontend dependencies are loaded before the event loop starts to avoid blocking I/O detection warnings. The list of pre-imports is maintained in bootstrap.py.

Startup Watchdog

The _WatchPendingSetups class monitors integration setup during boot:

  • Logs pending setups every 60 seconds
  • Lists which integrations are still initializing
  • Integrations that exceed their stage timeout are moved to background loading

Recovery Mode

Recovery mode is triggered when:

  1. configuration.yaml parsing fails
  2. Core component setup fails
  3. A critical integration (e.g., frontend) fails to load
  4. Manual activation via --recovery-mode flag or .safe_mode file

In recovery mode, only essential integrations are loaded. The web UI is accessible for configuration fixes.

Blocking I/O Detection

Home Assistant monkey-patches 17 blocking standard library calls to detect misuse in the async event loop:

Function Severity
HTTPConnection.putrequest Strict
time.sleep Strict
glob.glob, glob.iglob Strict (core)
os.walk, os.listdir, os.scandir Strict (core)
builtins.open Check allowed
importlib.import_module Strict (core)
SSLContext.load_verify_locations Strict (core)
SSLContext.load_cert_chain Strict (core)
SSLContext.set_default_verify_paths Strict (core)
SSLContext.load_default_certs Strict (core)
Path.open, Path.read_text, Path.read_bytes, Path.write_text, Path.write_bytes Strict

When a blocking call is detected in the event loop, Home Assistant logs a warning with a stack trace. In strict mode (core code), these are treated as errors.

Note

The blocking I/O detection system uses BlockingCall objects with configurable strict, strict_core, check_allowed, and skip_for_tests flags. Integration developers should use async alternatives for all I/O operations.

Log Management

Configuration Description
--verbose Write verbose logs to file
--log-file Custom log file path (default: CONFIG/home-assistant.log)
--log-rotate-days N Enable daily rotation, keep N days
--log-no-color Disable ANSI color codes in log output
Fault log CONFIG/home-assistant.log.fault — only created on crashes, auto-deleted if empty

Backup and Restore

Backup architecture:

  • Backups use securetar for encrypted tar archive creation
  • Supports full and partial backups (select which integrations/add-ons to include)
  • Backup version is validated against the current HA version before restore
  • The restore process runs pre-boot: the backup_restore.py module reads .HA_RESTORE and extracts the archive

Pre-boot restore flow:

1. On boot, check for .HA_RESTORE file (JSON)
2. Parse restore instructions: backup path, password, restore flags
3. Extract backup via securetar
4. Validate backup version compatibility
5. Write result to .HA_RESTORE_RESULT
6. ALWAYS remove .HA_RESTORE (prevents boot loops)
7. Return RESTART_EXIT_CODE to trigger a clean restart

Caution

The .HA_RESTORE file is always removed after processing, regardless of success or failure. This prevents infinite boot loops from a corrupted backup. Check .HA_RESTORE_RESULT for error details.

Service Management

Key services registered by core components:

Domain Service Description
homeassistant restart Restart Home Assistant (routed through Supervisor in HAOS)
homeassistant stop Stop Home Assistant
homeassistant reload_config_entry Reload a specific config entry
automation trigger Force-fire an automation (optional: skip conditions)
automation reload Reload automations from YAML
automation turn_on/turn_off/toggle Enable/disable automations
script reload Reload scripts from YAML
script turn_on/turn_off/toggle Start/stop scripts
mqtt publish Publish an MQTT message
mqtt dump Subscribe and dump messages to file

6. Performance

HTTP Client Performance

The aiohttp_client helper manages pooled HTTP sessions with:

Parameter Value
Total connections 4,096
Per-host connections 100
Cleanup interval 60 seconds (vs default 2s)
User-Agent HomeAssistant/{version} (immutable)
DNS Resolver HassAsyncDNSResolver (wraps AsyncDualMDNSResolver)
Response parsing orjson (faster than stdlib json)

Sessions are keyed by (verify_ssl, address_family, ssl_cipher) for connection pooling.

JWT Performance Optimizations

The authentication system uses several caching layers:

Cache Size Purpose
JWS _load() result cache LRU 16 Skip repeated JWS header parsing
JWT payload decode cache Per-token Avoid redundant payload deserialization
unverified_hs256_token_decode() — Fast initial claim extraction without full verification
Max token size 8,192 bytes Reject oversized tokens early

Recorder Performance

Optimization Description
WAL mode SQLite Write-Ahead Logging for concurrent reads during writes
Compressed state format Uses HA constants for minimal wire format
Attribute caching attr_cache dict prevents re-deserializing identical JSON attribute blobs
LazyState @cached_property for lazy attribute/timestamp deserialization from DB rows
UUID/ULID conversion @lru_cache(16) on byte-string converters
Database-specific optimizers Boolean flags for MariaDB range-in-select, MySQL dependent-subquery workarounds

Registry Performance

Pattern Implementation
Indexed lookups Multi-index structures for labels, floors, aliases
json_fragment Cached JSON serialization for WebSocket responses
Versioned storage Migration system (e.g., AreaRegistry v1.9 with 9 migrations)
Frozen dataclasses Immutable entries with cached computed properties
Thread safety verify_event_loop_thread() on all mutations

Async Utilities

Utility Purpose
create_eager_task() Task(eager_start=True) — executes synchronous prefix immediately
gather_with_limited_concurrency() Semaphore-based concurrency limiter
run_callback_threadsafe() Safe cross-thread callback scheduling with shutdown detection
Throttle decorator Per-instance rate limiting with threading.Lock, supports both sync/async

Tip

Use create_eager_task() instead of asyncio.create_task() for coroutines that might complete synchronously (e.g., returning cached data). This avoids the overhead of scheduling a task on the event loop.


7. Security

Authentication Architecture

Home Assistant uses a layered authentication system:

Login Flow:
  1. Client presents credentials to auth provider
  2. AuthManager validates via provider chain
  3. If MFA enabled: inject MFA verification step (5-min session)
  4. On success: create Credentials, link to User
  5. Issue RefreshToken (90-day expiry)
  6. Client exchanges RefreshToken for AccessToken (JWT HS256, 30-min expiry)
  7. AccessToken used in Authorization: Bearer header for all API calls

Token types:

Type Expiry Purpose
Access Token 30 minutes Short-lived JWT for API authentication
Refresh Token 90 days Used to obtain new access tokens
Long-Lived Access Token None (manual revocation) Created by users for API integrations
System Token None Internal use by system-generated users

Each refresh token has its own JWT signing key (64-byte hex), providing per-token revocation without a shared secret compromise.

Default user groups:

Group ID Permissions
Administrators system-admin Full access to all entities and config
Users system-users Full entity access, limited config access
Read Only system-read-only View-only access to entities

Permission System

The permission system uses hierarchical policy compilation:

Policy evaluation order (entity permissions):
  1. all — blanket grant/deny
  2. area_ids — by area assignment
  3. device_ids — by device assignment
  4. domains — by entity domain
  5. entity_ids — by specific entity ID

Permission keys: POLICY_READ, POLICY_CONTROL, POLICY_EDIT.

Policy merging follows "most permissive wins": True > Dict > None.

Event subscription allowlist: Non-admin users can only subscribe to 19 non-sensitive event types (state changes, registry updates, service events, theme/panel updates, recorder statistics).

Warning

The owner account cannot be deactivated. System-generated users (like the Supervisor user) cannot enable MFA or have client-bound refresh tokens.

SSRF Protection

The aiohttp_client helper includes built-in SSRF (Server-Side Request Forgery) protection:

  • Redirect analysis — _ssrf_redirect_middleware blocks redirects from non-loopback to loopback addresses
  • RFC 1035 trailing dot handling — normalizes hostnames before checking
  • "localhost" detection — blocks both localhost and 127.0.0.1 resolution
  • IP resolution checks — resolves hostnames to verify they don't point to internal addresses

Input Validation

Function Purpose
raise_if_invalid_filename() Blocks ~, .., /, \ in filenames
raise_if_invalid_path() Blocks path traversal attacks
slugify() Unicode-aware sanitization for identifiers
voluptuous schemas Type-checked configuration validation
JWT max size: 8,192 bytes Prevents token-based DoS

API Permission Model

Endpoint Required Permission
GET /api/states Token (entity-filtered for non-admins)
POST /api/states/{entity_id} Token
DELETE /api/states/{entity_id} Admin only
POST /api/events/{event_type} Admin only
POST /api/template Admin only
GET /api/stream Admin only
POST /api/services/{domain}/{service} Token

Caution

The event stream (GET /api/stream) and template rendering (POST /api/template) endpoints are admin-only because they can expose arbitrary internal state. Long-lived access tokens should be treated as sensitive credentials — store them securely and rotate them periodically.


8. Developer Internals

Repository Structure

home-assistant/core/
├── homeassistant/           # Main application package
│   ├── __main__.py          # CLI entry point (hass command)
│   ├── core.py              # HomeAssistant class, event bus, state machine
│   ├── bootstrap.py         # Staged startup orchestration
│   ├── config.py            # YAML config parsing, validation, packages
│   ├── const.py             # Constants (version, required Python, exit codes)
│   ├── runner.py            # Process runner, single-instance lock
│   ├── backup_restore.py    # Pre-boot backup restore
│   ├── block_async_io.py    # Blocking I/O detection patches
│   ├── loader.py            # Integration/component loader
│   ├── requirements.py      # Dependency installation management
│   ├── setup.py             # Integration setup orchestration
│   ├── exceptions.py        # Exception hierarchy
│   ├── auth/                # Authentication subsystem (5 files)
│   │   ├── __init__.py      # AuthManager, login flows
│   │   ├── auth_store.py    # Persistent user/token storage
│   │   ├── jwt_wrapper.py   # Performance-optimized JWT handling
│   │   ├── models.py        # User, RefreshToken, Credentials, Group
│   │   ├── const.py         # Token expiration constants
│   │   └── permissions/     # Hierarchical permission system (9 files)
│   ├── helpers/             # 74 utility modules
│   │   ├── aiohttp_client.py    # Managed HTTP sessions, SSRF protection
│   │   ├── area_registry.py     # Physical location management
│   │   ├── device_registry.py   # Device tracking
│   │   ├── entity_registry.py   # Entity state management
│   │   ├── floor_registry.py    # Floor/level management
│   │   ├── label_registry.py    # Label/tag management
│   │   ├── category_registry.py # Category management
│   │   ├── template.py          # Jinja2 template engine
│   │   ├── storage.py           # JSON persistence with atomic writes
│   │   └── ...
│   ├── util/                # 38 low-level utilities
│   │   ├── __init__.py      # slugify, Throttle, random
│   │   ├── async_.py        # Async helpers (eager tasks, gather)
│   │   ├── color.py         # Color space conversions (RGB, XY, HSV, CT)
│   │   ├── dt.py            # Date/time utilities
│   │   └── ...
│   ├── components/          # 2,000+ integration packages
│   │   ├── api/             # REST API endpoints
│   │   ├── automation/      # Automation engine
│   │   ├── mqtt/            # MQTT integration (53 files)
│   │   ├── alexa/           # Alexa Smart Home (16 files)
│   │   ├── hassio/          # Supervisor integration (30 files)
│   │   ├── template/        # Template entities (32 files)
│   │   ├── recorder/        # State/event persistence
│   │   ├── config/          # WebSocket config management
│   │   ├── go2rtc/          # WebRTC streaming
│   │   ├── ssdp/            # UPnP device discovery
│   │   ├── emulated_hue/    # Philips Hue bridge emulation
│   │   ├── mcp_server/      # Model Context Protocol for AI
│   │   ├── script/          # Script engine
│   │   └── ...
│   └── generated/           # 17 auto-generated files
│       ├── bluetooth.py     # Bluetooth device matchers
│       ├── config_flows.py  # Integration config flow registry
│       ├── ssdp.py          # SSDP device matchers
│       ├── zeroconf.py      # mDNS service matchers
│       ├── dhcp.py          # DHCP device matchers
│       ├── usb.py           # USB device matchers
│       └── ...
├── script/                  # Development scripts (20 files)
│   ├── hassfest/            # Manifest validation framework (32 files, 22 plugins)
│   ├── translations/        # Translation management
│   ├── scaffold/            # Integration scaffolding generator
│   └── ...
├── tests/                   # Test suite
├── pylint/                  # Custom pylint plugins
│   └── plugins/             # HA-specific lint rules
├── rootfs/                  # Container root filesystem
└── machine/                 # Machine/board type definitions

Architecture Deep Dive

HomeAssistant Class (core.py)

The HomeAssistant class is the central coordinator:

  • Event Bus — pub/sub system for all inter-component communication. Events are typed via EventType[T] generics.
  • State Machine — tracks all entity states as State objects (entity_id, state string, attributes dict, timestamps). Fires EVENT_STATE_CHANGED on every update.
  • Service Registry — maps (domain, service) to handler callables. Services are the primary action mechanism.
  • Config — runtime configuration (location, units, timezone, component list).

Integration Loading

Integrations are loaded via the loader module:

  1. manifest.json declares metadata: domain, name, dependencies, requirements, config_flow type
  2. __init__.py provides async_setup() (YAML) and/or async_setup_entry() (config entry)
  3. Platform modules (sensor.py, switch.py, etc.) provide entity classes
  4. config_flow.py handles UI-based configuration

Registry System

Six parallel registries track the entity/device hierarchy:

AreaRegistry ←── FloorRegistry
     ↕                 ↕
DeviceRegistry ←── LabelRegistry
     ↕                 ↕
EntityRegistry ←── CategoryRegistry

All registries share the same pattern:

  • Frozen dataclass entries with json_fragment cached property
  • Versioned storage with migration functions
  • Multi-index lookups for efficient filtering
  • Thread-safe mutations via verify_event_loop_thread()
  • Event-driven updates — fire EVENT_*_REGISTRY_UPDATED on changes

Storage Pattern

The helpers.storage.Store class provides JSON persistence:

- Lazy loading on first access
- Atomic writes (write to temp, rename)
- Configurable save delay (default 1 second) for batching rapid changes
- Version-tracked with migration support
- Used by: auth store, registries, entity config, emulated hue IDs

Module Reference

homeassistant/bootstrap.py — Startup Orchestration

Key functions:

  • async_setup_hass() — creates HomeAssistant instance, enables logging, activates recovery mode if needed
  • async_load_base_functionality() — parallel registry loading, config entry init, template/translation init
  • _async_setup_multi_components() — parallel integration setup with dependency resolution
  • _WatchPendingSetups — logs slow startups every 60s

Stage definitions (integration groups):

  • Stage 0: logging, frontend, recorder, debugger, zeroconf, labs
  • Stage 1: bluetooth, dhcp, ssdp, usb, mqtt_eventstream, cloud, hassio (120s timeout)
  • Stage 2: All remaining user domains (300s timeout)

Pre-loaded storage keys (~40): entity registry, device registry, area registry, core config, auth, and more.

homeassistant/auth/ — Authentication System

AuthManager orchestrates:

  • Provider chain evaluation (configurable, default: homeassistant provider)
  • MFA module injection into login flows
  • User CRUD operations
  • Token lifecycle (create, validate, revoke refresh/access tokens)
  • Credential-to-user linking

AuthStore persists:

  • Users (with group memberships, system_generated flag, active flag, local_only flag)
  • Refresh tokens (with per-token JWT keys, version tracking, credential references)
  • Groups (admin, user, read-only with policy dicts)
  • Token-to-user index for O(1) lookup

homeassistant/helpers/aiohttp_client.py — HTTP Client

  • Session pooling keyed by (verify_ssl, family, ssl_cipher)
  • HomeAssistantTCPConnector — custom connector with 60s cleanup vs 2s default
  • SSRF middleware — blocks loopback redirect attacks
  • async_aiohttp_proxy_web() / async_aiohttp_proxy_stream() — streaming proxy utilities
  • Auto-cleanup on config entry unload or HA shutdown
  • Connection limits: 4,096 total, 100 per host

homeassistant/util/color.py — Color Conversion Library

Comprehensive color space conversion supporting:

  • RGB ↔ XY (CIE 1931) ↔ HSV ↔ HS ↔ RGBW ↔ RGBWW
  • Color temperature (Kelvin) ↔ RGB, mired, XY
  • Gamut-aware XY clamping for Philips Hue compatibility
  • 148 CSS3 named colors + "homeassistant" brand color
  • brightness_to_value() / value_to_brightness() scaling

homeassistant/components/automation/ — Automation Engine

  • BaseAutomationEntity → AutomationEntity hierarchy
  • Trigger-condition-action evaluation with execution tracing
  • Blueprint support via CONF_USE_BLUEPRINT
  • Smart reload: diff-based entity management (only recreates changed automations)
  • Labs feature flag new_triggers_conditions gates experimental trigger/condition platforms
  • Services: trigger, reload, turn_on, turn_off, toggle
  • Events: EVENT_AUTOMATION_TRIGGERED, EVENT_AUTOMATION_RELOADED
  • Reference lookups: automations_with_entity(), automations_with_device(), etc.

homeassistant/components/mqtt/ — MQTT Integration (53 files)

  • MQTT client class manages broker connection, pub/sub, and reconnection
  • Config entry migration system (v1 → v2.1) for backward compatibility
  • MQTT discovery: devices publish to {prefix}/<component>/<node_id>/<object_id>/config
  • Entity platforms for all major domains (sensor, switch, light, climate, etc.)
  • Subscription restore on reconnect
  • MAX_RECONNECT_WAIT = 300 seconds
  • Services: publish (topic, payload, QoS, retain), dump (debug subscribe), reload
  • Two YAML config styles: list-of-dicts (preferred) and legacy nested-dict

homeassistant/components/api/ — REST API

Views (all extend HomeAssistantView):

  • APIStatusView — GET /api/ health check
  • APICoreStateView — GET /api/core/state (used by Supervisor)
  • APIEventStream — GET /api/stream SSE (admin, 50s ping interval)
  • APIConfigView — GET /api/config
  • APIStatesView — GET /api/states (gzip compressed, permission-filtered)
  • APIEntityStateView — CRUD for individual entity states
  • APIEventView — POST /api/events/{type} (admin only)
  • APIServicesView — GET /api/services
  • APIDomainServicesView — POST /api/services/{domain}/{service} (with ?return_response support)
  • APIComponentsView — GET /api/components
  • APITemplateView — POST /api/template (admin only)
  • Service call timeout: 10 seconds (SERVICE_WAIT_TIMEOUT)

homeassistant/components/config/ — WebSocket Config API

17 submodules, each registering WebSocket commands for:

  • area_registry — CRUD + reorder, aliases, floor assignment, labels, humidity/temperature entity IDs
  • auth — user management (create, delete, update)
  • auth_provider_homeassistant — credential management, password/username changes
  • automation, script, scene — YAML config management
  • device_registry, entity_registry — device/entity management
  • floor_registry, label_registry, category_registry — organizational registries
  • config_entries — integration config entry management
  • core — core settings updates

All mutating operations require admin permissions.

homeassistant/components/hassio/ — Supervisor Integration (30 files)

  • HassIO — HTTP client wrapper for Supervisor API (via SUPERVISOR_TOKEN)
  • Three data coordinators: main, add-on, stats
  • Hardware auto-detection maps board types to integrations
  • Overrides restart/stop services to route through Supervisor
  • Manages add-on panels, ingress proxy, discovery relay
  • Fires events for Supervisor state changes
  • Creates system user for Supervisor authentication

homeassistant/components/recorder/ — State Persistence

  • SQLAlchemy-based database layer with schema versioning (v41+)
  • LazyState — memory-efficient state representation with @cached_property lazy deserialization
  • DatabaseEngine + DatabaseOptimizer — database-specific query optimizations
  • Statistics system: StatisticData, StatisticPeriod (calendar, fixed, rolling window)
  • StatisticMeanType enum: NONE, ARITHMETIC, CIRCULAR (for compass bearings, etc.)
  • Auto-repair system for event data corruption

homeassistant/components/ssdp/ — Device Discovery

  • Active scanner: multicast search every 10 minutes on all non-loopback interfaces
  • IPv4 broadcast search for devices that don't respond to multicast (e.g., Sonos)
  • IntegrationMatchers — pre-indexed lookup by manufacturer, search target, device type, notification type
  • Callback system for integration-specific discovery handlers
  • Device tracking via SsdpDeviceTracker with description caching

homeassistant/components/go2rtc/ — WebRTC Streaming

  • System integration (auto-configured with default_config)
  • Manages go2rtc binary lifecycle in Docker/HAOS
  • Unix socket communication for security
  • WebRTCProvider — handles WebRTC signaling (offer/answer/ICE)
  • Camera stream registration with ffmpeg orientation transforms
  • Recommended go2rtc version: 1.9.14

homeassistant/components/mcp_server/ — AI Integration

  • Exposes HA as a Model Context Protocol server
  • Streamable HTTP transport: POST /api/mcp (stateless per-request)
  • SSE transport: GET /mcp_server/sse + POST /mcp_server/messages/{session_id}
  • Bridges to HA's llm and conversation helpers
  • Configurable LLM API selection (default: Assist)
  • Requirements: mcp==1.26.0

Code Patterns and Conventions

Pattern Convention
Entity domain DOMAIN constant matching component directory name
State naming <DOMAIN>.<OBJECT_ID> (e.g., light.living_room)
Service scope Services published only under own domain
Config entry async_setup_entry() + async_unload_entry() lifecycle
YAML config async_setup() with voluptuous schema validation
Platform setup async_setup_entry() receiving AddConfigEntryEntitiesCallback
Coordinator pattern DataUpdateCoordinator for polled data sources
Entity base Domain-specific base (e.g., SensorEntity, SwitchEntity)
Diagnostics async_get_config_entry_diagnostics() for debug dumps
Repairs RepairsFlow for surfacing integration issues to users
Config migration async_migrate_entry() with version bumping

Development Scripts

hassfest — Integration Validation (32 files)

The manifest validation and code generation framework. Runs in CI as the quality gate.

Plugin system (22 integration plugins + 4 global plugins):

Plugin Validates
manifest manifest.json schema, domain naming, documentation URLs
config_flow Config flow completeness and translations
dependencies Import-to-manifest dependency consistency
requirements requirements.txt entries match manifest
services Service YAML schema, field validation, selectors
translations Translation key format, placeholder validation, completeness
icons MDI icon validity, state icon coverage
conditions / triggers Condition/trigger platform schema validation
quality_scale Quality scale tier compliance
bluetooth / ssdp / dhcp / usb / zeroconf Discovery matcher validation

Modes: validate (CI — errors fail build) and generate (rewrites generated files, auto-fixes).

CLI:

python3 -m script.hassfest --action validate
python3 -m script.hassfest --action generate
python3 -m script.hassfest --integration-path homeassistant/components/my_integration
python3 -m script.hassfest --plugins manifest,services --core-path /path/to/core

Other Development Scripts

Script Purpose
script/translations/ Translation management (upload, download, clean, deduplicate)
script/scaffold/ Generate boilerplate for new integrations
script/version_bump.py Bump version numbers (with --commit for auto-commit)
script/split_tests.py Split test files into N buckets for CI parallelism
script/licenses.py Generate license inventory (licenses.json)
script/gen_requirements_all.py Generate requirements_all.txt from integration manifests
script/gen_copilot_instructions.py Generate GitHub Copilot instructions from project docs

Testing Strategy

Test infrastructure:

  • Framework: pytest with asyncio support
  • Custom fixtures for HomeAssistant instance setup/teardown
  • KNXTestKit pattern — integration-specific test utilities for injecting/asserting protocol messages
  • Snapshot testing via tests/snapshots/
  • Test configuration in tests/testing_config/

Coverage requirements (from codecov.yml):

  • 100% patch coverage required for: config_flow.py, device_action.py, device_condition.py, device_trigger.py, diagnostics.py, logbook.py, media_source.py, recorder.py, scene.py
  • Carry-forward flag enabled for partial CI runs

Pre-commit hooks (13 hooks):

  • ruff — linting and formatting
  • codespell — spell checking
  • zizmor — GitHub Actions security scanning
  • yamllint — YAML validation
  • prettier — JSON formatting and sorting
  • mypy — type checking
  • pylint — with custom HA-specific plugins
  • hassfest — manifest validation

Custom pylint plugins (pylint/plugins/):

  • HA-specific lint rules enforcing coding conventions
  • Import ordering, decorator usage, async pattern compliance

Quality Scale

Integrations are rated on a quality scale:

Tier Requirements
Bronze Basic functionality, config flow
Silver Full entity platforms, diagnostics, translations
Gold Complete test coverage, quality documentation
Platinum Full quality scale compliance across all criteria

Non-scaled tiers exist for internal/system integrations.

Potential Improvements

Based on source analysis:

  1. API endpoint extraction gap — The AST extractor found 0 API endpoints because they use HomeAssistantView class-based routing rather than decorator patterns. Endpoint documentation is derived from module source reading.
  2. Large integration files — Some components (MQTT at 53 files, template at 32 files, hassio at 30 files) would benefit from further modularization.
  3. Pre-commit complexity — 13 pre-commit hooks can slow developer workflow. Consider tiering hooks into fast (ruff, codespell) and slow (mypy, hassfest) groups.
  4. Database optimizer flags — The DatabaseOptimizer uses static boolean flags rather than runtime detection for DB-specific workarounds. Runtime probing could adapt to database version updates automatically.

Contributing

Development setup:

git clone https://github.com/home-assistant/core.git
cd core
python3 -m venv venv
source venv/bin/activate
pip install -e ".[dev]"
pre-commit install

Integration scaffolding:

python3 -m script.scaffold --integration custom_component

Running tests:

pytest tests/components/my_integration/

Validating integration manifest:

python3 -m script.hassfest --integration-path homeassistant/components/my_integration

Key conventions:

  • Each integration lives in homeassistant/components/<domain>/
  • Domain name must match directory name and DOMAIN constant
  • manifest.json is required with domain, name, version, documentation fields
  • Config entries use async_setup_entry()/async_unload_entry() lifecycle
  • YAML config uses async_setup() with voluptuous schema
  • Services defined in services.yaml with voluptuous schemas
  • Translations in strings.json
  • Icons in icons.json (MDI format, e.g., mdi:lightbulb)

9. Integration Points

REST API

Full REST API documentation in the User Guide. Admin-level endpoints:

Endpoint Method Description
/api/stream GET Server-sent event stream (50s ping, admin only)
/api/events/{event_type} POST Fire arbitrary events
/api/template POST Render Jinja2 templates
/api/states/{entity_id} DELETE Remove entity state
/api/core/state GET Core state + recorder migration status (used by Supervisor health checks)

WebSocket API

The WebSocket API at ws://host:8123/api/websocket provides:

  • Real-time state updates
  • Service calls
  • Config management (all config/* commands)
  • Registry operations (area, device, entity, floor, label, category CRUD)
  • Subscription management
  • Integration-specific commands (Insteon ALDB, MQTT diagnostics, etc.)

MQTT Discovery Protocol

Devices publish configuration to:

{discovery_prefix}/{component}/{node_id}/{object_id}/config

Default discovery_prefix: homeassistant. Supported components match all HA entity platforms (sensor, switch, light, climate, etc.).

SSDP/UPnP Discovery

Home Assistant discovers devices via:

  • Multicast search — M-SEARCH on 239.255.255.250:1900
  • IPv4 broadcast search — for devices that don't respond to multicast
  • Passive listening — NOTIFY advertisements from devices

Integration matchers are pre-indexed by: manufacturer, st (search target), device_type, nt (notification type), manufacturer_url.

Bluetooth Discovery

Integration-specific Bluetooth matchers (from homeassistant/generated/bluetooth.py) match on:

  • Manufacturer data IDs
  • Local name patterns
  • Service UUIDs
  • Service data UUIDs

Model Context Protocol (MCP)

External AI tools connect via:

  • Streamable HTTP: POST /api/mcp — stateless JSON-RPC request/response
  • SSE (legacy): GET /mcp_server/sse + POST /mcp_server/messages/{session_id}

All HA actions/tools available through configured LLM APIs become MCP tools.

Emulated Hue Bridge

Emulates Philips Hue API for voice assistant integration:

  • HTTP API on configurable port (default 8300, Alexa requires 80)
  • UPnP/SSDP discovery via datagram endpoint
  • Supports: lights, climate, covers, fans, humidifiers, media players, scenes, scripts
  • Entity numbering persisted to emulated_hue_ids.json

Supervisor API

In HAOS/Supervised, the hassio integration communicates with the Supervisor via:

  • HTTP API authenticated with SUPERVISOR_TOKEN
  • Manages: add-ons, OS updates, host control, backups, network, hardware
  • Ingress proxy for add-on web UIs
  • Discovery relay for add-on-provided services

Troubleshooting

Error: RuntimeError: Run from Home Assistant root

Cause: hassfest is run from the wrong directory.

Solution:

  1. Change to the Home Assistant Core repository root directory
  2. Run: python3 -m script.hassfest --action validate

Prevention: Always run development scripts from the repository root.

Error: ruff not found (hassfest)

Cause: The ruff linter is not installed in the development environment.

Solution:

  1. Install development dependencies: pip install -e ".[dev]"
  2. Or install ruff directly: pip install ruff

Prevention: Use pip install -e ".[dev]" for development setup.

Error: Error on Supervisor API

Cause: Communication with the Supervisor failed (network issue, Supervisor restart, or API error).

Solution:

  1. Check Supervisor container status: docker ps | grep hassio_supervisor
  2. Review Supervisor logs: docker logs hassio_supervisor
  3. Verify SUPERVISOR_TOKEN is set correctly
  4. Restart the Supervisor if necessary

Prevention: Monitor Supervisor health via the hassio integration's sensor entities.

Error: Go2RTCWatchdogError: Process ended / API error

Cause: The go2rtc process crashed or its API became unresponsive.

Solution:

  1. Check go2rtc logs in the Home Assistant system log
  2. The watchdog will automatically attempt to restart the process
  3. If persistent, check for port conflicts on 11984, 18554, or 18555

Prevention: Ensure adequate system resources and no port conflicts with other services.

Error: BackupReaderWriterError: Backup failed

Cause: Backup creation encountered an error (disk full, permission denied, or Supervisor API error).

Solution:

  1. Check available disk space: df -h
  2. Verify permissions on the backup directory
  3. Review the error details in Supervisor logs
  4. For partial failures, check which backup components succeeded

Prevention: Maintain sufficient free disk space (at least 2x the expected backup size). Schedule backups during low-activity periods.

Warning

When restoring backups across major version boundaries, validate that the backup version is compatible with the target Home Assistant version. The restore process checks this automatically, but downgrades are not supported.

Error: UnsupportedDialect (Recorder)

Cause: The recorder is configured with a database backend that is not supported.

Solution:

  1. Use a supported database: SQLite (default), MySQL 8+, MariaDB 10.3+, or PostgreSQL 12+
  2. Check the connection URI format in your recorder configuration

Prevention: Stick with SQLite unless you have specific scalability requirements.

Error: AlexaBridgeUnreachableError: Alexa API not enabled

Cause: The Alexa Smart Home integration is not configured but an Alexa request was received.

Solution:

  1. Configure the alexa integration in configuration.yaml
  2. Ensure smart_home section is present with valid client_id and client_secret

Prevention: Complete the full Alexa skill setup before attempting voice control.

Error: HassioAPIError (various Supervisor operations)

Cause: A Supervisor API call returned an error response.

Solution:

  1. Parse the error message (usually contains the API endpoint and status)
  2. Check Supervisor logs for the detailed error
  3. Common causes: add-on not installed, insufficient permissions, network timeout

Prevention: Verify add-on status before performing operations. Use the hassio coordinator's available property to check connectivity.

Tip

Enable the logger integration with homeassistant.components.hassio: debug to see full Supervisor API request/response details in the log.