This guide covers features and best practices for using Home Assistant CLI with LLMs (Large Language Models) and AI agents.
- TOON Format: Default output uses TOON (Token-Oriented Object Notation) for ~40% fewer tokens than JSON
- Structured Responses: Clear headers with field names and predictable data layouts
- Query Language: Simple expression syntax for filtering entities
- Batch Operations: Execute multiple operations in a single command
- Comprehensive Discovery: Explore all entities, registries, and statistics efficiently
- Full API Coverage: Access to all Home Assistant API endpoints
- Registry Access: Query entity, device, area, floor, label, and category registries
- Statistics: Access historical data and analytics
- List Management: Manage todo lists, shopping lists, and notifications
-
Capability discovery (implemented): Use
hassio capabilities --format jsonto retrieve instance-specific API availability, supervisor status, and orchestration hints. -
Capability-driven execution planning (implemented): Use
hassio capabilities --agent-plan --format jsonto getrecommended_commands,avoid_commands, andnotes. -
Structured execution profile (implemented): Use
hassio capabilities --agent-profile --format jsonto get a stable profile with:
preferred_output_format(toon)capabilitiesstatus matrixplanning.fast_pathstarter command sequenceplanning.streaming_readyboolean
- One-shot context payload (implemented):
Use
hassio capabilities --agent-context --redact-private --format jsonto get:
summary(counts + status totals)plan(recommended_commands,avoid_commands,notes)profile(stable execution profile)suggested_sequence(starter command chain)
- Service schema normalization + preflight validation (implemented):
Use
hassio services --schema --format jsonto retrieve normalized service rows:
required_fieldsoptional_fieldsaccepts_targethas_response
Use hassio call-service <domain> <service> --validate-input to validate payloads against live service definitions before execution.
Use --strict-input to fail on unknown keys (recommended for agent-written automation).
- Output contracts for parser-safe automation (implemented):
Use
hassio schema --output-contracts --format jsonto retrieve:
- per-format
media_type - parseability mode (
strictorbest_effort) - parser hints
- baseline schema contracts for CI and agent tooling
-
Cursor-based pagination (future): Add
--cursor+--limitfor entity-heavy installations so agents can page deterministically. -
Stable machine error envelope (future): Standardize failures to
{ code, message, hint, retriable }across all commands and formats.
TOON (Token-Oriented Object Notation) is designed for LLM efficiency:
states[3]{entity_id,state,last_changed}:
light.living_room,on,2024-01-01T00:00:00Z
switch.kitchen,off,2024-01-01T01:00:00Z
sensor.temperature,22.5,2024-01-01T02:00:00Z
vs JSON:
[
{"entity_id": "light.living_room", "state": "on", "last_changed": "2024-01-01T00:00:00Z"},
{"entity_id": "switch.kitchen", "state": "off", "last_changed": "2024-01-01T01:00:00Z"},
{"entity_id": "sensor.temperature", "state": "22.5", "last_changed": "2024-01-01T02:00:00Z"}
]Savings: 137 characters vs 225 characters (~40% reduction)
Quickly explore all entities in your Home Assistant:
# Get overview of all entities
hassio discover
# List all domains with counts
hassio discover --domains
# Find unavailable entities
hassio discover --unavailableExample output:
total_entities: 637
domains: 28
top_domains[5]:
sensor: 300
binary_sensor: 53
update: 46
media_player: 43
automation: 36
state_summary:
on: 45
off: 82
unavailable: 88
unavailable_count: 88
Filter entities with multiple criteria:
# By domain
hassio entities -d light
# By state
hassio entities -s on
# By pattern
hassio entities -p living_room
# Combined filters
hassio entities -d light -s on
# Only count (efficient)
hassio entities --count
# Group by domain
hassio entities --domains
# Limit rows for token budgets
hassio entities -d sensor --limit 25
# Select specific attributes
hassio entities -d sensor -a unit_of_measurement,device_classUse simple expressions to query entities:
# Basic queries
hassio query "domain:light"
hassio query "domain:sensor state:on"
hassio query "name:living"
# With attributes
hassio query "domain:light attributes:brightness"
hassio query "domain:sensor attributes:unit_of_measurement=C"
# Summary only
hassio query "domain:light" --summaryQuery Syntax:
domain:<name>- Filter by domain (light, sensor, switch, etc.)state:<value>- Filter by state (on, off, unavailable, etc.)name:<pattern>- Filter by entity_id substringattributes:<name>- Filter by attribute presenceattributes:<name>=<value>- Filter by attribute value
Execute the same service on multiple entities:
# Turn off multiple lights
hassio batch -d light -s turn_off -e light.living_room,light.kitchen,light.bedroom
# Set brightness on multiple lights
hassio batch -d light -s turn_on -e light.living_room,light.kitchen -d '{"brightness": 200}'
# Stop multiple media players
hassio batch -d media_player -s media_stop -e media_player.living_room,media_player.bedroomDeep dive into a specific entity:
# Fast environment snapshot for planning
hassio summary
# Basic inspection
hassio inspect light.living_room
# With recent history
hassio inspect sensor.temperature --history
# Limit history entries
hassio inspect sensor.temperature --history -l 5Access entity metadata and configuration:
# List all registered entities
hassio registries --entities
# Count entities
hassio registries --entities --count
# Filter by domain
hassio registries --entities -d light
# Filter by device
hassio registries --entities --device-id device_123Use Cases:
- Find disabled entities
- See entity names vs original names
- Check which integration provides each entity
- View entity categories and labels
Access device information:
# List all devices
hassio registries --devices
# Filter by area
hassio registries --devices --area-id area_living_room
# Count devices
hassio registries --devices --countUse Cases:
- List all devices by manufacturer
- Find devices without an area
- Check firmware versions
Access area (room) information:
# List all areas
hassio registries --areas
# Count areas
hassio registries --areas --count# Floor registry
hassio registries --floors
# Label registry
hassio registries --labels
# Category registry
hassio registries --categories
# All registries
hassio registriesQuery historical statistics data:
# Get statistics for an entity
hassio statistics -e sensor.temperature -p hour
# Get statistics for multiple entities
hassio statistics -e sensor.temp1,sensor.temp2 -p day
# Get statistics during a period
hassio statistics -e sensor.energy --during-period \
-s "2024-01-01T00:00:00Z" -t "2024-01-31T23:59:59Z" \
-p day --types mean,max,min
# Available periods: 5minute, hour, day, week, month
# Available types: change, last_reset, max, mean, min, state, sumGet Home Assistant system analytics:
hassio analyticsReturns: active integrations, component count, installation type, version, etc.
# List all todo lists
hassio todo --lists
# Get items from a specific list
hassio todo -e todo.shopping# List all items
hassio shopping-list --list
# Show only pending items
hassio shopping-list --pending
# Add item
hassio shopping-list -a "Milk"
# Mark as complete
hassio shopping-list -u item_id --complete
# Clear completed items
hassio shopping-list --clear-completed# List notifications
hassio notifications --list
# Dismiss notification
hassio notifications -d notification_id# 1. Discover lights that are off
hassio entities -d light -s off
# 2. Turn them on in batch
hassio batch -d light -s turn_on -e light.living_room,light.kitchen,light.hallway
# 3. Verify
hassio entities -d light -s on# 1. Get overall status
hassio discover
# 2. Check for unavailable entities
hassio discover --unavailable
# 3. Get error log (last 20 lines)
hassio error-log | tail -20
# 4. Check config validity
hassio check-config
# 5. Get analytics
hassio analytics# 1. Query all temperature sensors
hassio query "domain:sensor attributes:unit_of_measurement=°C" --summary
# 2. Get all temperature readings
hassio query "domain:sensor attributes:unit_of_measurement=°C"
# 3. Check specific sensor history
hassio inspect sensor.living_room_temperature --history
# 4. Get temperature statistics
hassio statistics -e sensor.temperature -p hour --types mean,max,min# 1. Get all devices
hassio registries --devices
# 2. Get entities for a specific device
hassio registries --entities --device-id device_123
# 3. Find devices in an area
hassio registries --devices --area-id area_living_room
# 4. List all areas
hassio registries --areas# 1. Find all media players
hassio entities -d media_player
# 2. Stop all playing media
hassio batch -d media_player -s media_stop \
-e $(hassio entities -d media_player -s playing --format json-compact | jq -r '.[].entity_id' | tr '\n' ',')# 1. List existing backups
hassio backups --list
# 2. Create new backup
hassio backups -c "Pre-Update Backup"
# 3. Download backup
hassio backups --download backup_slug -o backup.tar
# 4. Restore if needed
hassio backups -r backup_slug# 1. List available conversation agents
hassio conversation --agents
# 2. Ask a question
hassio ask "what time is it"
# 3. Control devices via voice
hassio ask "turn on living room light"
# 4. Multi-turn conversation
hassio conversation -t "turn on the lights" -c "conv-123"
hassio conversation -t "also close the blinds" -c "conv-123"# 1. List TTS engines
hassio tts --engines
# 2. Speak a message
hassio say "The front door is open" -p media_player.kitchen
# 3. Use specific engine
hassio say "Welcome home" -p media_player.living_room -e tts.cloud# 1. Search entities
hassio search "living room"
# 2. Quick local search (faster, no API)
hassio search "temp" --quick
# 3. Search with filters
hassio search "sensor" -d sensor --count
# 4. Find by pattern
hassio find "battery" -d sensorhassio search automatically falls back to local entity-state search when /api/search is unavailable.
Always use TOON format (default) for minimal token usage:
# Default is TOON
hassio entities
# Only use JSON if you need nested data parsing
hassio states sensor.temperature --format jsonWhen you only need to know if entities exist or how many:
# Efficient
hassio entities --count
# Less efficient
hassio entities | wc -lInstead of multiple commands:
# Good
hassio query "domain:light state:on"
# Less efficient
hassio entities | grep "light\." | grep ",on,"Always use batch for multiple service calls:
# Good - one API call
hassio batch -d light -s turn_off -e light.a,light.b,light.c
# Less efficient - multiple API calls
hassio call-service light turn_off -e light.a
hassio call-service light turn_off -e light.b
hassio call-service light turn_off -e light.c# Get statistics without full data
hassio query "domain:binary_sensor" --summaryUse registries when you need configuration metadata:
# Get entity configuration
hassio registries --entities -d light
# Check for disabled entities
hassio registries --entities | grep "disabled"Use statistics for time-series analysis:
# Get daily averages
hassio statistics -e sensor.temperature -p day --types meanRender Home Assistant templates for dynamic queries:
# Get count of entities in a domain
hassio render-template "{{ states.light | list | length }}"
# Get entity with specific attribute
hassio render-template "{{ states.sensor | selectattr('attributes.unit_of_measurement', 'eq', '°C') | list | length }}"
# Complex template from file
hassio render-template "" --file template.jinjaThe CLI provides structured error output:
# Connection errors include helpful messages
hassio status
# Error: Failed to connect to Home Assistant at http://192.168.1.100:8123.
# Please check the URL and ensure Home Assistant is running.
# Validation helps catch issues early
hassio settings validate
# 404 errors indicate endpoint not available
hassio persons
# Error: 404 - Not Found (person integration not enabled)- Start with discovery: Use
hassio discoverto understand what's available - Filter progressively: Start broad, then narrow down
- Use batch for actions: Group multiple operations
- Validate before actions: Check states before changing them
- Monitor with history: Use
--historyfor context - Handle errors gracefully: Check exit codes and error messages
- Use registries for metadata: When you need configuration info
- Use statistics for trends: When analyzing historical data
- Count first: Before fetching full lists
- Check availability: Not all endpoints available in all installations
import subprocess
import json
def hassio_command(cmd):
"""Execute hassio CLI command and return structured output."""
result = subprocess.run(
["hassio"] + cmd,
capture_output=True,
text=True
)
if result.returncode != 0:
return {"error": result.stderr}
# Parse TOON format or JSON based on output
return parse_output(result.stdout)
# Example: Turn on all lights in living room
def turn_on_living_room_lights():
# Find lights
lights = hassio_command([
"entities", "-d", "light",
"-p", "living",
"-s", "off",
"--format", "json-compact"
])
if "error" in lights:
return lights
# Turn them on in batch
entity_ids = ",".join(l["entity_id"] for l in lights)
return hassio_command([
"batch",
"-d", "light",
"-s", "turn_on",
"-e", entity_ids
])
# Example: Get system health
def get_system_health():
return {
"status": hassio_command(["status"]),
"config": hassio_command(["check-config"]),
"discovery": hassio_command(["discover"]),
"analytics": hassio_command(["analytics"]),
}- Use
--format json-compactfor programmatic parsing - Use
--countinstead of counting lines - Use
--summaryfor statistics - Use
--minimal-responsewith history for faster queries - Use
--no-attributeswhen you don't need attributes - Batch operations instead of individual calls
- Filter on server using query parameters when possible
- Cache registry data - it changes infrequently
- Use statistics instead of history for aggregated data
- Store tokens securely (config file has 600 permissions)
- Use environment variables for CI/CD
- Never log full tokens
- Validate inputs before executing commands
- Check which integrations are enabled before querying specific endpoints
- Be careful with backup operations - they can be destructive
Some endpoints return 404 if the corresponding integration is not enabled or the REST API endpoint is not available:
persons- Now uses entity states (always available)zones- Now uses entity states (always available)registries- May not be available via REST API; falls back to entity states for areasbackups- Requires Hass.io/Supervisor; uses service callsanalytics- May require analytics to be enabled in Home Assistant
For large installations, increase timeout:
hassio --timeout 60000 discoverVerify token is correct and not expired:
hassio settings validate