qldsdk-lm 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. qldsdk_lm-0.1.0/LICENSE +21 -0
  2. qldsdk_lm-0.1.0/PKG-INFO +163 -0
  3. qldsdk_lm-0.1.0/README.md +119 -0
  4. qldsdk_lm-0.1.0/pyproject.toml +124 -0
  5. qldsdk_lm-0.1.0/setup.cfg +4 -0
  6. qldsdk_lm-0.1.0/setup.py +24 -0
  7. qldsdk_lm-0.1.0/src/qldsdk_lm/__init__.py +46 -0
  8. qldsdk_lm-0.1.0/src/qldsdk_lm/core/__init__.py +14 -0
  9. qldsdk_lm-0.1.0/src/qldsdk_lm/core/base.py +398 -0
  10. qldsdk_lm-0.1.0/src/qldsdk_lm/core/exceptions.py +17 -0
  11. qldsdk_lm-0.1.0/src/qldsdk_lm/devices/__init__.py +5 -0
  12. qldsdk_lm-0.1.0/src/qldsdk_lm/devices/ar4.py +23 -0
  13. qldsdk_lm-0.1.0/src/qldsdk_lm/devices/sdk_device.py +170 -0
  14. qldsdk_lm-0.1.0/src/qldsdk_lm/devices/x8.py +14 -0
  15. qldsdk_lm-0.1.0/src/qldsdk_lm/persist/__init__.py +4 -0
  16. qldsdk_lm-0.1.0/src/qldsdk_lm/persist/edf_handler.py +150 -0
  17. qldsdk_lm-0.1.0/src/qldsdk_lm/sdk/__init__.py +23 -0
  18. qldsdk_lm-0.1.0/src/qldsdk_lm/sdk/ar4_sdk.py +913 -0
  19. qldsdk_lm-0.1.0/src/qldsdk_lm/sdk/libs/Ar4SDK.h +347 -0
  20. qldsdk_lm-0.1.0/src/qldsdk_lm/sdk/libs/liblibAr4SDK.dll +0 -0
  21. qldsdk_lm-0.1.0/src/qldsdk_lm/sdk/libs/libwinpthread-1.dll +0 -0
  22. qldsdk_lm-0.1.0/src/qldsdk_lm/utils/__init__.py +10 -0
  23. qldsdk_lm-0.1.0/src/qldsdk_lm/utils/converter.py +52 -0
  24. qldsdk_lm-0.1.0/src/qldsdk_lm/utils/logger.py +98 -0
  25. qldsdk_lm-0.1.0/src/qldsdk_lm.egg-info/PKG-INFO +163 -0
  26. qldsdk_lm-0.1.0/src/qldsdk_lm.egg-info/SOURCES.txt +27 -0
  27. qldsdk_lm-0.1.0/src/qldsdk_lm.egg-info/dependency_links.txt +1 -0
  28. qldsdk_lm-0.1.0/src/qldsdk_lm.egg-info/requires.txt +27 -0
  29. qldsdk_lm-0.1.0/src/qldsdk_lm.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 QLSDK Project Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,163 @@
1
+ Metadata-Version: 2.4
2
+ Name: qldsdk-lm
3
+ Version: 0.1.0
4
+ Summary: Python SDK for X8/X8M/AR4/AR4M portable EEG devices
5
+ Author: QLSDK Project Team
6
+ License-Expression: MIT
7
+ Keywords: eeg,biosignal,neuroscience,ar4,x8
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Scientific/Engineering
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Operating System :: Microsoft :: Windows
18
+ Requires-Python: <3.13,>=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: numpy>=1.21.0
22
+ Requires-Dist: loguru>=0.6.0
23
+ Requires-Dist: pyedflib==0.1.42
24
+ Provides-Extra: analysis
25
+ Requires-Dist: scipy>=1.7.0; extra == "analysis"
26
+ Requires-Dist: pandas>=1.3.0; extra == "analysis"
27
+ Provides-Extra: visualization
28
+ Requires-Dist: matplotlib>=3.4.0; extra == "visualization"
29
+ Provides-Extra: gui
30
+ Requires-Dist: PySide6>=6.0.0; extra == "gui"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
33
+ Requires-Dist: pytest-cov>=3.0.0; extra == "dev"
34
+ Requires-Dist: pytest-timeout>=2.1.0; extra == "dev"
35
+ Requires-Dist: black>=22.0.0; extra == "dev"
36
+ Requires-Dist: isort>=5.10.0; extra == "dev"
37
+ Requires-Dist: flake8>=4.0.0; extra == "dev"
38
+ Requires-Dist: mypy>=0.950; extra == "dev"
39
+ Requires-Dist: sphinx>=4.5.0; extra == "dev"
40
+ Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "dev"
41
+ Provides-Extra: all
42
+ Requires-Dist: qldsdk-lm[analysis,gui,visualization]; extra == "all"
43
+ Dynamic: license-file
44
+
45
+ # qldsdk-lm
46
+
47
+ Python SDK for X8/X8M/AR4/AR4M portable EEG devices(Windows x64,Python 3.10–3.12)。
48
+
49
+ 通过 ctypes 封装厂商 `liblibAr4SDK.dll`,提供设备发现、连接、采集、数据订阅、数字/物理值换算和 EDF+ 存储。
50
+
51
+ | 设备 | 说明 | 真机验证 |
52
+ |------|------|----------|
53
+ | AR4 / AR4M | 4 通道 EEG + 三轴加速度计,单设备 / Hub | 是 |
54
+ | X8 / X8M | 8 通道 EEG,单设备 / Hub | 否 |
55
+
56
+ ## 安装
57
+
58
+ ```bash
59
+ pip install qldsdk-lm # 依赖 numpy、loguru、pyedflib==0.1.42
60
+ ```
61
+
62
+ 包内自带 x64 的 `liblibAr4SDK.dll`,只发布 `win_amd64` wheel。pyedflib 0.1.42 只提供 cp310–cp312 的 Windows wheel,因此不支持 Python 3.13。
63
+
64
+ 从源码开发:
65
+
66
+ ```bash
67
+ py -3.12 -m venv venv
68
+ venv\Scripts\activate
69
+ pip install -e .
70
+ pip install -r requirements-dev.txt # 测试依赖
71
+ ```
72
+
73
+ ## 使用
74
+
75
+ ```python
76
+ import time
77
+ from queue import Empty
78
+ from qldsdk_lm import AR4M, configure_logger
79
+
80
+ configure_logger(log_dir="./logs", level="INFO")
81
+
82
+ hub = AR4M()
83
+ try:
84
+ hub.search() # 后台每 2 秒枚举一次,新设备自动连接
85
+ deadline = time.time() + 15
86
+ while not hub.devices and time.time() < deadline:
87
+ time.sleep(0.5)
88
+
89
+ mac, dev = next(iter(hub.devices.items()))
90
+ print(dev.box_name, dev.serial_number, dev.box_mac, dev.sample_frequency, "Hz")
91
+
92
+ dev.set_storage_path("./data") # EDF+:ar4_<序列号>_<时间>.edf
93
+ topic, q = dev.subscribe("physical") # eeg 单位 µV,acc 单位 mG
94
+ dev.start_acquisition()
95
+ try:
96
+ end = time.time() + 10
97
+ while time.time() < end:
98
+ try:
99
+ pkt = q.get(timeout=1) # pkt.eeg[ch][sample]
100
+ except Empty:
101
+ continue
102
+ finally:
103
+ dev.stop_acquisition()
104
+ dev.unsubscribe(topic)
105
+ finally:
106
+ hub.close() # 必须:释放 SDK 连接
107
+ ```
108
+
109
+ 已知 MAC 时可直接 `AR4("0x43df64e8335b3b9b")`(构造即连接),用完调用 `disconnect()`。
110
+
111
+ ## API 概要
112
+
113
+ 设备 `AR4` / `X8`(基类 `LMDevice`):
114
+
115
+ - 标识:`box_name` 设备名称,`serial_number` 设备序列号(SDK box_info 的 `boxId`),`box_mac` MAC(`0x` + 16 位小写十六进制),`device_tag` 日志/文件名标记(序列号,未知时为 MAC),`head_mac` 记录子 MAC
116
+ - 参数:`sample_frequency`、`channel_count`、`eeg_phy_min` / `eeg_phy_max`、`connected`、`recording`
117
+ - 方法:`start_acquisition()`、`stop_acquisition()`、`disconnect()`、`subscribe("digital" | "physical")`、`unsubscribe(topic)`、`eeg2phy()`、`acc2phy()`、`set_storage_path(path, enable=True)`
118
+ - `battery_level` 尚未实现,恒为 0
119
+
120
+ Hub `AR4M` / `X8M`:`search()`、`stop_search()`、`close()`、`devices`、`add_device(mac) -> bool`、`remove_device(mac) -> bool`
121
+
122
+ 数据包 `LMPacket`:`time_stamp`(ms)、`pkg_id`、`notify_id`、`eeg[ch][sample]`、`acc[axis][sample]`(无加速度计时为 None)。digital 订阅为 int 数字量,physical 订阅为 float 物理量。
123
+
124
+ 异常(均继承 `LMDeviceException`):`DeviceConnectionError`、`AcquisitionError`、`DLLLoadError`。
125
+
126
+ ## EDF 存储
127
+
128
+ - pyedflib 0.1.42 写 EDF+,每条记录 1 秒
129
+ - 采样率取设备实际采样率,仅支持 500 / 1000 Hz;其它采样率在 `start_acquisition()` 时抛 `AcquisitionError`
130
+ - 写入设备原始数字量,头部使用设备的数字/物理量程,读取端还原为 µV
131
+ - 头部 equipment 字段为 `<设备类型>_<序列号>`,recording additional 字段为 `MAC_<mac>`
132
+ - 丢包时由 SDK 补 0,停止采集时末尾不足 1 秒的部分补物理 0
133
+
134
+ ## 日志
135
+
136
+ 设备相关日志以 `[序列号]` 开头,并在 `record["extra"]["device"]` 中携带序列号,可按设备过滤:
137
+
138
+ ```python
139
+ from loguru import logger
140
+ logger.add("dev_210125010255.log", filter=lambda r: r["extra"].get("device") == "210125010255")
141
+ ```
142
+
143
+ ## 测试
144
+
145
+ ```bash
146
+ venv\Scripts\python -m pytest tests/unit # 不需要设备
147
+ venv\Scripts\python -m pytest tests/integration -m integration # 需要 AR4
148
+ venv\Scripts\python -m pytest tests/system -m system # 需要 AR4,约 18 分钟
149
+ ```
150
+
151
+ ## 注意:SDK 独占串口和 UDP 54366
152
+
153
+ 同一时刻只能有一个进程加载 SDK。若上一个进程没有退出(或另一个程序正在采集),新进程打开串口会失败(Windows 错误 5)、绑定 UDP 54366 会失败,表现为设备枚举恒为 0。遇到时先确认没有其它进程占用:
154
+
155
+ ```powershell
156
+ Get-NetUDPEndpoint -LocalPort 54366 | Select OwningProcess
157
+ ```
158
+
159
+ 卡在串口 I/O 里的进程无法用 taskkill 结束,需要拔插 USB 接收器。
160
+
161
+ ## 许可证
162
+
163
+ MIT
@@ -0,0 +1,119 @@
1
+ # qldsdk-lm
2
+
3
+ Python SDK for X8/X8M/AR4/AR4M portable EEG devices(Windows x64,Python 3.10–3.12)。
4
+
5
+ 通过 ctypes 封装厂商 `liblibAr4SDK.dll`,提供设备发现、连接、采集、数据订阅、数字/物理值换算和 EDF+ 存储。
6
+
7
+ | 设备 | 说明 | 真机验证 |
8
+ |------|------|----------|
9
+ | AR4 / AR4M | 4 通道 EEG + 三轴加速度计,单设备 / Hub | 是 |
10
+ | X8 / X8M | 8 通道 EEG,单设备 / Hub | 否 |
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ pip install qldsdk-lm # 依赖 numpy、loguru、pyedflib==0.1.42
16
+ ```
17
+
18
+ 包内自带 x64 的 `liblibAr4SDK.dll`,只发布 `win_amd64` wheel。pyedflib 0.1.42 只提供 cp310–cp312 的 Windows wheel,因此不支持 Python 3.13。
19
+
20
+ 从源码开发:
21
+
22
+ ```bash
23
+ py -3.12 -m venv venv
24
+ venv\Scripts\activate
25
+ pip install -e .
26
+ pip install -r requirements-dev.txt # 测试依赖
27
+ ```
28
+
29
+ ## 使用
30
+
31
+ ```python
32
+ import time
33
+ from queue import Empty
34
+ from qldsdk_lm import AR4M, configure_logger
35
+
36
+ configure_logger(log_dir="./logs", level="INFO")
37
+
38
+ hub = AR4M()
39
+ try:
40
+ hub.search() # 后台每 2 秒枚举一次,新设备自动连接
41
+ deadline = time.time() + 15
42
+ while not hub.devices and time.time() < deadline:
43
+ time.sleep(0.5)
44
+
45
+ mac, dev = next(iter(hub.devices.items()))
46
+ print(dev.box_name, dev.serial_number, dev.box_mac, dev.sample_frequency, "Hz")
47
+
48
+ dev.set_storage_path("./data") # EDF+:ar4_<序列号>_<时间>.edf
49
+ topic, q = dev.subscribe("physical") # eeg 单位 µV,acc 单位 mG
50
+ dev.start_acquisition()
51
+ try:
52
+ end = time.time() + 10
53
+ while time.time() < end:
54
+ try:
55
+ pkt = q.get(timeout=1) # pkt.eeg[ch][sample]
56
+ except Empty:
57
+ continue
58
+ finally:
59
+ dev.stop_acquisition()
60
+ dev.unsubscribe(topic)
61
+ finally:
62
+ hub.close() # 必须:释放 SDK 连接
63
+ ```
64
+
65
+ 已知 MAC 时可直接 `AR4("0x43df64e8335b3b9b")`(构造即连接),用完调用 `disconnect()`。
66
+
67
+ ## API 概要
68
+
69
+ 设备 `AR4` / `X8`(基类 `LMDevice`):
70
+
71
+ - 标识:`box_name` 设备名称,`serial_number` 设备序列号(SDK box_info 的 `boxId`),`box_mac` MAC(`0x` + 16 位小写十六进制),`device_tag` 日志/文件名标记(序列号,未知时为 MAC),`head_mac` 记录子 MAC
72
+ - 参数:`sample_frequency`、`channel_count`、`eeg_phy_min` / `eeg_phy_max`、`connected`、`recording`
73
+ - 方法:`start_acquisition()`、`stop_acquisition()`、`disconnect()`、`subscribe("digital" | "physical")`、`unsubscribe(topic)`、`eeg2phy()`、`acc2phy()`、`set_storage_path(path, enable=True)`
74
+ - `battery_level` 尚未实现,恒为 0
75
+
76
+ Hub `AR4M` / `X8M`:`search()`、`stop_search()`、`close()`、`devices`、`add_device(mac) -> bool`、`remove_device(mac) -> bool`
77
+
78
+ 数据包 `LMPacket`:`time_stamp`(ms)、`pkg_id`、`notify_id`、`eeg[ch][sample]`、`acc[axis][sample]`(无加速度计时为 None)。digital 订阅为 int 数字量,physical 订阅为 float 物理量。
79
+
80
+ 异常(均继承 `LMDeviceException`):`DeviceConnectionError`、`AcquisitionError`、`DLLLoadError`。
81
+
82
+ ## EDF 存储
83
+
84
+ - pyedflib 0.1.42 写 EDF+,每条记录 1 秒
85
+ - 采样率取设备实际采样率,仅支持 500 / 1000 Hz;其它采样率在 `start_acquisition()` 时抛 `AcquisitionError`
86
+ - 写入设备原始数字量,头部使用设备的数字/物理量程,读取端还原为 µV
87
+ - 头部 equipment 字段为 `<设备类型>_<序列号>`,recording additional 字段为 `MAC_<mac>`
88
+ - 丢包时由 SDK 补 0,停止采集时末尾不足 1 秒的部分补物理 0
89
+
90
+ ## 日志
91
+
92
+ 设备相关日志以 `[序列号]` 开头,并在 `record["extra"]["device"]` 中携带序列号,可按设备过滤:
93
+
94
+ ```python
95
+ from loguru import logger
96
+ logger.add("dev_210125010255.log", filter=lambda r: r["extra"].get("device") == "210125010255")
97
+ ```
98
+
99
+ ## 测试
100
+
101
+ ```bash
102
+ venv\Scripts\python -m pytest tests/unit # 不需要设备
103
+ venv\Scripts\python -m pytest tests/integration -m integration # 需要 AR4
104
+ venv\Scripts\python -m pytest tests/system -m system # 需要 AR4,约 18 分钟
105
+ ```
106
+
107
+ ## 注意:SDK 独占串口和 UDP 54366
108
+
109
+ 同一时刻只能有一个进程加载 SDK。若上一个进程没有退出(或另一个程序正在采集),新进程打开串口会失败(Windows 错误 5)、绑定 UDP 54366 会失败,表现为设备枚举恒为 0。遇到时先确认没有其它进程占用:
110
+
111
+ ```powershell
112
+ Get-NetUDPEndpoint -LocalPort 54366 | Select OwningProcess
113
+ ```
114
+
115
+ 卡在串口 I/O 里的进程无法用 taskkill 结束,需要拔插 USB 接收器。
116
+
117
+ ## 许可证
118
+
119
+ MIT
@@ -0,0 +1,124 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "qldsdk-lm"
7
+ version = "0.1.0"
8
+ description = "Python SDK for X8/X8M/AR4/AR4M portable EEG devices"
9
+ readme = "README.md"
10
+ # pyedflib 0.1.42 仅提供 cp310–cp312 的 Windows wheel
11
+ requires-python = ">=3.10,<3.13"
12
+ license = "MIT"
13
+ license-files = ["LICENSE"]
14
+ authors = [
15
+ {name = "QLSDK Project Team"}
16
+ ]
17
+ keywords = ["eeg", "biosignal", "neuroscience", "ar4", "x8"]
18
+ classifiers = [
19
+ "Development Status :: 3 - Alpha",
20
+ "Intended Audience :: Science/Research",
21
+ "Intended Audience :: Developers",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Topic :: Scientific/Engineering",
27
+ "Topic :: Software Development :: Libraries :: Python Modules",
28
+ "Operating System :: Microsoft :: Windows",
29
+ ]
30
+
31
+ dependencies = [
32
+ "numpy>=1.21.0",
33
+ "loguru>=0.6.0",
34
+ "pyedflib==0.1.42",
35
+ ]
36
+
37
+ [project.optional-dependencies]
38
+ analysis = [
39
+ "scipy>=1.7.0",
40
+ "pandas>=1.3.0",
41
+ ]
42
+ visualization = [
43
+ "matplotlib>=3.4.0",
44
+ ]
45
+ gui = [
46
+ "PySide6>=6.0.0",
47
+ ]
48
+ dev = [
49
+ "pytest>=7.0.0",
50
+ "pytest-cov>=3.0.0",
51
+ "pytest-timeout>=2.1.0",
52
+ "black>=22.0.0",
53
+ "isort>=5.10.0",
54
+ "flake8>=4.0.0",
55
+ "mypy>=0.950",
56
+ "sphinx>=4.5.0",
57
+ "sphinx-rtd-theme>=1.0.0",
58
+ ]
59
+ all = [
60
+ "qldsdk-lm[analysis,visualization,gui]",
61
+ ]
62
+
63
+ [tool.setuptools]
64
+ package-dir = {"" = "src"}
65
+
66
+ [tool.setuptools.packages.find]
67
+ where = ["src"]
68
+ include = ["qldsdk_lm*"]
69
+
70
+ [tool.setuptools.package-data]
71
+ qldsdk_lm = ["sdk/libs/*.dll", "sdk/libs/*.h"]
72
+
73
+ [tool.black]
74
+ line-length = 100
75
+ target-version = ['py310', 'py311', 'py312']
76
+ include = '\.pyi?$'
77
+
78
+ [tool.isort]
79
+ profile = "black"
80
+ line_length = 100
81
+ multi_line_output = 3
82
+
83
+ [tool.mypy]
84
+ python_version = "3.10"
85
+ warn_return_any = true
86
+ warn_unused_configs = true
87
+ disallow_untyped_defs = false
88
+ disallow_incomplete_defs = false
89
+ check_untyped_defs = true
90
+ no_implicit_optional = true
91
+
92
+ [tool.pytest.ini_options]
93
+ minversion = "7.0"
94
+ testpaths = ["tests"]
95
+ python_files = ["test_*.py"]
96
+ python_classes = ["Test*"]
97
+ python_functions = ["test_*"]
98
+ addopts = [
99
+ "-v",
100
+ "--strict-markers",
101
+ "--tb=short",
102
+ ]
103
+ markers = [
104
+ "unit: Unit tests",
105
+ "integration: Integration tests",
106
+ "hardware: Tests requiring physical hardware",
107
+ "slow: Slow running tests",
108
+ ]
109
+ timeout = 300
110
+
111
+ [tool.coverage.run]
112
+ source = ["src"]
113
+ omit = ["*/tests/*", "*/examples/*"]
114
+
115
+ [tool.coverage.report]
116
+ exclude_lines = [
117
+ "pragma: no cover",
118
+ "def __repr__",
119
+ "raise AssertionError",
120
+ "raise NotImplementedError",
121
+ "if __name__ == .__main__.:",
122
+ "if TYPE_CHECKING:",
123
+ "@abstractmethod",
124
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,24 @@
1
+ """qldsdk-lm 构建脚本:元数据在 pyproject.toml,这里只修正 wheel 平台标签。
2
+
3
+ 包内自带 x64 的 liblibAr4SDK.dll,wheel 不能标成 py3-none-any,
4
+ 否则 Linux / macOS / 32 位 Python 也会装上一个无法加载的包。
5
+ 纯 Python 代码不依赖解释器 ABI,因此标签为 py3-none-win_amd64。
6
+ """
7
+ from setuptools import setup
8
+
9
+ try: # setuptools >= 70.1 自带 bdist_wheel;新版 wheel 已移除该模块
10
+ from setuptools.command.bdist_wheel import bdist_wheel
11
+ except ImportError:
12
+ from wheel.bdist_wheel import bdist_wheel
13
+
14
+
15
+ class PlatformWheel(bdist_wheel):
16
+ def finalize_options(self):
17
+ super().finalize_options()
18
+ self.root_is_pure = False
19
+
20
+ def get_tag(self):
21
+ return "py3", "none", "win_amd64"
22
+
23
+
24
+ setup(cmdclass={"bdist_wheel": PlatformWheel})
@@ -0,0 +1,46 @@
1
+ """QLSDK-LM: Python SDK for X8/X8M/AR4/AR4M Portable EEG Devices
2
+
3
+ Examples:
4
+ >>> from qldsdk_lm import AR4M
5
+ >>> hub = AR4M()
6
+ >>> hub.search()
7
+ >>> ...
8
+ >>> for mac, device in hub.devices.items():
9
+ ... print(device.box_name, device.serial_number, mac)
10
+ >>> hub.close()
11
+ """
12
+
13
+ __version__ = "0.1.0"
14
+
15
+ from .core import (
16
+ AcquisitionError,
17
+ DeviceConnectionError,
18
+ DLLLoadError,
19
+ Hub,
20
+ LMDevice,
21
+ LMDeviceException,
22
+ LMPacket,
23
+ ValueType,
24
+ )
25
+ from .devices import AR4, AR4M, X8, X8M
26
+ from .utils import configure_logger, device_logger, digital_to_physical, physical_to_digital
27
+
28
+ __all__ = [
29
+ "__version__",
30
+ "Hub",
31
+ "LMDevice",
32
+ "LMPacket",
33
+ "ValueType",
34
+ "AR4",
35
+ "AR4M",
36
+ "X8",
37
+ "X8M",
38
+ "LMDeviceException",
39
+ "DeviceConnectionError",
40
+ "AcquisitionError",
41
+ "DLLLoadError",
42
+ "configure_logger",
43
+ "device_logger",
44
+ "digital_to_physical",
45
+ "physical_to_digital",
46
+ ]
@@ -0,0 +1,14 @@
1
+ """核心模块:基类与异常"""
2
+ from .base import Hub, LMDevice, LMPacket, ValueType
3
+ from .exceptions import AcquisitionError, DeviceConnectionError, DLLLoadError, LMDeviceException
4
+
5
+ __all__ = [
6
+ "Hub",
7
+ "LMDevice",
8
+ "LMPacket",
9
+ "ValueType",
10
+ "LMDeviceException",
11
+ "DeviceConnectionError",
12
+ "AcquisitionError",
13
+ "DLLLoadError",
14
+ ]