Skip to main content

qldsdk-lm

Python SDK for X8/X8M/AR4/AR4M portable EEG devices(Windows x64,Python 3.10 及以上)。

通过 ctypes 封装厂商 liblibAr4SDK.dll,提供设备发现、连接、采集、数据订阅、数字/物理值换算和 EDF+ 存储。

设备 说明 真机验证
AR4 / AR4M 4 通道 EEG + 三轴加速度计,单设备 / Hub 是
X8 / X8M 8 通道 EEG,单设备 / Hub 否

安装

pip install qldsdk-lm                 # 依赖 numpy、loguru、pyedflib==0.1.42

包内自带 x64 的 liblibAr4SDK.dll,只发布 win_amd64 wheel。

Python pyedflib 0.1.42 安装方式 验证状态
3.10–3.12 官方 wheel,直接安装 3.12.13 已验证(含真机)
3.13 源码编译 3.13.7 单元测试通过
3.14 / 3.15 源码编译 未验证

3.13 及以上需要先安装 Microsoft C++ Build Tools(勾选"使用 C++ 的桌面开发"),并按下方说明设置 PYTHONUTF8=1。

从源码开发:

py -3.12 -m venv venv
venv\Scripts\activate
pip install -e .
pip install -r requirements-dev.txt   # 测试依赖

使用

import time
from queue import Empty
from qldsdk.lm import AR4M, configure_logger

configure_logger(log_dir="./logs", level="INFO")

hub = AR4M()
try:
    hub.search()                          # 后台每 2 秒枚举一次,新设备自动连接
    deadline = time.time() + 15
    while not hub.devices and time.time() < deadline:
        time.sleep(0.5)

    mac, dev = next(iter(hub.devices.items()))
    print(dev.box_name, dev.serial_number, dev.box_mac, dev.sample_frequency, "Hz")

    dev.set_storage_path("./data")        # EDF+:ar4_<序列号>_<年月日>_<时分秒>_<毫秒>.edf
    topic, q = dev.subscribe("physical")  # eeg 单位 µV,acc 单位 mG
    dev.start_acquisition()
    try:
        end = time.time() + 10
        while time.time() < end:
            try:
                pkt = q.get(timeout=1)    # pkt.eeg[ch][sample]
            except Empty:
                continue
    finally:
        dev.stop_acquisition()
        dev.unsubscribe(topic)
finally:
    hub.close()                           # 必须:释放 SDK 连接

已知 MAC 时可直接 AR4("0x43df64e8335b3b9b")(构造即连接),用完调用 disconnect()。

API 概要

设备 AR4 / X8(基类 LMDevice):

  • 标识:box_name 设备名称,serial_number 设备序列号(SDK box_info 的 boxId),box_mac MAC(0x + 16 位小写十六进制),device_tag 日志/文件名标记(序列号,未知时为 MAC),head_mac 记录子 MAC
  • 参数:sample_frequency、channel_count、eeg_phy_min / eeg_phy_max、connected、recording
  • 方法:start_acquisition()、stop_acquisition()、disconnect()、subscribe("digital" | "physical")、unsubscribe(topic)、eeg2phy()、acc2phy()、set_storage_path(path, enable=True, fill_lost=False)、fill_lost
  • battery_level 尚未实现,恒为 0

Hub AR4M / X8M:search()、stop_search()、close()、devices、add_device(mac) -> bool、remove_device(mac) -> bool

数据包 LMPacket:time_stamp(ms)、pkg_id、notify_id、eeg[ch][sample]、acc[axis][sample](无加速度计时为 None)。digital 订阅为 int 数字量,physical 订阅为 float 物理量。

异常(均继承 LMDeviceException):DeviceConnectionError、AcquisitionError、DLLLoadError。

EDF 存储

  • pyedflib 0.1.42 写 EDF+,每条记录 1 秒
  • 采样率取设备实际采样率,仅支持 500 / 1000 Hz;其它采样率在 start_acquisition() 时抛 AcquisitionError
  • 写入设备原始数字量,头部使用设备的数字/物理量程,读取端还原为 µV
  • 头部 equipment 字段为 <设备类型>_<序列号>,recording additional 字段为 MAC_<mac>
  • 丢包处理由 set_storage_path(path, fill_lost=...) 配置,默认不补:
    • fill_lost=False(默认):丢失的数据直接跳过,EDF 时长会短于实际采集时长
    • fill_lost=True:按丢失的采样点数补物理 0,保持时间轴连续
    • 两种方式都会记录一条丢包告警日志;订阅者收到的数据始终不补 0
  • 开始时间为第一个采样点的时刻:EDF 头部只能精确到秒,因此头部写整秒,开头补 (秒以下部分 × 采样率) 个物理 0,使第一个真实采样点落在正确时刻(误差主要来自约 12–50 ms 的无线传输延迟)
  • 停止采集时末尾不足 1 秒的部分补物理 0
  • 文件名精确到毫秒,同名文件已存在时追加 _1、_2…,不会覆盖已有文件
dev.set_storage_path("./data", fill_lost=True)   # 丢包补 0

···

安装异常时先对齐编码再尝试

bash

set PYTHONUTF8=1 pip install pyedflib==0.1.42

powershell

$env:PYTHONUTF8="1" pip install pyedflib==0.1.42 ···

日志

设备相关日志以 [序列号] 开头,并在 record["extra"]["device"] 中携带序列号,可按设备过滤:

from loguru import logger
logger.add("dev_210125010255.log", filter=lambda r: r["extra"].get("device") == "210125010255")

测试

venv\Scripts\python -m pytest tests/unit                          # 不需要设备
venv\Scripts\python -m pytest tests/integration -m integration    # 需要 AR4
venv\Scripts\python -m pytest tests/system -m system              # 需要 AR4,约 18 分钟

注意:SDK 独占串口和 UDP 54366

同一时刻只能有一个进程加载 SDK。若上一个进程没有退出(或另一个程序正在采集),新进程打开串口会失败(Windows 错误 5)、绑定 UDP 54366 会失败,表现为设备枚举恒为 0。遇到时先确认没有其它进程占用:

Get-NetUDPEndpoint -LocalPort 54366 | Select OwningProcess

卡在串口 I/O 里的进程无法用 taskkill 结束,需要拔插 USB 接收器。

许可证

MIT

Metadata

Release files for qldsdk-lm 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qldsdk-lm 0.1.2
File Size Uploaded Provenance Actions
qldsdk_lm-0.1.2.tar.gz 3.9 MB Without provenance Details for qldsdk_lm-0.1.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for qldsdk-lm 0.1.2
File Interpreter ABI Platform Actions
qldsdk_lm-0.1.2-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for qldsdk_lm-0.1.2-py3-none-win_amd64.whl

Total release size: 7.7 MB

Release files / qldsdk_lm-0.1.2.tar.gz

Download URL qldsdk_lm-0.1.2.tar.gz
Size 3.9 MB
Tags Source
SHA-256 checksum
How to use checksums
44980628e3e97da8232779c497d66732fc8ca76cb01d1bcffe60f9deb5ad4c25
BLAKE2b-256 checksum
How to use checksums
18a19a25e080be246c8411509620d75f01b58a34344cc709504b00c7b0742900
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / qldsdk_lm-0.1.2-py3-none-win_amd64.whl

Download URL qldsdk_lm-0.1.2-py3-none-win_amd64.whl
Size 3.9 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
d8be53dba0ef5e80987c5197aaed6420926afaac9bcc15cfa1c1486932db6330
BLAKE2b-256 checksum
How to use checksums
afe9f58bf0f889116dd9111f958a88801a1444f96d3b16a4c1754fd38f42be14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Security for qldsdk-lm 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page