18 KiB
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 响应格式
成功:
{
// 具体数据,见各接口定义
}
HTTP Status: 200
失败:
{
"message": "错误描述"
}
HTTP Status: 400(业务错误)/ 401(认证失败)/ 500(服务器错误)
2. A 组接口:网关 → Vol.Pro
调用方: 网关
接收方: Vol.Pro 后端
端口: 9100
2.1 A1 — 网关注册
网关启动时调用,上报身份与能力,获取所管理的顶层设备列表。
- Endpoint:
POST /api/gateway/register - 认证: NodeToken
- 逻辑: Upsert — NodeCode 匹配则更新,不匹配则插入
请求体
{
"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 | ✅ | 网关自身地址(含端口),供管理端回调 |
响应体(成功)
{
"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 | 适配器扩展数据 |
响应体(失败)
// HTTP 401
{
"message": "认证失败"
}
请求示例
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 秒
请求体
{
"nodeCode": "gw-31ku",
"token": "a1b2c3d4e5f6"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nodeCode | string | ✅ | 网关唯一编码 |
| token | string | ✅ | 认证令牌 |
响应体
{
"status": "ok",
"serverTime": "2026-05-16 15:30:00"
}
| 字段 | 类型 | 说明 |
|---|---|---|
| status | string | 固定 "ok" |
| serverTime | string | Vol.Pro 当前时间,供网关校时 |
请求示例
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
- 字段分治: 首次入库写全量,已有记录仅更新网关字段
请求体
{
"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? | 父设备第三方ID,Vol.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 仅在首次写入
响应体
{
"added": 2,
"updated": 0,
"removed": 0
}
| 字段 | 类型 | 说明 |
|---|---|---|
| added | int | 新增设备数 |
| updated | int | 更新设备数 |
| removed | int | 删除设备数(FullReplace 模式下可能 >0) |
请求示例
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
请求体
{
"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" |
响应体
{
"added": 1
}
3. B 组接口:Vol.Pro / 管理端 → 网关
调用方: Vol.Pro 后端 / 管理端 / warehouse 端
接收方: 网关
端口: 5100
认证: 内网直连(无认证)
3.1 B1 — 健康检查
- Endpoint:
GET /api/gateway/health
响应体
{
"gateway": "ok",
"adapters": {
"MC4:31ku": true,
"Owl:main": true
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| gateway | string | 固定 "ok" |
| adapters | object | key=AdapterCode, value=true(在线)/false(离线) |
请求示例
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 模糊搜索 |
响应体
{
"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 |
响应体
{
"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 |
响应体
{
"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)
路径参数 + 请求体
// POST /api/gateway/realtime/MC4:31ku/control
{
"deviceSourceId": "1001",
"pointIndex": 2,
"value": 1
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| deviceSourceId | string | ✅ | 第三方设备ID |
| pointIndex | int | ✅ | 点位索引 |
| value | double | ✅ | 设置值(开关: 0/1, 模拟量: 实际数值) |
响应体
{
"status": "sent"
}
注意: 响应仅表示指令已发送,不保证设备已执行。如需确认,应再次调 B4 查询实时值。
3.6 B6a — 实时取流
获取实时播放流地址。
- Endpoint:
GET /api/gateway/streams/{adapter}/{channelId}/live - 适配器: IHasStreams (Owl)
响应体
{
"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" |
响应体
{
"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)
请求体
{
"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 未实现。
响应体
{
"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 | 告警等级: 提示/普通/重要/紧急 |
响应体
{
"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 |
响应体
{
"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 更新
文档结束