# JH2028 新协议服务通讯功能流程图 本文档描述 `jh2028-new-service` 的服务通讯主流程,覆盖 TCP 接收、设备识别、协议解码、本地缓存、大屏展示、MQTT 上报和阿里云上报。 ## 0. 通讯角色说明 现场通讯里需要先区分两个角色: - **本程序是 TCP 服务端**:本程序监听固定 IP 和端口,等待设备数据盒子主动连接。 - **设备数据盒子是 TCP 客户端**:盒子连接本程序后,持续发送设备透传数据。 因此,从 TCP 连接方向看: ```text 设备数据盒子 TCP 客户端 ---> 本程序 TCP 服务端 ``` 从数据流方向看: ```text 设备/透传盒 ---> 本程序 ---> MQTT / 阿里云 / 监测大屏 ``` 本程序启动后监听 `config.tcp.host` 和 `config.tcp.port`。设备列表中维护每台设备盒子的 `ip`、`deviceId`、`name`,程序根据 TCP 来源 IP 匹配设备编号。 ## 1. 总体通讯流程 ```mermaid flowchart TD A[JH2028 设备] --> B[串口透传盒子] B -->|主动连接 TCP 服务端
持续发送数据| C[本程序 TCP 服务端
tcp-service.js] C --> D{来源 IP 是否在
config.devices 中} D -->|否| D1[记录未知设备日志
丢弃本包数据] D -->|是| E[绑定设备编号 deviceId] E --> F[接收二进制数据流] F --> G[按 55 AA 帧头和 LEN 拆包] G --> H{是否完整帧} H -->|否| H1[继续缓存等待后续数据] H -->|是| I[CRC8 校验] I --> J{CRC 是否正确} J -->|否| J1[记录校验失败日志
丢弃该帧] J -->|是| K[协议解码
decoder.js] K --> L{帧类型} L -->|实时数据
CMDTYPE=01 CMDID=00| M[解析治疗/温度/压力/血液指标] L -->|血压数据
CMDTYPE=01 CMDID=01| N[解析 N/O/P
写入 M=接收时间] L -->|血压错误码| N1[只记录日志
不更新缓存/不上报] L -->|未知命令| L1[记录不支持命令日志] M --> O[更新设备本地缓存
state-cache.js] N --> O O --> P[生成完整上报数据
包含最后一次实时数据和血压数据] P --> Q[刷新大屏快照
dashboard-service.js] Q --> Q1[浏览器大屏
SSE 实时更新/轮询兜底] P --> R{上报通道配置
send.channels} R -->|mqtt| S[MQTT 上报
mqtt-service.js] R -->|aliyun| T[阿里云上报
aliyun-service.js] R -->|mqtt + aliyun| S R -->|mqtt + aliyun| T S --> U{上报结果} T --> U U -->|成功| U1[记录成功日志] U -->|失败| U2[记录失败日志
不补发] ``` ## 2. 服务启动流程 ```mermaid flowchart TD A[启动 app.js] --> B[读取 config.json] B --> C[校验 tcp/devices/protocol/send 配置] C --> D[初始化日志 logger] D --> E[加载物模型 alModel.json] E --> F[初始化 StateCache] F --> G{send.channels} G -->|包含 mqtt| H[初始化 MQTT 服务] G -->|包含 aliyun| I[初始化阿里云服务] G --> J[初始化 DashboardService] H --> K[启动 TCP 服务] I --> K J --> K K --> L[监听 TCP 端口
默认 9000] J --> M[监听大屏端口
默认 9100] L --> N[等待设备盒子接入] M --> O[等待浏览器访问] ``` ## 3. 单包数据处理时序 ```mermaid sequenceDiagram participant Device as JH2028设备/透传盒子 participant TCP as TCP服务 participant Decoder as 协议解码器 participant Cache as 本地状态缓存 participant UI as 监测大屏 participant MQTT as MQTT服务 participant Aliyun as 阿里云服务 Device->>TCP: 主动建立 TCP 连接 Device->>TCP: 持续发送 55 AA 新协议数据帧 TCP->>TCP: 根据来源 IP 匹配 deviceId TCP->>TCP: 数据流拆包,得到完整帧 TCP->>Decoder: CRC8 校验并解码 Decoder-->>TCP: 返回 realtime 或 bloodPressure 数据 TCP->>Cache: 合并到设备最后一次完整缓存 Cache-->>TCP: 返回完整 payload TCP->>UI: 推送最新设备状态和指标 TCP->>MQTT: 按原 Topic 规则立即上报完整 payload TCP->>Aliyun: 获取/复用三元组并立即上报完整 payload MQTT-->>TCP: 返回上报结果 Aliyun-->>TCP: 返回上报结果 TCP->>TCP: 成功/失败均记录日志,失败不补发 ``` ## 4. 设备连接状态流程 ```mermaid stateDiagram-v2 [*] --> 未连接 未连接 --> 已连接: 设备盒子主动连接 已连接 --> 等待数据: 已匹配设备 IP 等待数据 --> 数据正常: 收到并成功解码一帧 数据正常 --> 数据正常: 持续收到有效数据 数据正常 --> 数据超时: 超过 staleDataMs 未更新 数据超时 --> 数据正常: 再次收到有效数据 已连接 --> 离线: socket close/error/timeout 等待数据 --> 离线: socket close/error/timeout 数据正常 --> 离线: socket close/error/timeout 数据超时 --> 离线: socket close/error/timeout 离线 --> 已连接: 设备盒子重新连接 ``` ## 5. 阿里云上报子流程 ```mermaid flowchart TD A[收到完整 payload] --> B{是否启用 aliyun 通道} B -->|否| B1[跳过阿里云上报] B -->|是| C{设备是否已有可用连接} C -->|有| H[调用 postProps 上报属性] C -->|没有| D[按 deviceId 请求三元组接口] D --> E{三元组是否完整} E -->|否| E1[记录失败日志
本次不补发] E -->|是| F[创建阿里云 IoT Device 实例] F --> G[等待/复用连接] G --> H H --> I{postProps 是否成功} I -->|成功| I1[记录上报成功] I -->|失败| I2[记录失败原因
不补发] ``` ## 6. 大屏数据来源 ```mermaid flowchart LR A[config.devices
设备清单] --> D[大屏快照] B[TCP 连接会话
在线/离线/连接时间] --> D C[StateCache
最后一次完整 payload] --> D D --> E[/api/snapshot] D --> F[/events SSE] E --> G[浏览器大屏] F --> G ``` ## 7. 当前关键规则 - 本程序是 TCP 服务端,设备数据盒子作为 TCP 客户端主动连接本程序。 - 设备身份按 `config.devices` 中配置的来源 IP 匹配,不从报文中解析设备编号。 - 服务端不回复设备,设备会持续主动发送数据。 - 收到实时数据或血压数据后,立即合并缓存并上传完整 payload。 - 血压数据接收时写入 `M`,值为服务端接收时间。 - 平均压、心率不齐、血压错误码不上传;血压错误码只记录日志。 - MQTT Topic 沿用老项目规则。 - 阿里云三元组获取规则沿用老项目,`deviceName = deviceId`。 - 上报失败只记录日志,不做补发。 - 大屏只读取内存状态,不影响 TCP 接收和上报链路。