sensor-sdk 0.0.3__py3-none-any.whl → 0.0.5__py3-none-any.whl

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.

Potentially problematic release.


This version of sensor-sdk might be problematic. Click here for more details.

sensor/gforce.py CHANGED
@@ -16,6 +16,8 @@ from bleak import (
16
16
  BleakGATTCharacteristic,
17
17
  )
18
18
 
19
+ from sensor import utils
20
+
19
21
 
20
22
  @dataclass
21
23
  class Characteristic:
@@ -146,15 +148,15 @@ class DataSubscription(IntEnum):
146
148
  LOG = (0x00000800,)
147
149
 
148
150
  DNF_EEG = (0x00010000,)
149
-
151
+
150
152
  DNF_ECG = (0x00020000,)
151
-
153
+
152
154
  DNF_IMPEDANCE = (0x00040000,)
153
-
155
+
154
156
  DNF_IMU = (0x00080000,)
155
-
157
+
156
158
  DNF_ADS = (0x00100000,)
157
-
159
+
158
160
  DNF_BRTH = (0x00200000,)
159
161
 
160
162
  DNF_CONCAT_BLE = (0x80000000,)
@@ -181,8 +183,8 @@ class DataType(IntEnum):
181
183
 
182
184
  class SampleResolution(IntEnum):
183
185
  BITS_8 = (8,)
184
- BITS_12 = 12,
185
- BITS_16 = 16,
186
+ BITS_12 = (12,)
187
+ BITS_16 = (16,)
186
188
  BITS_24 = 24
187
189
 
188
190
 
@@ -215,6 +217,7 @@ class EmgRawDataConfig:
215
217
  )
216
218
  return cls(fs, channel_mask, batch_len, resolution)
217
219
 
220
+
218
221
  @dataclass
219
222
  class EegRawDataConfig:
220
223
  fs: SamplingRate = 0
@@ -240,6 +243,7 @@ class EegRawDataConfig:
240
243
  )
241
244
  return cls(fs, channel_mask, batch_len, resolution, K)
242
245
 
246
+
243
247
  @dataclass
244
248
  class EegRawDataCap:
245
249
  fs: SamplingRate = 0
@@ -262,7 +266,8 @@ class EegRawDataCap:
262
266
  data,
263
267
  )
264
268
  return cls(fs, channel_count, batch_len, resolution)
265
-
269
+
270
+
266
271
  @dataclass
267
272
  class EcgRawDataConfig:
268
273
  fs: SamplingRate = SamplingRate.HZ_250
@@ -287,7 +292,8 @@ class EcgRawDataConfig:
287
292
  data,
288
293
  )
289
294
  return cls(fs, channel_mask, batch_len, resolution, K)
290
-
295
+
296
+
291
297
  @dataclass
292
298
  class ImuRawDataConfig:
293
299
  channel_count: int = 0
@@ -295,6 +301,7 @@ class ImuRawDataConfig:
295
301
  batch_len: int = 0
296
302
  accK: float = 0
297
303
  gyroK: float = 0
304
+
298
305
  def to_bytes(self) -> bytes:
299
306
  body = b""
300
307
  body += struct.pack("<i", self.channel_count)
@@ -311,7 +318,8 @@ class ImuRawDataConfig:
311
318
  data,
312
319
  )
313
320
  return cls(channel_count, fs, batch_len, accK, gyroK)
314
-
321
+
322
+
315
323
  @dataclass
316
324
  class BrthRawDataConfig:
317
325
  fs: SamplingRate = 0
@@ -336,7 +344,8 @@ class BrthRawDataConfig:
336
344
  data,
337
345
  )
338
346
  return cls(fs, channel_mask, batch_len, resolution, K)
339
-
347
+
348
+
340
349
  @dataclass
341
350
  class Request:
342
351
  cmd: Command
@@ -361,7 +370,9 @@ class Response:
361
370
 
362
371
 
363
372
  class GForce:
364
- def __init__(self, device: BLEDevice, cmd_char: str, data_char: str, isUniversalStream: bool):
373
+ def __init__(
374
+ self, device: BLEDevice, cmd_char: str, data_char: str, isUniversalStream: bool
375
+ ):
365
376
  self.device_name = ""
366
377
  self.client = None
367
378
  self.cmd_char = cmd_char
@@ -371,21 +382,33 @@ class GForce:
371
382
  self._num_channels = 8
372
383
  self._device = device
373
384
  self._is_universal_stream = isUniversalStream
374
- self._raw_data_buf:queue.Queue[bytes] = None
385
+ self._raw_data_buf: queue.Queue[bytes] = None
375
386
  self.packet_id = 0
376
387
  self.data_packet = []
377
388
 
378
389
  async def connect(self, disconnect_cb, buf: queue.Queue[bytes]):
379
390
  client = BleakClient(self._device, disconnected_callback=disconnect_cb)
380
- await client.connect()
381
-
382
391
  self.client = client
383
392
  self.device_name = self._device.name
384
393
  self._raw_data_buf = buf
385
- if (not self._is_universal_stream):
386
- await client.start_notify(self.cmd_char,self._on_cmd_response)
394
+
395
+ try:
396
+ await asyncio.wait_for(client.connect(), utils._TIMEOUT)
397
+ except Exception as e:
398
+ return
399
+
400
+ if not client.is_connected:
401
+ return
402
+ if not self._is_universal_stream:
403
+ await asyncio.wait_for(
404
+ client.start_notify(self.cmd_char, self._on_cmd_response),
405
+ utils._TIMEOUT,
406
+ )
387
407
  else:
388
- await client.start_notify(self.data_char,self._on_universal_response)
408
+ await asyncio.wait_for(
409
+ client.start_notify(self.data_char, self._on_universal_response),
410
+ utils._TIMEOUT,
411
+ )
389
412
 
390
413
  def _on_data_response(self, q: Queue[bytes], bs: bytearray):
391
414
  bs = bytes(bs)
@@ -537,6 +560,7 @@ class GForce:
537
560
  num_channels = 6
538
561
 
539
562
  return emg_gesture_data.reshape(-1, num_channels)
563
+
540
564
  def _on_universal_response(self, _: BleakGATTCharacteristic, bs: bytearray):
541
565
  self._raw_data_buf.put_nowait(bytes(bs))
542
566
 
@@ -675,7 +699,6 @@ class GForce:
675
699
  )
676
700
  )
677
701
 
678
-
679
702
  async def system_reset(self):
680
703
  await self._send_request(
681
704
  Request(
@@ -684,11 +707,8 @@ class GForce:
684
707
  )
685
708
  )
686
709
 
687
-
688
710
  async def set_motor(self, switchStatus):
689
- body = [
690
- switchStatus == True
691
- ]
711
+ body = [switchStatus == True]
692
712
  body = bytes(body)
693
713
  ret = await self._send_request(
694
714
  Request(
@@ -699,9 +719,7 @@ class GForce:
699
719
  )
700
720
 
701
721
  async def set_led(self, switchStatus):
702
- body = [
703
- switchStatus == True
704
- ]
722
+ body = [switchStatus == True]
705
723
  body = bytes(body)
706
724
  ret = await self._send_request(
707
725
  Request(
@@ -712,9 +730,7 @@ class GForce:
712
730
  )
713
731
 
714
732
  async def set_log_level(self, logLevel):
715
- body = [
716
- 0xFF & logLevel
717
- ]
733
+ body = [0xFF & logLevel]
718
734
  body = bytes(body)
719
735
  ret = await self._send_request(
720
736
  Request(
@@ -724,7 +740,6 @@ class GForce:
724
740
  )
725
741
  )
726
742
 
727
-
728
743
  async def set_emg_raw_data_config(self, cfg=EmgRawDataConfig()):
729
744
  body = cfg.to_bytes()
730
745
  await self._send_request(
@@ -757,7 +772,7 @@ class GForce:
757
772
  )
758
773
  )
759
774
  return EmgRawDataConfig.from_bytes(buf)
760
-
775
+
761
776
  async def get_eeg_raw_data_config(self) -> EegRawDataConfig:
762
777
  buf = await self._send_request(
763
778
  Request(
@@ -766,7 +781,7 @@ class GForce:
766
781
  )
767
782
  )
768
783
  return EegRawDataConfig.from_bytes(buf)
769
-
784
+
770
785
  async def get_eeg_raw_data_cap(self) -> EegRawDataCap:
771
786
  buf = await self._send_request(
772
787
  Request(
@@ -784,7 +799,7 @@ class GForce:
784
799
  )
785
800
  )
786
801
  return EcgRawDataConfig.from_bytes(buf)
787
-
802
+
788
803
  async def get_imu_raw_data_config(self) -> ImuRawDataConfig:
789
804
  buf = await self._send_request(
790
805
  Request(
@@ -792,8 +807,8 @@ class GForce:
792
807
  has_res=True,
793
808
  )
794
809
  )
795
- return ImuRawDataConfig.from_bytes(buf)
796
-
810
+ return ImuRawDataConfig.from_bytes(buf)
811
+
797
812
  async def get_brth_raw_data_config(self) -> BrthRawDataConfig:
798
813
  buf = await self._send_request(
799
814
  Request(
@@ -801,8 +816,8 @@ class GForce:
801
816
  has_res=True,
802
817
  )
803
818
  )
804
- return BrthRawDataConfig.from_bytes(buf)
805
-
819
+ return BrthRawDataConfig.from_bytes(buf)
820
+
806
821
  async def set_subscription(self, subscription: DataSubscription):
807
822
  body = [
808
823
  0xFF & subscription,
@@ -819,20 +834,27 @@ class GForce:
819
834
  )
820
835
  )
821
836
 
822
- async def start_streaming(self, q:queue.Queue):
823
- await self.client.start_notify(
824
- self.data_char,
825
- lambda _, data: self._on_data_response(q, data),
837
+ async def start_streaming(self, q: queue.Queue):
838
+ await asyncio.wait_for(
839
+ self.client.start_notify(
840
+ self.data_char,
841
+ lambda _, data: self._on_data_response(q, data),
842
+ ),
843
+ utils._TIMEOUT,
826
844
  )
827
845
 
828
846
  async def stop_streaming(self):
829
847
  exceptions = []
830
848
  try:
831
- await self.set_subscription(DataSubscription.OFF)
849
+ await asyncio.wait_for(
850
+ self.set_subscription(DataSubscription.OFF), utils._TIMEOUT
851
+ )
832
852
  except Exception as e:
833
853
  exceptions.append(e)
834
854
  try:
835
- await self.client.stop_notify(self.data_char)
855
+ await asyncio.wait_for(
856
+ self.client.stop_notify(self.data_char), utils._TIMEOUT
857
+ )
836
858
  except Exception as e:
837
859
  exceptions.append(e)
838
860
 
@@ -841,7 +863,10 @@ class GForce:
841
863
 
842
864
  async def disconnect(self):
843
865
  with suppress(asyncio.CancelledError):
844
- await self.client.disconnect()
866
+ try:
867
+ await asyncio.wait_for(self.client.disconnect(), utils._TIMEOUT)
868
+ except Exception as e:
869
+ pass
845
870
 
846
871
  def _get_response_channel(self, cmd: Command) -> Queue:
847
872
  q = Queue()
@@ -856,9 +881,11 @@ class GForce:
856
881
  bs = bytes([req.cmd])
857
882
  if req.body is not None:
858
883
  bs += req.body
859
- await self.client.write_gatt_char(self.cmd_char, bs)
884
+ await asyncio.wait_for(
885
+ self.client.write_gatt_char(self.cmd_char, bs), utils._TIMEOUT
886
+ )
860
887
 
861
888
  if not req.has_res:
862
889
  return None
863
890
 
864
- return await asyncio.wait_for(q.get(), 3)
891
+ return await asyncio.wait_for(q.get(), utils._TIMEOUT)
@@ -5,24 +5,28 @@ from typing import Callable, Dict, List, Optional, Tuple
5
5
  import bleak
6
6
 
7
7
  from sensor import sensor_profile
8
+ from sensor import utils
8
9
  from sensor.sensor_profile import DeviceStateEx, SensorProfile
9
10
  import asyncio
10
11
 
11
- from sensor.utils import start_loop, sync_timer, timer
12
+ from sensor.utils import async_timer, start_loop, sync_timer, timer
12
13
  from bleak import (
13
14
  BleakScanner,
14
15
  AdvertisementData,
15
16
  )
17
+
16
18
  SERVICE_GUID = "0000ffd0-0000-1000-8000-00805f9b34fb"
17
19
  RFSTAR_SERVICE_GUID = "00001812-0000-1000-8000-00805f9b34fb"
18
20
 
21
+
19
22
  class SensorController:
20
23
  _instance_lock = threading.Lock()
24
+
21
25
  def __new__(cls, *args, **kwargs):
22
26
  if not hasattr(SensorController, "_instance"):
23
27
  with SensorController._instance_lock:
24
28
  if not hasattr(SensorController, "_instance"):
25
- SensorController._instance = object.__new__(cls)
29
+ SensorController._instance = object.__new__(cls)
26
30
  return SensorController._instance
27
31
 
28
32
  """
@@ -34,16 +38,23 @@ class SensorController:
34
38
  初始化 SensorController 实例。
35
39
  """
36
40
  self._event_loop = asyncio.new_event_loop()
37
- self._event_thread = threading.Thread(target=start_loop, args=(self._event_loop,))
41
+ self._event_thread = threading.Thread(
42
+ target=start_loop, args=(self._event_loop,)
43
+ )
38
44
  self._event_thread.daemon = True
39
45
  self._event_thread.name = "SensorController event"
40
46
  self._event_thread.start()
41
47
  self._gforce_event_loop = asyncio.new_event_loop()
42
- self._gforce_event_thread = threading.Thread(target=start_loop, args=(self._gforce_event_loop,))
48
+ self._gforce_event_thread = threading.Thread(
49
+ target=start_loop, args=(self._gforce_event_loop,)
50
+ )
43
51
  self._gforce_event_thread.daemon = True
44
52
  self._gforce_event_thread.name = "BLE operation"
45
53
  self._gforce_event_thread.start()
46
- self._scanner = BleakScanner(detection_callback=self._match_device,service_uuids=[SERVICE_GUID,RFSTAR_SERVICE_GUID])
54
+ self._scanner = BleakScanner(
55
+ detection_callback=self._match_device,
56
+ service_uuids=[SERVICE_GUID, RFSTAR_SERVICE_GUID],
57
+ )
47
58
  self._is_scanning = False
48
59
  self._device_callback: Callable[[List[sensor_profile.BLEDevice]], None] = None
49
60
  self._device_callback_period = 0
@@ -59,18 +70,19 @@ class SensorController:
59
70
  self._gforce_event_loop.close()
60
71
 
61
72
  def terminate(self):
73
+ utils._terminated = True
62
74
  for sensor in self._sensor_profiles.values():
63
- if sensor.deviceState == DeviceStateEx.Connected or sensor.deviceState == DeviceStateEx.Ready:
75
+ if (
76
+ sensor.deviceState == DeviceStateEx.Connected
77
+ or sensor.deviceState == DeviceStateEx.Ready
78
+ ):
64
79
  sensor._destroy()
65
-
66
80
 
67
81
  def _match_device(self, _device: bleak.BLEDevice, adv: AdvertisementData):
68
82
  if _device.name == None:
69
83
  return False
70
84
 
71
- if (
72
- SERVICE_GUID in adv.service_uuids
73
- ):
85
+ if SERVICE_GUID in adv.service_uuids:
74
86
  print("Device found: {0}, RSSI: {1}".format(_device.name, adv.rssi))
75
87
  return True
76
88
 
@@ -113,7 +125,9 @@ class SensorController:
113
125
  return self._device_callback != None
114
126
 
115
127
  @hasDeviceFoundCallback.setter
116
- def onDeviceFoundCallback(self, callback: Callable[[List[sensor_profile.BLEDevice]], None]):
128
+ def onDeviceFoundCallback(
129
+ self, callback: Callable[[List[sensor_profile.BLEDevice]], None]
130
+ ):
117
131
  """
118
132
  设置扫描设备回调。
119
133
 
@@ -121,29 +135,82 @@ class SensorController:
121
135
  """
122
136
  self._device_callback = callback
123
137
 
124
- async def _device_scan_callback(self, found_devices: Dict[str, Tuple[bleak.BLEDevice, AdvertisementData]]):
138
+ def _process_ble_devices(
139
+ self, found_devices: Dict[str, Tuple[bleak.BLEDevice, AdvertisementData]]
140
+ ) -> List[sensor_profile.BLEDevice]:
141
+ devices: List[sensor_profile.BLEDevice] = list()
142
+ deviceMap: Dict[str, SensorProfile] = self._sensor_profiles.copy()
143
+ for uuid in found_devices:
144
+ device = found_devices[uuid][0]
145
+ if device.name == None:
146
+ continue
147
+ adv = found_devices[uuid][1]
148
+ if SERVICE_GUID in adv.service_uuids:
149
+ mac = None
150
+ if adv.service_data.get(SERVICE_GUID) != None:
151
+ bytes_val = adv.service_data[SERVICE_GUID]
152
+ mac = ":".join(f"{byte:02X}" for byte in bytes_val)
153
+ elif adv.service_data.get(RFSTAR_SERVICE_GUID) != None:
154
+ bytes_val = adv.service_data[RFSTAR_SERVICE_GUID]
155
+ mac = ":".join(f"{byte:02X}" for byte in reversed(bytes_val))
156
+
157
+ if mac == None:
158
+ continue
159
+ if deviceMap.get(mac) != None:
160
+ devices.append(self._sensor_profiles[mac].BLEDevice)
161
+ else:
162
+ newSensor = SensorProfile(device, adv, mac, self._gforce_event_loop)
163
+ deviceMap[mac] = newSensor
164
+ devices.append(newSensor.BLEDevice)
165
+
166
+ self._sensor_profiles = deviceMap
167
+ return devices
168
+
169
+ async def _async_scan(self, period):
170
+ self._is_scanning = True
171
+ found_devices = await self._scanner.discover(
172
+ timeout=period / 1000, return_adv=True
173
+ )
174
+ self._is_scanning = False
175
+ return self._process_ble_devices(found_devices)
176
+
177
+ def scan(self, period) -> List[sensor_profile.BLEDevice]:
178
+ """
179
+ 扫描一段时间后返回BLEDevice列表。
180
+
181
+ :param periodInMs (int): 扫描时长(毫秒)
182
+
183
+ :return: List[sensor_profile.BLEDevice]: BLEDevice列表
184
+ """
185
+ return sync_timer(self._gforce_event_loop, 0, self._async_scan(period))
186
+
187
+ async def asyncScan(self, period) -> List[sensor_profile.BLEDevice]:
188
+ """
189
+ 扫描一段时间后返回BLEDevice列表。
190
+
191
+ :param periodInMs (int): 扫描时长(毫秒)
192
+
193
+ :return: List[sensor_profile.BLEDevice]: BLEDevice列表
194
+ """
195
+ return await async_timer(self._gforce_event_loop, 0, self._async_scan(period))
196
+
197
+ async def _device_scan_callback(self, devices: List[sensor_profile.BLEDevice]):
125
198
  if self._device_callback:
126
- devices:List[sensor_profile.BLEDevice] = list()
127
- deviceMap :Dict[str, SensorProfile] = self._sensor_profiles.copy()
128
- for mac in found_devices:
129
- device = found_devices[mac][0]
130
- adv = found_devices[mac][1]
131
- if SERVICE_GUID in adv.service_uuids:
132
- if deviceMap.get(mac) != None:
133
- devices.append(self._sensor_profiles[mac].BLEDevice)
134
- else:
135
- newSensor = SensorProfile(device, adv,self._gforce_event_loop)
136
- deviceMap[mac] = newSensor
137
- devices.append(newSensor.BLEDevice)
138
- self._sensor_profiles = deviceMap
139
- self._device_callback(devices)
199
+ try:
200
+ self._device_callback(devices)
201
+ except Exception as e:
202
+ print(e)
140
203
 
141
204
  if self._is_scanning:
142
205
  timer(self._gforce_event_loop, 0, self._startScan())
143
206
 
144
207
  async def _startScan(self) -> bool:
145
- devices = await self._scanner.discover(timeout=self._device_callback_period / 1000, return_adv=True)
208
+ found_devices = await self._scanner.discover(
209
+ timeout=self._device_callback_period / 1000, return_adv=True
210
+ )
211
+ devices = self._process_ble_devices(found_devices)
146
212
  timer(self._event_loop, 0, self._device_scan_callback(devices))
213
+
147
214
  def startScan(self, periodInMs: int) -> bool:
148
215
  """
149
216
  开始扫描。
@@ -152,12 +219,12 @@ class SensorController:
152
219
 
153
220
  :return: bool: 扫描是否成功启动
154
221
  """
155
- if (self._is_scanning):
222
+ if self._is_scanning:
156
223
  return True
157
-
224
+
158
225
  self._is_scanning = True
159
226
  self._device_callback_period = periodInMs
160
-
227
+
161
228
  timer(self._gforce_event_loop, 0, self._startScan())
162
229
  return True
163
230
 
@@ -165,12 +232,14 @@ class SensorController:
165
232
  """
166
233
  停止扫描。
167
234
  """
168
- if (not self._is_scanning):
169
- return
170
-
235
+ if not self._is_scanning:
236
+ return
237
+
171
238
  self._is_scanning = False
172
239
 
173
- def requireSensor(self, device: sensor_profile.BLEDevice) -> Optional[SensorProfile]:
240
+ def requireSensor(
241
+ self, device: sensor_profile.BLEDevice
242
+ ) -> Optional[SensorProfile]:
174
243
  """
175
244
  根据设备信息获取或创建SensorProfile。
176
245
 
@@ -200,9 +269,12 @@ class SensorController:
200
269
 
201
270
  :return: List[SensorProfile]: 已连接的SensorProfile列表
202
271
  """
203
- sensors:List[SensorProfile] = list()
272
+ sensors: List[SensorProfile] = list()
204
273
  for sensor in self._sensor_profiles.values():
205
- if sensor.deviceState == DeviceStateEx.Connected or sensor.deviceState == DeviceStateEx.Ready:
274
+ if (
275
+ sensor.deviceState == DeviceStateEx.Connected
276
+ or sensor.deviceState == DeviceStateEx.Ready
277
+ ):
206
278
  sensors.append(sensor)
207
279
 
208
280
  return sensors
@@ -213,11 +285,15 @@ class SensorController:
213
285
 
214
286
  :return: List[BLEDevice]: 已连接的蓝牙设备列表
215
287
  """
216
- devices:List[sensor_profile.BLEDevice] = list()
288
+ devices: List[sensor_profile.BLEDevice] = list()
217
289
  for sensor in self._sensor_profiles.values():
218
- if sensor.deviceState == DeviceStateEx.Connected or sensor.deviceState == DeviceStateEx.Ready:
290
+ if (
291
+ sensor.deviceState == DeviceStateEx.Connected
292
+ or sensor.deviceState == DeviceStateEx.Ready
293
+ ):
219
294
  devices.append(sensor.BLEDevice)
220
295
 
221
296
  return devices
222
297
 
298
+
223
299
  SensorControllerInstance = SensorController()
sensor/sensor_data.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from enum import Enum, IntEnum
2
2
  from typing import Dict, List
3
3
 
4
+
4
5
  # 一个采样数据
5
6
  # 该类用于存储单个采样数据的相关信息,包括数据值、阻抗、饱和度、采样索引和是否丢包的标志
6
7
  class Sample:
@@ -14,34 +15,36 @@ class Sample:
14
15
  # :param is_lost: 是否丢包的标志,True 表示丢包,False 表示正常
15
16
  # """
16
17
  # def __init__(self, data: int, impedance: int, saturation: int, sample_index: int, is_lost: bool):
17
- # self.data = data
18
- # self.impedance = impedance
19
- # self.saturation = saturation
20
- # self.sampleIndex = sample_index
21
- # self.isLost = is_lost
18
+ # self.data = data
19
+ # self.impedance = impedance
20
+ # self.saturation = saturation
21
+ # self.sampleIndex = sample_index
22
+ # self.isLost = is_lost
22
23
 
23
24
  def __init__(self):
24
25
  self.rawData = 0
25
- self.data = 0
26
- self.impedance = 0
27
- self.saturation = 0
28
- self.sampleIndex = 0
29
- self.isLost = False
26
+ self.data = 0
27
+ self.impedance = 0
28
+ self.saturation = 0
29
+ self.sampleIndex = 0
30
+ self.isLost = False
30
31
  self.timeStampInMs = 0
31
32
  self.channelIndex = 0
32
33
  self.sampleIndex = 0
33
34
 
35
+
34
36
  # 对应 DataType 枚举
35
37
  # 该枚举类定义了不同类型的数据,用于区分传感器采集的不同类型的数据
36
38
  class DataType(IntEnum):
37
- NTF_ACC = 0x1 # 加速度,用于标识加速度传感器采集的数据
38
- NTF_GYRO = 0x2 # 陀螺仪,用于标识陀螺仪传感器采集的数据
39
- NTF_EEG = 0x10 # EEG,用于标识脑电传感器采集的数据
40
- NTF_ECG = 0x11 # ECG,用于标识心电传感器采集的数据
41
- NTF_IMPEDANCE = 0x12, # 阻抗数据
42
- NTF_IMU = 0x13, # 包含ACC和GYRO数据
43
- NTF_ADS = 0x14, # 无单位ads数据
44
- NTF_BRTH = 0x15 # 呼吸,用于标识呼吸传感器采集的数据
39
+ NTF_ACC = 0x1 # 加速度,用于标识加速度传感器采集的数据
40
+ NTF_GYRO = 0x2 # 陀螺仪,用于标识陀螺仪传感器采集的数据
41
+ NTF_EEG = 0x10 # EEG,用于标识脑电传感器采集的数据
42
+ NTF_ECG = 0x11 # ECG,用于标识心电传感器采集的数据
43
+ NTF_IMPEDANCE = (0x12,) # 阻抗数据
44
+ NTF_IMU = (0x13,) # 包含ACC和GYRO数据
45
+ NTF_ADS = (0x14,) # 无单位ads数据
46
+ NTF_BRTH = 0x15 # 呼吸,用于标识呼吸传感器采集的数据
47
+
45
48
 
46
49
  # 一次采样的数据,包含多个通道的数据,channal_samples 为一个二维数组, 第一个维度为通道索引,第二个维度为采样索引
47
50
  # 该类用于存储一次采样的完整数据,包括设备 MAC 地址、数据类型、采样率、通道数量、包中采样数量以及通道采样数据
@@ -55,35 +58,35 @@ class SensorData:
55
58
  # :param channel_count: The number of channels in the data.
56
59
  # :param package_sample_count: The number of samples in the package.
57
60
  # :param channel_samples: A list of lists containing the sample data for each channel.
58
- # """
61
+ # """
59
62
  # def __init__(self, device_mac: str, data_type: DataType, sample_rate: int, channel_count: int,
60
63
  # package_sample_count: int, channel_samples: List[List[Sample]]):
61
- # self.deviceMac = device_mac
62
- # self.dataType = data_type
63
- # self.sampleRate = sample_rate
64
- # self.channelCount = channel_count
65
- # self.packageSampleCount = package_sample_count
66
- # self.channelSamples = channel_samples
64
+ # self.deviceMac = device_mac
65
+ # self.dataType = data_type
66
+ # self.sampleRate = sample_rate
67
+ # self.channelCount = channel_count
68
+ # self.packageSampleCount = package_sample_count
69
+ # self.channelSamples = channel_samples
67
70
  # self.lastPackageCounter = 0
68
- # self.lastPackageIndex = 0
69
- # self.resolutionBits = 0
70
- # self.channelMask = 0
71
- # self.minPackageSampleCount = 0
72
- # self.K = 0
71
+ # self.lastPackageIndex = 0
72
+ # self.resolutionBits = 0
73
+ # self.channelMask = 0
74
+ # self.minPackageSampleCount = 0
75
+ # self.K = 0
73
76
 
74
77
  def __init__(self):
75
- self.deviceMac = ""
76
- self.dataType = DataType.NTF_EEG
77
- self.sampleRate = 0
78
- self.channelCount = 0
79
- self.packageSampleCount = 0
80
- self.channelSamples:List[List[Sample]] = list()
78
+ self.deviceMac = ""
79
+ self.dataType = DataType.NTF_EEG
80
+ self.sampleRate = 0
81
+ self.channelCount = 0
82
+ self.packageSampleCount = 0
83
+ self.channelSamples: List[List[Sample]] = list()
81
84
  self.lastPackageCounter = 0
82
- self.lastPackageIndex = 0
83
- self.resolutionBits = 0
84
- self.channelMask = 0
85
- self.minPackageSampleCount = 0
86
- self.K = 0
85
+ self.lastPackageIndex = 0
86
+ self.resolutionBits = 0
87
+ self.channelMask = 0
88
+ self.minPackageSampleCount = 0
89
+ self.K = 0
87
90
 
88
91
  def clear(self):
89
92
  self.channelSamples.clear()