QAUP_Management/.kiro/specs/traffic-light-integration/design.md

464 lines
14 KiB
Markdown
Raw 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.

# 设计文档
## 概述
红绿灯信号集成功能为QAUP机场管理系统提供实时路口状态监控能力。该功能通过TCP服务器监听外部红绿灯硬件发送的状态信号解析DI格式的原始数据转换为系统内部的标准化消息格式并通过WebSocket实时广播给前端客户端。
该设计遵循现有系统的架构模式集成到现有的数据采集和WebSocket通信框架中确保与其他系统组件的一致性和兼容性。
## 架构
### 整体架构图
```mermaid
graph TB
A[红绿灯硬件] -->|TCP连接<br/>端口8082| B[TrafficLightTcpServer]
B --> C[TrafficLightDataCollector]
C --> D[DataProcessingService]
D --> E[TrafficLightSignalParser]
E --> F[TrafficLightStatusEvent]
F --> G[WebSocketMessageBroadcaster]
G -->|WebSocket| H[前端客户端]
I[Spring配置] --> B
J[应用配置文件] --> I
subgraph "datacollector模块"
B
C
end
subgraph "dataprocessing模块"
D
E
F
end
subgraph "现有系统组件"
G
K[UniversalMessage]
L[TrafficLightStatusPayload]
end
F --> K
F --> L
```
### 数据流程
1. **信号接收**: TCP服务器datacollector模块监听8082端口接收红绿灯硬件发送的JSON格式信号
2. **数据采集**: TrafficLightDataCollector收集原始信号数据传递给数据处理服务
3. **数据处理**: DataProcessingServicedataprocessing模块调用信号解析器处理数据
4. **信号解析**: TrafficLightSignalParser将DI格式的原始信号转换为标准化的红绿灯状态
5. **事件发布**: 数据处理服务通过Spring事件机制发布红绿灯状态变更事件
6. **WebSocket广播**: 事件监听器将状态更新广播给所有连接的前端客户端
## 组件和接口
### 1. TrafficLightTcpServer (datacollector模块)
**职责**: TCP服务器负责监听和接收红绿灯硬件信号
**接口设计**:
```java
@Component
public class TrafficLightTcpServer {
// 启动TCP服务器
public void startServer();
// 停止TCP服务器
public void stopServer();
// 处理客户端连接
private void handleClientConnection(Socket clientSocket);
// 获取服务器状态
public ServerStatus getServerStatus();
}
```
**配置属性**:
- `traffic.light.tcp.port`: TCP监听端口默认8082
- `traffic.light.tcp.enabled`: 是否启用TCP服务器默认true
- `traffic.light.tcp.max-connections`: 最大连接数默认10
### 2. TrafficLightDataCollector (datacollector模块)
**职责**: 集成到现有数据采集框架,收集红绿灯原始数据并传递给数据处理服务
**接口设计**:
```java
@Service
public class TrafficLightDataCollector {
// 处理TCP服务器接收到的原始信号
public void collectTrafficLightSignal(String rawJsonSignal);
// 获取采集统计信息
public CollectionStatistics getStatistics();
}
```
### 3. TrafficLightSignalParser (dataprocessing模块)
**职责**: 解析DI格式的红绿灯信号转换为内部状态枚举
**接口设计**:
```java
@Component
public class TrafficLightSignalParser {
// 解析原始JSON信号
public TrafficLightStatus parseSignal(String rawJsonSignal);
// 验证信号格式
public boolean isValidSignal(String rawJsonSignal);
// 获取解析统计信息
public ParseStatistics getStatistics();
}
```
**信号状态枚举**:
```java
public enum SignalState {
RED("red"),
YELLOW("yellow"),
GREEN("green"),
UNKNOWN("unknown");
}
public class TrafficLightStatus {
private String deviceId; // 红绿灯设备编号
private String intersectionId; // 关联的路口编号
private SignalState nsStatus; // 南北方向状态
private SignalState ewStatus; // 东西方向状态
private long timestamp; // 信号时间戳
private String rawSignal; // 原始信号数据(用于调试)
}
```
### 6. IntersectionService (新增服务)
**职责**: 管理路口信息提供路口数据的CRUD操作
**接口设计**:
```java
@Service
public class IntersectionService {
// 根据路口编号获取路口信息
public Intersection getIntersectionById(String intersectionId);
// 获取所有激活的路口
public List<Intersection> getAllActiveIntersections();
// 添加新路口
public void addIntersection(Intersection intersection);
// 更新路口信息
public void updateIntersection(Intersection intersection);
}
```
### 7. TrafficLightService (新增服务)
**职责**: 管理红绿灯设备信息提供设备数据的CRUD操作
**接口设计**:
```java
@Service
public class TrafficLightService {
// 根据设备编号获取红绿灯信息
public TrafficLight getTrafficLightByDeviceId(String deviceId);
// 根据路口编号获取红绿灯设备
public List<TrafficLight> getTrafficLightsByIntersection(String intersectionId);
// 更新设备在线状态
public void updateDeviceOnlineStatus(String deviceId, boolean isOnline);
// 更新设备心跳时间
public void updateDeviceHeartbeat(String deviceId);
}
```
**实体类**:
```java
@Entity
@Table(name = "intersections")
public class Intersection {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "intersection_id", unique = true, nullable = false)
private String intersectionId;
@Column(name = "intersection_name", nullable = false)
private String intersectionName;
@Column(name = "latitude", nullable = false)
private Double latitude;
@Column(name = "longitude", nullable = false)
private Double longitude;
@Column(name = "area_code")
private String areaCode;
@Column(name = "description")
private String description;
@Column(name = "is_active")
private Boolean isActive = true;
// getters and setters...
}
@Entity
@Table(name = "traffic_lights")
public class TrafficLight {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "device_id", unique = true, nullable = false)
private String deviceId;
@Column(name = "device_name", nullable = false)
private String deviceName;
@Column(name = "intersection_id", nullable = false)
private String intersectionId;
@Column(name = "device_type")
private String deviceType = "STANDARD";
@Column(name = "manufacturer")
private String manufacturer;
@Column(name = "model")
private String model;
@Column(name = "install_date")
private LocalDate installDate;
@Column(name = "is_online")
private Boolean isOnline = false;
@Column(name = "last_heartbeat")
private LocalDateTime lastHeartbeat;
@Column(name = "is_active")
private Boolean isActive = true;
// getters and setters...
}
```
### 4. DataProcessingService扩展 (dataprocessing模块)
**职责**: 在现有数据处理服务中添加红绿灯数据处理逻辑
**接口扩展**:
```java
@Service
public class DataProcessingService {
// 现有方法...
// 新增:处理红绿灯信号数据
public void processTrafficLightSignal(String rawJsonSignal);
// 创建WebSocket消息载荷包含路口位置信息
private TrafficLightStatusPayload createTrafficLightPayload(
TrafficLightStatus status,
TrafficLight device,
Intersection intersection
);
// 发布状态变更事件
private void publishTrafficLightStatusEvent(TrafficLightStatusPayload payload);
// 验证设备是否存在和在线
private boolean isValidTrafficLightDevice(String deviceId);
// 更新设备心跳和在线状态
private void updateDeviceStatus(String deviceId);
}
```
### 5. TrafficLightStatusEventListener (websocket模块)
**职责**: 监听红绿灯状态事件通过WebSocket广播更新
**接口设计**:
```java
@Component
public class TrafficLightStatusEventListener {
// 处理红绿灯状态事件
@EventListener
public void handleTrafficLightStatusEvent(TrafficLightStatusEvent event);
// 广播WebSocket消息
private void broadcastStatusUpdate(TrafficLightStatusPayload payload);
}
```
## 数据模型
### 原始信号格式
```json
{
"device_id": "TL_001", // 红绿灯设备编号(新增)
"DI-01": 0,
"DI-02": 0,
"DI-11": 1, // 北红
"DI-12": 0, // 北黄
"DI-13": 0, // 北绿
"DI-14": 0, // 东红
"DI-15": 0, // 东黄
"DI-16": 1, // 东绿
"DI-17": 0,
"DI-18": 0
}
```
### 内部状态模型
```java
public class TrafficLightStatus {
private SignalState nsStatus; // 南北方向状态
private SignalState ewStatus; // 东西方向状态
private long timestamp; // 微秒级时间戳
private String intersectionId; // 路口标识符
}
```
### WebSocket消息格式
```json
{
"type": "intersection_traffic_light_status",
"timestamp": 1704067200000000,
"payload": {
"intersection_id": "INTERSECTION_001",
"intersection_name": "主要路口1号",
"device_id": "TL_001",
"device_name": "主路口红绿灯1号",
"position": {
"latitude": 39.9042,
"longitude": 116.4074
},
"ns_status": "red",
"ew_status": "green",
"timestamp": 1704067200000000,
"area_code": "AREA_A"
}
}
```
## 错误处理
### 1. 网络错误处理
- **连接断开**: 记录日志,等待客户端重新连接
- **端口占用**: 尝试备用端口,记录错误信息
- **网络超时**: 设置合理的超时时间,自动重试机制
### 2. 数据解析错误处理
- **JSON格式错误**: 记录原始数据,跳过当前消息
- **DI字段缺失**: 使用默认安全状态(红灯)
- **无效状态值**: 映射到UNKNOWN状态记录警告
### 3. 系统错误处理
- **内存不足**: 限制连接数,清理过期数据
- **线程池满**: 使用队列缓冲,记录性能指标
- **WebSocket断开**: 继续处理信号,不影响数据采集
## 测试策略
### 1. 单元测试
- **信号解析器测试**: 验证各种DI组合的解析结果
- **状态转换测试**: 验证信号状态到枚举的映射
- **错误处理测试**: 验证异常情况的处理逻辑
### 2. 集成测试
- **TCP服务器测试**: 模拟红绿灯硬件连接和数据发送
- **WebSocket广播测试**: 验证消息格式和广播功能
- **端到端测试**: 从信号接收到前端显示的完整流程
### 3. 性能测试
- **高频信号测试**: 验证每秒多次信号的处理能力
- **并发连接测试**: 验证多个硬件设备同时连接
- **长时间运行测试**: 验证系统稳定性和内存泄漏
## 配置管理
### 应用配置文件 (application.yml)
```yaml
traffic:
light:
tcp:
enabled: true
port: 8082
max-connections: 50 # 支持更多路口连接
connection-timeout: 30000
processing:
enable-statistics: true
statistics-interval: 60000
default-intersection:
latitude: 0.0 # 默认坐标,实际坐标从数据库获取
longitude: 0.0
```
### 数据库表设计
#### 路口信息表 (intersections)
```sql
CREATE TABLE intersections (
id BIGSERIAL PRIMARY KEY,
intersection_id VARCHAR(50) UNIQUE NOT NULL, -- 路口编号
intersection_name VARCHAR(100) NOT NULL, -- 路口名称
latitude DECIMAL(10, 8) NOT NULL, -- 纬度
longitude DECIMAL(11, 8) NOT NULL, -- 经度
area_code VARCHAR(20), -- 区域编码
description TEXT, -- 路口描述
is_active BOOLEAN DEFAULT true, -- 是否激活
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建索引
CREATE INDEX idx_intersection_id ON intersections(intersection_id);
CREATE INDEX idx_area_code ON intersections(area_code);
```
#### 红绿灯设备表 (traffic_lights)
```sql
CREATE TABLE traffic_lights (
id BIGSERIAL PRIMARY KEY,
device_id VARCHAR(50) UNIQUE NOT NULL, -- 红绿灯设备编号
device_name VARCHAR(100) NOT NULL, -- 设备名称
intersection_id VARCHAR(50) NOT NULL, -- 关联的路口编号
device_type VARCHAR(20) DEFAULT 'STANDARD', -- 设备类型
manufacturer VARCHAR(50), -- 制造商
model VARCHAR(50), -- 型号
install_date DATE, -- 安装日期
is_online BOOLEAN DEFAULT false, -- 是否在线
last_heartbeat TIMESTAMP, -- 最后心跳时间
is_active BOOLEAN DEFAULT true, -- 是否激活
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 外键约束
CONSTRAINT fk_traffic_light_intersection
FOREIGN KEY (intersection_id)
REFERENCES intersections(intersection_id)
);
-- 创建索引
CREATE INDEX idx_traffic_light_device_id ON traffic_lights(device_id);
CREATE INDEX idx_traffic_light_intersection ON traffic_lights(intersection_id);
CREATE INDEX idx_traffic_light_online ON traffic_lights(is_online);
```
### 日志配置
- **信号接收日志**: DEBUG级别记录原始信号数据
- **解析错误日志**: WARN级别记录解析失败的信号
- **系统状态日志**: INFO级别定期记录处理统计信息
- **网络错误日志**: ERROR级别记录连接和网络问题