# 山外山血透机远程通讯协议(V1.11)整理摘要 > 说明:本文件是根据你提供的协议截图做的技术要点整理,方便在网关程序中实现解析逻辑,非原文逐字抄录。 ## 1. 通信总览 - **传输方式**:TCP - **服务器端口**:默认 `10000` - **终端角色**:血液透析机作为 TCP 客户端,主动连接透析中心服务器并发送数据 - **信息粒度**:协议以“数据帧”为单位,不同业务含义对应不同“数据帧类型” ## 2. 帧总体结构 每一帧的基本结构如下(按顺序排列): | 字段 | 长度 | 说明 | |----------------|---------|----------------------------| | 帧头 | 4 字节 | 固定标识,文中示例为 `0x55555555`(十六进制) | | 机器类型 | 1 字节 | 标识具体机型 | | 机器编号 | 5 字节 | 机器的出厂编号 | | 机器运行模式 | 1 字节 | 当前运行模式(待机 / 透析 / 滤过等) | | 数据帧类型 | 1 字节 | 区分运行参数、报警信息、血压测量等帧 | | 协议版本 | 1 字节 | 版本号编码(见后文) | | 保留 | 7 字节 | 预留字段 | | 数据信息 | N 字节 | 实际业务数据区 | ### 2.1 机器类型 机器类型字段为 1 字节,主要取值示意: - `0x01`:SWS-4000 - `0x02`:SWS-4000A - `0x31`:SWS-6000 - `0x32`:SWS-6000A ### 2.2 机器编号 - 机器编号为 **5 字节**,表示机器出厂编号,例如文档示例:`6210100001`。 - 协议未在截图中明确说明编码方式,一般实现中可按 **ASCII** 或 **BCD** 存储,需要结合现场抓包确认。 ### 2.3 机器运行模式 机器运行模式为 1 字节,常见取值(节选): | 值 | 模式示意 | |-------|---------------------| | 0x00 | 待机 | | 0x01 | 透析 | | 0x02 | 滤过 / 净化 | | 0x03 | 透析滤过 | | 0x04 | 序贯-透析 | | 0x05 | 单纯超滤 | | 0x06 | 序贯-单超 | | 0x07 | 预充 | | 0x08 | 清洗 | | 0x09 | 清洗消毒 | | 0x0C | 自检 | | 0x14 | 透析结束 | | 0x15 | 清洗结束 | | 0x16 | 透析滤过结束 | | 0x17 | 单纯超滤结束 | | 0x18 | 序贯治疗结束 | | ... | 其它模式参见原表 | > 上表为对截图模式表的概括,具体值-文案映射可按业务需要在网关侧定义常量或枚举,不影响解析。 ### 2.4 数据帧类型 数据帧类型字段为 1 字节,主要取值: - `0x1F`:**运行参数帧**(定期上报透析运行过程中的各种参数) - `0x26`:**报警信息帧**(产生报警 / 解除报警即时上报) - `0x29`:**血压测量数据帧**(每次测量血压后即时上报) ### 2.5 协议版本编码 - 协议版本字段为 1 字节。 - 编码规则:取协议版本号中的**数字部分**乘以 100,再转为 16 进制传输。 - 例如当前版本 `V1.10` → 数值 `1.10 × 100 = 110` → 十六进制 `0x6E`。 ## 3. 运行参数帧(0x1F) ### 3.1 报文特性 - **数据帧类型**:`0x1F` - **数据区长度**:约 220 字节 - **发送时机**: - 客户端(透析机)与服务器建立 TCP 连接成功后; - 当透析机处于“治疗界面”时,每隔约 **4 秒**向服务器发送一次运行参数帧。 ### 3.2 运行参数数据区结构(节选) 数据区由多个字段按固定偏移排布。截图中的表按“偏移值(从 0 开始)+ 字节数 + 含义”的形式列出。下面摘录部分关键字段,辅助和 `schema.json` 中的物模型做对应: > 注意:偏移和长度根据截图识别,实际以正式文档为准,解析实现时建议结合真实抓包核对。 | 偏移 | 长度 (Byte) | 含义示意 | 对应物模型(示例) | |------|-------------|------------------------------------|--------------------| | 0 | 4 | 设置治疗时间 (s) | `SetTreatmentTime` | | 4 | 4 | 已治疗时间 (s) | `K` / 自定义 | | 8 | 2~4 | 血泵流量 (ml/min) | `D` | | 10 | 1 | 血泵运行标志 0/1 停止/运行 | `xlyxbj` | | 11 | 1 | 抗凝方式 0/1 无抗凝/肝素抗凝 | `klfs` | | 12 | 1 | 肝素泵运行标志 0/1 停止/运行 | `z` | | 13 | 2~4 | 肝素泵流量 (ml/h,放大 10 倍) | `E` | | 17 | 2~4 | 肝素提前结束时间 (min) | `gstqjssj` | | 21 | 4 | 超滤总量 (ml) | `A` | | 25 | 4 | 已超滤量 (ml) | `B` | | 29 | 1 | 超滤泵运行标志 0/1 停止/运行 | `cllyxbj` | | 30 | 1 | 旁路标志 0/1 旁路关/旁路开 | `plbj` | | 31 | 2~4 | 透析液流量 (ml/min) | `L` | | 33 | 2~4 | 透析液实际温度 (℃,放大 10 倍) | `F` | | 35 | 2~4 | 透析液电导值 (mS/cm,放大 100 倍) | `G` | | 37 | 2~4 | 血液总量/超滤率等 | `C`/自定义 | | 41 | 4 | 已补入置换液量 (ml) | `ypyzhyl` | | 45 | 1~2 | 补液补入模式 0/1 前稀释/后稀释 | `pyprfs` | | 46 | 2 | 内毒素滤器 1 使用时间 (h) | `ldslq` | | 48 | 2 | 内毒素滤器 2 使用时间 (h) | `ldslq2sysj` | | 50 | 4 | 机器总运行时间 (min) | `jqzyxsj` | | 54 | 2 | 动脉压 (mmHg) | `o` | | 56 | 2 | 静脉压 (mmHg) | `H` | | 58 | 2 | 跨膜压 (mmHg) | `J` | | 60 | 2 | 透析液压 (kPa,放大 10 倍) | `I` | | 62 | 1~2 | 尿素下降率 (%) | `lsxjl` | | 64 | 1~2 | 实时清除率值 (放大 100 倍) | `ssqclz` | | 66 | 1~2 | 静脉血温 (℃,放大 10 倍) | `jmyxh` | | 68 | 1~2 | 动脉血温 (℃,放大 10 倍) | `dmyxw` | | 69 | 1~2 | 相对血容量 (%) | `xdxrl` | | 其余 | 若干 | 预留/扩展字段 | 见原文 | 通过上述偏移-字段对照,可以在程序中将运行参数帧直接拆解成结构化对象,然后再映射到 `schema.json` 中定义的属性标识符。 ## 4. 报警信息帧(0x26) ### 4.1 报文特性 - **数据帧类型**:`0x26` - **数据区长度**:约 150 字节 - **发送时机**: - 透析机每当产生报警时,立即发送一个报警信息帧; - 报警解除后,同样发送一个报警信息帧,用于表示“报警消除”。 ### 4.2 报警信息数据区结构(概要) 截图中给出的字段包括(偏移从 0 开始): - 报警编号(2 字节) - 报警类型(1 字节):0/1 → 消除报警 / 产生报警 - 产生报警时间:按 年-月-日-时-分-秒 分别占若干字节存储(类似 `YYYY-MM-DD HH:MM:SS` 拆分编码) - 预留字段若干 网关侧实现时可将这些字段合并为: ```json { "alarmCode": , "alarmType": 0 | 1, // 0=解除, 1=产生 "alarmTime": "YYYY-MM-DD HH:MM:SS" } ``` 并按需要记录报警历史或转发至上位系统。 ## 5. 血压测量数据帧(0x29) ### 5.1 报文特性 - **数据帧类型**:`0x29` - **数据区长度**:约 150 字节 - **发送时机**: - 客户端与服务器建立 TCP 连接成功后; - 血液透析机每测量一次血压,立即发送一帧血压测量数据。 ### 5.2 血压测量数据区结构(概要) 根据截图表格,主要包含: - 测量模式(1 字节):0/1 → 手动测量 / 自动测量 - 测量结果(1 字节):0/1 → 测量出错 / 测量成功 - 测量时间:年、月、日、时、分、秒(各占若干字节,类似报警时间编码方式) - 血压与心率: - 收缩压 (mmHg) - 舒张压 (mmHg) - 脉搏/心率 - 平均动脉压 (mmHg) - 预留字段 在网关中可归纳为: ```json { "bpMode": 0 | 1, // 手动/自动 "bpResult": 0 | 1, // 出错/成功 "bpTime": "YYYY-MM-DD HH:MM:SS", "systolic": , // 收缩压 "diastolic": , // 舒张压 "heartRate": , // 心率 "map": // 平均动脉压 } ``` ## 6. 与现有网关代码的对应关系建议 结合你仓库中的 `schema.json` 与 README 里的物模型介绍,推荐的映射思路: 1. **帧头识别与拆包** - 在 `protocol.js` 中: - 按 4 字节帧头 = `0x55555555` 查找帧起始; - 之后根据固定总长度(例如 4+1+5+1+1+1+7+数据区长度)从流中截取完整帧; - 未完整的一部分留在 buffer 中等待下一次数据。 2. **公共头部解析** - 把机器类型、机器编号、运行模式、数据帧类型、协议版本先解析出来,挂在统一的 `meta` 上。 3. **按数据帧类型分支解析** - 当 `frameType == 0x1F` → 调用 `parseRunParams()`,按上文偏移表解析运行参数; - 当 `frameType == 0x26` → 调用 `parseAlarm()`; - 当 `frameType == 0x29` → 调用 `parseBloodPressure()`。 4. **与物模型字段对齐** - 运行参数里的:超滤总量、已超滤量、血泵流量、动/静/跨膜压、透析液温度/电导、尿素下降率、相对血容量等,对应 `schema.json` 中的 `A/B/C/D/F/G/H/I/J/...` 和诸如 `lsxjl`、`xdxrl` 等自定义标识符; - 在解析函数中直接生成以这些 **identifier** 为 key 的对象,方便后续 `PropertyMapper` 直接透传或做二次包装。 5. **时间与缩放处理** - 所有“放大 N 倍”的数值(如温度放大 10 倍、电导放大 100 倍、清除率放大 100 倍)建议在解析时还原为物理量(除以 N),再存入缓存; - 年/月/日/时/分/秒推荐组合成标准字符串 `YYYY-MM-DD HH:mm:ss`,便于上位系统直接使用。 --- 上面这份 `docs/protocol.md` 已经在仓库里生成,你可以打开对照原 PDF 看是否有需要补充或修正的地方。如果你愿意,下一步我可以基于这份整理直接把 `src/protocol.js` 的拆包和字段解析逻辑改成真实实现。需要的话告诉我你希望**优先解析哪些字段**(比如只要运行参数中的 A/B/C/D/F/G/H/I/J 和动静脉压等)。