边缘计算实战:树莓派 24/7 Always-On Agent Node 完整搭建
第37章:边缘计算实战:树莓派 24/7 Always-On Agent Node 完整搭建
概述
树莓派是 OpenClaw Headless Node 的最佳载体之一。它体积小、功耗低、可以全天候运行,价格亲民,且具备丰富的 GPIO 接口用于传感器接入。本章将从硬件选型开始,一步步带你将一块树莓派配置为一个生产级的 Always-On Agent Node:始终连接到你的 Gateway,随时响应 Agent 的远程命令,并能自主采集摄像头和传感器数据。
37.1 硬件选型
推荐配置
| 型号 | RAM | 推荐程度 | 适用场景 |
|---|---|---|---|
| Raspberry Pi 5 (4GB) | 4 GB | 首选 | 高频命令执行、多传感器 |
| Raspberry Pi 5 (8GB) | 8 GB | 旗舰 | 本地轻量推理 + Node 双用途 |
| Raspberry Pi 4B (4GB) | 4 GB | 推荐 | 标准 Node 场景 |
| Raspberry Pi 4B (2GB) | 2 GB | 可用 | 低负载纯命令执行 |
| Raspberry Pi Zero 2W | 512 MB | 不推荐 | RAM 太小,Node.js 22 吃力 |
推荐选择 Raspberry Pi 4B 4GB 或 Raspberry Pi 5 4GB。 Pi 5 的性能提升约 2-3 倍,USB 3.0 带宽对接摄像头更充裕。
必要配件
- MicroSD 卡:32GB+,Class 10 / A1 评级(推荐 Samsung EVO 系列)
- 电源:官方 USB-C 电源适配器(Pi 4B: 15W / Pi 5: 27W)
- 散热:主动散热风扇或铝制散热壳(7/24运行必备)
- 网络:有线以太网优先(稳定性 > 无线)
- 可选:USB 摄像头(Logitech C920 / Pi Camera Module 3)
存储建议
对于生产用途,强烈建议使用 SSD 替代 MicroSD 卡(通过 USB 3.0 转接):
# Pi 5 也支持 NVMe HAT(M.2 SSD 直连)
# SSD 相比 MicroSD 寿命提升约 10 倍,读写速度提升约 5 倍
37.2 系统配置
操作系统选择
| 系统 | 优点 | 适用场景 |
|---|---|---|
| Ubuntu Server 24.04 LTS (ARM64) | 软件包最新、与主流文档一致 | 推荐,生产首选 |
| Raspberry Pi OS Lite (64-bit) | 官方优化、硬件兼容性最好 | 需要 GPIO/Camera 模块时 |
| Debian 12 Bookworm (ARM64) | 最稳定 | 极低维护需求场景 |
本章以 Ubuntu Server 24.04 LTS ARM64 为例。
烧录系统
# 使用 Raspberry Pi Imager(推荐)
# 或使用 dd 命令(Linux/macOS):
sudo dd if=ubuntu-24.04-preinstalled-server-arm64+raspi.img.xz \
of=/dev/sdX bs=4M status=progress conv=fsync
在 Raspberry Pi Imager 中,烧录前配置:
- 设置主机名:
openclaw-node-01 - 启用 SSH(公钥认证)
- 设置 Wi-Fi(若不使用有线)
- 设置时区:Asia/Shanghai(或你的本地时区)
初次启动配置
# SSH 连接
ssh [email protected]
# 更新系统
sudo apt update && sudo apt upgrade -y
# 设置时区
sudo timedatectl set-timezone Asia/Shanghai
# 配置 hostname
sudo hostnamectl set-hostname openclaw-node-01
# 启用并配置防火墙(允许 SSH)
sudo ufw allow OpenSSH
sudo ufw enable
# 禁用不必要的服务(降低功耗)
sudo systemctl disable bluetooth
sudo systemctl disable cups
sudo systemctl stop bluetooth cups
内存优化配置
编辑 /boot/firmware/config.txt(Ubuntu)或 /boot/config.txt(Pi OS):
# 减少 GPU 内存分配(无图形界面时)
gpu_mem=16
# 启用 USB 引导(如果使用 SSD)
# program_usb_boot_mode=1
37.3 Node.js 22 LTS 安装
OpenClaw Node 需要 Node.js 22 LTS(当前 LTS 版本)。
方法一:使用 NodeSource 官方源(推荐)
# 安装 NodeSource 脚本
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
# 安装 Node.js
sudo apt install -y nodejs
# 验证安装
node --version # v22.x.x
npm --version # 10.x.x
方法二:使用 nvm(适合开发机)
# 安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
# 重新加载 shell
source ~/.bashrc
# 安装 Node.js 22
nvm install 22
nvm use 22
nvm alias default 22
验证环境
node --version
# v22.14.0
npm --version
# 10.9.2
# 验证 ARM64 架构
node -e "console.log(process.arch)"
# arm64
37.4 安装 OpenClaw Node
# 全局安装 OpenClaw CLI(包含 node 子命令)
sudo npm install -g @openclaw/cli
# 验证安装
openclaw --version
# openclaw 4.2.1
# 初始化 Node 配置
openclaw node init
openclaw node init 会引导你完成:
- 输入 Gateway 地址(例如:
192.168.1.100或mygateway.ts.net) - 设置节点显示名称(例如:
Pi Node - Living Room) - 选择要声明的 Capability(Headless 模式默认
system.run) - 生成并保存节点 ID
配置文件默认保存在 ~/.openclaw/node.json:
{
"nodeId": "node-a1b2c3d4",
"displayName": "Pi Node - Living Room",
"gateway": {
"host": "192.168.1.100",
"port": 18789,
"tls": false
},
"capabilities": ["system.run", "system.which"],
"reconnect": {
"enabled": true,
"initialDelay": 5,
"maxDelay": 300,
"multiplier": 2
}
}
37.5 远程连接命令
基本连接命令
# 前台运行(测试用)
openclaw node run \
--host 192.168.1.100 \
--port 18789 \
--display-name "Pi Node - Living Room"
# 使用配置文件运行(推荐)
openclaw node run --config ~/.openclaw/node.json
# 连接到 Tailscale 地址的 Gateway
openclaw node run \
--host mygateway.ts.net \
--port 18789 \
--display-name "Raspberry Pi 4B" \
--tls
# 指定额外 Capability
openclaw node run \
--host 192.168.1.100 \
--port 18789 \
--display-name "Pi Camera Node" \
--capabilities system.run,system.which
连接验证
成功连接后,Gateway 侧输出:
[Gateway] Node connected: Pi Node - Living Room (node-a1b2c3d4)
[Gateway] Capabilities registered: system.run, system.which
[Gateway] Node status: pending (awaiting approval)
在 Gateway 主机上审批:
openclaw devices list
# ID DISPLAY NAME PLATFORM STATUS
# req-x1y2 Pi Node - Living Room headless pending
openclaw devices approve req-x1y2
# ✓ Device approved: Pi Node - Living Room
37.6 架构图:Gateway 在云端,树莓派在本地
┌─────────────────────────────────────────────────────┐
│ 云端 (AWS) │
│ │
│ ┌─────────────┐ ┌─────────────────────────────┐ │
│ │ OpenClaw │ │ Gateway │ │
│ │ Agent │◄──►│ (推理 + 路由 + WebSocket) │ │
│ │ (LLM调用) │ │ port: 18789 │ │
│ └─────────────┘ └──────────┬──────────────────┘ │
│ │ WebSocket (TLS) │
└────────────────────────────────┼────────────────────┘
│
Internet / Tailscale VPN
│
┌────────────────────────────────┼────────────────────┐
│ 本地网络 │
│ │ │
│ ┌─────────────────────────────▼──────────────────┐ │
│ │ 树莓派 4B / 5 │ │
│ │ │ │
│ │ openclaw node run (role: "node") │ │
│ │ │ │
│ │ Capabilities: │ │
│ │ ✓ system.run ← Shell 命令执行 │ │
│ │ ✓ system.which │ │
│ │ │ │
│ │ 可选扩展: │ │
│ │ ✓ USB 摄像头 → camera.snap │ │
│ │ ✓ 温湿度传感器 (DHT22) → sensor.read │ │
│ │ ✓ GPIO 控制 → gpio.write │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
工作流程:
用户 → Control UI → Gateway → Agent 推理 →
Tool Call(system.run) → 路由至树莓派 →
本地执行命令 → 返回结果 → Agent → 用户
37.7 systemd 开机自启服务配置
创建专用用户(安全最佳实践)
# 创建无 shell 的系统用户
sudo useradd --system --no-create-home --shell /usr/sbin/nologin openclaw-node
# 创建配置目录
sudo mkdir -p /etc/openclaw /var/log/openclaw
sudo chown openclaw-node:openclaw-node /var/log/openclaw
# 复制配置文件
sudo cp ~/.openclaw/node.json /etc/openclaw/node.json
sudo chown openclaw-node:openclaw-node /etc/openclaw/node.json
sudo chmod 640 /etc/openclaw/node.json
systemd 服务单元文件
创建 /etc/systemd/system/openclaw-node.service:
[Unit]
Description=OpenClaw Agent Node
Documentation=https://docs.openclaw.ai/nodes
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=5
[Service]
Type=simple
User=openclaw-node
Group=openclaw-node
# 可执行文件路径(使用 which openclaw 确认)
ExecStart=/usr/bin/openclaw node run --config /etc/openclaw/node.json
# 工作目录
WorkingDirectory=/var/lib/openclaw
# 环境变量(不要在此处放置密钥,使用 EnvironmentFile)
Environment=NODE_ENV=production
Environment=LOG_LEVEL=info
EnvironmentFile=-/etc/openclaw/node.env
# 重启策略
Restart=on-failure
RestartSec=10s
# 日志输出
StandardOutput=append:/var/log/openclaw/node.log
StandardError=append:/var/log/openclaw/node-error.log
# 安全加固
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/var/lib/openclaw /var/log/openclaw /etc/openclaw
AmbientCapabilities=
# 资源限制
LimitNOFILE=65536
MemoryMax=512M
[Install]
WantedBy=multi-user.target
环境变量文件
创建 /etc/openclaw/node.env(600 权限):
# Node 特定环境变量(如有需要)
OPENCLAW_NODE_LOG_LEVEL=info
OPENCLAW_NODE_RECONNECT_ENABLED=true
sudo chown root:openclaw-node /etc/openclaw/node.env
sudo chmod 640 /etc/openclaw/node.env
创建工作目录
sudo mkdir -p /var/lib/openclaw
sudo chown openclaw-node:openclaw-node /var/lib/openclaw
启用并启动服务
# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 启用开机自启
sudo systemctl enable openclaw-node
# 立即启动服务
sudo systemctl start openclaw-node
# 检查服务状态
sudo systemctl status openclaw-node
验证服务运行
# 查看实时日志
sudo journalctl -u openclaw-node -f
# 查看日志文件
sudo tail -f /var/log/openclaw/node.log
# 典型的正常启动日志:
# [2026-04-26 09:00:00] OpenClaw Node v4.2.1 starting...
# [2026-04-26 09:00:01] Connecting to Gateway: 192.168.1.100:18789
# [2026-04-26 09:00:02] WebSocket connected
# [2026-04-26 09:00:02] Capabilities declared: system.run, system.which
# [2026-04-26 09:00:03] Node status: online (node-a1b2c3d4)
37.8 摄像头接入与自动上报
硬件准备
USB 摄像头(推荐 Logitech C920):
# 检查摄像头识别
lsusb | grep -i logitech
# Bus 002 Device 003: ID 046d:082d Logitech, Inc. HD Pro Webcam C920
ls /dev/video*
# /dev/video0 /dev/video1
# 安装 ffmpeg
sudo apt install -y ffmpeg v4l-utils
# 测试拍照
ffmpeg -f v4l2 -i /dev/video0 -frames:v 1 /tmp/test.jpg
Raspberry Pi Camera Module 3(CSI 接口):
# Ubuntu 上启用 CSI 摄像头
echo "dtoverlay=imx708" | sudo tee -a /boot/firmware/config.txt
# Pi OS 上使用 libcamera
sudo apt install -y libcamera-apps
libcamera-jpeg -o /tmp/test.jpg --width 1920 --height 1080
为 Node 添加 camera.snap 能力
修改 /etc/openclaw/node.json:
{
"nodeId": "node-a1b2c3d4",
"displayName": "Pi Camera Node",
"gateway": {
"host": "192.168.1.100",
"port": 18789
},
"capabilities": ["system.run", "system.which", "camera.snap"],
"camera": {
"device": "/dev/video0",
"snapCommand": "ffmpeg -f v4l2 -i /dev/video0 -frames:v 1 {output} -y",
"outputDir": "/tmp/openclaw-camera"
}
}
定时自动拍照上报
使用 Cron 任务(通过 Control UI 创建):
# 每30分钟拍一张照片
*/30 * * * * node_invoke camera.snap --node node-a1b2c3d4 --upload-to memory
或者通过 system.run 触发自定义脚本:
# /usr/local/bin/camera-snap.sh
#!/bin/bash
OUTPUT="/tmp/openclaw-camera/snap-$(date +%Y%m%d-%H%M%S).jpg"
mkdir -p /tmp/openclaw-camera
ffmpeg -f v4l2 -i /dev/video0 -frames:v 1 "$OUTPUT" -y -loglevel quiet
echo "$OUTPUT"
37.9 传感器数据采集方案(GPIO/I2C)
DHT22 温湿度传感器
# 安装 Python GPIO 库
sudo apt install -y python3-pip
pip3 install adafruit-circuitpython-dht
# 读取脚本:/usr/local/bin/read-dht22.py
#!/usr/bin/env python3
import adafruit_dht
import board
import json
import sys
dht = adafruit_dht.DHT22(board.D4) # GPIO4
try:
temperature = dht.temperature
humidity = dht.humidity
result = {
"temperature_c": round(temperature, 1),
"temperature_f": round(temperature * 9/5 + 32, 1),
"humidity_percent": round(humidity, 1),
"timestamp": __import__('time').time()
}
print(json.dumps(result))
except Exception as e:
print(json.dumps({"error": str(e)}), file=sys.stderr)
sys.exit(1)
Agent 通过 system.run 调用:
python3 /usr/local/bin/read-dht22.py
# {"temperature_c": 24.5, "temperature_f": 76.1, "humidity_percent": 58.3, "timestamp": 1745625600}
BMP280 气压传感器(I2C)
# 启用 I2C
sudo raspi-config nonint do_i2c 0
# 或编辑 /boot/firmware/config.txt 添加: dtparam=i2c_arm=on
# 检查 I2C 设备
i2cdetect -y 1
# 77: BMP280 默认地址
pip3 install adafruit-circuitpython-bmp280
#!/usr/bin/env python3
import adafruit_bmp280
import board
import busio
import json
i2c = busio.I2C(board.SCL, board.SDA)
bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c)
bmp280.sea_level_pressure = 1013.25
print(json.dumps({
"pressure_hpa": round(bmp280.pressure, 2),
"altitude_m": round(bmp280.altitude, 1),
"temperature_c": round(bmp280.temperature, 1)
}))
37.10 低功耗优化
CPU 降频配置
# 查看当前频率
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
# 设置保守调频策略(适合持续轻负载)
echo "conservative" | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
# 永久设置(编辑 /boot/firmware/config.txt)
# arm_freq=1500 # Pi 4B 默认 1800,降至 1500 节省约 15% 功耗
# over_voltage=0
禁用不必要的硬件
# 禁用 Wi-Fi(有线网络时)
sudo rfkill block wifi
# 禁用蓝牙
sudo rfkill block bluetooth
# 关闭 HDMI 输出(无显示器时节省约 25mA)
# 添加到 /etc/rc.local:
# /usr/bin/tvservice -o
# 禁用 USB 电源(若无 USB 设备,Pi 4B)
# echo '1-1' | sudo tee /sys/bus/usb/drivers/usb/unbind
典型功耗参考(Pi 4B)
| 配置 | 典型功耗 |
|---|---|
| 满负载(1.8GHz + USB 设备) | ~6.4W |
| 空闲(Wi-Fi 禁用,无 USB) | ~2.7W |
| 优化后(降频 + HDMI 关闭) | ~2.1W |
| 深度睡眠(不适合 Always-On) | ~1.4W |
37.11 常见问题排查
问题1:Node 频繁断线重连
# 检查网络稳定性
ping -c 100 192.168.1.100 | tail -5
# 若丢包率 > 1%,优先排查网络硬件
# 检查 Gateway 是否过载
openclaw gateway status
# 增大重连退避时间(避免风暴)
# 编辑 node.json:
# "reconnect": { "initialDelay": 10, "maxDelay": 600, "multiplier": 3 }
问题2:system.run 执行失败
# 检查可执行文件路径
which python3 ffmpeg bash
# openclaw-node 用户权限测试
sudo -u openclaw-node /usr/bin/python3 -c "print('ok')"
# 若需要访问 /dev/video0,添加用户到 video 组
sudo usermod -aG video openclaw-node
sudo systemctl restart openclaw-node
问题3:内存不足(OOM)
# 检查内存使用
free -h
sudo journalctl -k | grep -i "oom\|killed"
# 为 Node 进程添加内存限制保护
# 已在 systemd 文件中配置 MemoryMax=512M
# 若系统整体内存不足,增加 swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
问题4:Node 未在 Gateway 出现
# 确认防火墙允许出站 18789
sudo ufw status
# 测试 TCP 连通性
nc -zv 192.168.1.100 18789
# 检查 Node 日志
sudo journalctl -u openclaw-node --since "5 minutes ago"
# 常见原因:Gateway 地址错误、TLS 配置不匹配
问题5:摄像头权限拒绝
# 检查 /dev/video0 权限
ls -la /dev/video0
# crw-rw----+ 1 root video 81, 0 Apr 26 09:00 /dev/video0
# 确认用户已加入 video 组(需重启服务生效)
sudo usermod -aG video openclaw-node
sudo systemctl restart openclaw-node
groups openclaw-node
# openclaw-node : openclaw-node video
37.12 更新与维护
更新 OpenClaw Node
# 检查当前版本
openclaw --version
# 更新到最新稳定版
sudo npm update -g @openclaw/cli
# 更新后重启服务
sudo systemctl restart openclaw-node
日志轮转配置
创建 /etc/logrotate.d/openclaw-node:
/var/log/openclaw/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
postrotate
systemctl kill --signal=USR1 openclaw-node.service 2>/dev/null || true
endscript
}
37.13 小结
通过本章的配置,你的树莓派现在是一个:
- 全天候在线的 Agent Node,断线自动重连
- 安全运行在专用系统用户下,权限最小化
- 可观测的服务,日志完整、轮转有序
- 可扩展的平台,随时添加摄像头、传感器和 GPIO 控制能力
结合第36章介绍的能力矩阵,你已经完全掌握了将物理设备接入 OpenClaw Agent 的完整技术路径。下一章将聚焦 Control UI 的深度使用。
下一章:第38章 — Control UI 深度:配置编辑、实时日志、审批管理与 Dream Diary