← Back to Plugins
Tools

My Peripheral

ytyuy By ytyuy ⭐ 1 stars 👁 22 views ▲ 0 votes

openclaw my-peripheral-plugin

GitHub

Install

npm install
```

Configuration Example

{
  "plugins": {
    "entries": {
      "my-peripheral-plugin": {
        "enabled": true,
        "config": {
          "gatewayEndpoint": "http://127.0.0.1:8080",
          "defaultDeviceId": "ws63-demo-01"
        }
      }
    }
  }
}

README

# my-peripheral-plugin

**通用 IoT 外设网关插件** — 零代码接入任意设备

Go | TypeScript | JSON 描述符驱动

[快速开始](#快速开始) | [使用方式](#使用方式) | [添加新设备](#添加新设备) | [API 参考](#gateway-api) | [示例](#示例)

---

## 插件概览

| 基础工具 | 动态工具 | 协议 | 设备描述符 |
|:---:|:---:|:---:|:---:|
| **9** | **自动生成** | **3** | **JSON** |
| 始终可用 | 按设备命令注册 | UPM / REST / MIXED | 新设备零代码接入 |

## 这是什么

my-peripheral-plugin 是一个运行在 OpenClaw 平台上的通用外设网关插件。通过中间层 Go Gateway 与实际硬件通信,支持任意 IoT 设备接入。

核心特性:

- **零代码接入** — 新设备只需写一个 JSON 描述符,无需改任何代码
- **动态命令发现** — Gateway 注册了什么命令,Plugin 自动生成对应工具
- **多协议支持** — UPM 二进制协议、REST HTTP、混合模式
- **风险分级** — 高危命令自动标记,执行前需用户确认

架构:

```
Agent 对话
  └─ Plugin(TypeScript,进程内)
       └─ Go Gateway(REST API,独立进程)
            └─ 设备(HI3863 / ESP32 / STM32 / ...)
```

## 项目结构

```
my_peripheral_plugin/
├── openclaw.plugin.json          # 插件清单(平台识别入口,文件名不可改)
├── package.json                  # npm 依赖
├── index.ts                      # 插件主入口
├── SKILL.md                      # Agent 技能描述
├── src/
│   ├── gateway-client.ts         # Gateway HTTP 客户端
│   ├── base-tools.ts             # 9 个基础工具
│   ├── tool-discovery.ts         # 动态命令发现与工具注册
│   └── types/
│       └── openclaw-plugin-sdk.d.ts  # 平台 SDK 类型声明(最小化)
├── gateway/                      # Go Gateway 后端
│   ├── cmd/                      #   程序入口
│   ├── internal/                 #   业务逻辑(命令路由、设备管理、REST API)
│   ├── configs/devices/          #   设备描述符(新设备加在这里)
│   │   ├── index.json            #     描述符索引
│   │   └── profiles/             #     设备配置文件
│   │       ├── hi3863.json       #       HI3863 WiFi/BLE/SLE 模组
│   │       └── generic-upm.json  #       通用 UPM 示例
│   ├── Dockerfile                #   容器构建
│   └── deployments/              #   docker-compose
└── examples/                     # 新设备接入示例
    ├── esp32-sensor.json         #   REST 协议 - 温湿度传感器
    └── stm32-motor-upm.json      #   UPM 协议 - 电机控制器
```

---

## 快速开始

### 前置条件

| 依赖 | 版本 | 用途 |
|------|------|------|
| Go | 1.23+ | 编译 Gateway |
| OpenClaw | 最新版 | 宿主平台 |

**1. 启动 Go Gateway:**

```bash
cd gateway
go build -o gateway ./cmd/my_peripheral_plugin
./gateway
# 输出: my_peripheral_plugin starting at 127.0.0.1:8080
```

**2. 将插件放入扩展目录:**

```bash
# 项目级(推荐,仅当前项目生效)
cp -r my-peripheral-plugin  <项目>/.openclaw/extensions/my-peripheral-plugin

# 或用户级(全局生效)
cp -r my-peripheral-plugin  ~/.openclaw/extensions/my-peripheral-plugin

# 安装依赖(仅首次)
cd <目标路径>/my-peripheral-plugin
npm install
```

安装包极小:仅 2 个依赖(@sinclair/typebox + typescript),约 26MB。
平台 SDK 由 OpenClaw 运行时通过 jiti 别名注入,不需要本地安装。

**3. 在配置文件中启用:**

配置文件路径为 `~/.openclaw/openclaw.json`(Windows 为 `%USERPROFILE%\.openclaw\openclaw.json`),
在 `plugins.entries` 中添加:

```json
{
  "plugins": {
    "entries": {
      "my-peripheral-plugin": {
        "enabled": true,
        "config": {
          "gatewayEndpoint": "http://127.0.0.1:8080",
          "defaultDeviceId": "ws63-demo-01"
        }
      }
    }
  }
}
```

### Docker 环境部署

> 以下内容适用于 OpenClaw 以 Docker Compose 方式运行的场景。
> 如果 OpenClaw 运行在宿主机上,请使用上方标准流程。

#### 前置条件

| 依赖 | 版本 | 用途 |
|------|------|------|
| Docker | 20+ | 容器化运行 |
| OpenClaw | 最新版 | Docker 镜像已构建 |

#### 1. 在 OpenClaw 的 `docker-compose.yml` 中添加 `peripheral-gateway` 服务

```yaml
services:
  peripheral-gateway:
    build:
      context: ./extensions/my-peripheral-plugin/gateway
      dockerfile: Dockerfile
    environment:
      MY_PERIPHERAL_PLUGIN_BIND_ADDR: "0.0.0.0:8080"
      MY_PERIPHERAL_PLUGIN_DESCRIPTOR_INDEX: "configs/devices/index.json"
      MY_PERIPHERAL_PLUGIN_CACHE_TTL: "30s"
      MY_PERIPHERAL_PLUGIN_AUDIT_STORE: "memory"
      MY_PERIPHERAL_PLUGIN_IDEMPOTENCY_TTL: "24h"
    ports:
      - "127.0.0.1:8080:8080"
    restart: unless-stopped

  openclaw-gateway:
    # ... 已有配置 ...
    depends_on:
      - peripheral-gateway
    volumes:
      # 挂载插件目录到容器内
      - ./extensions/my-peripheral-plugin:/app/extensions/my-peripheral-plugin
```

#### 2. 在 OpenClaw 配置文件中启用插件(Docker 内网地址)

```json
{
  "plugins": {
    "entries": {
      "my-peripheral-plugin": {
        "enabled": true,
        "config": {
          "gatewayEndpoint": "http://peripheral-gateway:8080",
          "defaultDeviceId": "ws63-demo-01"
        }
      }
    }
  }
}
```

注意 `gatewayEndpoint` 使用 Docker 内网地址 `http://peripheral-gateway:8080`,
同一 compose 网络中服务名即主机名,无需暴露端口到宿主机。

#### 3. 构建并启动

```bash
cd <openclaw项目根目录>

# 首次构建 Gateway 镜像
docker compose build peripheral-gateway

# 启动全部服务
docker compose up -d
```

#### 4. 验证

```bash
# 检查容器状态
docker compose ps
# peripheral-gateway-1   running   0.0.0.0:8080->8080/tcp
# openclaw-gateway-1     running   0.0.0.0:18789->18789/tcp

# 检查 Gateway 健康
curl http://127.0.0.1:8080/healthz
# {"status":"ok","service":"my_peripheral_plugin"}

# 查看 OpenClaw 日志确认插件加载
docker compose logs openclaw-gateway | grep peripheral
```

成功加载时日志输出:

```
my-peripheral-plugin 已加载,endpoint=http://peripheral-gateway:8080
动态命令发现完成,注册 13 个工具
设备轮询启动,间隔 30000ms
```

#### 重启与更新

```bash
# 重启全部服务(配置变更后)
docker compose up -d --force-recreate

# 仅重建 Gateway(Go 代码或描述符变更后)
docker compose build peripheral-gateway && docker compose up -d

# 查看实时日志
docker compose logs -f openclaw-gateway peripheral-gateway
```

### 插件加载机制

```
OpenClaw 启动
  → 扫描 extensions/ 目录
    → 发现 my-peripheral-plugin/openclaw.plugin.json
    → 读取插件 ID 和 configSchema
  → jiti 加载 index.ts(运行时编译,无需预构建)
  → 调用 register(api)
    → 注册 9 个基础工具(立即可用)
    → 启动命令发现服务(连接 Gateway,异步注册 cmd_* 动态工具)
    → 启动设备轮询服务
    → 注册 /peripheral/health HTTP 路由
```

**插件发现位置(按优先级):**

| 优先级 | 路径 | 来源 |
|:---:|------|------|
| 1 | 配置文件中 `plugins.load.paths` 指定的路径 | 配置级 |
| 2 | `<工作目录>/.openclaw/extensions/` | 项目级 |
| 3 | `~/.openclaw/extensions/` | 用户级 |
| 4 | OpenClaw 仓库内 `extensions/`(Docker 内 `/app/extensions/`) | 内置级 |

内置插件默认禁用,需要在配置中显式 `"enabled": true`。
项目级和用户级插件默认启用,无需额外配置。

**插件配置项:**

| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `gatewayEndpoint` | `http://127.0.0.1:8080` | Gateway REST API 地址(Docker 中用服务名) |
| `gatewayToken` | 空 | API 认证令牌(可选) |
| `defaultDeviceId` | 空 | 默认设备,省略时每次调用需指定 |
| `pollIntervalMs` | `30000` | 设备轮询间隔(ms),0 为禁用 |

插件加载后,Agent 对话中自动获得所有注册的工具,无需手动触发。
用户在对话中描述需求(如"扫描 WiFi"),Agent 自动选择对应工具执行。

---

## 使用方式

### 基础工具(9 个,始终可用)

| 工具 | 用途 |
|------|------|
| `list_devices` | 查询所有设备,支持按在线状态和能力过滤 |
| `query_device_status` | 查询设备综合状态(WiFi/BLE/SLE/外设) |
| `query_device_resources` | 查询 CPU、内存、网络等资源 |
| `probe_device` | 检测设备是否在线 |
| `list_commands` | 查看所有可用命令及参数定义 |
| `execute_device_command` | 通用命令执行入口(兜底) |
| `query_audit_logs` | 查询操作审计日志 |
| `query_alerts` | 查询系统告警 |
| `gateway_status` | 查看 Gateway 运行时状态 |

### 动态工具(自动生成,cmd_ 前缀)

根据 Gateway 中注册的设备命令自动生成,不同设备产生不同工具集。
例如内置设备生成:

```
cmd_wifi_scan          cmd_query_device_status
...
```

使用 `list_commands` 查看当前完整列表。

### 对话示例

用户在 OpenClaw Chat 中输入自然语言指令,Agent 自动调用对应工具执行:

**WiFi 扫描 — 调用 `cmd_wifi_scan` 获取周围热点列表:**

![WiFi 扫描命令执行](0.png)

**扫描结果整理 — Agent 将原始数据解析为可读表格(SSID、RSSI、信道、加密方式):**

![WiFi 扫描结果表格](1.png)

更多对话场景:

```
用户:查看设备当前状态
Agent:[调用 query_device_status] WiFi 已连接,信号 -45dBm,内存 78%...
```

---

## 添加新设备

新设备接入只需 2 个文件操作,不需要写任何代码。

### Step 1 - 编写设备描述符

在 `gateway/configs/devices/profiles/` 下新建 JSON 文件:

```json
{
  "version": "1.0",
  "name": "my-new-device",
  "devices": [
    {
      "id": "new-device-01",
      "autoload": true,
      "endpoint": "http://192.168.1.100",
      "vendor": "vendor-name",
      "model": "MODEL-X",
      "profile": "device-v1",
      "protocol": "rest",
      "capabilities": ["wifi", "sensor"]
    }
  ],
  "commands": [
    {
      "name": "read_sensor",
      "category": "query",
      "protocol": "REST",
      "rest_path": "/api/sensor/read",
      "priority": "low",
      "risk_level": "safe",
      "permission": "read",
      "idempotent": true,
      "supported_profiles": ["device-v1"]
    }
  ]
}
```

### Step 2 - 注册到索引

编辑 `gateway/configs/devices/index.json`:

```diff
  "includes": [
    "profiles/hi3863.json",
    "profiles/generic-upm.json",
+   "profiles/my-new-device.json"
  ]
```

重启 Gateway,新工具 `cmd_read_sensor` 立即可用。

### 命令字段参考

| 字段 | 必填 | 取值 | 说明 |
|------|:---:|------|------|
| `name` | 是 | 字符串 | 命令名,生成 `cmd_<name>` 工具 |
| `category` | 是 | `query` `control` `config` `admin` | 命令分类 |
| `protocol` | 是 | `UPM` `REST` `MIXED` | 通信协议 |
| `upm_opcode` | UPM 时 | `"0x04"` | UPM 操作码 |
| `rest_path` | REST 时 | `"/api/..."` | HTTP 接口路径 |
| `priority` | 是 | `low` `normal` `high` | 执行优先级 |
| `risk_level` | 是 | `safe` `sensitive` `dangerous` `critical` | 风险等级 |
| `permission` | 是 | `read` `control` `config` `admin` | 权限要求 |
| `idempotent` | 是 | `true` / `false` | 是否幂等 |
| `require_confirm` | | `true` | 高危命令需用户确认 |
| `param_schema` | | 对象 | 参数定义(见下表) |
| `supported_profiles` | 是 | 字符串数组 | 适用的设备规格 |

### param_schema 参数类型

| type | 对应 | 示例 |
|------|------|------|
| `string` | 字符串 | SSID、设备 ID |
| `number` | 浮点数 | 温度阈值 |
| `integer` | 整数 | 寄存器地址、RPM |
| `boolean` | 布尔 | 开关标志 |
| `object` | 键值对 | 扩展参数 |

---

## Gateway API

| 端点 | 方法 | 说明 |
|------|:---:|------|
| `/healthz` | GET | 健康检查 |
| `/api/v1/devices` | GET | 设备列表(支持 `?online=true&capability=wifi`) |
| `/api/v1/devices/:id/status` | GET | 设备状态(支持 `?refresh=true`) |
| `/api/v1/devices/:id/resources` | GET | 设备资源 |
| `/api/v1/devices/:id/probe` | GET | 设备在线探测 |
| `/api/v1/commands` | GET | 命令发现(列出所有已注册命令及参数定义) |
| `/api/v1/commands/:name` | POST | 执行命令 |
| `/api/v1/audit/logs` | GET | 审计日志(支持 `?device_id=&command=&limit=`) |
| `/api/v1/alerts/logs` | GET | 告警日志(支持 `?severity=&state=&limit=`) |
| `/api/v1/runtime/descriptor` | GET | 描述符运行时状态 |

---

## 示例

`examples/` 目录包含可直接使用的设备描述符模板:

| 文件 | 协议 | 设备类型 | 命令数 |
|------|:---:|----------|:---:|
| `esp32-sensor.json` | REST | ESP32 温湿度传感器 | 4 |
| `stm32-motor-upm.json` | UPM | STM32 电机控制器 | 7 |

使用方式:

```bash
# 复制示例到描述符目录
cp examples/esp32-sensor.json gateway/configs/devices/profiles/

# 在 index.json 的 includes 中加入
# "profiles/esp32-sensor.json"

# 重启 Gateway 即可
```

---

## 常见问题

**Q: Plugin 加载后没有动态工具?**
检查 Gateway 是否正常运行:`curl http://127.0.0.1:8080/healthz`

**Q: 命令执行超时?**
Gateway 默认超时 8 秒。检查设备 endpoint 是否可达:`curl <设备地址>`

**Q: 如何

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...