Docs / Strand / connectors/home-assistant
Home Assistant Connector
Direction: Read/Write | Type: homeassistant
Control smart home devices, read entity states, fire events, and render templates from your Strand workflows via the Home Assistant REST API.
Prerequisites
Your instance must be reachable from the internet
This is the first thing to sort out, because most Home Assistant installs are on a home network and Strand runs in the cloud. Strand can only connect to addresses that are publicly reachable, so a URL like http://homeassistant.local:8123 or http://192.168.1.50:8123 will not work — even though it works perfectly from your own browser. Private addresses (10.x, 172.16–31.x, 192.168.x, 127.x) and .local mDNS names are all in that category.
Any of these gives Strand a reachable address:
- Home Assistant Cloud (Nabu Casa) — use your
*.ui.nabu.casaURL. The - A reverse proxy or tunnel — Cloudflare Tunnel, Tailscale Funnel, or your
- A public hostname with HTTPS pointing at your instance.
simplest option, and no ports are opened on your router.
own nginx/Caddy with a real certificate.
Whichever you choose, confirm the URL loads from outside your home network before creating the connector.
Access token
You need a Long-Lived Access Token from your Home Assistant instance:
- Open your Home Assistant dashboard
- Click your profile icon (bottom-left)
- Scroll to Long-Lived Access Tokens
- Click Create Token, name it (e.g., "Strand"), and copy the token
Tip: Use a dedicated token for your Strand workflows. Tokens can be revoked individually from your HA profile page.
Required Permissions
The access token inherits the permissions of the user who created it. For full access to all operations, use an administrator account.
| Operation | API Endpoint | Notes |
|---|---|---|
| Call Service | POST /api/services/{domain}/{service} |
Controls devices |
| Fire Event | POST /api/events/{event_type} |
Fires events on the bus |
| Set State | POST /api/states/{entity_id} |
Creates/updates entities |
| Get Entity State | GET /api/states/{entity_id} |
Reads a single entity |
| Get All States | GET /api/states |
Reads all entities |
| Get History | GET /api/history/period/{timestamp} |
Requires history integration |
| Get Services | GET /api/services |
Lists available services |
| Render Template | POST /api/template |
Server-side Jinja2 rendering |
Connector Setup
Create a Home Assistant connector from the Connectors page.
Configuration Fields
| Field | Required | Description |
|---|---|---|
| Name | Yes | Friendly name (e.g., "Home HA") |
| Base URL | Yes | Publicly reachable HA URL (e.g., https://your-id.ui.nabu.casa). A private or .local address is rejected — see Prerequisites. |
| Access Token | Yes | Long-lived access token (encrypted at rest) |
| Timeout | No | Request timeout in seconds (default: 30, range: 1-300) |
| Verify SSL | No | Verify SSL certificate (default: true). Disable for self-signed certs. |
Operations
Call Service
Control any Home Assistant device by calling a service action.
| Field | Required | Description |
|---|---|---|
| Domain | Yes | Service domain (e.g., light, switch, automation, climate, script) |
| Service | Yes | Service action (e.g., turn_on, turn_off, toggle) |
| Target (JSON) | No | Target entities, devices, or areas as JSON |
| Service Data (JSON) | No | Additional service parameters as JSON (e.g., brightness, color) |
| Return Response | No | Whether to return service response data (default: No) |
Example: Turn on a light at 50% brightness:
- Domain:
light - Service:
turn_on - Target:
{"entity_id": "light.living_room"}
- Service Data:
{"brightness_pct": 50}
Example: Run a script with variables:
- Domain:
script - Service:
{{ payload.script_name }} - Service Data:
{"message": "{{ payload.alert_message }}"}
Fire Event
Fire a custom event on the Home Assistant event bus to trigger automations.
| Field | Required | Description |
|---|---|---|
| Event Type | Yes | Event type name (e.g., strand_notification) |
| Event Data (JSON) | No | Event data payload as JSON |
Example: Fire a notification event:
- Event Type:
strand_notification - Event Data:
{"message": "{{ payload.alert }}", "severity": "warning", "source": "strand"}
Set State
Create or update the state and attributes of an entity.
| Field | Required | Description |
|---|---|---|
| Entity ID | Yes | Entity ID to create or update (e.g., sensor.strand_status) |
| State | Yes | New state value |
| Attributes (JSON) | No | Entity attributes as JSON |
Example: Update a custom sensor:
- Entity ID:
sensor.strand_last_run - State:
{{ payload.status }} - Attributes:
{"friendly_name": "Last Strand Run", "timestamp": "{{ payload.timestamp }}"}
Get Entity State
Get the current state and attributes of a single entity.
| Field | Required | Description |
|---|---|---|
| Entity ID | Yes | Entity ID to retrieve (e.g., sensor.temperature, light.living_room) |
Get All States
Get the current state of every entity in Home Assistant. No fields required.
Note: This can return a large payload depending on the number of entities in your HA instance. Use Get Entity State for targeted lookups.
Get History
Get state change history for entities over a time period.
| Field | Required | Description |
|---|---|---|
| Entity ID | No | Filter to a specific entity. If empty, returns all entities (may be large). |
| Start Time | No | ISO 8601 start time (default: 1 day ago) |
| End Time | No | ISO 8601 end time (default: now) |
| Minimal Response | No | Return only state and last_changed for a smaller payload (default: No) |
Example: Get last 24 hours of a sensor:
- Entity ID:
sensor.outdoor_temperature - Minimal Response: Yes
Get Services
List all available service domains and their actions. No fields required.
Useful for discovering what services are available on your HA instance.
Render Template
Render a Home Assistant Jinja2 template on the HA server.
| Field | Required | Description |
|---|---|---|
| Template | Yes | Home Assistant Jinja2 template string |
Note: This template is rendered by Home Assistant, not Strand. You can use Strand Jinja templates to inject dynamic values into the HA template.
Example: Get a computed value:
{{ states("sensor.temperature") }} {{ state_attr("sensor.temperature", "unit_of_measurement") }}
Example: Count lights that are on:
{{ states.light | selectattr("state", "eq", "on") | list | count }}
Output
Call Service Output
{
"success": true,
"status": "completed",
"data": {
"domain": "light",
"service": "turn_on",
"response": []
},
"service": "homeassistant",
"operation": "call_service"
}
Fire Event Output
{
"success": true,
"status": "fired",
"data": {
"event_type": "strand_notification",
"message": "Event strand_notification fired."
},
"service": "homeassistant",
"operation": "fire_event"
}
Set State Output
{
"success": true,
"status": "completed",
"data": {
"entity_id": "sensor.strand_status",
"state": "active",
"attributes": {
"friendly_name": "Strand Status",
"timestamp": "2025-01-15T10:30:00Z"
}
},
"service": "homeassistant",
"operation": "set_state"
}
Get Entity State Output
{
"success": true,
"status": "completed",
"data": {
"entity_id": "sensor.temperature",
"state": "22.5",
"attributes": {
"unit_of_measurement": "\u00b0C",
"friendly_name": "Temperature Sensor",
"device_class": "temperature"
},
"last_changed": "2025-01-15T10:30:00+00:00",
"last_updated": "2025-01-15T10:30:00+00:00"
},
"service": "homeassistant",
"operation": "get_state"
}
Key fields for subsequent nodes:
{{ steps.node_id.output_payload.data.state }}: Entity state value{{ steps.node_id.output_payload.data.attributes.friendly_name }}: An attribute{{ steps.node_id.output_payload.data.last_changed }}: Last state change time
Get All States Output
{
"success": true,
"status": "completed",
"data": {
"entities": [ ... ],
"count": 156
},
"service": "homeassistant",
"operation": "get_states"
}
Get History Output
{
"success": true,
"status": "completed",
"data": {
"history": [
[
{"state": "21.0", "last_changed": "2025-01-15T08:00:00+00:00"},
{"state": "22.5", "last_changed": "2025-01-15T10:30:00+00:00"}
]
],
"entity_id": "sensor.temperature"
},
"service": "homeassistant",
"operation": "get_history"
}
Get Services Output
{
"success": true,
"status": "completed",
"data": {
"services": [
{"domain": "light", "services": {"turn_on": {}, "turn_off": {}, "toggle": {}}},
{"domain": "switch", "services": {"turn_on": {}, "turn_off": {}, "toggle": {}}}
],
"count": 2
},
"service": "homeassistant",
"operation": "get_services"
}
Render Template Output
{
"success": true,
"status": "completed",
"data": {
"template": "{{ states('sensor.temperature') }}",
"rendered": "22.5"
},
"service": "homeassistant",
"operation": "render_template"
}
Key field: {{ steps.node_id.output_payload.data.rendered }}: The rendered template result
Errors
| Error | Meaning |
|---|---|
| Home Assistant authentication failed | Access token is invalid or expired. Regenerate from your HA profile. |
| SSL verification failed | Self-signed certificate detected. Disable "Verify SSL" in connector settings. |
| Failed to connect to Home Assistant | Instance unreachable. Most often the Base URL is a private or .local address, which Strand cannot connect to from the cloud — see Prerequisites. Otherwise check the URL and that the instance is up. |
| API endpoint not found (404) | Entity ID doesn't exist or the URL is wrong. |
| Access to '…' is blocked | The Base URL resolves to a private address. Give Strand a publicly reachable URL — see Prerequisites. |
| Home Assistant API error (400) | Bad request; check entity IDs, service names, or template syntax. |
| Template rendering failed | Invalid Home Assistant Jinja2 template syntax. |
Example Workflow
- Get Entity State: Check a temperature sensor: entity_id
sensor.outdoor_temperature - Logic node: Evaluate if temperature > 30
- Call Service: Turn on the AC: domain
climate, serviceset_temperature, target{"entity_id": "climate.living_room"}, service data{"temperature": 24} - Fire Event: Log the action: event_type
strand_ac_activated, event data{"temperature": "{{ steps.step1.output_payload.data.state }}"}
Limitations
- WebSocket API: Only the REST API is supported. WebSocket-based subscriptions and real-time event streams are not available.
- Media: Media upload/download and camera proxy endpoints are not supported.
- Config entries: Managing HA integrations and config entries via API is not supported.
- Large history queries: History queries for many entities over long periods may timeout. Use the entity_id filter and minimal_response option for large datasets.
- Rate limiting: Home Assistant does not enforce rate limits by default, but rapid-fire requests may slow down the instance.
Tendrl