跳转至

IEEE 11073标准

学习目标

通过本文档的学习,你将能够:

  • 理解核心概念和原理
  • 掌握实际应用方法
  • 了解最佳实践和注意事项

前置知识

在学习本文档之前,建议你已经掌握:

  • 基础的嵌入式系统知识
  • C/C++编程基础
  • 相关领域的基本概念

概述

IEEE 11073是个人健康设备(Personal Health Devices, PHD)通信标准系列,定义了医疗和健康设备与计算机系统之间的数据交换。该标准特别适用于家庭和移动健康监护设备。

标准架构

IEEE 11073系列标准

标准编号 名称 内容
11073-10101 命名法 医疗设备术语和代码
11073-10201 域信息模型 抽象数据模型
11073-10404 脉搏血氧仪 血氧饱和度设备
11073-10407 血压计 血压测量设备
11073-10408 体温计 体温测量设备
11073-10415 体重秤 体重测量设备
11073-10417 血糖仪 血糖测量设备
11073-20601 应用配置文件 优化交换协议

域信息模型(DIM)

对象模型

Medical Device System (MDS)
  └── Virtual Medical Device (VMD)
        └── Channel
              └── Metric
                    └── Attribute

示例:血压计模型

MDS (血压计系统)
  └── VMD (血压测量模块)
        └── Channel (血压通道)
              ├── Metric (收缩压)
              │     ├── Unit: mmHg
              │     └── Value: 120
              ├── Metric (舒张压)
              │     ├── Unit: mmHg
              │     └── Value: 80
              └── Metric (平均压)
                    ├── Unit: mmHg
                    └── Value: 93

命名法(Nomenclature)

MDC代码

// IEEE 11073-10101 术语代码
#define MDC_PART_SCADA          0x0002  // 监控和数据采集
#define MDC_PART_DIM            0x0004  // 域信息模型

// 生命体征
#define MDC_PRESS_BLD_NONINV    0x4A14  // 无创血压
#define MDC_PRESS_BLD_NONINV_SYS 0x4A15 // 收缩压
#define MDC_PRESS_BLD_NONINV_DIA 0x4A16 // 舒张压
#define MDC_PRESS_BLD_NONINV_MEAN 0x4A17 // 平均压

#define MDC_PULS_OXIM_SAT_O2    0x4A3C  // 血氧饱和度
#define MDC_PULS_OXIM_PULS_RATE 0x4A3D  // 脉率

#define MDC_TEMP_BODY           0x4A88  // 体温

#define MDC_MASS_BODY_ACTUAL    0x4A8C  // 体重

#define MDC_CONC_GLU_CAPILLARY_WHOLEBLOOD 0x4A9C // 毛细血管全血血糖

// 单位
#define MDC_DIM_MMHG            0x0F0E  // mmHg
#define MDC_DIM_PERCENT         0x0220  // %
#define MDC_DIM_DEGC            0x17A0  // 摄氏度
#define MDC_DIM_KG              0x1760  // 千克
#define MDC_DIM_MILLI_G_PER_DL  0x06A1  // mg/dL

IEEE 11073-20601协议

通信模型

Agent (医疗设备)  <--->  Manager (手机/网关)

状态机:
1. Unassociated (未关联)
2. Associating (关联中)
3. Associated (已关联)
4. Operating (运行中)
5. Disassociating (断开关联中)

协议数据单元(APDU)

关联请求(Association Request)

typedef struct {
    uint16_t protocol_version;
    uint16_t encoding_rules;
    uint32_t nomenclature_version;
    uint32_t functional_units;
    uint32_t system_type;
    uint8_t system_id[8];
    uint16_t dev_config_id;
    // ... 配置信息
} AssocReq;

测量数据(Measurement Data)

typedef struct {
    uint16_t obj_handle;      // 对象句柄
    uint32_t rel_time_stamp;  // 相对时间戳
    uint16_t measure_type;    // 测量类型(MDC代码)
    float value;              // 测量值
    uint16_t unit;            // 单位(MDC代码)
} ScanReportFixed;

实现示例

Python实现(使用Antidote)

from antidote import ieee11073
from antidote.hdp import HealthDevice

# 创建血压测量数据
def create_blood_pressure_measurement(systolic, diastolic, mean_pressure):
    # 创建扫描报告
    scan_report = {
        'data-req-id': 0x1234,
        'scan-report-no': 1,
        'obs-scan-fixed': [
            {
                'obj-handle': 1,
                'obs-val-data': {
                    'compound-simple-nu-observed-value': {
                        'count': 3,
                        'value': [
                            {
                                'attribute-id': MDC_PRESS_BLD_NONINV_SYS,
                                'attribute-value': systolic
                            },
                            {
                                'attribute-id': MDC_PRESS_BLD_NONINV_DIA,
                                'attribute-value': diastolic
                            },
                            {
                                'attribute-id': MDC_PRESS_BLD_NONINV_MEAN,
                                'attribute-value': mean_pressure
                            }
                        ]
                    }
                }
            }
        ]
    }

    return scan_report

# 血压计Agent实现
class BloodPressureAgent(HealthDevice):
    def __init__(self):
        super().__init__()
        self.device_config_id = 0x0190  # 血压计配置

    def get_configuration(self):
        """返回设备配置"""
        config = {
            'dev-config-id': self.device_config_id,
            'config-obj-list': [
                {
                    'obj-class': MDC_MOC_VMO_METRIC_NU,
                    'obj-handle': 1,
                    'attributes': [
                        {
                            'attribute-id': MDC_ATTR_ID_TYPE,
                            'attribute-value': MDC_PRESS_BLD_NONINV
                        },
                        {
                            'attribute-id': MDC_ATTR_UNIT_CODE,
                            'attribute-value': MDC_DIM_MMHG
                        }
                    ]
                }
            ]
        }
        return config

    def send_measurement(self, systolic, diastolic):
        """发送血压测量数据"""
        mean_pressure = (systolic + 2 * diastolic) / 3

        scan_report = create_blood_pressure_measurement(
            systolic, diastolic, mean_pressure
        )

        self.send_data(scan_report)

# 使用示例
agent = BloodPressureAgent()
agent.connect('00:11:22:33:44:55')  # 连接到Manager
agent.send_measurement(120, 80)

C实现

#include <stdint.h>
#include <string.h>

// IEEE 11073-20601 APDU类型
#define APDU_TYPE_ASSOC_REQ     0xE200
#define APDU_TYPE_ASSOC_RES     0xE300
#define APDU_TYPE_RLRQ          0xE400
#define APDU_TYPE_RLRE          0xE500
#define APDU_TYPE_PRST          0xE700

// 数据结构
typedef struct {
    uint16_t choice;
    uint16_t length;
    uint8_t value[];
} APDU;

typedef struct {
    uint16_t obj_handle;
    uint16_t attribute_id;
    uint16_t attribute_len;
    uint8_t attribute_value[];
} AttributeList;

// 创建关联请求
APDU* create_association_request() {
    APDU *apdu = malloc(sizeof(APDU) + 256);
    apdu->choice = APDU_TYPE_ASSOC_REQ;

    uint8_t *data = apdu->value;
    uint16_t offset = 0;

    // 协议版本
    *(uint16_t*)(data + offset) = htons(0x8000);  // Version 1
    offset += 2;

    // 编码规则
    *(uint16_t*)(data + offset) = htons(0x8000);  // MDER
    offset += 2;

    // 命名法版本
    *(uint32_t*)(data + offset) = htonl(0x20000000);
    offset += 4;

    // 功能单元
    *(uint32_t*)(data + offset) = htonl(0x00000000);
    offset += 4;

    // 系统类型
    *(uint32_t*)(data + offset) = htonl(0x00800000);  // Agent
    offset += 4;

    // 系统ID(8字节)
    memcpy(data + offset, "\x11\x22\x33\x44\x55\x66\x77\x88", 8);
    offset += 8;

    // 设备配置ID
    *(uint16_t*)(data + offset) = htons(0x0190);  // 血压计
    offset += 2;

    apdu->length = htons(offset);

    return apdu;
}

// 创建血压测量数据
APDU* create_blood_pressure_data(uint16_t systolic, uint16_t diastolic) {
    APDU *apdu = malloc(sizeof(APDU) + 256);
    apdu->choice = APDU_TYPE_PRST;

    uint8_t *data = apdu->value;
    uint16_t offset = 0;

    // Invoke ID
    *(uint16_t*)(data + offset) = htons(0x0001);
    offset += 2;

    // 数据请求ID
    *(uint16_t*)(data + offset) = htons(0x1234);
    offset += 2;

    // 扫描报告编号
    *(uint16_t*)(data + offset) = htons(0x0001);
    offset += 2;

    // 观察数量
    *(uint16_t*)(data + offset) = htons(3);  // 收缩压、舒张压、平均压
    offset += 2;

    // 收缩压
    *(uint16_t*)(data + offset) = htons(1);  // 对象句柄
    offset += 2;
    *(uint16_t*)(data + offset) = htons(MDC_PRESS_BLD_NONINV_SYS);
    offset += 2;
    *(uint16_t*)(data + offset) = htons(2);  // 长度
    offset += 2;
    *(uint16_t*)(data + offset) = htons(systolic);
    offset += 2;

    // 舒张压
    *(uint16_t*)(data + offset) = htons(1);
    offset += 2;
    *(uint16_t*)(data + offset) = htons(MDC_PRESS_BLD_NONINV_DIA);
    offset += 2;
    *(uint16_t*)(data + offset) = htons(2);
    offset += 2;
    *(uint16_t*)(data + offset) = htons(diastolic);
    offset += 2;

    // 平均压
    uint16_t mean = (systolic + 2 * diastolic) / 3;
    *(uint16_t*)(data + offset) = htons(1);
    offset += 2;
    *(uint16_t*)(data + offset) = htons(MDC_PRESS_BLD_NONINV_MEAN);
    offset += 2;
    *(uint16_t*)(data + offset) = htons(2);
    offset += 2;
    *(uint16_t*)(data + offset) = htons(mean);
    offset += 2;

    apdu->length = htons(offset);

    return apdu;
}

// 发送APDU
void send_apdu(int socket, APDU *apdu) {
    uint16_t total_len = sizeof(APDU) + ntohs(apdu->length);
    send(socket, apdu, total_len, 0);
}

// 使用示例
void blood_pressure_agent_example() {
    int sock = connect_to_manager("192.168.1.100", 9999);

    // 发送关联请求
    APDU *assoc_req = create_association_request();
    send_apdu(sock, assoc_req);
    free(assoc_req);

    // 等待关联响应
    // ... 接收和处理响应

    // 发送测量数据
    APDU *measurement = create_blood_pressure_data(120, 80);
    send_apdu(sock, measurement);
    free(measurement);

    close(sock);
}

Continua设计指南

Continua认证

Continua Health Alliance(现为Personal Connected Health Alliance)定义了基于IEEE 11073的互操作性指南。

认证要求

  1. 传输层: 蓝牙HDP或BLE
  2. 应用层: IEEE 11073-20601
  3. 设备专用: 对应的IEEE 11073-104xx标准
  4. 安全: 蓝牙配对和加密

认证设备类型

  • 血压计(Blood Pressure Monitor)
  • 血糖仪(Glucose Meter)
  • 体重秤(Weighing Scale)
  • 脉搏血氧仪(Pulse Oximeter)
  • 体温计(Thermometer)
  • 心率监护仪(Heart Rate Monitor)
  • 活动监测器(Activity Monitor)

与FHIR集成

# IEEE 11073到FHIR Observation的转换
def ieee11073_to_fhir_observation(ieee_data):
    observation = {
        'resourceType': 'Observation',
        'status': 'final',
        'category': [{
            'coding': [{
                'system': 'http://terminology.hl7.org/CodeSystem/observation-category',
                'code': 'vital-signs'
            }]
        }]
    }

    # 映射MDC代码到LOINC
    mdc_to_loinc = {
        MDC_PRESS_BLD_NONINV_SYS: '8480-6',  # 收缩压
        MDC_PRESS_BLD_NONINV_DIA: '8462-4',  # 舒张压
        MDC_PULS_OXIM_SAT_O2: '59408-5',     # 血氧
        MDC_TEMP_BODY: '8310-5',             # 体温
        MDC_MASS_BODY_ACTUAL: '29463-7'      # 体重
    }

    loinc_code = mdc_to_loinc.get(ieee_data['measure_type'])

    if loinc_code:
        observation['code'] = {
            'coding': [{
                'system': 'http://loinc.org',
                'code': loinc_code
            }]
        }

    # 映射单位
    mdc_to_ucum = {
        MDC_DIM_MMHG: 'mm[Hg]',
        MDC_DIM_PERCENT: '%',
        MDC_DIM_DEGC: 'Cel',
        MDC_DIM_KG: 'kg'
    }

    ucum_unit = mdc_to_ucum.get(ieee_data['unit'])

    observation['valueQuantity'] = {
        'value': ieee_data['value'],
        'unit': ucum_unit,
        'system': 'http://unitsofmeasure.org',
        'code': ucum_unit
    }

    return observation

测试与验证

Continua测试工具

# 使用Continua测试工具验证设备
def validate_continua_device(device):
    tests = [
        test_association(),
        test_configuration(),
        test_measurement_data(),
        test_disconnection()
    ]

    results = []
    for test in tests:
        result = test(device)
        results.append(result)
        print(f"{test.__name__}: {'PASS' if result else 'FAIL'}")

    return all(results)

最佳实践

  1. ✅ 使用标准MDC代码
  2. ✅ 实施完整的状态机
  3. ✅ 支持配置协商
  4. ✅ 实施错误处理
  5. ✅ 考虑Continua认证

参考资源


相关章节: - 蓝牙HDP - HL7 FHIR集成


💬 讨论区

欢迎在这里分享您的想法、提出问题或参与讨论。需要 GitHub 账号登录。