qlsdk2 0.6.0a4__tar.gz → 0.6.0a5__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.0a4 → qlsdk2-0.6.0a5}/PKG-INFO +1 -1
  2. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/setup.py +1 -1
  3. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/command/__init__.py +1 -1
  4. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/device/base.py +5 -1
  5. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/device/c256_rs.py +3 -0
  6. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/paradigm.py +124 -4
  7. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk2.egg-info/PKG-INFO +1 -1
  8. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/README.md +0 -0
  9. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/setup.cfg +0 -0
  10. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/__init__.py +0 -0
  11. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/ar4/__init__.py +0 -0
  12. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/ar4m/__init__.py +0 -0
  13. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/__init__.py +0 -0
  14. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/crc/__init__.py +0 -0
  15. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/crc/crctools.py +0 -0
  16. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/device.py +0 -0
  17. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/entity/__init__.py +0 -0
  18. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/exception.py +0 -0
  19. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/filter/__init__.py +0 -0
  20. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/filter/norch.py +0 -0
  21. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/local.py +0 -0
  22. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/message/__init__.py +0 -0
  23. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/message/command.py +0 -0
  24. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/message/tcp.py +0 -0
  25. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/message/udp.py +0 -0
  26. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/network/__init__.py +0 -0
  27. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/network/monitor.py +0 -0
  28. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/core/utils.py +0 -0
  29. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/entity/__init__.py +0 -0
  30. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/entity/message.py +0 -0
  31. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/entity/signal.py +0 -0
  32. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/interface/__init__.py +0 -0
  33. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/interface/analyzer.py +0 -0
  34. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/interface/collector.py +0 -0
  35. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/interface/device.py +0 -0
  36. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/interface/parser.py +0 -0
  37. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/interface/stimulator.py +0 -0
  38. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/interface/store.py +0 -0
  39. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/persist/__init__.py +0 -0
  40. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/persist/ars_edf.py +0 -0
  41. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/persist/edf.py +0 -0
  42. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/persist/rsc_edf.py +0 -0
  43. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/persist/stream.py +0 -0
  44. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/__init__.py +0 -0
  45. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/device/__init__.py +0 -0
  46. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/device/arskindling.py +0 -0
  47. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/device/c16_rs.py +0 -0
  48. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/device/c64_rs.py +0 -0
  49. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/device/c64s1.py +0 -0
  50. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/device/device_factory.py +0 -0
  51. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/eegion.py +0 -0
  52. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/entity.py +0 -0
  53. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/interface/__init__.py +0 -0
  54. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/interface/command.py +0 -0
  55. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/interface/device.py +0 -0
  56. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/interface/handler.py +0 -0
  57. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/interface/parser.py +0 -0
  58. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/manager/__init__.py +0 -0
  59. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/manager/container.py +0 -0
  60. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/manager/search.py +0 -0
  61. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/network/__init__.py +0 -0
  62. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/network/discover.py +0 -0
  63. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/parser/__init__.py +0 -0
  64. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/parser/base-new.py +0 -0
  65. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/parser/base.py +0 -0
  66. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/parser/rsc.py +0 -0
  67. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/rsc/proxy.py +0 -0
  68. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/sdk/__init__.py +0 -0
  69. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/sdk/ar4sdk.py +0 -0
  70. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/sdk/hub.py +0 -0
  71. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/sdk/libs/libAr4SDK.dll +0 -0
  72. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/sdk/libs/libwinpthread-1.dll +0 -0
  73. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/x8/__init__.py +0 -0
  74. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk/x8m/__init__.py +0 -0
  75. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk2.egg-info/SOURCES.txt +0 -0
  76. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk2.egg-info/dependency_links.txt +0 -0
  77. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk2.egg-info/requires.txt +0 -0
  78. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/src/qlsdk2.egg-info/top_level.txt +0 -0
  79. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/test/test.222.py +0 -0
  80. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/test/test.py +0 -0
  81. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/test/test_ar4m.py +0 -0
  82. {qlsdk2-0.6.0a4 → qlsdk2-0.6.0a5}/test/test_bdf.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qlsdk2
3
- Version: 0.6.0a4
3
+ Version: 0.6.0a5
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.0a4",
9
+ version="0.6.0a5",
10
10
  author="hehuajun",
11
11
  author_email="hehuajun@eegion.com",
12
12
  description="SDK for quanlan device",
@@ -233,7 +233,7 @@ class StartStimulationCommand(DeviceCommand):
233
233
  cmd_code = 0x48C
234
234
  cmd_desc = "启动刺激"
235
235
  def pack_body(self):
236
- return self.device.stim_paradigm.to_bytes()
236
+ return self.device.get_stim_param()
237
237
  # return bytes.fromhex('01000000000000008813000000000000010000000000000000000140420f00640064000000803f0000010000000000000000000000000000000000000000008813000000000000')
238
238
  def parse_body(self, body: bytes):
239
239
  # time - 8B
@@ -9,6 +9,7 @@ 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
11
  from qlsdk.rsc.command import StartImpedanceCommand, StopImpedanceCommand, StartStimulationCommand, StopStimulationCommand, SetAcquisitionParamCommand, StartAcquisitionCommand, StopAcquisitionCommand
12
+ from qlsdk.rsc.paradigm import StimulationParadigm
12
13
  from qlsdk.rsc.parser.base import TcpMessageParser
13
14
 
14
15
  class QLBaseDevice(IDevice):
@@ -91,7 +92,7 @@ class QLBaseDevice(IDevice):
91
92
  ]
92
93
  }
93
94
 
94
- self.stim_paradigm = None
95
+ self.stim_paradigm: StimulationParadigm = None
95
96
 
96
97
  signal_info = {
97
98
  "param" : None,
@@ -389,6 +390,9 @@ class QLBaseDevice(IDevice):
389
390
  t = Thread(target=self._stop_stimulation_trigger, args=(self.stim_paradigm.duration,), daemon=True)
390
391
  t.start()
391
392
 
393
+ def get_stim_param(self) -> bytes:
394
+ return self.stim_paradigm.to_bytes()
395
+
392
396
  def _stop_stimulation_trigger(self, duration):
393
397
  delay = duration
394
398
  while delay > 0:
@@ -225,6 +225,9 @@ class C256RS(QLBaseDevice):
225
225
  t = Thread(target=self._stop_stimulation_trigger, args=(self.stim_paradigm.duration,))
226
226
  t.start()
227
227
 
228
+ def get_stim_param(self) -> bytes:
229
+ return self.stim_paradigm.to_bytes_c256()
230
+
228
231
  def _stop_stimulation_trigger(self, duration):
229
232
  delay = duration
230
233
  while delay > 0:
@@ -61,6 +61,22 @@ class StimulationChannel(ABC):
61
61
 
62
62
  return result
63
63
 
64
+ def to_bytes_c256(self):
65
+ result = self.channel_id.to_bytes(1, 'little')
66
+ result += self.wave_form.to_bytes(1, 'little')
67
+
68
+ result += self._to_bytes_c256()
69
+
70
+ result += int(self.delay_time).to_bytes(4, 'little')
71
+ result += int(self.ramp_up * 1000).to_bytes(4, 'little')
72
+ result += int((self.duration + self.ramp_up) * 1000).to_bytes(4, 'little')
73
+ result += int(self.ramp_down * 1000).to_bytes(4, 'little')
74
+
75
+ return result
76
+
77
+ def _to_bytes_c256(self):
78
+ return bytes.fromhex("00000000000000000000000000000000000000000000000000000000")
79
+
64
80
  def _ext_bytes(self):
65
81
  return bytes.fromhex("00000000000000000000000000000000")
66
82
 
@@ -99,6 +115,9 @@ class DCStimulation(StimulationChannel):
99
115
  "delay_time": self.delay_time
100
116
  }
101
117
 
118
+ def _to_bytes_c256(self):
119
+ return int(self.current_max * 1000 ).to_bytes(2, 'little') + bytes.fromhex("0000000000000000000000000000000000000000000000000000")
120
+
102
121
  def from_json(self, param):
103
122
  pass
104
123
  def __str__(self):
@@ -140,9 +159,19 @@ class SquareWaveStimulation(StimulationChannel):
140
159
  result += int((self.duration + self.ramp_up) * 1000).to_bytes(4, 'little')
141
160
  result += int(self.ramp_down * 1000).to_bytes(4, 'little')
142
161
 
143
- return result
144
-
145
- # 刺激模式-交流
162
+ return result
163
+
164
+ def _to_bytes_c256(self):
165
+ result = int(self.current_max * 1000000 ).to_bytes(4, 'little')
166
+ result += int(self.frequency).to_bytes(2, 'little')
167
+ result += bytes.fromhex("0000")
168
+ result += struct.pack('<f', self.duty_cycle)
169
+ result = int(self.current_min * 1000000 ).to_bytes(4, 'little')
170
+ result += self._ext_bytes()
171
+ return result
172
+
173
+
174
+ # 刺激模式-正弦
146
175
  class ACStimulation(StimulationChannel):
147
176
  '''
148
177
  channel_id: int, 通道编号,从0开始
@@ -177,6 +206,15 @@ class ACStimulation(StimulationChannel):
177
206
 
178
207
  def from_json(self, param):
179
208
  pass
209
+
210
+ def _to_bytes_c256(self):
211
+ result = int(self.current_max * 1000 ).to_bytes(2, 'little')
212
+ result += bytes.fromhex("0000")
213
+ result += struct.pack('<f', self.frequency)
214
+ result += struct.pack('<f', self.phase_position)
215
+ result += self._ext_bytes()
216
+ return result
217
+
180
218
  def __str__(self):
181
219
  return f"ACStimulation(channel_id={self.channel_id}, waveform={self.waveform}, current={self.current_max}, duration={self.duration}, ramp_up={self.ramp_up}, ramp_down={self.ramp_down}, frequency={self.frequency}, phase_position={self.phase_position}, duration_delay={self.duration_delay})"
182
220
 
@@ -230,6 +268,15 @@ class PulseStimulation(StimulationChannel):
230
268
 
231
269
  return result
232
270
 
271
+ def _to_bytes_c256(self):
272
+ result = int(self.current_max * 1000000 ).to_bytes(4, 'little')
273
+ result += int(self.frequency).to_bytes(2, 'little')
274
+ result += bytes.fromhex("0000")
275
+ result += struct.pack('<f', self.duty_cycle)
276
+ result = int(self.current_min * 1000000 ).to_bytes(4, 'little')
277
+ result += self._ext_bytes()
278
+ return result
279
+
233
280
  def to_json(self):
234
281
  return {
235
282
  "channel_id": self.channel_id,
@@ -287,6 +334,17 @@ class StimulationParadigm(object):
287
334
  result += channel.to_bytes()
288
335
  return result
289
336
 
337
+ def to_bytes_c256(self):
338
+ result = to_bytes(list(self.channels.keys()), 256)
339
+ result += int(self.duration * 1000).to_bytes(4, 'little')
340
+ result += int(self.interval_time).to_bytes(4, 'little')
341
+ result += int(self.characteristic).to_bytes(4, 'little')
342
+ result += int(self.mode).to_bytes(1, 'little')
343
+ result += int(self.repeats).to_bytes(4, 'little')
344
+ for channel in self.channels.values():
345
+ result += channel.to_bytes()
346
+ return result
347
+
290
348
  def to_json(self):
291
349
  # Convert the object to JSON for transmission
292
350
  return {
@@ -306,8 +364,70 @@ class StimulationParadigm(object):
306
364
  def clear(self):
307
365
  self.channels = None
308
366
  self.duration = None
309
- self.interval_time = 0
367
+ self.interval_time = 25000
310
368
  self.characteristic = 1
311
369
  self.mode = 0
312
370
  self.repeats = 0
313
371
 
372
+
373
+ # 刺激范式
374
+ class C256StimulationParadigm(object):
375
+ def __init__(self):
376
+ self.channels = None
377
+ self.duration = None
378
+ self.interval_time = 0
379
+ self.characteristic = 1
380
+ self.mode = 0
381
+ self.repeats = 0
382
+
383
+ def add_channel(self, channel: StimulationChannel, update=False):
384
+ if self.channels is None:
385
+ self.channels = {}
386
+ channel_id = channel.channel_id + 1
387
+ if channel_id in self.channels.keys():
388
+ logger.warning(f"Channel {channel_id} already exists")
389
+ if update:
390
+ self.channels[channel_id] = channel
391
+ else:
392
+ self.channels[channel_id] = channel
393
+
394
+ # 计算刺激时间
395
+ duration = channel.duration + channel.ramp_up + channel.ramp_down
396
+ if self.duration is None or duration > self.duration:
397
+ self.duration = duration
398
+
399
+
400
+ def to_bytes(self):
401
+ result = to_bytes(list(self.channels.keys()), 64)
402
+ result += int(self.duration * 1000).to_bytes(4, 'little')
403
+ result += int(self.interval_time).to_bytes(4, 'little')
404
+ result += int(self.characteristic).to_bytes(4, 'little')
405
+ result += int(self.mode).to_bytes(1, 'little')
406
+ result += int(self.repeats).to_bytes(4, 'little')
407
+ for channel in self.channels.values():
408
+ result += channel.to_bytes()
409
+ return result
410
+
411
+ def to_json(self):
412
+ # Convert the object to JSON for transmission
413
+ return {
414
+ "channels": list(self.channels.keys()),
415
+ "duration": self.duration,
416
+ "interval_time": self.interval_time,
417
+ "characteristic": self.characteristic,
418
+ "mode": self.mode,
419
+ "repeats": self.repeats,
420
+ "stim": [channel.to_json() for channel in self.channels.values()]
421
+ }
422
+
423
+ # @staticmethod
424
+ # def from_json(param: Dict[str, Any]):
425
+ # pass
426
+
427
+ def clear(self):
428
+ self.channels = None
429
+ self.duration = None
430
+ self.interval_time = 0
431
+ self.characteristic = 1
432
+ self.mode = 0
433
+ self.repeats = 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qlsdk2
3
- Version: 0.6.0a4
3
+ Version: 0.6.0a5
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
File without changes
File without changes