WebSocket Streaming sensor data Low (~100ms) Medium
Zigbee/Z-Wave (via bridge) Local smart home Low Very High
Home Assistant Integration
Home Assistant is the most popular open-source home automation platform and integrates seamlessly with OpenClaw.
Setup
# config.yaml
integrations:
home_assistant:
url: "http://homeassistant.local:8123"
token: "${HASS_TOKEN}"
entities:
- light.*
- switch.*
- climate.*
- sensor.temperature_*
- cover.*
OpenClaw Skill for Home Assistant
// skills/home-control/index.js
const fetch = require("node-fetch");
module.exports = {
name: "home-control",
description: "Control smart home devices via Home Assistant",
tools: [
{
name: "control_device",
description: "Turn on/off or adjust a smart home device",
parameters: {
type: "object",
properties: {
entity_id: { type: "string", description: "e.g., light.living_room" },
action: { type: "string", enum: ["turn_on", "turn_off", "toggle"] },
attributes: {
type: "object",
description: "Optional: brightness, color_temp, temperature"
}
},
required: ["entity_id", "action"]
},
async execute({ entity_id, action, attributes = {} }) {
const url = process.env.HASS_URL;
const token = process.env.HASS_TOKEN;
const domain = entity_id.split(".")[0];
const response = await fetch(
`${url}/api/services/${domain}/${action}`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
entity_id,
...attributes
})
}
);
if (!response.ok) {
throw new Error(`Home Assistant error: ${response.statusText}`);
}
return { success: true, entity_id, action };
}
},
{
name: "get_device_state",
description: "Get the current state of a smart home device",
parameters: {
type: "object",
properties: {
entity_id: { type: "string" }
},
required: ["entity_id"]
},
async execute({ entity_id }) {
const url = process.env.HASS_URL;
const token = process.env.HASS_TOKEN;
const response = await fetch(
`${url}/api/states/${entity_id}`,
{
headers: { "Authorization": `Bearer ${token}` }
}
);
return response.json();
}
}
],
async onMessage(context, message) {
// The LLM will automatically use the tools above
// based on the user's natural language request
}
};
MQTT Direct Integration
For custom IoT devices communicating via MQTT:
// skills/mqtt-bridge/index.js
const mqtt = require("mqtt");
module.exports = {
name: "mqtt-bridge",
async onActivate(context) {
const client = mqtt.connect(process.env.MQTT_BROKER_URL);
client.on("connect", () => {
// Subscribe to sensor data
client.subscribe("home/sensors/#");
client.subscribe("home/devices/#/status");
});
client.on("message", (topic, payload) => {
const data = JSON.parse(payload.toString());
// Store sensor data in agent memory for queries
context.memory.set(`sensor:${topic}`, {
value: data,
timestamp: Date.now()
});
});
context.state.mqttClient = client;
},
tools: [
{
name: "mqtt_publish",
description: "Send a command to an IoT device via MQTT",
parameters: {
type: "object",
properties: {
topic: { type: "string" },
payload: { type: "object" }
},
required: ["topic", "payload"]
},
async execute({ topic, payload }, context) {
context.state.mqttClient.publish(
topic,
JSON.stringify(payload)
);
return { sent: true, topic };
}
}
]
};
Natural Language Commands
Train your agent to understand natural device commands:
system_prompt: |
You control smart home devices. Interpret natural language:
"Turn off the lights" → control_device(light.all, turn_off)
"It's too warm" → control_device(climate.living_room, set, {temperature: 20})
"Lock up for the night" →
1. control_device(lock.front_door, lock)
2. control_device(light.all, turn_off)
3. control_device(cover.all, close)
4. control_device(alarm.home, arm_night)
Room mapping:
- "living room" → entity suffix: _living_room
- "bedroom" → entity suffix: _bedroom
- "kitchen" → entity suffix: _kitchen
Always confirm destructive actions (locks, alarms).
Report device state after changes.
Automation Routines
Create complex routines triggered by conversation:
// skills/routines/index.js
const routines = {
"good morning": [
{ entity: "light.bedroom", action: "turn_on", attrs: { brightness: 50 } },
{ entity: "cover.bedroom", action: "open" },
{ entity: "climate.home", action: "set", attrs: { temperature: 22 } },
// Then fetch and report: weather, calendar, news
],
"movie time": [
{ entity: "light.living_room", action: "turn_on", attrs: { brightness: 15, color_temp: 500 } },
{ entity: "cover.living_room", action: "close" },
{ entity: "media_player.tv", action: "turn_on" },
],
"leaving home": [
{ entity: "light.all", action: "turn_off" },
{ entity: "climate.home", action: "set", attrs: { temperature: 18 } },
{ entity: "lock.front_door", action: "lock" },
{ entity: "alarm.home", action: "arm_away" },
]
};
Sensor Data Queries
Let the agent access and analyze sensor data:
User: "What's the temperature trend in the living room today?"
Agent:
1. get_device_state(sensor.temperature_living_room)
2. Query stored historical data from memory
3. Present: "Currently 22.5°C. Today's range: 19.8°C (6 AM)
to 23.1°C (2 PM). Trending slightly upward."
Security Considerations
Risk Mitigation
Unauthorized device control Require confirmation for security devices
Credential exposure Use environment variables, never log tokens
Network attacks Use TLS for MQTT, HTTPS for REST
Runaway automations Add rate limits and circuit breakers
Physical safety Never automate gas, water heaters without safeguards
# Security config
agent:
iot_security:
require_confirmation:
- lock.*
- alarm.*
- climate.* (temperature > 28 or < 15)
rate_limit:
max_commands_per_minute: 30
logging:
log_all_commands: true
alert_on_unusual_patterns: true
Troubleshooting
Issue Solution
"Device not responding" Check network, verify entity_id, test API directly
High latency Use MQTT instead of HTTP, check broker performance
Commands ignored Verify token permissions, check Home Assistant logs
Stale sensor data Increase MQTT polling rate, check sensor batteries
Wrong device activated Review entity naming, add room disambiguation
Tips for Reliable IoT Control
Name devices clearly : light.kitchen_ceiling not light.entity_47
Group devices logically : Create groups for rooms and scenarios
Add confirmation for safety-critical devices : Locks, alarms, heaters
Monitor command history : Log all IoT interactions
Set reasonable defaults : If the agent is unsure, ask rather than act
Test offline scenarios : What happens when a device is unreachable?
Use local control when possible : Reduces latency and cloud dependency
Related Articles Using OpenClaw for Home Automation with Smart Devices — Control smart home devices through OpenClaw using integrations with Home Assistant, MQTT, and more.Basic Commands to Control Your OpenClaw Agent — Master the essential commands to start, stop, configure, and interact with your OpenClaw agent.Human-in-the-Loop: Balancing Control and Autonomy — Design effective human-in-the-loop systems that balance AI agent autonomy with human oversight.Agent Cost Control: Token Budgets, Prompt Caching, and Model Routing — Practical ways to control AI agent costs using token budgets, prompt caching, and model routing.CrewAI Flows: Combining Role-Based Crews with Deterministic Control Flow — How CrewAI Flows wrap multi-agent Crews in predictable, code-defined control flow for reliable pipelines.
Explore all Clawpedia articles · Browse For Humans