实战篇:手把手搭建OpenClaw三层物联网——从ESP8266采集到服务器AI调度
本文是上一篇《基于OpenClaw(小龙虾)的家用三层物联网全屋智能架构方案》的实战续篇。上一篇讲「是什么」和「为什么」,这一篇讲「怎么做」——从架构图落地到真实代码,手把手带你用 ESP8266 采集温湿度数据 → ESP32 MimiClaw 本地网关汇聚 → 服务器 OpenClaw 全局调度,打通全链路。
一、全链路架构回顾
┌─────────────────────────────────────────────────────┐ │ 第一层:家用服务器 OpenClaw │ │ (全局大脑 · AI决策 · 数据存储 · 远程管控 · OTA) │ │ ↑ MQTT / HTTP / WebSocket ↓ │ ├─────────────────────────────────────────────────────┤ │ 第二层:ESP32 MimiClaw │ │ (本地智能中枢 · 离线自治 · 数据汇聚 · 设备调度) │ │ ↑ MQTT / Serial ↓ │ ├─────────────────────────────────────────────────────┤ │ 第三层:ESP8266 终端节点(N台) │ │ (DHT22温湿度 · 继电器 · 人体感应 · 光照采集) │ └─────────────────────────────────────────────────────┘
二、第三层:ESP8266 温湿度采集终端(最底层)
每个 ESP8266 节点是独立终端,通过 MQTT 上报数据至 ESP32 本地中枢。
使用 Arduino IDE 或 PlatformIO 烧录。
硬件清单
- ESP8266 开发板(NodeMCU v3 / Wemos D1 Mini)
- DHT22 温湿度传感器(精度 ±0.5°C,推荐优于 DHT11)
- 面包板 + 杜邦线若干
完整代码(ESP8266 端)
#include <ESP8266WiFi.h> #include <PubSubClient.h> #include <DHT.h> // ========== WiFi 配置 ========== const char* wifi_ssid = "YOUR_WIFI_SSID"; const char* wifi_password = "YOUR_WIFI_PASSWORD"; // ========== MQTT 配置 ========== // 指向 ESP32 MimiClaw 本地 MQTT Broker 地址 const char* mqtt_server = "192.168.1.100"; // ← 改成你的 ESP32 局域网IP const int mqtt_port = 1883; // ========== DHT22 引脚 ========== #define DHTPIN D2 // GPIO4 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); WiFiClient espClient; PubSubClient client(espClient); char deviceId[32]; unsigned long lastReport = 0; const unsigned long REPORT_INTERVAL = 30000; // 30秒上报一次 void setup_wifi() { delay(10); Serial.println(); Serial.print("Connecting to "); Serial.println(wifi_ssid); WiFi.begin(wifi_ssid, wifi_password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.print("WiFi connected, IP: "); Serial.println(WiFi.localIP()); // 生成唯一设备ID(基于MAC地址) sprintf(deviceId, "esp8266_sensor_%s", WiFi.macAddress().c_str()); deviceId[strcspn(deviceId, ":")] = '\0'; // 去掉冒号 } void callback(char* topic, byte* payload, unsigned int length) { // 处理来自上层(ESP32/服务器)的指令 Serial.print("Command received ["); Serial.print(topic); Serial.print("]: "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); } void reconnect() { // 循环直到MQTT连接成功 while (!client.connected()) { Serial.print("Attempting MQTT connection..."); if (client.connect(deviceId)) { Serial.println("connected"); // 订阅控制指令主题 client.subscribe("home/esp8266/+/cmd"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" retry in 5s"); delay(5000); } } } void setup() { Serial.begin(115200); dht.begin(); setup_wifi(); client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); } void loop() { if (!client.connected()) reconnect(); client.loop(); unsigned long now = millis(); if (now - lastReport >= REPORT_INTERVAL) { lastReport = now; // 读取DHT22 float humidity = dht.readHumidity(); float temperature = dht.readTemperature(); // 检查读取是否成功 if (isnan(humidity) || isnan(temperature)) { Serial.println("Failed to read from DHT sensor!"); return; } // 构建JSON数据包并上报 char payload[256]; snprintf(payload, sizeof(payload), "{" "\"device\":\"%s\"," "\"type\":\"sensor\"," "\"temperature\":%.1f," "\"humidity\":%.1f," "\"rssi\":%d," "\"uptime\":%lu" "}", deviceId, temperature, humidity, WiFi.RSSI(), now / 1000); // 上报到 ESP32 中枢的网关主题 char topic[64]; snprintf(topic, sizeof(topic), "home/%s/data", deviceId); if (client.publish(topic, payload)) { Serial.printf("[OK] Published: %s\n", payload); } else { Serial.println("[FAIL] Publish failed!"); } } }
- 每个 ESP8266 节点使用 MAC 地址生成唯一设备 ID,避免冲突
- 数据通过
home/{deviceId}/data主题上报到 ESP32 - 每 30 秒上报一次,可根据实际需求调整(温控场景建议 5-10s,环境监测 30-60s)
- 支持 OTA 远程升级,无需每次拔线烧录(后续代码会展示)
三、第二层:ESP32 MimiClaw 本地中枢
ESP32 刷入 MimiClaw 固件后,作为本地 MQTT Broker,汇聚所有 ESP8266 终端数据,并通过专有协议上报到服务器 OpenClaw。
3.1 MimiClaw 固件配置
MimiClaw 固件目前可从 OpenClaw GitHub 仓库 获取,烧录后通过 Web 面板进行配置:
# MimiClaw Web Config 关键参数示例 [WiFi] SSID = YOUR_WIFI_SSID Password = YOUR_WIFI_PASSWORD [MQTT] # 作为本地 Broker 监听 Local_Broker_Enabled = true Local_Broker_Port = 1883 # 订阅所有 ESP8266 终端的上报主题 Subscribe_Topics = home/+/data [Server] # 连接上层家用服务器 OpenClaw Server_Mode = mqtt Server_Host = 192.168.1.50 # 服务器 OpenClaw 的 IP Server_Port = 1883 Server_Token = your_server_token [Offline] # 离线自治规则(断网时自动执行) Rule_1 = IF temperature > 35 THEN publish home/alarm/high_temp Rule_2 = IF humidity < 30 THEN publish home/actuator/dehumidifier/on
3.2 ESP32 自定义脚本(数据汇聚转发)
MimiClaw 支持 Lua 脚本扩展,以下脚本实现数据汇聚和转发逻辑:
-- MimiClaw Data Hub Script (Lua) -- 功能:汇聚ESP8266上报数据,规整后上报服务器 -- 设备注册表:记录已注册的终端节点 local device_registry = {} -- 监听所有终端上报 mqtt.subscribe("home/+/data", function(topic, payload) local data = json.decode(payload) if not data then return end local device_id = data.device local now = os.time() -- 更新注册表 device_registry[device_id] = { last_seen = now, temperature = data.temperature, humidity = data.humidity, rssi = data.rssi, type = data.type } -- 数据规整:添加时间戳、网关ID后上报服务器 local report = { gateway = mqtt.client_id(), device = device_id, temperature = data.temperature, humidity = data.humidity, rssi = data.rssi, timestamp = now } -- 上报到家用服务器 OpenClaw mqtt.publish("gateway/sensor_report", json.encode(report)) -- 日志输出(可通过串口或Web查看) log.info(string.format("[%s] T=%.1f°C H=%.1f%% RSSI=%d", device_id, data.temperature, data.humidity, data.rssi)) end) -- 心跳上报(每60秒汇报节点健康状态) local timer = mqtt.timer(60000, function() local heartbeat = { gateway = mqtt.client_id(), uptime = system.uptime(), devices_online = 0, device_list = {} } for dev_id, info in pairs(device_registry) do -- 检查是否30秒内有心跳 if os.time() - info.last_seen < 30 then table.insert(heartbeat.device_list, dev_id) devices_online = devices_online + 1 end end heartbeat.devices_online = #heartbeat.device_list mqtt.publish("gateway/heartbeat", json.encode(heartbeat)) end) timer:start()
四、第一层:服务器 OpenClaw 全局调度
家用服务器部署完整版 OpenClaw,通过 MQTT/WebSocket 消费来自 ESP32 网关上报的全部数据,驱动 AI 决策引擎,实现智能场景联动。
4.1 OpenClaw 配置文件(gateway.yaml 关键片段)
# gateway.yaml - OpenClaw IoT 相关配置 mqtt: broker: host: "0.0.0.0" # 监听所有接口 port: 1883 auth: token: "your_server_token" # ESP32 连接用 topics: # 订阅 ESP32 网关上报的数据 - "gateway/+" sinks: # 传感器数据持久化到 InfluxDB gateway/sensor_report: handlers: - influxdb_iot # 时序数据库存储 - wecom_alert # 异常告警推送企业微信 agents: # 智能场景Agent - 根据传感器数据触发自动化 iot-automation: triggers: - mqtt:gateway/sensor_report action: type: script script: /etc/openclaw/scripts/iot_scene_engine.py
4.2 AI 场景引擎脚本(Python)
以下脚本运行在服务器端,接收 ESP32 上报的传感器数据,驱动智能场景联动:
#!/usr/bin/env python3 """ IoT 智能场景引擎 接收 ESP32 上报的传感器数据,根据规则自动联动设备 """ import json import time import paho.mqtt.client as mqtt from datetime import datetime # MQTT 配置 MQTT_HOST = "127.0.0.1" MQTT_PORT = 1883 MQTT_TOPIC_SENSOR = "gateway/sensor_report" # 场景规则配置 SCENE_RULES = { "high_temp_alert": { "condition": lambda d: d.get("temperature", 0) > 35, "action": "publish:home/actuator/fan/on", "alert": "🔥 温度异常!{device} 当前 {temperature}°C" }, "low_humidity_warn": { "condition": lambda d: d.get("humidity", 100) < 30, "action": "publish:home/actuator/humidifier/on", "alert": "💧 湿度过低!{device} 当前 {humidity}%" }, "temp_comfort": { "condition": lambda d: 22 <= d.get("temperature", 0) <= 26, "action": "publish:home/actuator/fan/off" } } def on_connect(client, userdata, flags, rc): if rc == 0: print("Connected to MQTT Broker!") client.subscribe(MQTT_TOPIC_SENSOR) print(f"Subscribed to {MQTT_TOPIC_SENSOR}") else: print(f"Failed to connect, return code {rc}") def on_message(client, userdata, msg): try: data = json.loads(msg.payload.decode()) device = data.get("device", "unknown") temp = data.get("temperature") hum = data.get("humidity") if temp is None or hum is None: return print(f"[{datetime.now()}] {device}: T={temp}°C H={hum}%") # 遍历规则,执行业务逻辑 for rule_name, rule in SCENE_RULES.items(): if rule["condition"](data): print(f" → Rule triggered: {rule_name}") # 执行动作(发布控制指令) action = rule["action"] if action.startswith("publish:"): topic = action.split(":", 1)[1] client.publish(topic, json.dumps({ "source": "scene_engine", "rule": rule_name, "triggered_by": device, "timestamp": time.time() })) print(f" Published to {topic}") except Exception as e: print(f"Error processing message: {e}") # 启动MQTT客户端 client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.connect(MQTT_HOST, MQTT_PORT, 60) client.loop_forever()
五、企业微信告警推送集成
通过 OpenClaw 的 WeCom 插件,将异常告警实时推送到企业微信群,让你不在家也能掌握一切:
# OpenClaw WeCom 告警配置示例 wecom-alert: triggers: # 温度过高告警 - mqtt: topic: "home/alarm/high_temp" action: type: wecom_message params: to: "@all" msgtype: "markdown" content: | ## 🔥 高温告警 > 设备:{device} > 温度:**{temperature}°C** > 建议:请检查空调/通风设备是否正常运行 # 设备离线告警 - mqtt: topic: "gateway/heartbeat" condition: field: "devices_online" operator: "lt" value: 1 action: type: wecom_message params: to: "@all" content: "⚠️ 所有传感器节点已离线!请检查网络/供电!"
六、OTA 远程升级(ESP8266)
当你的 ESP8266 部署在天花板或墙内时,OTA 升级是刚需。以下代码片段为 ESP8266 添加 OTA 能力:
#include <ArduinoOTA.h> void setup_ota() { // OTA 主机名(用于Arduino IDE中识别) ArduinoOTA.setHostname(deviceId); // OTA 密码保护 ArduinoOTA.setPassword("iot_ota_2026"); ArduinoOTA.onStart([]() { Serial.println("OTA Update Start"); }); ArduinoOTA.onEnd([]() { Serial.println("OTA Update End"); }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress * 100) / total); }); ArduinoOTA.onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); } // 在 loop() 中添加: // ArduinoOTA.handle();
七、硬件成本清单
* 一个 ESP32 中枢 + 一个 ESP8266 温湿度节点 + 一个 DHT22,起步成本不到 70 元。
八、完整部署步骤
- 准备硬件:按照清单采购 ESP32 ×1 + ESP8266 ×N + DHT22 ×N + 面包板和杜邦线
- 烧录 ESP8266:用 Arduino IDE 烧录本篇第二章的温湿度采集代码,确认串口输出正常
- 部署 ESP32:刷入 MimiClaw 固件,配置 WiFi 和 MQTT,确认 Web 面板能正常访问
- 部署服务器:安装完整版 OpenClaw,配置 MQTT Broker 和 AI 场景引擎
- 连接测试:观察 ESP32 Web 面板能否看到 ESP8266 上报的数据
- 配置告警:在服务器端配置企业微信告警推送,手机验证告警通知
- 扩展部署:添加更多 ESP8266 节点(温湿度、人体感应、继电器控制等)
九、常见问题
Q:ESP8266 连不上 ESP32 的 MQTT Broker?
A:检查 ESP32 的防火墙设置,确认 1883 端口开放,并确保两个设备在同一个局域网段。
Q:传感器数据不准?
A:DHT22 在 2 米外会受干扰,建议使用屏蔽线,且传感器不要紧贴 ESP8266 芯片(芯片发热会影响读数)。
Q:ESP8266 频繁掉线重连?
A:检查 WiFi 信号强度(RSSI),如果低于 -70dBm,考虑增加 WiFi 中继或更换天线。
Q:外网断了还有智能功能吗?
A:ESP32 MimiClaw 内置离线自治引擎,基础场景联动(温度过高开风扇等)不受影响。远程告警和 AI 决策会暂缓,网络恢复后自动同步。
十、总结
从这篇实战文章可以看出,基于 OpenClaw(小龙虾)生态的三层物联网架构,不只是停留在概念层面。从 ESP8266 几行 Arduino 代码的传感器采集,到 ESP32 MimiClaw 的 Lua 数据汇聚,再到 服务器 OpenClaw 的 AI 场景引擎和 WeCom 告警推送,每一层都有成熟的开源代码和官方技术支持。
全套硬件成本不到百元,但获得的是一个:可远程管控 | 可离线自治 | 可无限扩展 | 可 AI 决策 的全屋智能系统。这正是小龙虾生态的核心魅力——让物联网不再只是极客玩具,而是每个家庭都能轻松上手的实用方案。
相关文章:
- 基于OpenClaw(小龙虾)的家用三层物联网全屋智能架构方案 — 架构总览篇
资源链接:
- OpenClaw 官方:https://github.com/openclaw/openclaw
- MimiClaw 固件:OpenClaw GitHub
- Arduino IDE 下载:arduino.cc







黑公网安备 23010302001359号