本文档基于当前项目代码实现、现场抓包校验结果和
schema.json物模型整理。适用项目:
SWS-Communication主要对应文件:
-src/protocol.js
-src/tcpServer.js
-schema.json
当前网关通过 TCP 接收山外山透析机上报的数据帧,按帧类型拆分并解码为结构化对象,然后写入缓存、输出本地日志,并按配置转发到 MQTT / 阿里云。
当前已实现并验证的帧类型:
0x1F:运行参数帧0x26:报警帧0x29:血压测量帧每一帧的公共头长度固定为 20 字节:
| 偏移 | 长度 | 含义 |
|---|---|---|
| 0 | 4 | 帧头,固定为 55 55 55 55 |
| 4 | 1 | 机器类型 |
| 5 | 5 | 机器编号 |
| 10 | 1 | 机器运行模式 |
| 11 | 1 | 数据帧类型 |
| 12 | 1 | 协议版本 |
| 13 | 7 | 保留 |
当前代码映射如下:
| 值 | 机型 |
|---|---|
0x01 |
SWS-4000 |
0x02 |
SWS-4000A |
0x31 |
SWS-6000 |
0x32 |
SWS-6000A |
当前实现已根据现场数据确认:
例如:
E1 73 CB 72 016220903393项目中对应字段:
n:机器编号字符串当前已实现的运行模式映射:
| 值 | 含义 |
|---|---|
0x00 |
待机 |
0x01 |
透析 |
0x02 |
滤过 |
0x03 |
透析滤过 |
0x04 |
序贯-透析 |
0x05 |
单纯超滤 |
0x06 |
序贯-单超 |
0x07 |
预充 |
0x08 |
清洗 |
0x09 |
清洗消毒 |
0x14 |
透析结束 |
0x15 |
清洗结束 |
0x16 |
透析滤过结束 |
0x17 |
单纯超滤结束 |
当前代码和现场抓包已对齐的长度如下:
| 帧类型 | 含义 | 整帧长度 | 数据区长度 |
|---|---|---|---|
0x1F |
运行参数帧 | 220 字节 |
200 字节 |
0x26 |
报警帧 | 150 字节 |
130 字节 |
0x29 |
血压帧 | 150 字节 |
130 字节 |
说明:
20 字节公共头 + 数据区长度 计算整帧。3 字节,防止垃圾数据导致缓冲区无限增长。当前项目中经过现场验证后的字节序规则如下:
0x1F对应:
readUInt16LEreadUInt32LEreadInt16LE0x260x290x1F当前代码 parseRunParams() 中已经实现并使用的字段如下:
| 偏移 | 长度 | 协议含义 | 当前字段 | 当前保存方式 |
|---|---|---|---|---|
| 0 | 4 | 设置治疗时间(秒) | SetTreatmentTime |
转换为分钟后保存 |
| 4 | 4 | 已治疗时间(秒) | K |
转换为分钟后保存 |
| 8 | 2 | 血泵流量(ml/min) | D |
原值 |
| 10 | 1 | 血泵运行标志 | xlyxbj |
原值 |
| 11 | 1 | 抗凝方式 | klfs |
原值 |
| 12 | 1 | 肝素泵运行标志 | z |
原值 |
| 13 | 2 | 肝素泵流量(放大 10 倍) | E |
除以 10 |
| 15 | 2 | 肝素提前结束时间(min) | gstqjssj |
原值 |
| 17 | 4 | 超滤总量(ml) | A |
转换为 L,保留 3 位小数 |
| 21 | 4 | 已超滤量(ml) | B |
转换为 L,保留 3 位小数 |
| 25 | 4 | 超滤率(ml/h) | C |
原值 |
| 29 | 1 | 超滤泵运行标志 | cllyxbj |
原值 |
| 30 | 1 | 旁路标志 | plbj |
原值 |
| 31 | 2 | 透析液流量(ml/min) | L |
原值 |
| 33 | 2 | 透析液实际温度(放大 10 倍) | F |
除以 10 |
| 35 | 2 | 透析液电导值(放大 100 倍) | G |
除以 100 |
| 37 | 4 | 补液总量(ml) | pyzl |
原值 |
| 41 | 4 | 已补入置换液量(ml) | ypyzhyl |
原值 |
| 45 | 1 | 补液补入模式 | pyprfs |
原值 |
| 46 | 2 | 内毒素滤器1使用时间(h) | ldslq |
原值 |
| 48 | 2 | 内毒素滤器2使用时间(h) | ldslq2sysj |
原值 |
| 50 | 4 | 机器总运行时间(min) | jqzyxsj |
原值 |
| 54 | 2 | 动脉压(mmHg) | o |
readInt16LE |
| 56 | 2 | 静脉压(mmHg) | H |
readInt16LE |
| 58 | 2 | 跨膜压(mmHg) | J |
readInt16LE |
| 60 | 2 | 透析液压(kPa × 10) | I |
readInt16LE 后除以 10 |
| 62 | 1 | 尿素下降率(%) | lsxjl |
原值 |
| 64 | 2 | 实时清除率值(放大 100 倍) | ssqclz |
除以 100 |
| 66 | 2 | 静脉血温(放大 10 倍) | jmyxh |
除以 10 |
| 68 | 2 | 动脉血温(放大 10 倍) | dmyxw |
除以 10 |
| 69 | 1 | 相对血容量(%) | xdxrl |
原值 |
协议原始值单位为“秒”,但当前项目保存为“分钟”:
SetTreatmentTime = Math.round(秒 / 60)K = Math.round(秒 / 60)说明:
SetTreatmentTime、K 现在是“分钟值”。schema.json 中字段名仍保留旧命名(如 已透析时间s),但当前代码语义已改为“分钟”。协议原始值单位为 ml,当前保存为 L:
A = (ml / 1000).toFixed(3)B = (ml / 1000).toFixed(3)示例:
1800 ml -> 1.800500 ml -> 0.500现场抓包已确认以下字段必须按 有符号数 解析:
o:动脉压H:静脉压J:跨膜压I:透析液压原因:
65411 这样的异常大正数0x26当前代码 parseAlarm() 解码规则:
| 偏移 | 长度 | 含义 | 当前字段 |
|---|---|---|---|
| 0 | 2 | 报警编号(小端) | alarmCode |
| 2 | 1 | 报警类型(0=解除,1=产生) | bjlx |
| 3 | 2 | 年(小端) | bjsj 组成部分 |
| 5 | 1 | 月 | bjsj 组成部分 |
| 6 | 1 | 日 | bjsj 组成部分 |
| 7 | 1 | 时 | bjsj 组成部分 |
| 8 | 1 | 分 | bjsj 组成部分 |
| 9 | 1 | 秒 | bjsj 组成部分 |
输出字段:
{
"alarmCode": 283,
"bjlx": 1,
"bjsj": "2026-03-16 10:30:45"
}
当前已通过现场帧验证:
0x29当前代码 parseBloodPressure() 解码规则:
| 偏移 | 长度 | 含义 | 当前字段 |
|---|---|---|---|
| 0 | 1 | 测量模式(0/1=手动/自动) | bpMode |
| 1 | 1 | 测量结果(0/1=失败/成功) | bpResult |
| 2 | 2 | 年(小端) | M 组成部分 |
| 4 | 1 | 月 | M 组成部分 |
| 5 | 1 | 日 | M 组成部分 |
| 6 | 1 | 时 | M 组成部分 |
| 7 | 1 | 分 | M 组成部分 |
| 8 | 1 | 秒 | M 组成部分 |
| 9 | 2 | 收缩压(小端) | N |
| 11 | 2 | 舒张压(小端) | O |
| 13 | 2 | 脉搏(小端) | P |
| 15 | 2 | 平均动脉压(小端) | BPMPJDMY |
输出字段:
{
"bpMode": 1,
"bpResult": 1,
"M": "2026-03-16 10:32:15",
"N": 143,
"O": 98,
"P": 80,
"BPMPJDMY": 113
}
当前已通过现场帧验证:
9 / 11 / 13 / 15每次成功解析后,当前统一输出的基础字段包括:
| 字段 | 含义 |
|---|---|
suedtime |
网关接收时间 |
deviceType |
机器类型 |
IPAddress |
设备来源 IP |
n |
机器编号 |
jqyxms |
机器运行模式(中文) |
jqyxmsRaw |
机器运行模式原始值 |
frameType |
帧类型 |
protocolVersion |
协议版本 |
然后按帧类型追加:
当前项目已经接入本地日志,并可追踪以下关键链路:
Device connected:设备什么时间连上Raw TCP data received:设备发来了什么原始十六进制数据Parsed frame / Dialysis frame parsed:报文解析成功Dialysis frame payload:完整解析对象MQTT publish success:MQTT 上报成功Aliyun postProps success:阿里云上报成功Device disconnected:设备何时断开、在线多久、收了多少字节和帧schema.json 与当前业务语义存在部分差异当前代码已经做了业务换算,但 schema.json 的部分名称还是旧含义:
K 的名称仍写成“已透析时间s”,但当前保存值是“分钟”SetTreatmentTime 当前也已经改为“分钟”A/B 在 schema.json 中是文本类型,当前保存为升值字符串,例如 1.800如果后续要进一步规范,建议:
A/B 改成 float/double 类型本文档的目标是说明:**当前程序实际是怎么解码和上报的**,便于联调、排障、交付。
如果后续协议理解继续修正,建议同步维护:
src/protocol.jsschema.jsondocs/current-protocol-decoding.md每次现场确认新字段时,建议按下面顺序更新:
src/protocol.js 中补偏移和解码逻辑schema.json 中补 identifier 与字段说明如果需要,我下一步还可以继续给你输出一份: