当前位置:首页 > 技术分享 > 正文内容

实战篇:手把手搭建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();

七、硬件成本清单

组件 型号 参考单价 数量 总价
家用服务器 云服务器/旧电脑/NAS 1 已有设备
ESP32 开发板 ESP32-DevKitC / WROOM-32 ¥25 1 ¥25
ESP8266 开发板 NodeMCU v3 / D1 Mini ¥15 N台 ¥15×N
温湿度传感器 DHT22 (AM2302) ¥8 N台 ¥8×N
继电器模块 2路/4路 5V继电器 ¥6 按需 ¥6/个
人体感应 HC-SR501 ¥5 按需 ¥5/个
起步总成本 ≈ ¥70起

* 一个 ESP32 中枢 + 一个 ESP8266 温湿度节点 + 一个 DHT22,起步成本不到 70 元。

八、完整部署步骤

  1. 准备硬件:按照清单采购 ESP32 ×1 + ESP8266 ×N + DHT22 ×N + 面包板和杜邦线
  2. 烧录 ESP8266:用 Arduino IDE 烧录本篇第二章的温湿度采集代码,确认串口输出正常
  3. 部署 ESP32:刷入 MimiClaw 固件,配置 WiFi 和 MQTT,确认 Web 面板能正常访问
  4. 部署服务器:安装完整版 OpenClaw,配置 MQTT Broker 和 AI 场景引擎
  5. 连接测试:观察 ESP32 Web 面板能否看到 ESP8266 上报的数据
  6. 配置告警:在服务器端配置企业微信告警推送,手机验证告警通知
  7. 扩展部署:添加更多 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 决策全屋智能系统。这正是小龙虾生态的核心魅力——让物联网不再只是极客玩具,而是每个家庭都能轻松上手的实用方案。


相关文章:

资源链接:

扫描二维码推送至手机访问。

版权声明:本文由点度点度金讯时代-BLOG发布,如需转载请注明出处。

本文链接:https://www.lmwmm.com/post/10407.html

分享给朋友:

“实战篇:手把手搭建OpenClaw三层物联网——从ESP8266采集到服务器AI调度” 的相关文章

解决Chrome浏览器翻译无法使用

解决Chrome浏览器翻译无法使用

由于谷歌翻译退出中国,目前,谷歌浏览器Chrome的翻译功能也无法使用,根据科技博客TechCrunch的消息称,谷歌发言人通过电子邮件告诉TechCrunch,该公司由于“使用率低”的原因,已停止中国大陆的谷歌翻译服务。这一变化也影响了中…

普通2.4g遥控车改4g遥控车资料-8266

普通2.4g遥控车改4g遥控车资料-8266

  背景:传统遥控器都是航模为代表的2.4G遥控器,它们在室外且无障碍物时遥控距离很长,可达几千米,但是有障碍物时,遥控距离可能仅有10多米。市面上也有一些2.4g遥控改装4G的,是读取2.4g遥控信号,并转发至服务器,…

Win11又现重大BUG:硬盘掉速,只能卸载

Win11又现重大BUG:硬盘掉速,只能卸载

最近,Windows 11 系统又出现问题了。据部分用户报告,在安装了Windows 11版本22H2-KB5023706更新后,固态硬盘性能大幅下滑。起初,只是一些威刚XPG SX8200 Pro(1TB)的用户发现了这个问题,称他们的…

问情问心,又如何问得清

问情问心,又如何问得清

本篇文章来源于微信公众号: 美在高处…

Apple Pencil或将融入iPhone:突破CQ9电子新时代

Apple Pencil或将融入iPhone:突破CQ9电子新时代

多年来,有关iPhone是否支持Apple Pencil触控笔的传闻一直在CQ9游戏圈流传,但遗憾的是,直到现在仍未实现。甚至有传言称,苹果在iPhone 14发布前临时取消了这一计划。然而,最新曝光的苹果此技术可能重新激起人们的期待。美国…

安卓手机迎来磁吸充电新时代?外媒看好华硕在ibb游戏领域的竞争优势

安卓手机迎来磁吸充电新时代?外媒看好华硕在ibb游戏领域的竞争优势

新一代Qi2无线充电标准崭露头角,苹果iPhone率先实现支持,然而Android阵营何时跟进成为焦点。媒体《9to5google》瞄准华硕,或许成为首个Qi2兼容手机的品牌。Qi2是由苹果与无线充电联盟(WPC)共同打造的通用充电标准,结…