量子多任务法全量执行 · 软件部分和接口页面全部先做 · IGateAdapter标准接口+5家厂商协议适配+12步联动状态机+软件架构设计
| 阶段 | 任务编号 | 任务名称 | 类型 | 依赖 | 状态 | 完成度 | 产出物 |
|---|---|---|---|---|---|---|---|
| 阶段一 技术调研+标准定义 第1-2周 |
T1.1 | 5家主流厂商协议调研 | 文档 | 无 | ✅ 已完成 | 厂商协议对比表 | |
| T1.2 | IGateAdapter标准接口定义 | 接口规范 | T1.1 | ✅ 已完成 | 30+方法接口文档 | ||
| T1.3 | 统一数据模型定义 | 数据模型 | T1.2 | ✅ 已完成 | 15+数据结构 | ||
| T1.4 | 错误码体系设计 | 规范 | T1.2 | ✅ 已完成 | 4类50+错误码 | ||
| T1.5 | 边缘网关硬件选型 | 硬件 | 无 | ⏸️ 待采购 | 硬件BOM清单 | ||
| 阶段二 适配层核心开发 第3-6周 |
T2.1 | 适配器注册中心开发 | 核心框架 | T1.2 | 🔄 进行中 | AdapterRegistry类 | |
| T2.2 | 协议转换引擎开发 | 核心框架 | T1.3 | 🔄 进行中 | ProtocolConverter | ||
| T2.3 | 捷顺适配器开发(P0) | 厂商适配 | T2.1 | 📋 待开发 | JieshunAdapter | ||
| T2.4 | 富士适配器开发(P0) | 厂商适配 | T2.1 | 📋 待开发 | FujistarAdapter | ||
| T2.5 | 指令映射表配置化 | 配置 | T2.2 | 📋 待开发 | command-mapping.json | ||
| T2.6 | 适配器单元测试框架 | 测试 | T2.1 | 📋 待开发 | AdapterTestBase | ||
| 阶段三 边缘网关+联动开发 第7-10周 |
T3.1 | 本地AI车牌识别引擎集成 | AI | T1.5 | ⏸️ 待硬件 | PlateRecognizer | |
| T3.2 | 断网自治模块开发 | 核心功能 | T2.1 | 🔄 进行中 | OfflineManager | ||
| T3.3 | 12步联动状态机开发 | 核心功能 | T2.1 | 🔄 进行中 | LinkageStateMachine | ||
| T3.4 | 失败补偿+回滚机制 | 可靠性 | T3.3 | 📋 待开发 | CompensationEngine | ||
| T3.5 | 红门适配器开发(P1) | 厂商适配 | T2.1 | 📋 待开发 | HongmenAdapter | ||
| T3.6 | 科拓适配器开发(P1) | 厂商适配 | T2.1 | 📋 待开发 | KeytopAdapter | ||
| 阶段四 安全+稳定性+测试 第11-12周 |
T4.1 | 五重防砸软件逻辑 | 安全 | T3.3 | 📋 待开发 | AntiCrushManager | |
| T4.2 | 安全红线规则引擎 | 安全 | T4.1 | 📋 待开发 | SafetyRuleEngine | ||
| T4.3 | 压力测试脚本开发 | 测试 | T3.3 | 📋 待开发 | stress-test.js | ||
| T4.4 | 百胜适配器开发(P1) | 厂商适配 | T2.1 | 📋 待开发 | BaishengAdapter | ||
| T4.5 | 通用GPIO适配器开发 | 厂商适配 | T2.1 | 📋 待开发 | GpioAdapter | ||
| 阶段五 试点现场联调 第13-14周 |
T5.1 | 试点场地选择+勘测 | 现场 | 无 | ⏸️ 待硬件 | 勘测报告 | |
| T5.2 | 硬件安装+系统部署 | 现场 | T5.1 | ⏸️ 待硬件 | 部署文档 | ||
| T5.3 | 现场联调+参数优化 | 现场 | T5.2 | ⏸️ 待硬件 | 联调报告 | ||
| 阶段六 试运行+规模化 第15-16周+ |
T6.1 | 30天试运行监控 | 运营 | T5.3 | ⏸️ 待试点 | 运营数据报表 | |
| T6.2 | 标准化部署手册编制 | 文档 | T5.3 | 📋 待编制 | 部署手册v1.0 | ||
| T6.3 | 规模化复制推广 | 运营 | T6.1 | ⏸️ 待验收 | 10小区推广计划 |
// ============================================================ // IGateAdapter 道闸适配器标准接口 v1.0 // 所有厂商适配器必须实现此接口 // ============================================================ interface IGateAdapter { // ===== 1. 基础信息(5个方法)===== getVendor(): string; // 获取厂商名称 getModel(): string; // 获取设备型号 getProtocol(): string; // 获取通信协议 getVersion(): string; // 获取固件版本 getCapabilities(): DeviceCapabilities; // 获取设备能力清单 // ===== 2. 连接管理(5个方法)===== connect(config: DeviceConfig): Promise<boolean>; disconnect(): Promise<boolean>; isConnected(): boolean; reconnect(): Promise<boolean>; getConnectionInfo(): ConnectionInfo; // ===== 3. 车牌识别(4个方法)===== recognizePlate(image: Buffer): Promise<PlateResult>; recognizePlateMultiFrame(images: Buffer[]): Promise<PlateResult>; getRecognizeConfig(): RecognizeConfig; setRecognizeConfig(config: RecognizeConfig): boolean; // ===== 4. 道闸控制(5个方法)===== openGate(reason: string, plate?: string): Promise<GateResult>; closeGate(): Promise<GateResult>; stopGate(): Promise<GateResult>; resetGate(): Promise<GateResult>; getGateStatus(): Promise<GateStatus>; // ===== 5. 通行记录(4个方法)===== getRecords(filter: RecordFilter): Promise<Record[]>; onRecord(callback: (record: Record) => void): void; syncRecords(): Promise<number>; exportRecords(filter: RecordFilter, format: string): Promise<Buffer>; // ===== 6. 白名单/计费(4个方法)===== checkWhitelist(plate: string): Promise<WhitelistResult>; calculateBilling(entry: Date, exit: Date, plate: string): Promise<BillingResult>; syncWhitelist(): Promise<number>; getBillingRules(): BillingRule[]; // ===== 7. 事件告警(3个方法)===== onEvent(callback: (event: GateEvent) => void): void; getEvents(filter: EventFilter): Promise<GateEvent[]>; acknowledgeEvent(eventId: string): boolean; // ===== 8. 设备管理(5个方法)===== getDeviceInfo(): DeviceInfo; getDeviceStatus(): Promise<DeviceStatus>; reboot(): Promise<boolean>; upgradeFirmware(url: string, md5: string): Promise<boolean>; getLogs(level: string, limit: number): Promise<string[]>; } // ============================================================ // AdapterRegistry 适配器注册中心(热插拔) // ============================================================ class AdapterRegistry { private adapters: Map<string, IGateAdapter>; register(vendor: string, adapter: IGateAdapter): void; unregister(vendor: string): void; getAdapter(vendor: string): IGateAdapter | null; listAdapters(): string[]; getByGateId(gateId: string): IGateAdapter | null; loadAdapter(path: string): Promise<boolean>; // 动态加载 }
| 厂商 | 优先级 | 通信协议 | 数据格式 | 开闸指令 | 识别方式 | 适配难度 | 适配器类名 |
|---|---|---|---|---|---|---|---|
| 捷顺科技 | P0 | TCP长连接 | JSON | {"cmd":"OPEN_GATE","gateId":"G001"} | 内置AI识别 | 低 | JieshunAdapter |
| 富士智能 | P0 | HTTP REST | XML | POST /api/openGate <gateId>G001</gateId> | 内置AI识别 | 低 | FujistarAdapter |
| 红门智能 | P1 | RS485串口 | Modbus RTU | 0x01 0x05 0x0000 0xFF00 | 外接摄像头 | 中 | HongmenAdapter |
| 科拓股份 | P1 | MQTT | JSON | topic: gate/cmd/G001 payload:{"action":"open"} | 内置AI识别 | 低 | KeytopAdapter |
| 百胜智能 | P1 | UDP广播 | 二进制 | 0xFF 0x01 0x01 0x00 0x01 0xFE | 外接摄像头 | 高 | BaishengAdapter |
class JieshunAdapter implements IGateAdapter { private socket: net.Socket; private config: DeviceConfig; private connected: boolean = false; private requestQueue: Map<string, Function>; // 基础信息 getVendor() { return 'jieshun'; } getProtocol() { return 'tcp_json'; } // 连接管理 async connect(config: DeviceConfig): Promise<boolean> { this.config = config; return new Promise((resolve, reject) => { this.socket = net.connect(config.port, config.host, () => { this.connected = true; resolve(true); }); this.socket.on('data', (data) => this.handleResponse(data)); this.socket.on('error', reject); this.socket.on('close', () => { this.connected = false; }); }); } // 道闸控制 - 核心方法 async openGate(reason: string, plate?: string): Promise<GateResult> { const cmd = { cmd: 'OPEN_GATE', gateId: this.config.gateId, reason: reason, plateNumber: plate || '', timestamp: Date.now() }; const response = await this.sendRequest(cmd, 3000); // 3秒超时 return { success: response.code === 0, message: response.message, action: 'open', timestamp: new Date() }; } // 车牌识别 async recognizePlate(image: Buffer): Promise<PlateResult> { const cmd = { cmd: 'RECOGNIZE_PLATE', gateId: this.config.gateId, imageBase64: image.toString('base64') }; const response = await this.sendRequest(cmd, 5000); return { plateNumber: response.plateNumber, plateColor: response.plateColor, confidence: response.confidence, vehicleType: response.vehicleType }; } // 私有方法:发送请求并等待响应 private async sendRequest(cmd: any, timeout: number): Promise<any> { const requestId = uuid(); cmd.requestId = requestId; return new Promise((resolve, reject) => { const timer = setTimeout(() => { this.requestQueue.delete(requestId); reject(new Error('Request timeout')); }, timeout); this.requestQueue.set(requestId, (response) => { clearTimeout(timer); resolve(response); }); this.socket.write(JSON.stringify(cmd) + '\n'); }); } }
enum EntryState { ARRIVED = 'ARRIVED', // 1.车辆到达识别区 PLATE_RECOGNIZED = 'PLATE_RECOGNIZED', // 2.车牌已识别 WHITELIST_CHECKED = 'WHITELIST_CHECKED', // 3.白名单已查询 PARKING_ASSIGNED = 'PARKING_ASSIGNED', // 4.车位已分配 GATE_OPENED = 'GATE_OPENED', // 5.道闸已开 ENTERED = 'ENTERED', // 6.已入场 NAVIGATING = 'NAVIGATING', // 7.导航中 ARRIVED_PARKING = 'ARRIVED_PARKING', // 8.已到达车位 LOCK_DOWN = 'LOCK_DOWN', // 9.地锁已降下 PARKED = 'PARKED', // 10.已停好 CHARGING = 'CHARGING', // 11.充电中 COMPLETED = 'COMPLETED' // 12.流程完成 } class LinkageStateMachine { private currentState: EntryState; private context: LinkageContext; private transitions: Map<EntryState, StateTransition>; constructor() { this.currentState = EntryState.ARRIVED; this.initTransitions(); } // 状态转换定义(严格时序,不可跳跃) private initTransitions() { this.transitions.set(EntryState.ARRIVED, { next: EntryState.PLATE_RECOGNIZED, action: async (ctx) => { const result = await ctx.adapter.recognizePlate(ctx.image); if (result.confidence < 0.8) throw new Error('Low confidence'); ctx.plate = result.plateNumber; }, timeout: 2000, retries: 2 }); // ... 其他11个状态转换定义 } // 执行下一步(带重试+超时+补偿) async next(): Promise<boolean> { const transition = this.transitions.get(this.currentState); if (!transition) return false; for (let i = 0; i < transition.retries; i++) { try { await this.executeWithTimeout(transition.action, transition.timeout); this.currentState = transition.next; return true; } catch (e) { await sleep(500 * (i + 1)); // 指数退避 } } // 重试失败,触发补偿+回滚 await this.compensate(); return false; } // 补偿机制(根据当前状态回滚) private async compensate() { switch (this.currentState) { case EntryState.LOCK_DOWN: await this.context.lockAdapter.raiseLock(); // 升起地锁 await this.context.parkingService.release(); // 释放车位 break; // ... 其他状态的补偿逻辑 } await this.triggerAlarm('LINKAGE_FAILED', this.currentState); } }
| 层级 | 技术选型 | 版本 | 用途 | 资源占用 |
|---|---|---|---|---|
| 操作系统 | Ubuntu Core 22.04 | 22.04 LTS | 精简型Linux,安全更新自动 | ~500MB |
| 容器运行时 | Docker + Docker Compose | 24.x | 应用容器化部署,一键升级 | ~100MB |
| 应用运行时 | Node.js LTS | 20.x | 主应用运行时,异步IO | ~200MB |
| AI推理引擎 | ONNX Runtime | 1.16+ | 本地车牌识别模型推理 | ~150MB |
| 本地数据库 | SQLite + Redis | SQLite3 / Redis7 | 配置存储+缓存+白名单 | ~50MB |
| 时序数据库 | InfluxDB | 2.x | 通行记录+设备状态时序存储 | ~100MB |
| 消息队列 | Mosquitto (MQTT Broker) | 2.x | 本地设备消息总线 | ~20MB |
| 监控 | Prometheus + Grafana | 最新 | 本地监控+可视化 | ~200MB |
| Web管理 | Vue3 + Element Plus | 最新 | 本地管理界面(断网可用) | ~50MB |
// ===== 车牌识别结果 ===== interface PlateResult { plateNumber: string; // 车牌号 如"闽A12345" plateColor: 'blue' | 'green' | 'yellow' | 'white'; confidence: number; // 置信度 0-1 vehicleType: 'car' | 'truck' | 'motorcycle' | 'bus'; recognizedAt: Date; imageUrl?: string; } // ===== 道闸控制结果 ===== interface GateResult { success: boolean; message: string; action: 'open' | 'close' | 'stop' | 'reset'; timestamp: Date; errorCode?: string; } // ===== 道闸状态 ===== interface GateStatus { gateId: string; status: 'open' | 'closed' | 'moving' | 'fault' | 'offline'; currentAngle: number; // 当前角度 0-90 lastAction: string; lastActionAt: Date; faultCode?: string; online: boolean; motorCurrent?: number; // 电机电流(A) motorTemp?: number; // 电机温度(℃) } // ===== 通行记录 ===== interface Record { recordId: string; gateId: string; plateNumber: string; direction: 'in' | 'out'; passType: 'recognized' | 'manual' | 'free' | 'monthly'; entryTime: Date; exitTime?: Date; imageUrl?: string; confidence: number; vehicleType: string; parkingLotId: string; synced: boolean; // 是否已同步到云端 } // ===== 白名单查询结果 ===== interface WhitelistResult { plateNumber: string; inWhitelist: boolean; whitelistType?: 'monthly' | 'vip' | 'employee' | 'free' | 'temp'; expireTime?: Date; remainingTimes?: number; // 次卡剩余次数 discountRate?: number; // 折扣率 0-1 freeHours?: number; // 免费时长(小时) } // ===== 计费结果 ===== interface BillingResult { durationMinutes: number; freeMinutes: number; billableMinutes: number; originalAmount: number; discountAmount: number; finalAmount: number; currency: string; billingRuleId: string; breakdown: BillingItem[]; } // ===== 事件告警 ===== interface GateEvent { eventId: string; gateId: string; eventType: 'fault' | 'alarm' | 'info'; eventCode: string; eventName: string; severity: 'low' | 'medium' | 'high' | 'critical'; description: string; timestamp: Date; deviceStatus?: any; acknowledged: boolean; }
| 错误码 | 类别 | 说明 | 处理建议 |
|---|---|---|---|
GATE_1001 | 连接错误 | 设备连接失败 | 检查网络/串口连接,重试3次 |
GATE_1002 | 连接错误 | 连接超时 | 检查设备是否在线,增加超时时间 |
GATE_1003 | 连接错误 | 连接被拒绝 | 检查端口/权限/防火墙 |
GATE_2001 | 识别错误 | 车牌识别失败 | 检查摄像头/光照,触发人工审核 |
GATE_2002 | 识别错误 | 识别置信度过低 | 多帧融合识别,仍低则人工确认 |
GATE_2003 | 识别错误 | 摄像头故障 | 切换备用摄像头,触发告警 |
GATE_3001 | 控制错误 | 开闸指令失败 | 重试3次,仍失败则人工开闸 |
GATE_3002 | 控制错误 | 道闸电机过载 | 立即停止,检查机械障碍 |
GATE_3003 | 控制错误 | 道闸超时未响应 | 检查控制器,触发紧急停止 |
GATE_4001 | 安全错误 | 防砸设备故障 | 锁定手动模式,禁止自动开闸 |
GATE_4002 | 安全错误 | 地感线圈故障 | 切换红外/雷达检测,触发维修 |
GATE_4003 | 安全错误 | 紧急停止被触发 | 人工确认安全后复位 |
GATE_5001 | 系统错误 | 本地数据库异常 | 自动修复,修复失败则恢复备份 |
GATE_5002 | 系统错误 | 存储空间不足 | 清理旧记录,触发云端同步 |
GATE_5003 | 系统错误 | 网络断开(已切换离线模式) | 本地自治运行,网络恢复自动同步 |