- Posted on
- • Artificial Intelligence
Artificial Intelligence IoT Automation
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence IoT Automation from the Linux Bash Shell
The average industrial site or smart home already has more sensors than people. They produce a flood of readings that are either ignored or acted on manually hours later. That delay can waste energy, cause downtime, or miss safety events. What if your Linux box could continuously “think” about those readings and trigger the right action in real time—using a few Bash commands and a tiny AI component?
In this guide, you’ll build a minimal, production-friendly IoT automation loop that:
Ingests sensor data (MQTT)
Scores it with a lightweight AI step (local microservice or remote API)
Publishes an action for an actuator
Runs as a systemd service so it survives reboots
You’ll get actionable steps, real-world examples, and copy-paste snippets you can adapt today.
Why AI-driven IoT automation is worth it
Speed and reliability: Decisions in milliseconds at the edge—no humans, no dashboards, no manual polling.
Privacy and cost: Keep raw sensor data local; only publish useful decisions to the cloud (or not at all).
Scalability: One pipeline pattern handles 10 to 10,000 devices with the same Bash foundations.
Flexibility: Swap models, thresholds, and destinations without rewriting your stack.
What we’ll build
A simple pipeline you can run on any Linux distro:
sensors → MQTT topic → Bash subscriber → AI microservice → decision → actuator topic
We’ll use mosquitto clients for MQTT, jq for JSON, and a tiny Python script for AI inference.
You can switch the AI step to a remote API with curl if you prefer cloud models.
1) Install dependencies
We’ll install:
mosquitto (optional: local MQTT broker)
mosquitto-clients (MQTT pub/sub CLI)
jq (JSON parsing)
curl (HTTP integration; optional for cloud AI)
python3 (for a small local inference microservice)
Choose your package manager.
Ubuntu/Debian (apt):
sudo apt update
sudo apt install -y mosquitto mosquitto-clients jq curl python3
Fedora/RHEL/CentOS Stream (dnf):
sudo dnf install -y mosquitto mosquitto-clients jq curl python3
openSUSE (zypper):
sudo zypper refresh
sudo zypper install -y mosquitto mosquitto-clients jq curl python3
Optional: Start a local MQTT broker (only if you don’t already have one):
sudo systemctl enable --now mosquitto
sudo systemctl status mosquitto
Quick sanity test:
# In terminal A (subscriber):
mosquitto_sub -h localhost -t 'sensors/temperature' -v
# In terminal B (publisher):
mosquitto_pub -h localhost -t 'sensors/temperature' -m '{"temp_c": 22.5, "room": "lab"}'
You should see the JSON payload appear in terminal A.
2) Create a tiny local AI microservice
To keep this fully portable, we’ll implement a very small logistic model that estimates “probability of overheat” based on temperature. In real life, swap this for a proper model (TensorFlow Lite, ONNX Runtime, or an API call). The interface is the same: JSON in, JSON out.
Create ai_infer.py:
#!/usr/bin/env python3
import sys, json, math
# Minimal coefficients for a demo logistic model:
# prob_overheat = sigmoid(bias + w_temp * temp_c)
W = {"temp_c": 0.18, "bias": -10.5}
def predict(x):
try:
temp = float(x.get("temp_c", 0))
except Exception:
temp = 0.0
z = W["bias"] + W["temp_c"] * temp
p = 1.0 / (1.0 + math.exp(-z))
return {"prob_overheat": round(p, 4)}
if __name__ == "__main__":
raw = sys.stdin.read()
try:
features = json.loads(raw) if raw.strip() else {}
except Exception:
features = {}
out = predict(features)
print(json.dumps(out))
Make it executable:
chmod +x ./ai_infer.py
Test it:
printf '{"temp_c": 30}' | ./ai_infer.py
# {"prob_overheat": 0.5003} (your number may vary slightly)
Prefer cloud AI? Replace the Python step with a curl call to your API:
# Example placeholder; replace URL, headers, and payload per your provider
printf '{"temp_c": 30}' | curl -sS -X POST https://api.example.ai/infer \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $AI_TOKEN" \
-d @-
3) Wire it up with Bash: subscribe → infer → publish action
Create iot_ai_automation.sh:
#!/usr/bin/env bash
set -euo pipefail
# Config (override via environment vars or systemd Environment=)
BROKER_HOST="${BROKER_HOST:-localhost}"
BROKER_PORT="${BROKER_PORT:-1883}"
BROKER_USER="${BROKER_USER:-}"
BROKER_PASS="${BROKER_PASS:-}"
IN_TOPIC="${IN_TOPIC:-sensors/temperature}"
OUT_TOPIC="${OUT_TOPIC:-actuators/hvac}"
CLIENT_ID="${CLIENT_ID:-ai-automation-$(hostname)-$$}"
AI_CMD="${AI_CMD:-./ai_infer.py}" # or "curl ...your API..."
MQTT_AUTH=()
if [[ -n "$BROKER_USER" && -n "$BROKER_PASS" ]]; then
MQTT_AUTH=(-u "$BROKER_USER" -P "$BROKER_PASS")
fi
echo "Subscribing to mqtt://${BROKER_HOST}:${BROKER_PORT}/${IN_TOPIC} as $CLIENT_ID" >&2
mosquitto_sub -h "$BROKER_HOST" -p "$BROKER_PORT" -t "$IN_TOPIC" -i "$CLIENT_ID" -q 1 "${MQTT_AUTH[@]}" \
| while IFS= read -r line; do
# Validate JSON
if ! jq -e . >/dev/null 2>&1 <<<"$line"; then
echo "Skipping non-JSON message: $line" >&2
continue
fi
# Extract features
temp=$(jq -r '.temp_c // empty' <<<"$line")
room=$(jq -r '.room // "unknown"' <<<"$line")
if [[ -z "${temp:-}" ]]; then
echo "Missing temp_c; skipping" >&2
continue
fi
# Run inference (local or remote)
pred_json=$(jq -n --argjson in "$line" '$in' | jq -c . | "$AI_CMD")
if ! jq -e . >/dev/null 2>&1 <<<"$pred_json"; then
echo "Bad AI output; got: $pred_json" >&2
continue
fi
prob=$(jq -r '.prob_overheat // 0' <<<"$pred_json")
# Simple policy: if prob_overheat > 0.7, turn cooling on; else hold
action="hold"
if awk -v p="$prob" 'BEGIN{exit(p>0.7?0:1)}'; then
action="cool_on"
fi
payload=$(jq -n \
--arg room "$room" \
--arg action "$action" \
--argjson prob "$prob" \
--argjson src "$line" \
'{
room: $room,
action: $action,
prob_overheat: $prob,
ts: (now|floor),
src: $src
}')
mosquitto_pub -h "$BROKER_HOST" -p "$BROKER_PORT" -t "$OUT_TOPIC" -q 1 -m "$payload" "${MQTT_AUTH[@]}"
echo "Published action=$action prob=$prob room=$room" >&2
done
Make it executable and test:
chmod +x ./iot_ai_automation.sh
./iot_ai_automation.sh
In another terminal, publish a few test readings:
mosquitto_pub -h localhost -t sensors/temperature -m '{"temp_c": 24.1, "room":"lab"}'
mosquitto_pub -h localhost -t sensors/temperature -m '{"temp_c": 38.0, "room":"lab"}'
Subscribe to the actuator topic to see decisions:
mosquitto_sub -h localhost -t actuators/hvac -v
4) Run it as a service (systemd)
Create a service unit so the pipeline starts on boot and restarts on failure.
Create /etc/systemd/system/iot-ai-automation.service:
[Unit]
Description=AI IoT Automation (MQTT -> AI -> Actuator)
After=network-online.target mosquitto.service
Wants=network-online.target
[Service]
Type=simple
User=%i
WorkingDirectory=/opt/iot-ai
Environment=BROKER_HOST=localhost
Environment=BROKER_PORT=1883
Environment=IN_TOPIC=sensors/temperature
Environment=OUT_TOPIC=actuators/hvac
# Optionally:
# Environment=BROKER_USER=automation
# Environment=BROKER_PASS=secret
ExecStart=/opt/iot-ai/iot_ai_automation.sh
Restart=on-failure
RestartSec=2s
[Install]
WantedBy=multi-user.target
Deploy files and enable:
sudo mkdir -p /opt/iot-ai
sudo cp ./iot_ai_automation.sh ./ai_infer.py /opt/iot-ai/
sudo chmod +x /opt/iot-ai/*.sh /opt/iot-ai/ai_infer.py
# Run as root or create a dedicated user, e.g., iotbot:
sudo useradd -r -s /usr/sbin/nologin iotbot || true
sudo chown -R iotbot:iotbot /opt/iot-ai
# If running as iotbot, use the instance template name with @iotbot:
# Save service as: /etc/systemd/system/iot-ai-automation@.service (note the @)
# Then:
# sudo systemctl daemon-reload
# sudo systemctl enable --now iot-ai-automation@iotbot
# If running as root and not templated:
sudo systemctl daemon-reload
sudo systemctl enable --now iot-ai-automation.service
sudo systemctl status iot-ai-automation.service
View logs:
journalctl -u iot-ai-automation.service -f
5) Real-world patterns you can copy today
Energy-efficient HVAC and lighting
- Combine room temperature and occupancy topics; predict demand and publish “cool_on/heater_on/light_dim.”
- Savings: 10–30% in small offices by avoiding overcooling when unoccupied.
Predictive maintenance
- Vibration or motor current sensors → anomaly score → “maintenance_check” event long before a hard fault.
- Downtime reduction by moving to condition-based maintenance.
Cold-chain monitoring
- Refrigerators/freezers → overheat or door-ajar probability → control relay or send a high-priority alert.
- Protect product integrity by automating quick corrective actions.
Security and reliability notes
MQTT authentication/TLS
- Use broker auth: create a user and password, then pass -u/-P to mosquitto_pub/sub.
- Prefer TLS (port 8883) with certificates; configure your broker accordingly.
Least privilege
- Run the service as a dedicated system user (e.g., iotbot).
- Limit broker ACLs so your client can only read/write allowed topics.
Backpressure and health
- Consider qos=1 or qos=2 for critical paths.
- Add a watchdog or health topic to confirm liveness (publish heartbeat messages periodically).
Observability
- Keep logs in journalctl and ship summaries to a dashboard (e.g., Loki/Grafana) if desired.
Troubleshooting
No messages?
- Verify topics and broker host/port.
- Test manually:
mosquitto_sub -h "$BROKER_HOST" -t "$IN_TOPIC" -vJSON parsing errors?
- Confirm your publisher emits valid JSON:
mosquitto_pub -h "$BROKER_HOST" -t "$IN_TOPIC" -m '{"temp_c": 25.0}'AI step failing?
- Test the microservice alone:
printf '{"temp_c": 35}' | ./ai_infer.pyService not starting?
- Check logs:
journalctl -u iot-ai-automation.service -b -e
Conclusion and next steps (CTA)
You’ve built a complete AI-driven IoT automation loop using nothing but standard Linux tools, MQTT, and a tiny inference script—productionized with systemd. From here, you can:
Swap the model for a real one (TensorFlow Lite, ONNX Runtime, or a cloud API).
Extend policies (combine sensors, add hysteresis, and escalation rules).
Containerize the service and deploy with Ansible/Fleet.
Add dashboards (Grafana), storage (InfluxDB), and flows (Node-RED) as your needs grow.
Pick one device and one action you care about—then wire it up with this pattern today. Your sensors are already talking; it’s time to let them act.