# Home Assistant Core — Administrator & Developer Guide

## 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

```text
                    ┌─────────────────────────────────┐
                    │         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:**

```text
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:**

```text
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

```yaml
# 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:

```yaml
# 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:

```text
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:**

```text
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:

```text
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:

```text
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

```text
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:

```text
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:

```text
- 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:**

```bash
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:**

```bash
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:**

```bash
python3 -m script.scaffold --integration custom_component
```

**Running tests:**

```bash
pytest tests/components/my_integration/
```

**Validating integration manifest:**

```bash
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:

```text
{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.

---

_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. Unofficial; not affiliated with or reviewed by the project._
