- Posted on
- • Artificial Intelligence
Artificial Intelligence Smart Home Automation
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
AI-Powered Smart Home Automation on Linux (Bash-Friendly Guide)
Tired of cloud-only assistants that phone home, lock you in, and break when the internet hiccups? With a modest Linux box and a few open-source tools, you can run a private, fast, and extensible AI smart home—entirely on your LAN. This guide shows you how to stand up a local stack—MQTT, Home Assistant, Node-RED, and a local LLM—then wire up real automations with nothing but Bash and a few containers.
What you’ll get:
A local, private, low-latency AI home hub
Hardware control via Zigbee/Z-Wave (e.g., lights, sensors)
Natural-language control without the cloud
Reproducible, scriptable setups you can automate with Bash
Why local AI for smart homes is worth it
Privacy by default: Your commands, presence, and routines never leave your LAN.
Reliability and latency: Actions complete in milliseconds, even without internet.
Freedom and extensibility: Open protocols (MQTT), pluggable tools (Home Assistant, Node-RED), and local LLMs give you complete control.
Cost control: No subscriptions; run on spare hardware (old mini PC, Pi-class boards).
What we’ll build (architecture)
Mosquitto (MQTT broker): The event bus for your devices and automations.
Home Assistant: Device discovery, dashboards, and deep integrations.
Node-RED: Low-code logic and HTTP endpoints for glue/automation.
Zigbee2MQTT: Bridges Zigbee devices to MQTT (Z-Wave alternatives exist).
Ollama: Local LLM server for natural-language understanding.
We’ll run most services in containers (Podman) for portability and easy updates.
1) Prerequisites: Install base tools
Install Podman (containers), Mosquitto (MQTT), Git, curl, and jq. Pick your package manager:
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y podman mosquitto mosquitto-clients git curl jq
sudo systemctl enable --now mosquitto
- Fedora/RHEL (dnf):
sudo dnf install -y podman mosquitto mosquitto-clients git curl jq
sudo systemctl enable --now mosquitto
- openSUSE (zypper):
sudo zypper install -y podman mosquitto git curl jq
sudo systemctl enable --now mosquitto
Optional: If your firewall blocks ports, open these:
Home Assistant: 8123/tcp
Node-RED: 1880/tcp
MQTT: 1883/tcp
Zigbee2MQTT frontend: 8080/tcp
Example (firewalld):
sudo firewall-cmd --add-port=8123/tcp --add-port=1880/tcp --add-port=1883/tcp --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
Create directories to hold container data:
mkdir -p ~/containers/{homeassistant/config,nodered/data,zigbee2mqtt/data}
2) Spin up your backbone services (Home Assistant + Node-RED)
We’ll run these in Podman with host networking to make MQTT/home services simple.
- Home Assistant (stable):
podman run -d --name homeassistant \
--restart=always --privileged --network=host \
-v ~/containers/homeassistant/config:/config \
ghcr.io/home-assistant/home-assistant:stable
Access: http://localhost:8123 (first-run setup will guide you).
- Node-RED:
podman run -d --name nodered \
--restart=always --network=host \
-v ~/containers/nodered/data:/data \
docker.io/nodered/node-red:latest
Access: http://localhost:1880
Tip: In Node-RED, add the Home Assistant palette for easy service calls:
- Menu > Manage palette > Install: node-red-contrib-home-assistant-websocket
3) Add local AI: Ollama (run LLMs on your LAN)
Install Ollama (serves models at http://localhost:11434):
curl -fsSL https://ollama.com/install.sh | sh
systemctl --user enable --now ollama || ollama serve &
Download a model that fits your hardware:
ollama pull phi3:mini # lightweight
# or
ollama pull llama3:8b # stronger model, needs more RAM/VRAM
Quick test:
curl -s http://localhost:11434/api/generate -d '{
"model": "phi3:mini",
"prompt": "In one sentence, explain what MQTT is."
}' | jq -r '.response'
4) Bridge the physical world: Zigbee2MQTT
Plug in your Zigbee coordinator (e.g., CC2652-based USB dongle) and grant serial access:
sudo usermod -aG dialout $USER
# Log out/in or reboot for group change to take effect
ls -l /dev/serial/by-id/
Create Zigbee2MQTT config:
cat > ~/containers/zigbee2mqtt/data/configuration.yaml <<'YAML'
homeassistant: true
permit_join: false
mqtt:
base_topic: zigbee2mqtt
server: 'mqtt://127.0.0.1:1883'
serial:
port: '/dev/serial/by-id/usb-TI_CC2652...'
frontend:
port: 8080
YAML
Run the container:
podman run -d --name zigbee2mqtt \
--restart=always --network=host \
--device /dev/ttyUSB0 \
-v ~/containers/zigbee2mqtt/data:/app/data \
docker.io/koenkk/zigbee2mqtt:latest
Note:
Prefer the stable by-id path in configuration.yaml; keep
--devicealigned (e.g., /dev/ttyACM0).Access the Zigbee2MQTT UI at http://localhost:8080 to pair devices and see logs.
5) Real-world automations you can run today
Here are three Bash-first examples that show how to glue it all together.
A) Natural-language light control with Ollama + Home Assistant
Goal: Type “set the living room lights to warm 40%” and let the LLM turn that into a service call.
1) Create a long-lived token in Home Assistant (Profile > Create Token). Save it as HA_TOKEN.
2) Bash helper that parses natural language into JSON using Ollama, then calls HA:
#!/usr/bin/env bash
set -euo pipefail
HA_URL="http://127.0.0.1:8123"
HA_TOKEN="<PUT_YOUR_HA_TOKEN_HERE>"
MODEL="phi3:mini"
NL="$*"
if [[ -z "${NL}" ]]; then
echo "Usage: $0 \"turn kitchen light on warm 40%\"" >&2
exit 1
fi
SYSTEM_PROMPT='You convert home commands to strict JSON. Keys: device (string), action (on|off|toggle), brightness (0-255, optional), color_temp (153-500 mireds, optional). Only output JSON.'
USER_PROMPT="Command: ${NL}"
PAYLOAD=$(jq -n --arg sp "$SYSTEM_PROMPT" --arg up "$USER_PROMPT" \
'{model:"'"$MODEL"'", system:$sp, prompt:$up, format:"json"}')
JSON=$(curl -s http://127.0.0.1:11434/api/generate -d "$PAYLOAD" | jq -r '.response')
DEVICE=$(jq -r '.device' <<<"$JSON")
ACTION=$(jq -r '.action' <<<"$JSON")
BRI=$(jq -r 'try .brightness // empty' <<<"$JSON")
CT=$(jq -r 'try .color_temp // empty' <<<"$JSON")
# map your device names to HA entity_ids
declare -A MAP=( ["living room"]="light.living_room" ["kitchen"]="light.kitchen" )
ENTITY="${MAP[$DEVICE]}"
if [[ -z "${ENTITY:-}" ]]; then
echo "Unknown device: $DEVICE" >&2
exit 1
fi
SERVICE="light/turn_${ACTION}"
BODY=$(jq -n --arg e "$ENTITY" --argjson b "${BRI:-null}" --argjson c "${CT:-null}" '
.entity_id=$e
| if $b != null then .brightness=$b else . end
| if $c != null then .color_temp=$c else . end
')
curl -s -X POST "$HA_URL/api/services/$SERVICE" \
-H "Authorization: Bearer $HA_TOKEN" \
-H "Content-Type: application/json" \
-d "$BODY" | jq .
Use it:
./ai-light.sh "set the living room lights to warm 40%"
B) Quick “Goodnight” scene via MQTT (no HA call needed)
Assuming Zigbee2MQTT, publish to a specific light or group:
mosquitto_pub -h 127.0.0.1 -t zigbee2mqtt/bedroom_lamp/set -m '{"state":"OFF"}'
mosquitto_pub -h 127.0.0.1 -t zigbee2mqtt/hall_group/set -m '{"state":"OFF"}'
Wrap it with a simple LLM plan:
PLAN=$(curl -s http://127.0.0.1:11434/api/generate -d '{
"model":"phi3:mini",
"prompt":"Create a JSON array of MQTT commands to turn off all lights and set bedroom temperature cozy. Use topics zigbee2mqtt/<thing>/set with minimal fields."
}' | jq -r '.response')
jq -c '.[]' <<<"$PLAN" | while read -r cmd; do
TOPIC=$(jq -r '.topic' <<<"$cmd")
MSG=$(jq -c '.message' <<<"$cmd")
mosquitto_pub -h 127.0.0.1 -t "$TOPIC" -m "$MSG"
done
C) Energy coach: summarize usage and post a tip
1) Create a Home Assistant sensor for energy (e.g., sensor.energy_daily).
2) Bash script pulls the value, asks the LLM for a tip, and publishes to MQTT:
#!/usr/bin/env bash
set -euo pipefail
HA_URL="http://127.0.0.1:8123"
HA_TOKEN="<PUT_YOUR_HA_TOKEN_HERE>"
VAL=$(curl -s "$HA_URL/api/states/sensor.energy_daily" \
-H "Authorization: Bearer $HA_TOKEN" | jq -r '.state')
TIP=$(curl -s http://127.0.0.1:11434/api/generate -d "{
\"model\":\"phi3:mini\",
\"prompt\":\"Today's household energy use is ${VAL} kWh. In <=2 sentences, offer one specific, practical tip to reduce consumption tonight.\"
}" | jq -r '.response' | tr -s '\n' ' ')
mosquitto_pub -h 127.0.0.1 -t home/energy/tip -m "$TIP"
echo "Posted tip: $TIP"
Schedule with cron:
crontab -e
# at 21:00 daily
0 21 * * * /home/you/bin/energy-tip.sh >> /home/you/energy-tip.log 2>&1
Troubleshooting tips
Can’t reach MQTT from containers? Use
--network=hostand connect to 127.0.0.1. Make sure mosquitto is running:systemctl status mosquitto.Zigbee coordinator path: Prefer the by-id path from
/dev/serial/by-id/in configuration.yaml.Permissions: After adding your user to the dialout group, log out/in.
Performance: Try smaller models (e.g., phi3:mini) on low-RAM systems.
Node-RED to HA: Use the HA WebSocket nodes for easy entity discovery and service calls.
Conclusion and next steps (CTA)
You now have a private AI home hub running entirely on Linux—with device control, natural-language smarts, and portable automations you can script in Bash. Next:
In Home Assistant, add Assist + Piper for offline voice control.
In Node-RED, build flows that call Ollama for intent parsing.
Secure remote access via a reverse proxy and mTLS/WireGuard.
Back up
~/containers/*and your HA config regularly.
Share your automations and tweaks with the community, and show what Linux + local AI can do—no cloud required.