# Gambro Artis 协议规范(ORU^R31) - 文件来源:`artis_protocol_oru_r31.md` - 适用场景:实时监视治疗参数 - 最后更新:2023-10-27 ## 目录 - [1. 连接与通信基础](#1-连接与通信基础) - [2. 消息流程](#2-消息流程) - [3. 消息结构(XML)](#3-消息结构xml) - [3.1 MSH(消息头)](#31-msh消息头) - [3.2 OBX(观察结果,核心数据)](#32-obx观察结果核心数据) - [4. 常用临床参数列表](#4-常用临床参数列表) - [5. 完整消息示例](#5-完整消息示例) - [6. 开发实现要点](#6-开发实现要点) - [附录 A:文档中出现的示例代码片段](#附录-a文档中出现的示例代码片段) ## 1. 连接与通信基础 | 配置项 | 值/说明 | | --- | --- | | 端口 | 3021(TCP Server) | | 编码 | UTF-16(Unicode) | | 触发机制 | 治疗开始后,机器每 60 秒自动推送 | | ACK 策略 | 不需要客户端回复(MSH-15/16 = NE) | **⚠️ 重要警告**:客户端接收数据后**不要发送任何 ACK 消息**,否则可能导致机器断开连接或报错。 ## 2. 消息流程 1. 连接建立:客户端连接 Artis 机器的 3021 端口。 2. 数据推送:机器在治疗状态下,每隔 60 秒主动发送一条 ORU^R31 消息。 3. 数据处理:客户端接收并解析数据。 4. 静默接收:保持连接,不回复确认帧。 ## 3. 消息结构(XML) 根节点为 ``,消息通常包含 `MSH`、(可选)`PID/ORC/OBR`、以及若干个 `ORU_R31.OBSERVATION` 数据块。 ### 3.1 MSH(消息头) | 字段 | 关键值/说明 | | --- | --- | | MSH-9 | `ORU^R31` | | MSH-8 | CRC 校验码(4 位十六进制)。计算时需先置空,算出后填入。 | | MSH-15/16 | `NE`(Never Expect ACK)- 明确指示不需要确认。 | | MSH-18 | `UNICODE` | ### 3.2 OBX(观察结果,核心数据) 每条消息包含多个 `` 块,每个块包含一个 `` 段,代表一个临床参数。 **关键字段路径:** - 参数 ID:`OBX-3.CE.1`(例如:`7`) - 参数名:`OBX-3.CE.2`(例如:`Temperature`) - 数值:`OBX-5.FN.1`(例如:`37.500000`) - 单位:`OBX-6.CE.1`(例如:`cel`) - 状态:`OBX-11`(通常为 `F` - Final) ## 4. 常用临床参数列表 解析时请根据 `OBX-3` 中的 ID 区分数据: | ID | 参数名(EN) | 中文含义 | 单位示例 | 典型值示例 | | --- | --- | --- | --- | --- | | 0 | Operating Phase | 治疗阶段 | - | PRE TRT, HD-DN | | 1 | Remaining Time | 剩余时间 | s | 14400.000000 | | 2 | UF Volume | 超滤量 | L | 1.500000 | | 3 | UF Rate | 超滤率 | L/hr | 0.500000 | | 4 | Conductivity | 电导率 | mS/cm | 14.000000 | | 6 | Blood Flow | 血流速 | ml/min | 300.000000 | | 7 | Temperature | 温度 | cel | 37.500000 | | 8 | Dialysis Fluid Flow | 透析液流速 | ml/min | 500.000000 | | 12 | TMP Actual | 跨膜压 | mmHg | 120.000000 | | 13 | Venous Pressure | 静脉压 | mmHg | 80.000000 | | 14 | Arterial Pressure | 动脉压 | mmHg | -150.000000 | | 32 | Set Blood Flow | 设定血流速 | ml/min | 300.000000 | 💡 注意:如果某个参数在当前治疗模式下不适用,该 OBX 段的值可能为空或为 `0`。 ## 5. 完整消息示例 ```xml | ^~\& Gambro_171 SW_8.52_SN_12345 Client_PC HIS 20231027103000 A1B2 ORU R31 MSG_00123 P 2.5 NE NE UNICODE 7Temperature 37.500000 cel F ``` ## 6. 开发实现要点 在 VS Code 中开发时,可参考以下实现逻辑: ### TCP 接收与粘包处理 - 使用 Node.js `net` 模块监听逻辑。 - 维护 Buffer,直到检测到 `` 结尾才进行解析。 ### UTF-16 解码与 XML 解析 - 接收到的 Buffer 是 UTF-16 编码,需先转换为字符串。 - 使用 `xml2js` 库解析。 - 提取所有 `ORU_R31.OBSERVATION` 节点,根据 `OBX.3.CE.1` 的 ID 整理为 JSON 对象。 ### 特定参数监控 - 编写监控函数:若 Temperature(ID 7)> 42 或 < 35,或 Venous Pressure(ID 13)> 250,打印红色警告日志。 ### CRC 校验(可选) - 调试阶段可跳过 `MSH-8` 的 CRC 验证,直接解析消息体。 ## 附录 A:文档中出现的示例代码片段 > 说明:以下片段在原文中出现在“消息结构(XML)”段落中间,疑似为示例工程脚手架/客户端代码(且内容不完整)。为避免干扰协议说明,已移至附录;内容本身未做语义补全。 ```js // init-project.js const fs = require('fs'); const path = require('path'); const projectStructure = { 'config.js': `module.exports = { ARTIS: { host: '192.168.1.100', port: 3021, reconnectInterval: 5000, }, MONITOR: { temperature: { min: 35, max: 42 }, venousPressure: { max: 250 }, arterialPressure: { min: -200, max: 0 }, }, LOG: { enable: true, level: 'info', }, };`, 'src/artisClient.js': `const net = require('net'); const EventEmitter = require('events'); const MessageParser = require('./messageParser'); const DataMonitor = require('./dataMonitor'); const config = require('../config'); class ArtisClient extends EventEmitter { constructor() { super(); this.host = config.ARTIS.host; this.port = config.ARTIS.port; this.socket = null; this.buffer = Buffer.alloc(0); this.parser = new MessageParser(); this.monitor = new DataMonitor(); this.isConnected = false; this.reconnectTimer = null; } connect() { return new Promise((resolve, reject) => { console.log(\`[Client] 正在连接 \${this.host}:\${this.port}...\`); this.socket = net.createConnection({ host: this.host, port: this.port }); this.socket.on('connect', () => { this.isConnected = true; console.log('\\x1b[32m%s\\x1b[0m', '[Client] 连接成功!'); this.emit('connected'); resolve(); }); this.socket.on('data', (data) => this.handleData(data)); this.socket.on('error', (error) => { console.error('[Client] 连接错误:', error.message); this.isConnected = false; this.emit('error', error); reject(error); }); this.socket.on('close', () => { console.log('[Client] 连接已关闭'); this.isConnected = false; this.emit('disconnected'); this.scheduleReconnect(); }); }); } handleData(data) { this.buffer = Buffer ```