Files
SecMPS/doc/整合方案/SecMPS_最终整合方案_v2.0.md
2026-05-16 12:56:12 +08:00

397 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SecMPS 整合方案最终版IntegrationGateway + 统一设备管理
> **版本**: v2.0
> **日期**: 2026-05-16
> **状态**: 待实施
---
## 一、总体架构
```
前端层
web.vite 管理端(设备管理+网关管理) warehouse 大屏Map/Live/IoT/Alarm
| HTTP REST | HTTP REST + SignalR
v v
Vol.Pro 后端 (api_sqlsugar)
DeviceManagerController / GatewayNodeController / SignalR Hubs
Quartz: SyncDevicesJob / RealtimePollJob / AlarmPollJob
数据库: 6 张表 (base_device / video_channel / video_record / iot_devicedata / iot_alarm / gateway_nodes)
| 注册/下发设备/心跳/同步数据
v
IntegrationGateway 实例A (:5100) IntegrationGateway 实例B (:5101)
NodeCode: gw-31ku NodeCode: gw-11ku
Adapters: MC4 / Owl Adapters: MC4 / HikvisionISC
| HTTP | HTTP
v v
MC4.0 (:3000) Owl (:80) MC4.0 (:3000) 海康ISC (:80)
```
### 核心设计原则
- **网关无状态**:配置仅 NodeCode/Token/VolProUrl挂了重装即恢复
- **AdapterCode 双段标识**"mc4:31号库房" 区分同类型多实例
- **DeviceGroup 路由**:基类表用字典字段决定适配器和行为,不依赖扩展表
- **ExtraData JSON**:所有适配器特有字段存入 ExtraData新增适配器不增表
- **心跳机制**:网关 15s 心跳Vol.Pro 超 30s 级联设备离线
---
## 二、网关架构(方案 C+
### 2.1 网关注册与心跳流程
```
管理端: gateway_nodes 表新增 → 生成 NodeCode + Token
网关配置: { NodeCode, Token, VolProUrl }
网关启动 → POST /register { nodeCode,token,adapterTypes,baseUrl }
Vol.Pro 校验 → 更新 AdapterTypes/BaseUrl/IsOnline=在线
响应: { gatewayNodeId, devices: [base_device WHERE GatewayNodeId=当前] }
网关按 AdapterCode 分流 → Adapter 连接第三方 → 发现子设备
网关 → POST /sync → Vol.Pro 写入 base_device含 ExtraData)
网关每 15s → POST /heartbeat { nodeCode, token }
Vol.Pro Job: IsOnline=在线 且 LastHeartbeat < now-30s → IsOnline=离线 → 级联设备离线
```
### 2.2 网关配置
```json
{
"VolProBaseUrl": "http://localhost:9100",
"NodeCode": "gw-31ku",
"NodeToken": "xxxxxxxxxx"
}
```
### 2.3 适配器能力矩阵
| 接口 | Owl | MC4.0 | 门禁(未来) |
|------|:---:|:-----:|:----------:|
| IHasOwnDeviceTree | ❌ | ✅ | ❌ |
| IHasFlatDevices | ✅ | ❌ | ✅ |
| IHasPoints | ❌ | ✅ | ❌ |
| IHasStreams | ✅ | ❌ | ❌ |
| IHasAlarms | ⚠️ | ✅ | ✅ |
| IAcceptsMetadataPush | ✅ | ❌ | ⚠️ |
### 2.4 双向同步引擎
| 方向 | 说明 | MC4.0 | Owl |
|------|------|-------|-----|
| PullToVolPro | 第三方→Vol.Pro | FullReplace | Merge |
| PushToSource | Vol.Pro→第三方 | 告警确认/控制 | 元数据/PTZ |
| Bidirectional | 先写第三方再更新本地 | 告警确认 | — |
### 2.5 对接 API 规范
网关与 Vol.Pro 之间有两组接口,调用方向不同。
#### A. 网关 → Vol.Pro网关主动调用
| # | 接口 | 说明 |
|---|------|------|
| A1 | `POST /api/gateway/register` | 网关启动注册,上报身份与能力,获取所管设备列表 |
| A2 | `POST /api/gateway/heartbeat` | 心跳(每 15sVol.Pro 更新在线状态 |
| A3 | `POST /api/gateway/sync/devices` | 上送设备数据(新增/变更/离线) |
| A4 | `POST /api/gateway/sync/alarms` | 上送告警数据 |
**A1 注册** — 认证: NodeToken
```
Request: { nodeCode, token, adapterTypes, baseUrl }
Response: { nodeId, devices: [ base_device 列表(当前网关负责的顶层设备) ] }
Error: 401 认证失败
```
**A2 心跳** — 认证: NodeToken
```
Request: { nodeCode, token }
Response: { status: "ok" }
```
**A3 设备同步** — 认证: NodeToken
```
Request: { nodeCode, token, devices: [{ adapterCode, sourceId, name, category, group,
isParent, parentSourceId, isOnline, ipAddress, port, extraData }] }
Response: { added, updated, removed }
```
> 网关只发自己负责的字段ExtraData 中的适配器属性 + 公共状态字段不碰管理员字段DeviceName/Category/Location/MapModelId…。Vol.Pro 首次入库写全量,后续仅更新网关负责的列。
**A4 告警同步** — 认证: NodeToken
```
Request: { nodeCode, token, alarms: [{ sourceAlarmId, deviceSourceId, adapterCode,
level, desc, value, startTime }] }
Response: { added }
```
---
#### B. Vol.Pro / 管理端 → 网关(查询与控制)
| # | 接口 | 说明 |
|---|------|------|
| B1 | `GET /api/gateway/health` | 网关及所有适配器状态 |
| B2 | `GET /api/gateway/devices?adapter=&page=&size=` | 设备列表(实时查第三方) |
| B3 | `POST /api/gateway/devices/sync?adapter=` | 手动触发全量同步 |
| B4 | `GET /api/gateway/realtime/{adapter}/{deviceId}` | 实时点位值 |
| B5 | `POST /api/gateway/realtime/{adapter}/control` | 反向控制 { deviceSourceId, pointIndex, value } |
| B6 | `GET /api/gateway/streams/{adapter}/{channelId}/live` | 取流地址 → { wsFlv, httpFlv, hls, webrtc } |
| B7 | `POST /api/gateway/streams/{adapter}/{channelId}/ptz` | 云台控制 { direction, speed } |
| B8 | `GET /api/gateway/alarms/{adapter}?from=&to=&page=&size=` | 告警查询 |
| B9 | `POST /api/gateway/alarms/{adapter}/{alarmId}/confirm` | 告警确认(写回第三方) |
> B 组接口由管理端或 Vol.Pro 后端直接调用网关,认证方式为内网直连或网关侧 IP 白名单。
---
## 三、数据模型6 张表)
### 3.1 区域表 warehouse_regions现有
层级: warehouse_regions(区域) → warehouse_devicepoint(点位) → base_device(设备)
| 字段 | 说明 |
|------|------|
| Id | int PK |
| RegionName | nvarchar(255) |
| ParentId | int? (自引用树) |
### 3.2 网关节点表 gateway_nodes
| 字段 | 类型 | 说明 |
|------|------|------|
| NodeId | INT AUTO_INCREMENT | 网关节点ID |
| NodeCode | NVARCHAR(50) | 网关唯一编码(管理端配置) |
| NodeName | NVARCHAR(100) | 网关名称 |
| NodeToken | NVARCHAR(100) | 认证令牌(管理端生成) |
| AdapterTypes | NVARCHAR(200) | 适配器类型(网关上报) |
| BaseUrl | NVARCHAR(200) | 网关地址(网关上报) |
| LastHeartbeat | DATETIME | 上次心跳时间 |
| IsOnline | NVARCHAR(20) | 在线状态(字典: 在线/离线) |
| Enable | NVARCHAR(20) | 启用状态(字典: 启用/禁用) |
### 3.3 统一设备主表 base_device
| 字段 | 类型 | 说明 |
|------|------|------|
| DeviceId | INT AUTO_INCREMENT | Vol.Pro内部ID |
| DeviceName | NVARCHAR(100) | 设备名称 |
| AdapterCode | NVARCHAR(50) | "mc4:31号库房"(类型:实例) |
| SourceId | NVARCHAR(100) | 源系统设备ID |
| **DeviceCategory** | NVARCHAR(50) | 设备种类(字典: 摄像机/温湿度变送器/...) |
| **DeviceGroup** | NVARCHAR(20) | 设备分组(字典: 视频设备/IoT设备/门禁设备/道闸设备/报警设备) |
| PointId | INT? | 所属点位ID |
| GatewayNodeId | INT? | 所属网关节点ID |
| IsParent | NVARCHAR(20) | 是否父设备(字典: 是/否) |
| ParentDeviceId | INT? | 父设备自引用 |
| IsOnline | NVARCHAR(20) | 在线状态(字典: 在线/离线) |
| MapModelId | NVARCHAR(100) | VgoMap模型ID |
| MapModelScale | FLOAT | |
| MapModelRotation | NVARCHAR(100) | |
| **ExtraData** | TEXT | ★ 适配器扩展JSON(Owl/MC4/门禁字段均存于此) |
| LastSyncTime | DATETIME | |
| Enable | NVARCHAR(20) | 启用状态(字典: 启用/禁用) |
唯一约束: (AdapterCode, SourceId)
### 3.4 DeviceGroup 分组规则
Vol.Pro 同步接口通过 DeviceGroup 路由,无需硬编码:
| DeviceGroup | 网关适配器 | 前端按钮组 | 同步模式 |
|:---:|------|------|:---:|
| 视频设备 | OwlAdapter → IHasStreams | 实时预览/云台/回放/快照 | Merge |
| IoT设备 | Mc4Adapter → IHasPoints | 实时数据/控制/告警 | FullReplace |
| 门禁设备 | AccessAdapter | 远程开门/记录/告警 | Merge |
| 道闸设备 | BarrierAdapter | 抬杆/落杆/记录 | Merge |
| 报警设备 | AlarmAdapter | 查看告警/布防撤防 | Merge |
### 3.5 ExtraData 格式示例
```json
// 摄像机 (Owl)
{ "owlDeviceId": "gb_xxx", "protocol": "GB28181", "manufacturer": "海康" }
// 温湿度变送器 (MC4子设备)
{ "mc4DeviceId": 1001, "pointIndex": 0, "unit": "℃", "isControlPoint": false }
// 空调控制器 (MC4子设备)
{ "mc4DeviceId": 1002, "pointIndex": 2, "unit": null, "isControlPoint": true }
// 未来门禁
{ "hikDeviceId": "door_01", "doorType": "单门", "readerType": "IC卡" }
```
### 3.6 层级示例
```
gateway_nodes: gw-31ku
warehouse_regions → warehouse_devicepoint → base_device
区域 点位 设备
例: 厂区 → 新库区 → 31号库房(点位) → 设备
base_device (PointId=点位ID, GatewayNodeId=gw-31ku.NodeId):
东北角高位摄像机 (DeviceCategory=摄像机, DeviceGroup=视频设备, ExtraData={owlDeviceId,...})
人员计数摄像机 (DeviceCategory=摄像机, DeviceGroup=视频设备)
动环采集器 (DeviceCategory=动环采集器, DeviceGroup=IoT设备, IsParent=是)
├── 温湿度变送器 (DeviceCategory=温湿度变送器, ParentDeviceId=采集器, ExtraData={pointIndex:0,unit:"℃"})
├── 空调控制器 (DeviceCategory=空调控制器, ParentDeviceId=采集器, ExtraData={pointIndex:2,isControlPoint:true})
├── 除湿/恒湿机 (DeviceCategory=除湿/恒湿机, ParentDeviceId=采集器)
└── 紧急报警按钮 (DeviceCategory=紧急报警按钮, DeviceGroup=报警设备, ParentDeviceId=采集器)
```
---
## 四、Vol.Pro 同步接口(新增适配器零改动)
```csharp
// POST /api/gateway/sync
public async Task SyncDevices(string nodeCode, List<StandardDevice> devices)
{
var node = await _db.gateway_nodes.FirstAsync(n => n.NodeCode == nodeCode);
foreach (var d in devices)
{
var entity = await _db.base_device
.FirstOrDefaultAsync(x => x.AdapterCode == d.AdapterCode && x.SourceId == d.SourceId)
?? new base_device();
entity.DeviceName = d.Name;
entity.DeviceGroup = d.Group; // 字典: 视频设备/IoT设备/...
entity.DeviceCategory = d.Category; // 字典: 摄像机/温湿度变送器/...
entity.IsOnline = d.IsOnline ? "在线" : "离线";
entity.IsParent = d.IsParent ? "是" : "否";
entity.ParentDeviceId = d.ParentSourceId; // 网关同步过来的父级关系
entity.GatewayNodeId = node.NodeId;
entity.ExtraData = d.ExtraDataJson; // ★ 一行,适配器字段全在这里
// ... 公共字段赋值 ...
_db.base_device.Upsert(entity);
}
await _db.SaveChangesAsync();
}
```
---
## 五、管理端统一设备页面
### 5.1 操作按钮矩阵(按 DeviceGroup 路由)
| DeviceGroup | 操作按钮 |
|:---:|------|
| 视频设备 | 实时预览 / 云台控制 / 查看回放 / 获取快照 / 同步通道 |
| IoT设备 | 查看实时数据 / 设备控制 / 刷新点位 / 查看告警 |
| 门禁设备 | 远程开门 / 查看记录 / 查看告警 |
| 道闸设备 | 抬杆 / 落杆 / 查看记录 |
| 报警设备 | 查看告警 / 布防撤防 |
### 5.2 前端按钮路由
```javascript
// DeviceTable.vue
const actionMap = {
'视频设备': VideoDeviceActions,
'IoT设备': IoTDeviceActions,
'门禁设备': AccessDeviceActions,
'道闸设备': BarrierDeviceActions,
'报警设备': AlarmDeviceActions,
}
// 渲染: actionMap[device.DeviceGroup]
```
---
## 六、同步策略
### MC4.0 → 区域树+设备
- type=1 节点 → 名称匹配 warehouse_regions → 绑区或新建
- type=2 节点 → Upsert base_device, DeviceGroup=IoT设备, ExtraData 存点位属性
- 模式: FullReplace, 频率限制: 2次/秒
### Owl → 设备
- GET /devices → Upsert base_device (DeviceGroup=视频设备, IsParent=是)
- GET /channels → Upsert base_device (ParentDeviceId=NVR) + video_channel
- Owl 无区域概念 → PointId=NULL, 管理员手动分配
- 模式: Merge
### 反方向写回
| 操作 | Owl | MC4.0 |
|------|:---:|:-----:|
| 设备改名 | ✅ PUT /devices/:id | ❌ |
| 告警确认 | ⚠️ | ✅ |
| 设备控制 | ✅ PTZ | ✅ 点位写值 |
---
## 七、部署拓扑
```
Docker: Owl+ZLM (:80) MC4.0-1 (:3000) MC4.0-2 (:3000)
| | |
+----------+-----------+-------------------+
|
+----------+-----------+
| Gateway gw-31ku | Gateway gw-11ku
| :5100 | :5101
+----------+-----------+
|
+----------+-----------+
| VolPro.WebApi |
| :9100 |
| MySQL / Redis |
+----------+-----------+
|
+--------------+---------------+
| web.vite :9000 warehouse :9200 |
+--------------------------------+
```
---
## 八、实施路线
| 阶段 | 工期 | 内容 |
|------|------|------|
| Phase 0 | Day 1-2 | Gateway骨架 + 6张表建表 + 代码生成 |
| Phase 1 | Day 3-6 | OwlAdapter + 管理端视频设备页 |
| Phase 2 | Day 7-11 | Mc4Adapter + IoT管理 + 区域树匹配 + SignalR |
| Phase 3 | Day 12-17 | warehouse端改造 + 全链路联调 |
| Phase 4 | Day 18-20 | 验证 + 缓冲 |
总计: 18-20 个工作日
---
## 九、新增整合流程
以接入「海康门禁」为例:
1. 新建 IntegrationGateway.Adapters.HikvisionAccess 项目
2. 实现 IHasFlatDevices + IHasAlarms → 设备同步时填充 DeviceGroup=门禁设备
3. 管理端字典加一条"门禁设备"分组 → 按钮自动出现
4. Vol.Pro 同步接口零改动ExtraData 承载门禁字段)
5. 前端新增 AccessDeviceActions.vue (~80行)
总工作量: 1-2 天
---
## 十、代码组织规范
| 代码类型 | 路径 | 被覆盖? |
|----------|------|:---:|
| 第三方对接 | gateway/ | ❌ |
| 扩展Controller | Controllers/*/Partial/ | ❌ |
| Entity扩展 | DomainModels/*/partial/ | ❌ |
| 前端业务逻辑 | extension/warehouse/*.jsx | ❌ |
| 自定义页面 | views/warehouse/DeviceManager/ | ❌ |
| 自动生成代码 | 生成器默认路径 | ✅ |
---
> 取代: V1.0 系列所有整合方案文档