Smart Home Agent with Local AI
What this article covers
- What a Smart Home Agent is and how it works.
- How the agent makes autonomous decisions.
- How tool-calling works for Home Assistant control.
- Practical examples for energy, security, comfort, and maintenance.
- Best practices for safety, reliability, and fallbacks.
Introduction: Smart Home Agents explained
A Smart Home Agent is an AI agent that autonomously controls your home. It observes sensors, makes decisions, and executes actions, not just with simple if-then rules, but intelligently: “It’s warm, but someone is home → open windows instead of running air conditioning”. The agent plans, acts, and adapts.
This article is for advanced users who want to deploy AI agents in their smart homes. For foundational concepts, see AI Agents and Home Assistant with AI.
Why you need a Smart Home Agent
Traditional automation: “If temperature > 25°, turn on climate control”. An agent: “It’s warm, but the windows are open and the outside temperature is lower → ventilate instead of cooling”. The agent understands context and makes intelligent decisions.
Smart Home Agent in brief
Agent = LLM + Tools + Goal. The agent observes sensors, plans actions, executes them, and verifies results. Run it locally with Ollama, use Home Assistant as the action layer.
The core idea: don’t just react, act intelligently.
Who is this article for?
- Advanced users building autonomous smart home systems.
- AI agent developers implementing tool-calling in home automation.
- Home Assistant power users looking to move beyond standard automations.
- Tinkerers experimenting with advanced AI systems.
Key concepts
- AI Agent - An autonomous actor. When useful: the core concept.
- Tool-Calling - Invoking tools. When useful: for taking actions.
- Ollama - Local model server. When useful: the backend.
- Home Assistant - Smart home platform. When useful: for actions.
- Node-RED - Complex workflows. When useful: as a complement.
- Human Approval - Safety. When useful: for critical actions.
Architecture
Sensors (temperature, motion, windows, ...)
│
▼
Agent (Ollama + Tools)
│
├─ Observe: read sensor data
├─ Plan: what to do? (LLM decides)
├─ Act: call tools (HA services)
└─ Verify: did it work?
│
▼
Actions (Home Assistant Services)
│
├─ light.turn_on / light.turn_off
├─ climate.set_temperature
├─ cover.open / cover.close
├─ media_player.play / media_player.stop
└─ notify.notify (notification)
Practical example 1: Energy agent
class EnergyAgent:
"""Agent for energy management"""
def __init__(self):
self.tools = {
"get_energy_price": self.get_energy_price,
"turn_on_device": self.turn_on_device,
"turn_off_device": self.turn_off_device,
"get_consumption": self.get_consumption
}
async def run(self):
"""Agent loop"""
# 1. Observe
state = await self.observe()
# 2. Plan (LLM decides)
plan = await self.plan(state)
# 3. Act
for action in plan["actions"]:
await self.execute(action)
# 4. Verify
result = await self.verify()
return result
async def plan(self, state):
"""LLM plans actions"""
prompt = f"""You are an energy management agent.
Current state: {state}
Available actions:
- turn_on_device(device): turn on device
- turn_off_device(device): turn off device
- get_energy_price(): check electricity price
Goal: minimize energy costs, maintain comfort.
Plan the next actions as JSON:
{{"reasoning": "...", "actions": [{{"tool": "...", "params": {{...}}}}]}}"""
response = await ollama.generate(prompt)
return json.loads(response)
Practical example 2: Security agent
class SecurityAgent:
"""Agent for security monitoring"""
async def on_motion(self, sensor, time):
"""On motion detected"""
context = await self.gather_context()
# AI analyzes
analysis = await ollama.generate(f"""
Motion detected:
- Sensor: {sensor}
- Time: {time}
- People home: {context['people']}
- Recent alarms: {context['recent_alarms']}
- Window status: {context['windows']}
Is this suspicious? Reply as JSON:
{{"verdict": "normal|suspicious|critical", "reason": "...", "actions": [...]}}""")
result = json.loads(analysis)
if result["verdict"] == "critical":
await self.execute_emergency(result["actions"])
elif result["verdict"] == "suspicious":
await self.notify_owner(result)
async def execute_emergency(self, actions):
"""Critical actions with human approval"""
for action in actions:
if action["type"] == "critical":
# Wait for human approval
approved = await self.request_human_approval(action)
if approved:
await self.execute(action)
else:
await self.execute(action)
Practical example 3: Comfort agent
class ComfortAgent:
"""Agent for comfort optimization"""
async def optimize(self):
"""Optimize comfort"""
state = await self.observe()
# AI decides
decision = await ollama.generate(f"""
State:
- Temperature: {state['temp']}°C
- Humidity: {state['humidity']}%
- Light: {state['light']}
- People: {state['people']}
- Time of day: {state['time']}
- Weather: {state['weather']}
What should be done for optimal comfort?
Reply as JSON: {{"actions": [...], "reason": "..."}}""")
for action in json.loads(decision)["actions"]:
await self.execute(action)
Tool-calling for Home Assistant
# Define tools
tools = [
{
"type": "function",
"function": {
"name": "light_control",
"description": "Control lights",
"parameters": {
"type": "object",
"properties": {
"entity": {"type": "string", "description": "light.entity_id"},
"action": {"type": "string", "enum": ["turn_on", "turn_off", "toggle"]},
"brightness": {"type": "integer", "minimum": 0, "maximum": 255}
},
"required": ["entity", "action"]
}
}
},
{
"type": "function",
"function": {
"name": "climate_control",
"description": "Control climate",
"parameters": {
"type": "object",
"properties": {
"entity": {"type": "string"},
"temperature": {"type": "number"},
"mode": {"type": "string", "enum": ["heat", "cool", "off"]}
}
}
}
}
]
# Ollama with tools
response = requests.post("http://ollama:11434/api/chat", json={
"model": "llama3.1",
"messages": [
{"role": "system", "content": "You are a smart home agent. Use tools to take actions."},
{"role": "user", "content": "It's warm, cool it down."}
],
"tools": tools,
"stream": False
})
# Process tool calls
for tool_call in response.json()["message"].get("tool_calls", []):
await execute_tool(tool_call)
Security Considerations
- Human approval: Critical actions (unlocking doors, triggering alarms) require human sign-off. See Human Approval.
- Fallback: If the agent fails, critical automations should run in Home Assistant.
- Logging: Log all agent decisions. See Logging.
- Permissions: The agent should have only the minimum required permissions. See Tool Permissions.
- Validation: Verify agent outputs before executing actions.
Common Pitfalls
- Too autonomous: The agent shouldn’t make all decisions alone. Critical actions need approval.
- No fallback: If the agent crashes, automations stop. A Home Assistant fallback is essential.
- Too many tools: More than 5-7 tools overwhelm the model. Less is better.
- Poor tool descriptions: The model decides based on descriptions. Be precise.
- No iteration limit: Agents can get stuck in loops. Set a maximum iterations cap.
Further Reading
- AI Agents - Agent fundamentals.
- Home Assistant with AI - Home Assistant and AI.
- Local Voice Assistant - Voice control.
- Home Automation - Overview.
- Tool Permissions - Security.
- Human Approval - Approval workflows.
- Node-RED Home Assistant - For complex flows.
Key Takeaways:
- Smart Home Agent: observes, plans, acts, validates, autonomously.
- Tool-calling for Home Assistant control.
- Critical actions require human approval.
- Home Assistant fallback for essential automations.
- Local AI keeps all data private.
FAQ
What is a Smart Home Agent?
Agent or traditional automation?
Is an agent safe?
How does tool-calling work?
How much VRAM do I need?
What if the agent fails?
What does it cost?
Is my data private?
Sources and Further Reading
- Ollama - Local model server.
- Home Assistant - Smart home platform.
- LangChain Agents - Agent concepts.
- ReAct - Reasoning and acting.


