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

14 KiB
Raw Blame History

设计文档

概述

红绿灯信号集成功能为QAUP机场管理系统提供实时路口状态监控能力。该功能通过TCP服务器监听外部红绿灯硬件发送的状态信号解析DI格式的原始数据转换为系统内部的标准化消息格式并通过WebSocket实时广播给前端客户端。

该设计遵循现有系统的架构模式集成到现有的数据采集和WebSocket通信框架中确保与其他系统组件的一致性和兼容性。

架构

整体架构图

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服务器负责监听和接收红绿灯硬件信号

接口设计:

@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模块)

职责: 集成到现有数据采集框架,收集红绿灯原始数据并传递给数据处理服务

接口设计:

@Service
public class TrafficLightDataCollector {
    // 处理TCP服务器接收到的原始信号
    public void collectTrafficLightSignal(String rawJsonSignal);
    
    // 获取采集统计信息
    public CollectionStatistics getStatistics();
}

3. TrafficLightSignalParser (dataprocessing模块)

职责: 解析DI格式的红绿灯信号转换为内部状态枚举

接口设计:

@Component
public class TrafficLightSignalParser {
    // 解析原始JSON信号
    public TrafficLightStatus parseSignal(String rawJsonSignal);
    
    // 验证信号格式
    public boolean isValidSignal(String rawJsonSignal);
    
    // 获取解析统计信息
    public ParseStatistics getStatistics();
}

信号状态枚举:

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操作

接口设计:

@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操作

接口设计:

@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);
}

实体类:

@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模块)

职责: 在现有数据处理服务中添加红绿灯数据处理逻辑

接口扩展:

@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广播更新

接口设计:

@Component
public class TrafficLightStatusEventListener {
    // 处理红绿灯状态事件
    @EventListener
    public void handleTrafficLightStatusEvent(TrafficLightStatusEvent event);
    
    // 广播WebSocket消息
    private void broadcastStatusUpdate(TrafficLightStatusPayload payload);
}

数据模型

原始信号格式

{
  "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
}

内部状态模型

public class TrafficLightStatus {
    private SignalState nsStatus;    // 南北方向状态
    private SignalState ewStatus;    // 东西方向状态
    private long timestamp;          // 微秒级时间戳
    private String intersectionId;   // 路口标识符
}

WebSocket消息格式

{
  "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)

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)

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)

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级别记录连接和网络问题