Ezviz Open Picture

SkillDB 作者 ezviz-open v1.0.3

萤石设备批量抓图技能。支持多设备同时抓图,自动管理 Token 并可选下载图片到本地。 Use when: 需要获取多个摄像头实时画面、批量抓图存档、监控画面采集、定时抓图任务。 ⚠️ 安全要求:必须设置 EZVIZ_APP_KEY 和 EZVIZ_APP_SECRET 环境变量,使用最小权限凭证。

源码 ↗

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install skilldb:ezviz-open~ezviz-open-picture
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/skilldb%3Aezviz-open~ezviz-open-picture/file -o ezviz-open-picture.md
Git 仓库获取源码
git clone https://github.com/openclaw/skills/commit/a05803730cc9ffefe545c0f5a6a7aa5c60503815
# Ezviz Device Capture (萤石设备抓图)

批量获取萤石摄像头实时画面,支持多设备同时抓图。

---

## ⚠️ 安全警告 (安装前必读)

**在使用此技能前,请完成以下安全检查:**

| # | 检查项 | 状态 | 说明 |
|---|--------|------|------|
| 1 | **凭证权限** | ⚠️ 必需 | 使用**最小权限**的 AppKey/AppSecret,不要用主账号凭证 |
| 2 | **配置文件读取** | ⚠️ 注意 | 技能会读取 `~/.openclaw/*.json` 文件(**但环境变量优先级更高**) |
| 3 | **Token 缓存** | ⚠️ 注意 | Token 缓存在 `/tmp/ezviz_global_token_cache/` (权限 600) |
| 4 | **API 域名** | ✅ 已验证 | `openai.ys7.com` 是萤石官方 API 端点(`openai` = Open API,不是 AI) |
| 5 | **代码审查** | ✅ 推荐 | 审查 `scripts/device_capture.py` 和 `lib/token_manager.py` |

### 🔒 配置文件读取详细说明

**凭证获取优先级**(从高到低):

```
┌─────────────────────────────────────────────────────────────┐
│ 1. 环境变量 (最高优先级 - 推荐)                                │
│    ├─ EZVIZ_APP_KEY                                         │
│    ├─ EZVIZ_APP_SECRET                                      │
│    └─ EZVIZ_DEVICE_SERIAL                                   │
│    ✅ 优点:不读取配置文件,完全隔离                           │
├─────────────────────────────────────────────────────────────┤
│ 2. OpenClaw 配置文件 (仅当环境变量未设置时使用)                 │
│    ├─ ~/.openclaw/config.json                               │
│    ├─ ~/.openclaw/gateway/config.json                       │
│    └─ ~/.openclaw/channels.json                             │
│    ⚠️ 注意:只读取 channels.ezviz 字段,不读取其他服务凭证     │
├─────────────────────────────────────────────────────────────┤
│ 3. 命令行参数 (最低优先级)                                     │
│    python3 device_capture.py appKey appSecret deviceSerial  │
└─────────────────────────────────────────────────────────────┘
```

**安全建议**:
- ✅ **最佳实践**: 使用环境变量,完全避免配置文件读取
- ✅ **隔离配置**: 在专用配置文件只存放萤石凭证,不混用其他服务
- ⚠️ **风险缓解**: 设置环境变量覆盖配置文件(即使配置文件存在也会被忽略)

### 快速安全配置

```bash
# 1. 使用环境变量(优先级最高,避免配置文件意外使用)
export EZVIZ_APP_KEY="your_dedicated_app_key"
export EZVIZ_APP_SECRET="your_dedicated_app_secret"
export EZVIZ_DEVICE_SERIAL="dev1,dev2,dev3"

# 2. 高安全环境:禁用 Token 缓存
export EZVIZ_TOKEN_CACHE=0

# 3. 测试凭证(推荐先用测试账号)
# 登录 https://openai.ys7.com/ 创建专用应用,仅开通抓图相关权限
```

### 凭证优先级

技能按以下顺序获取凭证(**优先级从高到低**):
1. **环境变量** (`EZVIZ_APP_KEY`, `EZVIZ_APP_SECRET`) ← 推荐
2. **Channels 配置** (`~/.openclaw/config.json` 等)
3. **命令行参数** (直接传入)

---

## 快速开始

### 安装依赖

```bash
pip install requests
```

### 设置环境变量

```bash
export EZVIZ_APP_KEY="your_app_key"
export EZVIZ_APP_SECRET="your_app_secret"
export EZVIZ_DEVICE_SERIAL="dev1,dev2,dev3"
```

可选环境变量:
```bash
export EZVIZ_CHANNEL_NO="1"              # 通道号,默认 1
export EZVIZ_DOWNLOAD_PATH="./captures"  # 下载路径(可选)
export EZVIZ_TOKEN_CACHE="1"             # Token 缓存:1=启用 (默认), 0=禁用
```

**Token 缓存说明**:
- ✅ **默认启用**: 技能默认使用 Token 缓存,提升效率
- ⚠️ **禁用缓存**: 设置 `EZVIZ_TOKEN_CACHE=0` 每次重新获取 Token
- 📁 **缓存位置**: `/tmp/ezviz_global_token_cache/global_token_cache.json`
- 🔒 **文件权限**: 600 (仅所有者可读写)
- ⏰ **有效期**: 7 天,到期前 5 分钟自动刷新

**注意**: 
- 不需要设置 `EZVIZ_ACCESS_TOKEN`!技能会自动获取 Token
- 图片 URL 有效期 2 小时

### 运行

```bash
python3 {baseDir}/scripts/device_capture.py
```

命令行参数:
```bash
# 单个设备
python3 {baseDir}/scripts/device_capture.py appKey appSecret dev1 1

# 多个设备(逗号分隔)
python3 {baseDir}/scripts/device_capture.py appKey appSecret "dev1,dev2,dev3" 1

# 指定通道号
python3 {baseDir}/scripts/device_capture.py appKey appSecret "dev1:1,dev2:2" 1

# 带下载路径
python3 {baseDir}/scripts/device_capture.py appKey appSecret "dev1,dev2" 1 ./captures
```

## Channels 配置(推荐)

技能支持从 OpenClaw 的 channels 配置中自动读取萤石凭证,无需单独设置环境变量。

### 配置方式

在 `~/.openclaw/config.json` 或 `~/.openclaw/channels.json` 中添加:

```json
{
  "channels": {
    "ezviz": {
      "appId": "your_app_id",
      "appSecret": "your_app_secret",
      "domain": "https://openai.ys7.com",
      "enabled": true
    }
  }
}
```

### 配置搜索顺序

技能会按以下顺序查找配置文件:
1. `~/.openclaw/config.json`
2. `~/.openclaw/gateway/config.json`
3. `~/.openclaw/channels.json`

### 优先级

凭证获取优先级:
1. **环境变量** (最高优先级)
   - `EZVIZ_APP_KEY`
   - `EZVIZ_APP_SECRET`
2. **Channels 配置** (中等优先级)
   - `channels.ezviz.appId`
   - `channels.ezviz.appSecret`
3. **命令行参数** (最低优先级)

### 优势

- ✅ 集中管理凭证
- ✅ 无需每次设置环境变量
- ✅ 多个技能共享同一配置
- ✅ 更符合 OpenClaw 最佳实践

---

## 工作流程

```
1. 获取 Token (appKey + appSecret → accessToken)
 ↓
2. 设备抓图 (accessToken + deviceSerial → picUrl)
 ↓
3. 可选下载 (picUrl → 本地文件)
 ↓
4. 输出结果 (JSON + 控制台)
```

## Token 自动获取说明

**你不需要手动获取或配置 `EZVIZ_ACCESS_TOKEN`!**

技能会自动处理 Token 的获取:

```
首次运行:
 appKey + appSecret → 调用萤石 API → 获取 accessToken (有效期 7 天)
 ↓
保存到缓存文件(系统临时目录)
 ↓
后续运行:
 检查缓存 Token 是否过期
 ├─ 未过期 → 直接使用缓存 Token ✅
 └─ 已过期 → 重新获取新 Token
```

**Token 管理特性**:
- ✅ **自动获取**: 首次运行自动调用萤石 API 获取
- ✅ **有效期 7 天**: 获取的 Token 7 天内有效
- ✅ **智能缓存**: Token 有效期内不重复获取,提升效率
- ✅ **安全缓冲**: 到期前 5 分钟自动刷新,避免边界问题
- ✅ **无需配置**: 不需要手动设置 `EZVIZ_ACCESS_TOKEN` 环境变量
- ✅ **安全存储**: 缓存文件存储在系统临时目录,权限 600
- ⚠️ **可选禁用**: 设置 `EZVIZ_TOKEN_CACHE=0` 可禁用缓存(每次运行重新获取)

## 输出示例

```
======================================================================
Ezviz Device Capture Skill (萤石设备抓图)
======================================================================
[Time] 2026-03-18 20:14:51
[INFO] Target devices: 1
 - BF6985110 (Channel: 1)

======================================================================
SECURITY VALIDATION
======================================================================
[OK] Device serial format validated
[OK] Using credentials from environment variables

======================================================================
[Step 1] Getting access token...
======================================================================
[INFO] Using cached global token, expires: 2026-03-25 19:21:16
[SUCCESS] Using cached token, expires: 2026-03-25 19:21:16

======================================================================
[Step 2] Capturing images...
======================================================================

[Device] BF6985110 (Channel: 1)
[SUCCESS] Image captured: https://opencapture.ys7.com/...

======================================================================
CAPTURE SUMMARY
======================================================================
 Total devices: 1
 Success: 1
 Failed: 0
======================================================================
```

## 多设备格式

| 格式 | 示例 | 说明 |
|------|------|------|
| 单设备 | `dev1` | 默认通道 1 |
| 多设备 | `dev1,dev2,dev3` | 全部使用默认通道 |
| 指定通道 | `dev1:1,dev2:2` | 每个设备独立通道 |
| 混合 | `dev1,dev2:2,dev3` | 部分指定通道 |

## API 接口

| 接口 | URL | 文档 |
|------|-----|------|
| 获取 Token | `POST /api/lapp/token/get` | https://openai.ys7.com/help/81 |
| 设备抓图 | `POST /api/lapp/device/capture` | https://openai.ys7.com/help/687 |

## 网络端点

| 域名 | 用途 |
|------|------|
| `openai.ys7.com` | 萤石开放平台 API(Token、抓图) |

## 格式代码

**返回字段**:
- `picUrl` - 抓拍图片 URL(有效期 2 小时)
- `expire_hours` - URL 有效期(2 小时)

**错误码**:
- `200` - 操作成功
- `10002` - accessToken 过期
- `10028` - 抓图次数超限
- `20007` - 设备不在线
- `20008` - 设备响应超时

## Tips

- **多设备**: 逗号分隔 `dev1,dev2,dev3`
- **指定通道**: 冒号分隔 `dev1:1,dev2:2`
- **Token 有效期**: 7 天(每次运行自动获取)
- **图片有效期**: 2 小时
- **频率限制**: 设备间自动间隔 4 秒,避免限流
- **定时任务**: 建议 ≥5 分钟
- **下载路径**: 设置 `EZVIZ_DOWNLOAD_PATH` 自动下载图片

## 注意事项

⚠️ **频率限制**: 萤石抓图接口建议间隔 4 秒以上。技能已自动在设备间等待 4 秒,避免触发限流(错误码 10028)

⚠️ **隐私合规**: 使用摄像头监控可能涉及隐私问题,确保符合当地法律法规

⚠️ **设备要求**: 设备必须在线且支持抓图功能(`support_capture=1`)

⚠️ **Token 安全**: Token 会缓存到系统临时目录(自动管理),不写入日志,不发送到非萤石端点

## 数据流出说明

**本技能会向第三方服务发送数据**:

| 数据类型 | 发送到 | 用途 | 是否必需 |
|----------|--------|------|----------|
| appKey/appSecret | `openai.ys7.com` (萤石) | 获取访问 Token | ✅ 必需 |
| 设备序列号 | `openai.ys7.com` (萤石) | 请求抓图 | ✅ 必需 |
| 抓拍图片 URL | `openai.ys7.com` (萤石) | 返回图片地址 | ✅ 必需 |
| **EZVIZ_ACCESS_TOKEN** | **自动生成** | **每次运行自动获取** | **✅ 自动** |

**数据流出说明**:
- ✅ **萤石开放平台** (`openai.ys7.com`): Token 请求、设备抓图 - 萤石官方 API
- ❌ **无其他第三方**: 不会发送数据到其他服务
- ❌ **图片不上传**: 图片存储在萤石服务器,技能只获取 URL

**凭证权限建议**:
- 使用**最小权限**的 appKey/appSecret
- 仅开通必要的 API 权限(设备抓图)
- 定期轮换凭证
- 不要使用主账号凭证

**本地处理**:
- ✅ Token 缓存到系统临时目录(`/tmp/ezviz_global_token_cache/`),权限 600
- ✅ Token 有效期 7 天,到期前 5 分钟自动刷新
- ✅ 可禁用缓存:设置 `EZVIZ_TOKEN_CACHE=0` 环境变量
- ✅ 不记录完整 API 响应
- ✅ 图片 URL 只显示前 50 字符
- ✅ 可选下载图片到本地(默认不下载)

## 应用场景

| 场景 | 说明 |
|------|------|
| 📸 监