Home Assistant¶
What it does¶
The Home Assistant plugin lets you control your smart home by texting keywords to yourself (or a shared group chat). Each inbound iMessage is checked against a list of keyword → HA service mappings. On a match, the plugin POSTs to the Home Assistant services API and replies with a confirmation.
Examples of what you can do:
- Text "lights off" →
light.turn_offfires onlight.living_room - Text "good night" →
scene.turn_onfires onscene.night_mode - Text "coffee" →
switch.turn_onfires onswitch.coffee_maker
You can restrict each command to a list of trusted senders, so only your phone number (or family members) can trigger HA actions even if someone else texts the bridge number.
Install command¶
Then restart the chatwire bridge:
Configuration walkthrough¶
- Open chatwire in your browser (
http://localhost:8723). - Go to Settings → Plugins → Home Assistant.
- Toggle Enabled to ON.
- Enter your Home Assistant URL (e.g.
http://homeassistant.local:8123). - Paste a Long-lived access token (create one in HA under Profile → Long-Lived Access Tokens).
- Add one or more Command mappings (see below).
- Changes save automatically. The integration is active immediately.
Settings reference¶
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false |
Master switch. |
ha_url |
string | (required) | Base URL of your HA instance. |
access_token |
string | (required) | HA long-lived access token. |
commands |
array | [] |
List of keyword → HA service mappings (see below). |
Command mapping fields¶
Each entry in commands is an object with these fields:
| Field | Type | Required | Description |
|---|---|---|---|
keyword |
string | yes | Exact phrase the sender types (matched case-insensitively, whitespace-stripped). |
domain |
string | yes | HA domain, e.g. light, switch, scene, automation. |
service |
string | yes | HA service, e.g. turn_on, turn_off, trigger. |
entity_id |
string | yes | Target entity, e.g. light.living_room, scene.night_mode. |
description |
string | yes | Human-readable label sent back as the confirmation reply. |
allowed_senders |
array of strings | no | Optional list of handles that may trigger this command. Empty or absent = any sender. |
Config file path: ~/.chatwire/config.json under integrations.chatwire_ha.
Minimal config¶
{
"integrations": {
"chatwire_ha": {
"enabled": true,
"ha_url": "http://homeassistant.local:8123",
"access_token": "<long-lived token>",
"commands": [
{
"keyword": "lights off",
"domain": "light",
"service": "turn_off",
"entity_id": "light.living_room",
"description": "Living room lights off"
}
]
}
}
}
Full config with allowed_senders¶
{
"integrations": {
"chatwire_ha": {
"enabled": true,
"ha_url": "http://homeassistant.local:8123",
"access_token": "<long-lived token>",
"commands": [
{
"keyword": "lights off",
"domain": "light",
"service": "turn_off",
"entity_id": "light.living_room",
"description": "Living room lights off",
"allowed_senders": ["+15551234567", "+15559876543"]
},
{
"keyword": "good night",
"domain": "scene",
"service": "turn_on",
"entity_id": "scene.night_mode",
"description": "Night mode activated"
},
{
"keyword": "coffee",
"domain": "switch",
"service": "turn_on",
"entity_id": "switch.coffee_maker",
"description": "Coffee maker on",
"allowed_senders": ["+15551234567"]
}
]
}
}
}
In this example:
- "lights off": only
+15551234567or+15559876543can trigger it. - "good night": any sender can trigger it (no
allowed_sendersrestriction). - "coffee": only
+15551234567can trigger it.
How allowed_senders works¶
- The filter is per-command. Commands without
allowed_senders(or with an empty list) are open to any sender. - Matching is case-insensitive — useful for email-format handles (
[email protected]matches[email protected]). - Phone number handles are matched exactly as they arrive from the bridge (e.g.
+15551234567). - If a sender is not in the list, the message is silently ignored — no reply is sent.
Keyword matching rules¶
- The full message text is stripped of leading/trailing whitespace and lowercased before comparison.
- Matching is exact —
"lights"does not match the command"lights off". - There is no substring or regex matching; each keyword is a complete, literal phrase.
Home Assistant automation example¶
You can also trigger HA automations directly. In HA, create an automation with a webhook trigger, then map a keyword to it:
{
"keyword": "run morning routine",
"domain": "automation",
"service": "trigger",
"entity_id": "automation.morning_routine",
"description": "Morning routine triggered"
}
Or use a scene:
{
"keyword": "movie time",
"domain": "scene",
"service": "turn_on",
"entity_id": "scene.movie_mode",
"description": "Movie mode activated"
}
Troubleshooting / FAQ¶
The command fires but HA returns 401 Unauthorized.
Your access_token is invalid or expired. Generate a new one under Profile → Long-Lived Access Tokens in Home Assistant.
The command fires but HA returns 404 Not Found.
Check domain, service, and entity_id. Run the service manually in HA Developer Tools → Services to verify the call syntax.
I sent the keyword but got no reply.
- Confirm the integration is enabled and the bridge was restarted after saving config.
- Check that ha_url is reachable from the Mac running chatwire: curl -sf http://homeassistant.local:8123/api/.
- If you set allowed_senders, verify your handle is in the list.
Keyword matching isn't working. The match is exact after stripping and lowercasing. Type the keyword exactly as configured. Leading/trailing spaces are ignored but interior spaces are significant.
I want to trigger the same HA action from multiple keywords.
Add multiple command entries that share the same domain/service/entity_id but different keyword values.
How do I find the right entity_id? In Home Assistant go to Settings → Devices & Services → Entities. Search for the device; the entity ID is shown in the detail panel.