Gateway_VolPro_API_manual

This commit is contained in:
2026-05-16 14:47:33 +08:00
parent 1c2d33b341
commit 65f4b793d3

View File

@@ -0,0 +1,748 @@
# SecMPS 网关与 Vol.Pro 对接 API 手册
> **版本**: v1.0
> **日期**: 2026-05-16
> **基于**: SecMPS_最终整合方案_v3.0.md
> **接口数量**: 13 个A 组 4 个 + B 组 9 个)
---
## 1. 引言
### 1.1 目标与范围
本手册定义 IntegrationGateway网关与 Vol.Pro 后端之间所有 HTTP API 的接口规范。供网关开发、Vol.Pro 后端开发、前端开发和 AI Agent 编码时参考。
### 1.2 基本约定
| 约定 | 说明 |
|------|------|
| 请求方法 | A 组使用 **POST**B 组使用 **GET / POST** |
| 数据格式 | **JSON**`Content-Type: application/json` |
| 字符编码 | **UTF-8** |
| 认证方式 | A 组: `NodeToken`请求体中携带B 组: 内网直连,无认证 |
| 网关端口 | **5100**(默认) |
| Vol.Pro 端口 | **9100**(默认) |
### 1.3 响应格式
**成功**:
```json
{
// 具体数据,见各接口定义
}
```
HTTP Status: 200
**失败**:
```json
{
"message": "错误描述"
}
```
HTTP Status: 400业务错误/ 401认证失败/ 500服务器错误
---
## 2. A 组接口:网关 → Vol.Pro
> 调用方: 网关
> 接收方: Vol.Pro 后端
> 端口: 9100
---
### 2.1 A1 — 网关注册
网关启动时调用,上报身份与能力,获取所管理的顶层设备列表。
- **Endpoint**: `POST /api/gateway/register`
- **认证**: NodeToken
- **逻辑**: Upsert — NodeCode 匹配则更新,不匹配则插入
#### 请求体
```json
{
"nodeCode": "gw-31ku",
"token": "a1b2c3d4e5f6",
"adapterTypes": "MC4,Owl",
"baseUrl": "http://192.168.1.100:5100"
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|:---:|------|
| nodeCode | string | ✅ | 网关唯一编码,管理端生成 |
| token | string | ✅ | 认证令牌,管理端生成 |
| adapterTypes | string | ✅ | 支持的适配器类型,逗号分隔,例如 "MC4,Owl" |
| baseUrl | string | ✅ | 网关自身地址(含端口),供管理端回调 |
#### 响应体(成功)
```json
{
"nodeId": 1,
"devices": [
{
"deviceId": 10,
"deviceName": "动环采集器",
"adapterCode": "MC4:31ku",
"sourceId": "1001",
"deviceCategory": "动环采集器",
"deviceGroup": "IoT设备",
"isParent": "是",
"parentSourceId": null,
"isOnline": "在线",
"ipAddress": "10.0.1.100",
"port": 3000,
"extraData": {
"mc4DeviceId": 1001
}
}
]
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| nodeId | int | 网关在 Vol.Pro 中的 NodeId |
| devices | array | 当前网关负责的顶层设备列表base_device 中 GatewayNodeId=本网关 且 ParentDeviceId IS NULL 的记录) |
| devices[].deviceId | int | Vol.Pro 内部设备ID |
| devices[].adapterCode | string | 双段标识 "MC4:31ku" |
| devices[].sourceId | string | 第三方原始设备ID |
| devices[].extraData | object | 适配器扩展数据 |
#### 响应体(失败)
```json
// HTTP 401
{
"message": "认证失败"
}
```
#### 请求示例
```bash
curl -X POST http://localhost:9100/api/gateway/register \
-H "Content-Type: application/json" \
-d '{"nodeCode":"gw-31ku","token":"a1b2c3d4e5f6","adapterTypes":"MC4,Owl","baseUrl":"http://192.168.1.100:5100"}'
```
---
### 2.2 A2 — 网关心跳
网关每 15 秒调用Vol.Pro 更新 LastHeartbeat 和 IsOnline。
- **Endpoint**: `POST /api/gateway/heartbeat`
- **认证**: NodeToken
- **频率**: 每 15 秒
#### 请求体
```json
{
"nodeCode": "gw-31ku",
"token": "a1b2c3d4e5f6"
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|:---:|------|
| nodeCode | string | ✅ | 网关唯一编码 |
| token | string | ✅ | 认证令牌 |
#### 响应体
```json
{
"status": "ok",
"serverTime": "2026-05-16 15:30:00"
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| status | string | 固定 "ok" |
| serverTime | string | Vol.Pro 当前时间,供网关校时 |
#### 请求示例
```bash
curl -X POST http://localhost:9100/api/gateway/heartbeat \
-H "Content-Type: application/json" \
-d '{"nodeCode":"gw-31ku","token":"a1b2c3d4e5f6"}'
```
---
### 2.3 A3 — 设备数据同步
网关发现新设备或设备状态变更后,上送到 Vol.Pro。
- **Endpoint**: `POST /api/gateway/sync/devices`
- **认证**: NodeToken
- **字段分治**: 首次入库写全量,已有记录仅更新网关字段
#### 请求体
```json
{
"nodeCode": "gw-31ku",
"token": "a1b2c3d4e5f6",
"devices": [
{
"adapterCode": "MC4:31ku",
"sourceId": "1001",
"name": "动环采集器",
"category": "动环采集器",
"group": "IoT设备",
"isParent": true,
"parentSourceId": null,
"isOnline": true,
"ipAddress": "10.0.1.100",
"port": 3000,
"extraData": {
"mc4DeviceId": 1001
}
},
{
"adapterCode": "MC4:31ku",
"sourceId": "1001_0",
"name": "温湿度变送器",
"category": "温湿度变送器",
"group": "IoT设备",
"isParent": false,
"parentSourceId": "1001",
"isOnline": true,
"ipAddress": null,
"port": null,
"extraData": {
"mc4DeviceId": 1001,
"pointIndex": 0,
"unit": "℃"
}
}
]
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|:---:|------|
| nodeCode | string | ✅ | 网关编码 |
| token | string | ✅ | 认证令牌 |
| devices | array | ✅ | 设备列表 |
| devices[].adapterCode | string | ✅ | 双段标识 |
| devices[].sourceId | string | ✅ | 第三方原始ID |
| devices[].name | string | ✅ | 设备名称(仅首次写入) |
| devices[].category | string | ✅ | 设备种类(仅首次写入) |
| devices[].group | string | ✅ | 设备分组(仅首次写入) |
| devices[].isParent | bool | ✅ | 是否父设备 |
| devices[].parentSourceId | string? | | 父设备第三方IDVol.Pro 解析为 ParentDeviceId |
| devices[].isOnline | bool | ✅ | 在线状态 |
| devices[].ipAddress | string? | | IP 地址 |
| devices[].port | int? | | 端口 |
| devices[].extraData | object | | 适配器扩展数据 |
**字段分治规则**:
- **首次入库**DeviceId=0: 所有字段写入
- **已有记录**: 仅更新 isOnline、isParent、parentDeviceId解析后、extraData、ipAddress、port、lastSyncTime
- deviceName、category、group、pointId、location、lat/lng、mapModelId 仅在首次写入
#### 响应体
```json
{
"added": 2,
"updated": 0,
"removed": 0
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| added | int | 新增设备数 |
| updated | int | 更新设备数 |
| removed | int | 删除设备数FullReplace 模式下可能 >0 |
#### 请求示例
```bash
curl -X POST http://localhost:9100/api/gateway/sync/devices \
-H "Content-Type: application/json" \
-d '{"nodeCode":"gw-31ku","token":"a1b2c3d4e5f6","devices":[...]}'
```
---
### 2.4 A4 — 告警数据同步
网关发现新告警后上送。
- **Endpoint**: `POST /api/gateway/sync/alarms`
- **认证**: NodeToken
#### 请求体
```json
{
"nodeCode": "gw-31ku",
"token": "a1b2c3d4e5f6",
"alarms": [
{
"sourceAlarmId": "2183fda3-9e32-48ae-b433-f807cc81a237",
"deviceSourceId": "1001_0",
"adapterCode": "MC4:31ku",
"level": "重要",
"desc": "温度超限: [温湿度变送器][45℃]",
"value": 45.0,
"startTime": "2026-05-16 14:30:00"
}
]
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|:---:|------|
| nodeCode / token | string | ✅ | 认证信息 |
| alarms | array | ✅ | 告警列表 |
| alarms[].sourceAlarmId | string | ✅ | 源系统告警ID用于去重 |
| alarms[].deviceSourceId | string | ✅ | 告警所属设备的第三方ID |
| alarms[].adapterCode | string | ✅ | 双段标识 |
| alarms[].level | string | ✅ | 告警等级(字典: 提示/普通/重要/紧急) |
| alarms[].desc | string | ✅ | 告警描述 |
| alarms[].value | double | | 触发值 |
| alarms[].startTime | string | ✅ | 告警开始时间 "yyyy-MM-dd HH:mm:ss" |
#### 响应体
```json
{
"added": 1
}
```
---
## 3. B 组接口Vol.Pro / 管理端 → 网关
> 调用方: Vol.Pro 后端 / 管理端 / warehouse 端
> 接收方: 网关
> 端口: 5100
> 认证: 内网直连(无认证)
---
### 3.1 B1 — 健康检查
- **Endpoint**: `GET /api/gateway/health`
#### 响应体
```json
{
"gateway": "ok",
"adapters": {
"MC4:31ku": true,
"Owl:main": true
}
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| gateway | string | 固定 "ok" |
| adapters | object | key=AdapterCode, value=true(在线)/false(离线) |
#### 请求示例
```bash
curl http://localhost:5100/api/gateway/health
```
---
### 3.2 B2 — 设备列表
获取指定适配器下的设备列表(实时查询第三方)。
- **Endpoint**: `GET /api/gateway/devices`
- **适配器**: IHasFlatDevices
#### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|:---:|------|
| adapter | string | ✅ | AdapterCode例如 "Owl:main" |
| page | int | | 页码,默认 1 |
| size | int | | 每页大小,默认 50 |
| keyword | string | | 名称/ID 模糊搜索 |
#### 响应体
```json
{
"items": [
{
"sourceId": "gb_34020000001320000001",
"adapterCode": "Owl:main",
"name": "NVR-01",
"category": "硬盘录像机",
"group": "视频设备",
"isOnline": true,
"isParent": true,
"ipAddress": "192.168.1.100",
"port": 5060,
"channelCount": 4,
"extraData": {
"owlDeviceId": "gb_34020000001320000001",
"protocol": "GB28181",
"transport": "UDP"
}
}
],
"total": 50
}
```
---
### 3.3 B3 — 手动触发同步
管理端手动触发全量设备同步。
- **Endpoint**: `POST /api/gateway/devices/sync`
- **适配器**: 所有实现了 IHasFlatDevices 或 IHasOwnDeviceTree 的适配器
#### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|:---:|------|
| adapter | string | ✅ | AdapterCode |
#### 响应体
```json
{
"adapterCode": "Owl:main",
"added": 5,
"updated": 3,
"removed": 1,
"errors": [],
"startTime": "2026-05-16T15:30:00",
"endTime": "2026-05-16T15:30:05"
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| adapterCode | string | 适配器编码 |
| added | int | 新增数 |
| updated | int | 更新数 |
| removed | int | 删除数 |
| errors | array | 错误信息列表 |
| startTime / endTime | string | 同步起止时间 |
---
### 3.4 B4 — 实时点位值
获取设备所有点位的实时值。
- **Endpoint**: `GET /api/gateway/realtime/{adapter}/{deviceSourceId}`
- **适配器**: IHasPoints (MC4.0)
#### 路径参数
| 参数 | 说明 |
|------|------|
| adapter | AdapterCode例如 "MC4:31ku" |
| deviceSourceId | 设备在第三方系统中的 ID |
#### 响应体
```json
{
"deviceSourceId": "1001",
"points": [
{
"pointIndex": 0,
"name": "温度",
"value": 26.5,
"unit": "℃",
"updateTime": "2026-05-16 15:30:00",
"isValid": true
},
{
"pointIndex": 1,
"name": "湿度",
"value": 55.0,
"unit": "%",
"updateTime": "2026-05-16 15:30:00",
"isValid": true
}
]
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| deviceSourceId | string | 设备ID |
| points[].pointIndex | int | 点位索引 |
| points[].name | string | 点位名称 |
| points[].value | double | 当前值 |
| points[].unit | string | 单位 |
| points[].updateTime | string | 数据更新时间 |
| points[].isValid | bool | 数据是否有效false=传感器异常) |
---
### 3.5 B5 — 设备控制
反向控制设备(调空调温度、开关阀门等)。
- **Endpoint**: `POST /api/gateway/realtime/{adapter}/control`
- **适配器**: IHasPoints (MC4.0)
#### 路径参数 + 请求体
```json
// POST /api/gateway/realtime/MC4:31ku/control
{
"deviceSourceId": "1001",
"pointIndex": 2,
"value": 1
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|:---:|------|
| deviceSourceId | string | ✅ | 第三方设备ID |
| pointIndex | int | ✅ | 点位索引 |
| value | double | ✅ | 设置值(开关: 0/1, 模拟量: 实际数值) |
#### 响应体
```json
{
"status": "sent"
}
```
> 注意: 响应仅表示指令已发送,不保证设备已执行。如需确认,应再次调 B4 查询实时值。
---
### 3.6 B6a — 实时取流
获取实时播放流地址。
- **Endpoint**: `GET /api/gateway/streams/{adapter}/{channelId}/live`
- **适配器**: IHasStreams (Owl)
#### 响应体
```json
{
"wsFlv": "ws://192.168.1.108/proxy/sms/rtp/gb_xxx.live.flv",
"httpFlv": "http://192.168.1.108/proxy/sms/rtp/gb_xxx.live.flv",
"hls": "http://192.168.1.108/proxy/sms/rtp/gb_xxx/hls.fmp4.m3u8",
"webrtc": "webrtc://192.168.1.108/proxy/sms/index/api/webrtc?app=rtp&stream=gb_xxx&type=play",
"rtmp": "rtmp://192.168.1.108:1935/rtp/gb_xxx",
"rtsp": "rtsp://192.168.1.108:554/rtp/gb_xxx"
}
```
| 协议 | 建议用途 | 延迟 |
|------|----------|:---:|
| wsFlv | Web 实时预览(首选) | <1s |
| httpFlv | 兼容旧浏览器 | 1-2s |
| hls | iOS Safari / 回放 | 3-5s |
| webrtc | 超低延迟场景 | <500ms |
> 注意: GB28181 首次拉流有 1-3 秒 SIP 信令延迟。建议前端播放器在 3 秒内无画面时自动重试一次。
---
### 3.7 B6b — 回放取流
获取历史录像 HLS 播放地址。
- **Endpoint**: `GET /api/gateway/streams/{adapter}/{channelId}/playback`
- **适配器**: IHasStreams (Owl)
#### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|:---:|------|
| start | string | ✅ | 开始时间 "yyyy-MM-dd HH:mm:ss" |
| end | string | ✅ | 结束时间 "yyyy-MM-dd HH:mm:ss" |
#### 响应体
```json
{
"hls": "http://192.168.1.108/recordings/channels/gb_xxx/index.m3u8?start_ms=1714982400000&end_ms=1714982700000&token=xxx"
}
```
> 回放使用 HLS (VOD) 格式Owl 将指定时间范围内的 MP4 片段动态拼接为 m3u8 播放列表。
---
### 3.8 B7 — 云台控制
控制摄像机云台转动。
- **Endpoint**: `POST /api/gateway/streams/{adapter}/{channelId}/ptz`
- **适配器**: IHasStreams (Owl)
#### 请求体
```json
{
"direction": "left",
"speed": 0.5
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|:---:|------|
| direction | string | ✅ | **仅支持**: `up` / `down` / `left` / `right` / `zoom_in` / `zoom_out` / `stop` |
| speed | float | | 速度 0.0~1.0,默认 0.5 |
> ⚠️ Owl 当前版本仅实现了方向移动 (`continuous`) 和停止 (`stop`)**不支持**预设位操作 (`preset/set/goto/remove`) 和绝对/相对定位。ONVIF PTZ 未实现。
#### 响应体
```json
{
"status": "ok"
}
```
---
### 3.9 B8 — 告警查询
查询告警列表。
- **Endpoint**: `GET /api/gateway/alarms/{adapter}`
- **适配器**: IHasAlarms
#### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|:---:|------|
| from | string | ✅ | 开始时间 "yyyy-MM-dd HH:mm:ss" |
| to | string | ✅ | 结束时间 |
| page | int | | 页码,默认 1 |
| size | int | | 每页大小,默认 50 |
| confirmState | int | | MC4.0: 0=所有, 1=未确认, 2=已确认 |
| level | string | | 告警等级: 提示/普通/重要/紧急 |
#### 响应体
```json
{
"items": [
{
"alarmId": "2183fda3-9e32-48ae-b433-f807cc81a237",
"deviceId": "1001",
"adapterCode": "MC4:31ku",
"level": "重要",
"title": "温度超限",
"content": "[温湿度变送器][45℃]",
"occurTime": "2026-05-16 14:30:00",
"status": "未确认",
"thresholdValue": 40.0,
"actualValue": 45.0
}
],
"total": 120
}
```
---
### 3.10 B9 — 告警确认
确认告警,写回第三方系统。
- **Endpoint**: `POST /api/gateway/alarms/{adapter}/{alarmId}/confirm`
- **适配器**: IHasAlarms
#### 路径参数
| 参数 | 说明 |
|------|------|
| adapter | AdapterCode |
| alarmId | 源系统告警 ID |
#### 响应体
```json
{
"status": "confirmed"
}
```
> Vol.Pro 在收到成功响应后,同步更新本地 `iot_alarm.State='已确认'` 和 `ConfirmTime=当前时间`。
---
## 4. 错误码对照表
| HTTP Status | 含义 | 说明 |
|:----------:|------|------|
| 200 | 成功 | 正常响应 |
| 400 | 请求错误 | 参数缺失或格式错误 |
| 401 | 认证失败 | A 组接口 NodeCode 或 Token 不正确 |
| 404 | 未找到 | 适配器不存在或设备不存在 |
| 500 | 服务器错误 | 网关或 Vol.Pro 内部异常 |
| 502 | 第三方错误 | 网关调用 Owl/MC4.0 失败 |
---
## 5. 数据类型约定
| 类型 | JSON 示例 | 说明 |
|------|-----------|------|
| string | "hello" | 字符串 |
| int | 42 | 整数 |
| double | 26.5 | 浮点数 |
| bool | true / false | 布尔值 |
| object | { "key": "value" } | JSON 对象 |
| array | [ ... ] | JSON 数组 |
| datetime | "2026-05-16 15:30:00" | 日期时间字符串,格式 yyyy-MM-dd HH:mm:ss |
---
## 6. 对接检查清单
网关开发和 Vol.Pro 开发完成后,按以下清单逐项验证:
```
□ A1: 网关启动 → 注册成功 → 返回 nodeId + 设备列表
□ A2: 网关心跳 → Vol.Pro gateway_nodes.LastHeartbeat 更新
□ A3: 首次同步 → 设备入库,字段分治规则正确(管理员字段不覆盖)
□ A3: 二次同步 → 仅网关字段更新DeviceName 不变
□ A3: parentSourceId → Vol.Pro 正确解析为 ParentDeviceId
□ A4: 告警上报 → iot_alarm 表有数据
□ B1: 健康检查 → 返回所有适配器状态
□ B2: 设备列表 → 分页 + 关键字搜索正常
□ B3: 手动同步 → 返回 added/updated/removed 统计
□ B4: 实时数据 → 返回点位值和更新时间
□ B5: 设备控制 → 指令发送成功,设备实际响应
□ B6a: 实时取流 → 返回 6 种协议地址,前端可播放
□ B6b: 回放取流 → 返回 HLS 地址,前端可播放历史录像
□ B7: 云台控制 → 方向键有效stop 有效
□ B8: 告警查询 → 分页 + 筛选正常
□ B9: 告警确认 → 第三方确认成功 + Vol.Pro 本地 State 更新
```
---
> **文档结束**