qlsdk2 0.6.0a11__tar.gz → 0.6.0a13__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 (82) hide show
  1. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/PKG-INFO +1 -1
  2. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/setup.py +1 -1
  3. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/entity/__init__.py +13 -19
  4. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/command/__init__.py +18 -5
  5. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/device/arskindling.py +19 -2
  6. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/device/base.py +68 -48
  7. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/interface/device.py +7 -0
  8. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk2.egg-info/PKG-INFO +1 -1
  9. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/README.md +0 -0
  10. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/setup.cfg +0 -0
  11. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/__init__.py +0 -0
  12. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/ar4/__init__.py +0 -0
  13. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/ar4m/__init__.py +0 -0
  14. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/__init__.py +0 -0
  15. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/crc/__init__.py +0 -0
  16. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/crc/crctools.py +0 -0
  17. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/device.py +0 -0
  18. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/exception.py +0 -0
  19. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/filter/__init__.py +0 -0
  20. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/filter/norch.py +0 -0
  21. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/local.py +0 -0
  22. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/message/__init__.py +0 -0
  23. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/message/command.py +0 -0
  24. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/message/tcp.py +0 -0
  25. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/message/udp.py +0 -0
  26. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/network/__init__.py +0 -0
  27. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/network/monitor.py +0 -0
  28. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/core/utils.py +0 -0
  29. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/entity/__init__.py +0 -0
  30. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/entity/message.py +0 -0
  31. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/entity/signal.py +0 -0
  32. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/interface/__init__.py +0 -0
  33. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/interface/analyzer.py +0 -0
  34. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/interface/collector.py +0 -0
  35. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/interface/device.py +0 -0
  36. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/interface/parser.py +0 -0
  37. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/interface/stimulator.py +0 -0
  38. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/interface/store.py +0 -0
  39. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/persist/__init__.py +0 -0
  40. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/persist/ars_edf.py +0 -0
  41. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/persist/edf.py +0 -0
  42. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/persist/rsc_edf.py +0 -0
  43. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/persist/stream.py +0 -0
  44. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/__init__.py +0 -0
  45. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/device/__init__.py +0 -0
  46. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/device/c16_rs.py +0 -0
  47. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/device/c256_rs.py +0 -0
  48. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/device/c64_rs.py +0 -0
  49. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/device/c64s1.py +0 -0
  50. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/device/device_factory.py +0 -0
  51. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/eegion.py +0 -0
  52. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/entity.py +0 -0
  53. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/interface/__init__.py +0 -0
  54. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/interface/command.py +0 -0
  55. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/interface/handler.py +0 -0
  56. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/interface/parser.py +0 -0
  57. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/manager/__init__.py +0 -0
  58. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/manager/container.py +0 -0
  59. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/manager/search.py +0 -0
  60. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/network/__init__.py +0 -0
  61. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/network/discover.py +0 -0
  62. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/paradigm.py +0 -0
  63. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/parser/__init__.py +0 -0
  64. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/parser/base-new.py +0 -0
  65. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/parser/base.py +0 -0
  66. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/parser/rsc.py +0 -0
  67. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/rsc/proxy.py +0 -0
  68. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/sdk/__init__.py +0 -0
  69. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/sdk/ar4sdk.py +0 -0
  70. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/sdk/hub.py +0 -0
  71. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/sdk/libs/libAr4SDK.dll +0 -0
  72. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/sdk/libs/libwinpthread-1.dll +0 -0
  73. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/x8/__init__.py +0 -0
  74. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk/x8m/__init__.py +0 -0
  75. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk2.egg-info/SOURCES.txt +0 -0
  76. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk2.egg-info/dependency_links.txt +0 -0
  77. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk2.egg-info/requires.txt +0 -0
  78. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/src/qlsdk2.egg-info/top_level.txt +0 -0
  79. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/test/test.222.py +0 -0
  80. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/test/test.py +0 -0
  81. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/test/test_ar4m.py +0 -0
  82. {qlsdk2-0.6.0a11 → qlsdk2-0.6.0a13}/test/test_bdf.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qlsdk2
3
- Version: 0.6.0a11
3
+ Version: 0.6.0a13
4
4
  Summary: SDK for quanlan device
5
5
  Home-page: https://github.com/hehuajun/qlsdk
6
6
  Author: hehuajun
@@ -6,7 +6,7 @@ with open("README.md", "r", encoding='utf-8' ) as fh:
6
6
 
7
7
  setuptools.setup(
8
8
  name="qlsdk2",
9
- version="0.6.0a11",
9
+ version="0.6.0a13",
10
10
  author="hehuajun",
11
11
  author_email="hehuajun@eegion.com",
12
12
  description="SDK for quanlan device",
@@ -56,19 +56,13 @@ class RscPacket(Packet):
56
56
  return packet
57
57
 
58
58
  def __str__(self):
59
- return f"""
60
- time_stamp: {self.time_stamp}
61
- pkg_id: {self.pkg_id}
62
- origin_sample_rate: {self.origin_sample_rate}
63
- sample_rate: {self.sample_rate}
64
- sample_num: {self.sample_num}
65
- resolution: {self.resolution}
66
- filter: {self.filter}
67
- channels: {self.channels}
68
- data len: {self.data_len}
69
- trigger: {self.trigger}
70
- eeg: {self.eeg}
71
- """
59
+ return f"""[
60
+ "time_stamp": {self.time_stamp}
61
+ "pkg_id": {self.pkg_id}
62
+ "channels": {self.channels}
63
+ "trigger": {self.trigger}
64
+ "eeg": {self.eeg}
65
+ ]"""
72
66
 
73
67
  class ImpedancePacket(Packet):
74
68
  def __init__(self):
@@ -97,12 +91,12 @@ class ImpedancePacket(Packet):
97
91
  return packet
98
92
 
99
93
  def __str__(self):
100
- return f"""
101
- time_stamp: {self.time_stamp}
102
- pkg_id: {self.pkg_id}
103
- channels: {self.channels}
104
- impedance: {self.impedance}
105
- """
94
+ return f"""[
95
+ "time_stamp": {self.time_stamp}
96
+ "pkg_id": {self.pkg_id}
97
+ "channels": {self.channels}
98
+ "impedance": {self.impedance}
99
+ ]"""
106
100
 
107
101
 
108
102
  class C256RSPacket(Packet):
@@ -48,8 +48,9 @@ class DeviceCommand(abc.ABC):
48
48
  """构建消息体"""
49
49
  return b''
50
50
  def pack_header(self, body_len: int) -> bytes:
51
- device_id = int(self.device.device_id) if self.device and self.device.device_id else 0
51
+ # device_id = int(self.device.device_id) if self.device and self.device.device_id else 0
52
52
  device_type = int(self.device.device_type) if self.device and self.device.device_type else 0
53
+ device_id = bytes.fromhex(self.device.device_id)[::-1] if self.device.device_id else bytes.fromhex('00000000')
53
54
 
54
55
  #兼容设计
55
56
  b_device_type = None
@@ -61,7 +62,7 @@ class DeviceCommand(abc.ABC):
61
62
  DeviceCommand.HEADER_PREFIX
62
63
  + int(2).to_bytes(1, 'little') # pkgType
63
64
  + device_type.to_bytes(1, 'little')
64
- + device_id.to_bytes(4, 'little')
65
+ + device_id
65
66
  + (DeviceCommand.HEADER_LEN + body_len + 2).to_bytes(4, 'little') # +1 for checksum
66
67
  + self.cmd_code.to_bytes(2, 'little')
67
68
  )
@@ -204,6 +205,15 @@ class StopAcquisitionCommand(DeviceCommand):
204
205
  class SetImpedanceParamCommand(DeviceCommand):
205
206
  cmd_code = 0x411
206
207
  cmd_desc = "设置阻抗测量参数"
208
+ def pack_body(self):
209
+
210
+ return self.device.gen_set_impedance_param()
211
+ def parse_body(self, body):
212
+ result = body[8]
213
+ if result == 0x00:
214
+ logger.info("阻抗测量参数设置成功")
215
+ else:
216
+ logger.warning(f"阻抗测量参数设置失败: {int(result)}")
207
217
 
208
218
  # 启动阻抗测量
209
219
  class StartImpedanceCommand(DeviceCommand):
@@ -211,13 +221,16 @@ class StartImpedanceCommand(DeviceCommand):
211
221
  cmd_desc = "启动阻抗测量"
212
222
  def pack_body(self):
213
223
  body = bytes.fromhex('0000')
214
- body += to_bytes(self.device.acq_channels)
224
+ body += to_bytes(self.device.get_impedance_channels())
215
225
  body += bytes.fromhex('0000000000000000') # 8字节占位符
216
226
  return body
217
227
 
218
228
  def parse_body(self, body):
219
- logger.info(f"Received StartImpedance response: {body.hex()}")
220
- return super().parse_body(body)
229
+ result = body[8]
230
+ if result == 0x00:
231
+ logger.info("阻抗测量启动成功")
232
+ else:
233
+ logger.warning(f"阻抗测量启动失败: {int(result)}")
221
234
 
222
235
 
223
236
  # 停止阻抗测量
@@ -170,6 +170,22 @@ class ARSKindling(QLBaseDevice):
170
170
  self._sample_rate = sample_rate
171
171
  self._sample_range = sample_range
172
172
 
173
+ # 设置阻抗通道
174
+ # {'A': [1,2,3], 'B':[1,2,3]}
175
+ def set_impedance_channels(self, channels):
176
+
177
+ arr = []
178
+
179
+ # 根据映射关系做通道转换
180
+ for k in channels.keys():
181
+ if isinstance(channels[k], list):
182
+ temp = [k + str(i) for i in channels[k]]
183
+ arr += [self.channel_mapping.get(c, 1) for c in temp]
184
+ else:
185
+ arr += [k + str(channels[k])]
186
+
187
+ self._impedance_channels = arr
188
+
173
189
  @property
174
190
  def acq_channels(self):
175
191
  if self._acq_channels is None:
@@ -184,7 +200,7 @@ class ARSKindling(QLBaseDevice):
184
200
  def _produce_impedance(self, body: bytes):
185
201
  # 分发阻抗数据包给订阅者
186
202
  if len(self._impedance_consumer) > 0:
187
- packet = ImpedancePacket.transfer(body)
203
+ packet = self._impedance_wrapper(body)
188
204
  real_data = self.__impedance_transfer(packet)
189
205
  for topic, q in self._impedance_consumer.items():
190
206
  try:
@@ -222,7 +238,8 @@ class ARSKindling(QLBaseDevice):
222
238
  # 写入文件的缓存队列
223
239
  if self._signal_cache is None:
224
240
  self._signal_cache = Queue(1000000) # 缓冲队列
225
- self._signal_cache.put(real_data)
241
+ tmp = real_data
242
+ self._signal_cache.put(tmp)
226
243
 
227
244
  if len(self.signal_consumers) > 0 :
228
245
  # 订阅只返回物理值
@@ -8,11 +8,27 @@ import numpy as np
8
8
  from qlsdk.core.entity import RscPacket, ImpedancePacket
9
9
  from qlsdk.core.utils import to_bytes
10
10
  from qlsdk.rsc.interface import IDevice, IParser
11
- from qlsdk.rsc.command import StartImpedanceCommand, StopImpedanceCommand, StartStimulationCommand, StopStimulationCommand, SetAcquisitionParamCommand, StartAcquisitionCommand, StopAcquisitionCommand
11
+ from qlsdk.rsc.command import SetImpedanceParamCommand, StartImpedanceCommand, StopImpedanceCommand, StartStimulationCommand, StopStimulationCommand, SetAcquisitionParamCommand, StartAcquisitionCommand, StopAcquisitionCommand
12
12
  from qlsdk.rsc.paradigm import StimulationParadigm
13
13
  from qlsdk.rsc.parser.base import TcpMessageParser
14
14
 
15
+
16
+ def intersection_positions(A, B):
17
+ setB = set(B)
18
+ seen = set()
19
+ return [idx for idx, elem in enumerate(A)
20
+ if elem in setB and elem not in seen and not seen.add(elem)]
21
+
15
22
  class QLBaseDevice(IDevice):
23
+
24
+ __TRIGGER_MAPPING = {
25
+ 0x3E8: "Start of stimulation",
26
+ 0x3E9: "End of stimulation",
27
+ 0x3EA: "Ascending end of stimulation",
28
+ 0x3EB: "Descending start of stimulation ",
29
+ 0x3EC: "刺激参数有误",
30
+ 0x3ED: "End of stimulation (by force)",
31
+ }
16
32
  def __init__(self, socket):
17
33
  self.socket = socket
18
34
 
@@ -62,35 +78,9 @@ class QLBaseDevice(IDevice):
62
78
  "channels": [],
63
79
  }
64
80
 
65
- self._stim_param = {
66
- "stim_type": 0, # 刺激类型:0-所有通道参数相同, 1: 通道参数不同
67
- "channels": [],
68
- "param": [{
69
- "channel_id": 0, #通道号 从0开始 -- 必填
70
- "waveform": 3, #波形类型:0-直流,1-交流 2-方波 3-脉冲 -- 必填
71
- "current": 1, #电流强度(mA) -- 必填
72
- "duration": 30, #平稳阶段持续时间(s) -- 必填
73
- "ramp_up": 5, #上升时间(s) 默认0
74
- "ramp_down": 5, #下降时间(s) 默认0
75
- "frequency": 500, #频率(Hz) -- 非直流必填
76
- "phase_position": 0, #相位 -- 默认0
77
- "duration_delay": "0", #延迟启动时间(s) -- 默认0
78
- "pulse_width": 0, #脉冲宽度(us) -- 仅脉冲类型电流有效, 默认100us
79
- },
80
- {
81
- "channel_id": 1, #通道号 从0开始 -- 必填
82
- "waveform": 3, #波形类型:0-直流,1-交流 2-方波 3-脉冲 -- 必填
83
- "current": 1, #电流强度(mA) -- 必填
84
- "duration": 30, #平稳阶段持续时间(s) -- 必填
85
- "ramp_up": 5, #上升时间(s) 默认0
86
- "ramp_down": 5, #下降时间(s) 默认0
87
- "frequency": 500, #频率(Hz) -- 非直流必填
88
- "phase_position": 0, #相位 -- 默认0
89
- "duration_delay": "0", #延迟启动时间(s) -- 默认0
90
- "pulse_width": 0, #脉冲宽度(us) -- 仅脉冲类型电流有效, 默认100us
91
- }
92
- ]
93
- }
81
+ self._stim_param = None
82
+
83
+ self._impedance_channels = []
94
84
 
95
85
  self.stim_paradigm: StimulationParadigm = None
96
86
  # 信号采集状态
@@ -116,6 +106,7 @@ class QLBaseDevice(IDevice):
116
106
  self._signal_cache: Queue = None
117
107
  self._recording = False
118
108
 
109
+
119
110
  def parser(self) -> IParser:
120
111
  return self._parser
121
112
 
@@ -132,9 +123,9 @@ class QLBaseDevice(IDevice):
132
123
  self._produce_impedance(body)
133
124
 
134
125
  def _produce_impedance(self, body: bytes):
135
- packet = ImpedancePacket.transfer(body)
136
126
  # 分发阻抗数据包给订阅者
137
127
  if len(self._impedance_consumer) > 0:
128
+ packet = self._impedance_wrapper(body)
138
129
  for topic, q in self._impedance_consumer.items():
139
130
  try:
140
131
  # 队列满了就丢弃最早的数据
@@ -164,7 +155,8 @@ class QLBaseDevice(IDevice):
164
155
  # 写入文件的缓存队列
165
156
  if self._signal_cache is None:
166
157
  self._signal_cache = Queue(256 * 1024 * 1024) # 256MB缓存
167
- self._signal_cache.put(data)
158
+ tmp = data
159
+ self._signal_cache.put(tmp)
168
160
 
169
161
  if len(self.signal_consumers) > 0 :
170
162
  logger.trace(f"dg eeg: {data.eeg}")
@@ -178,7 +170,17 @@ class QLBaseDevice(IDevice):
178
170
  if q.full():
179
171
  q.get()
180
172
 
181
- q.put(data)
173
+ q.put(data)
174
+
175
+ def _impedance_wrapper(self, body: bytes):
176
+ packet = ImpedancePacket().transfer(body)
177
+ if self._impedance_channels is not None and len(self._impedance_channels) > 0:
178
+ # 只保留设置的阻抗通道
179
+ channel_pos = intersection_positions(packet.channels, self._impedance_channels)
180
+ packet.impedance = [packet.impedance[i] for i in channel_pos]
181
+ packet.channels = [packet.channels[i] for i in channel_pos]
182
+
183
+ return packet
182
184
 
183
185
  # 信号数据转换
184
186
  def _signal_wrapper(self, body: bytes):
@@ -252,6 +254,12 @@ class QLBaseDevice(IDevice):
252
254
  def device_type(self) -> int:
253
255
  return self._device_type
254
256
 
257
+ def set_impedance_channels(self, channels):
258
+ self._impedance_channels = channels
259
+
260
+ def get_impedance_channels(self):
261
+ return self._impedance_channels
262
+
255
263
  def start_message_parser(self) -> None:
256
264
  self._parser = TcpMessageParser(self)
257
265
  self._parser.start()
@@ -387,9 +395,17 @@ class QLBaseDevice(IDevice):
387
395
 
388
396
  def start_impedance(self):
389
397
  logger.info(f"[设备-{self.device_no}]启动阻抗测量")
390
- msg = StartImpedanceCommand.build(self).pack()
391
- logger.trace(f"start_impedance message is {msg.hex()}")
392
- self.socket.sendall(msg)
398
+ # 设置数据采集参数
399
+ # set_param_msg = SetImpedanceParamCommand.build(self).pack()
400
+ device_id = bytes.fromhex(self.device_id)[::-1].hex() if self.device_id else '00000000'
401
+ set_param_msg = bytes.fromhex(f'5aa50239{device_id}3f0000001104ffffffffffffffff000000000000000000000000000000000000000000000000e8030000fa00000010000164000000745c5aa50239390045243a00000012040000000000000000000000000000000000000000000000000000000000000000000001000000000000004c2a')
402
+ logger.debug(f"set_param_msg message is {set_param_msg.hex()}")
403
+ self.socket.sendall(set_param_msg)
404
+ sleep(0.5)
405
+
406
+ impedance_start_msg = StartImpedanceCommand.build(self).pack()
407
+ logger.debug(f"start_impedance message is {impedance_start_msg.hex()}")
408
+ self.socket.sendall(impedance_start_msg)
393
409
 
394
410
  def stop_impedance(self):
395
411
  logger.info(f"[设备{self.device_no}]停止阻抗测量")
@@ -493,6 +509,7 @@ class QLBaseDevice(IDevice):
493
509
  else:
494
510
  logger.info("已关闭文件记录,不会记录trigger信息")
495
511
 
512
+ # 设置信号采集参数
496
513
  def gen_set_acquirement_param(self) -> bytes:
497
514
 
498
515
  body = to_bytes(self.acq_channels)
@@ -503,7 +520,19 @@ class QLBaseDevice(IDevice):
503
520
  body += bytes.fromhex('00')
504
521
 
505
522
  return body
506
-
523
+ # 设置阻抗测量参数
524
+ def gen_set_impedance_param(self) -> bytes:
525
+
526
+ # 仅通道生效 32字节,其他不生效-272字节,实际73字节
527
+ body = to_bytes(self._impedance_channels)
528
+ # 100 bytes
529
+ # body += bytes.fromhex('00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
530
+ # # 100 bytes
531
+ # body += bytes.fromhex('00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
532
+ # 73 bytes
533
+ body += bytes.fromhex('00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
534
+
535
+ return bytes.fromhex('ffffffffffffffff000000000000000000000000000000000000000000000000e8030000fa00000010000164000000745c5aa50239390045243a0000001204000000000000000000000000000000000000000000000000000000000000000000000100000000000000')
507
536
  def disconnect(self):
508
537
  logger.info(f"[断开设备-{self.device_no}]的连接...")
509
538
  self._listening = False
@@ -522,7 +551,7 @@ class QLBaseDevice(IDevice):
522
551
  self.storage_enable = enable
523
552
 
524
553
  def trigger_info(self, code: int) -> str:
525
- return __TRIGGER_MAPPING.get(code, hex(code))
554
+ return QLBaseDevice.__TRIGGER_MAPPING.get(code, hex(code))
526
555
 
527
556
  def __str__(self):
528
557
  return f'''
@@ -543,13 +572,4 @@ class QLBaseDevice(IDevice):
543
572
  return self.device_type == other.device_type and self.device_no == other.device_no
544
573
 
545
574
  def __hash__(self):
546
- return hash((self.device_type, self.device_no))
547
-
548
- __TRIGGER_MAPPING = {
549
- 0x3E8: "Start of stimulation",
550
- 0x3E9: "End of stimulation",
551
- 0x3EA: "Ascending end of stimulation",
552
- 0x3EB: "Descending start of stimulation ",
553
- 0x3EC: "刺激参数有误",
554
- 0x3ED: "End of stimulation (by force)",
555
- }
575
+ return hash((self.device_type, self.device_no))
@@ -24,6 +24,10 @@ class IDevice(ABC):
24
24
  @property
25
25
  def device_no(self) -> str:
26
26
  pass
27
+
28
+ def set_impedance_channels(self):
29
+ raise NotImplementedError("Not Supported")
30
+
27
31
 
28
32
  def read_msg(self, size: int) -> bytes:
29
33
  raise NotImplementedError("Not Supported")
@@ -71,6 +75,9 @@ class IDevice(ABC):
71
75
  def enable_storage(self, enable: bool = True):
72
76
  pass
73
77
 
78
+ def set_impedance_channel(self):
79
+ raise NotImplementedError("Not Supported")
80
+
74
81
  def start_impedance(self):
75
82
  raise NotImplementedError("Not Supported")
76
83
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qlsdk2
3
- Version: 0.6.0a11
3
+ Version: 0.6.0a13
4
4
  Summary: SDK for quanlan device
5
5
  Home-page: https://github.com/hehuajun/qlsdk
6
6
  Author: hehuajun
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes