qldsdk-lm
Python SDK for X8/X8M/AR4/AR4M portable EEG devices(Windows x64,Python 3.10–3.12)。
通过 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。pyedflib 0.1.42 只提供 cp310–cp312 的 Windows wheel,因此不支持 Python 3.13。
从源码开发:
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_macMAC(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) 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> - 丢包时由 SDK 补 0,停止采集时末尾不足 1 秒的部分补物理 0
日志
设备相关日志以 [序列号] 开头,并在 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.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| qldsdk_lm-0.1.0.tar.gz | 3.9 MB | Without provenance | Details for qldsdk_lm-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| qldsdk_lm-0.1.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details for qldsdk_lm-0.1.0-py3-none-win_amd64.whl |
Total release size: 7.7 MB
Release files / qldsdk_lm-0.1.0.tar.gz
| Download URL | qldsdk_lm-0.1.0.tar.gz |
|---|---|
| Size | 3.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c979428c58934846d9ff9758fd807d3ac9bc7108971591442bc6f1fef6358e47
|
|
BLAKE2b-256 checksum How to use checksums |
932662a144aa3d11716d9af31c9f1156191b0f9ed82f4f5f4b7b0d01cc464240
|
| 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.0-py3-none-win_amd64.whl
| Download URL | qldsdk_lm-0.1.0-py3-none-win_amd64.whl |
|---|---|
| Size | 3.9 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
bc8b4c407d9a6a13d316e7c9b84815d6011ec34b037573de3ddff121b7fd706c
|
|
BLAKE2b-256 checksum How to use checksums |
74f72471d44e6da953038b4c8069ac589894225338a2911e19f72bb3412202e5
|
| 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.0
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.