sensor-sdk 0.0.7__tar.gz → 0.0.10__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.
Potentially problematic release.
This version of sensor-sdk might be problematic. Click here for more details.
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/PKG-INFO +1 -1
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor/gforce.py +18 -11
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor/sensor_controller.py +23 -25
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor/sensor_data_context.py +40 -286
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor/sensor_device.py +6 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor/sensor_profile.py +38 -80
- sensor-sdk-0.0.10/sensor/utils.py +382 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/PKG-INFO +1 -1
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/setup.py +1 -1
- sensor-sdk-0.0.7/sensor/utils.py +0 -73
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/LICENSE.txt +0 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/README.md +0 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor/__init__.py +0 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor/sensor_data.py +0 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/SOURCES.txt +0 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/dependency_links.txt +0 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/requires.txt +0 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/top_level.txt +0 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/zip-safe +0 -0
- {sensor-sdk-0.0.7 → sensor-sdk-0.0.10}/setup.cfg +0 -0
|
@@ -397,16 +397,20 @@ class GForce:
|
|
|
397
397
|
|
|
398
398
|
if not client.is_connected:
|
|
399
399
|
return
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
400
|
+
|
|
401
|
+
try:
|
|
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
|
+
)
|
|
407
|
+
else:
|
|
408
|
+
await asyncio.wait_for(
|
|
409
|
+
client.start_notify(self.data_char, self._on_universal_response),
|
|
410
|
+
utils._TIMEOUT,
|
|
411
|
+
)
|
|
412
|
+
except Exception as e:
|
|
413
|
+
return
|
|
410
414
|
|
|
411
415
|
def _on_data_response(self, q: Queue[bytes], bs: bytearray):
|
|
412
416
|
bs = bytes(bs)
|
|
@@ -875,4 +879,7 @@ class GForce:
|
|
|
875
879
|
if not req.has_res:
|
|
876
880
|
return None
|
|
877
881
|
|
|
878
|
-
|
|
882
|
+
try:
|
|
883
|
+
return await asyncio.wait_for(q.get(), utils._TIMEOUT)
|
|
884
|
+
except Exception as e:
|
|
885
|
+
return None
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
from concurrent.futures import ThreadPoolExecutor
|
|
2
3
|
import threading
|
|
3
4
|
from typing import Callable, Dict, List, Optional, Tuple
|
|
@@ -7,9 +8,8 @@ import bleak
|
|
|
7
8
|
from sensor import sensor_profile
|
|
8
9
|
from sensor import utils
|
|
9
10
|
from sensor.sensor_profile import DeviceStateEx, SensorProfile
|
|
10
|
-
import asyncio
|
|
11
11
|
|
|
12
|
-
from sensor.utils import async_call,
|
|
12
|
+
from sensor.utils import async_call, sync_call, async_exec
|
|
13
13
|
from bleak import (
|
|
14
14
|
BleakScanner,
|
|
15
15
|
AdvertisementData,
|
|
@@ -27,6 +27,7 @@ class SensorController:
|
|
|
27
27
|
with SensorController._instance_lock:
|
|
28
28
|
if not hasattr(SensorController, "_instance"):
|
|
29
29
|
SensorController._instance = object.__new__(cls)
|
|
30
|
+
|
|
30
31
|
return SensorController._instance
|
|
31
32
|
|
|
32
33
|
"""
|
|
@@ -37,21 +38,8 @@ class SensorController:
|
|
|
37
38
|
"""
|
|
38
39
|
初始化 SensorController 实例。
|
|
39
40
|
"""
|
|
40
|
-
self._event_loop = asyncio.new_event_loop()
|
|
41
|
-
self._event_thread = threading.Thread(target=start_loop, args=(self._event_loop,))
|
|
42
|
-
self._event_thread.daemon = True
|
|
43
|
-
self._event_thread.name = "SensorController event"
|
|
44
|
-
self._event_thread.start()
|
|
45
|
-
self._gforce_event_loop = asyncio.new_event_loop()
|
|
46
|
-
self._gforce_event_thread = threading.Thread(target=start_loop, args=(self._gforce_event_loop,))
|
|
47
|
-
self._gforce_event_thread.daemon = True
|
|
48
|
-
self._gforce_event_thread.name = "BLE operation"
|
|
49
|
-
self._gforce_event_thread.start()
|
|
50
|
-
self._scanner = BleakScanner(
|
|
51
|
-
detection_callback=self._match_device,
|
|
52
|
-
service_uuids=[SERVICE_GUID, RFSTAR_SERVICE_GUID],
|
|
53
|
-
)
|
|
54
41
|
self._is_scanning = False
|
|
42
|
+
self._scanner: BleakScanner = None
|
|
55
43
|
self._device_callback: Callable[[List[sensor_profile.BLEDevice]], None] = None
|
|
56
44
|
self._device_callback_period = 0
|
|
57
45
|
self._enable_callback: Callable[[bool], None] = None
|
|
@@ -62,15 +50,16 @@ class SensorController:
|
|
|
62
50
|
反初始化 SensorController 类的实例。
|
|
63
51
|
|
|
64
52
|
"""
|
|
65
|
-
self._event_loop.close()
|
|
66
|
-
self._gforce_event_loop.close()
|
|
67
53
|
|
|
68
54
|
def terminate(self):
|
|
69
55
|
utils._terminated = True
|
|
56
|
+
|
|
70
57
|
for sensor in self._sensor_profiles.values():
|
|
71
58
|
if sensor.deviceState == DeviceStateEx.Connected or sensor.deviceState == DeviceStateEx.Ready:
|
|
72
59
|
sensor._destroy()
|
|
73
60
|
|
|
61
|
+
utils.Terminate()
|
|
62
|
+
|
|
74
63
|
def _match_device(self, _device: bleak.BLEDevice, adv: AdvertisementData):
|
|
75
64
|
if _device.name == None:
|
|
76
65
|
return False
|
|
@@ -150,15 +139,23 @@ class SensorController:
|
|
|
150
139
|
if deviceMap.get(mac) != None:
|
|
151
140
|
devices.append(self._sensor_profiles[mac].BLEDevice)
|
|
152
141
|
else:
|
|
153
|
-
newSensor = SensorProfile(device, adv, mac
|
|
142
|
+
newSensor = SensorProfile(device, adv, mac)
|
|
154
143
|
deviceMap[mac] = newSensor
|
|
155
144
|
devices.append(newSensor.BLEDevice)
|
|
156
145
|
|
|
157
146
|
self._sensor_profiles = deviceMap
|
|
158
147
|
return devices
|
|
159
148
|
|
|
149
|
+
def _init_scan(self):
|
|
150
|
+
if self._scanner == None:
|
|
151
|
+
self._scanner = BleakScanner(
|
|
152
|
+
detection_callback=self._match_device,
|
|
153
|
+
service_uuids=[SERVICE_GUID, RFSTAR_SERVICE_GUID],
|
|
154
|
+
)
|
|
155
|
+
|
|
160
156
|
async def _async_scan(self, period):
|
|
161
157
|
self._is_scanning = True
|
|
158
|
+
self._init_scan()
|
|
162
159
|
found_devices = await self._scanner.discover(timeout=period / 1000, return_adv=True)
|
|
163
160
|
self._is_scanning = False
|
|
164
161
|
return self._process_ble_devices(found_devices)
|
|
@@ -171,7 +168,7 @@ class SensorController:
|
|
|
171
168
|
|
|
172
169
|
:return: List[sensor_profile.BLEDevice]: BLEDevice列表
|
|
173
170
|
"""
|
|
174
|
-
return sync_call(self.
|
|
171
|
+
return sync_call(self._async_scan(period))
|
|
175
172
|
|
|
176
173
|
async def asyncScan(self, period) -> List[sensor_profile.BLEDevice]:
|
|
177
174
|
"""
|
|
@@ -181,22 +178,23 @@ class SensorController:
|
|
|
181
178
|
|
|
182
179
|
:return: List[sensor_profile.BLEDevice]: BLEDevice列表
|
|
183
180
|
"""
|
|
184
|
-
return await async_call(self.
|
|
181
|
+
return await async_call(self._async_scan(period))
|
|
185
182
|
|
|
186
183
|
async def _device_scan_callback(self, devices: List[sensor_profile.BLEDevice]):
|
|
187
184
|
if self._device_callback:
|
|
188
185
|
try:
|
|
189
|
-
self._device_callback
|
|
186
|
+
asyncio.get_event_loop().run_in_executor(None, self._device_callback, devices)
|
|
190
187
|
except Exception as e:
|
|
191
188
|
print(e)
|
|
192
189
|
|
|
193
190
|
if self._is_scanning:
|
|
194
|
-
async_exec(self.
|
|
191
|
+
async_exec(self._startScan())
|
|
195
192
|
|
|
196
193
|
async def _startScan(self) -> bool:
|
|
194
|
+
self._init_scan()
|
|
197
195
|
found_devices = await self._scanner.discover(timeout=self._device_callback_period / 1000, return_adv=True)
|
|
198
196
|
devices = self._process_ble_devices(found_devices)
|
|
199
|
-
async_exec(self.
|
|
197
|
+
async_exec(self._device_scan_callback(devices))
|
|
200
198
|
|
|
201
199
|
def startScan(self, periodInMs: int) -> bool:
|
|
202
200
|
"""
|
|
@@ -212,7 +210,7 @@ class SensorController:
|
|
|
212
210
|
self._is_scanning = True
|
|
213
211
|
self._device_callback_period = periodInMs
|
|
214
212
|
|
|
215
|
-
async_exec(self.
|
|
213
|
+
async_exec(self._startScan())
|
|
216
214
|
return True
|
|
217
215
|
|
|
218
216
|
def stopScan(self) -> None:
|
|
@@ -5,13 +5,13 @@ from queue import Queue
|
|
|
5
5
|
import struct
|
|
6
6
|
from typing import Deque, List
|
|
7
7
|
|
|
8
|
+
from sensor import utils
|
|
8
9
|
from sensor.gforce import DataSubscription, GForce
|
|
9
10
|
from sensor.sensor_data import DataType, Sample, SensorData
|
|
10
11
|
|
|
11
12
|
from enum import Enum, IntEnum
|
|
12
13
|
|
|
13
14
|
from sensor.sensor_device import DeviceInfo
|
|
14
|
-
from sensor.utils import timer
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class SensorDataType(IntEnum):
|
|
@@ -228,20 +228,25 @@ class SensorProfileDataCtx:
|
|
|
228
228
|
if self.hasEEG():
|
|
229
229
|
# print("initEEG")
|
|
230
230
|
info.EegChannelCount = await self.initEEG(packageCount)
|
|
231
|
+
info.EegSampleRate = self.sensorDatas[SensorDataType.DATA_TYPE_EEG].sampleRate
|
|
231
232
|
|
|
232
233
|
if self.hasECG():
|
|
233
234
|
# print("initECG")
|
|
234
235
|
info.EcgChannelCount = await self.initECG(packageCount)
|
|
236
|
+
info.EcgSampleRate = self.sensorDatas[SensorDataType.DATA_TYPE_ECG].sampleRate
|
|
235
237
|
|
|
236
238
|
if self.hasBrth():
|
|
237
239
|
# print("initBrth")
|
|
238
240
|
info.BrthChannelCount = await self.initBrth(packageCount)
|
|
241
|
+
info.BrthSampleRate = self.sensorDatas[SensorDataType.DATA_TYPE_BRTH].sampleRate
|
|
239
242
|
|
|
240
243
|
if self.hasIMU():
|
|
241
244
|
# print("initIMU")
|
|
242
245
|
imuChannelCount = await self.initIMU(packageCount)
|
|
243
246
|
info.AccChannelCount = imuChannelCount
|
|
244
247
|
info.GyroChannelCount = imuChannelCount
|
|
248
|
+
info.AccSampleRate = self.sensorDatas[SensorDataType.DATA_TYPE_ACC].sampleRate
|
|
249
|
+
info.GyroSampleRate = self.sensorDatas[SensorDataType.DATA_TYPE_GYRO].sampleRate
|
|
245
250
|
|
|
246
251
|
self._device_info = info
|
|
247
252
|
|
|
@@ -280,14 +285,32 @@ class SensorProfileDataCtx:
|
|
|
280
285
|
await self.gForce.set_subscription(0)
|
|
281
286
|
return True
|
|
282
287
|
|
|
283
|
-
def process_data(self, buf: Queue[SensorData], sensor):
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
except Exception as e:
|
|
287
|
-
return
|
|
288
|
+
async def process_data(self, buf: Queue[SensorData], sensor, callback):
|
|
289
|
+
while self._is_running and self._rawDataBuffer.empty():
|
|
290
|
+
await asyncio.sleep(0.01)
|
|
288
291
|
|
|
289
|
-
|
|
290
|
-
|
|
292
|
+
while self._is_running and not self._rawDataBuffer.empty():
|
|
293
|
+
try:
|
|
294
|
+
data: bytes = self._rawDataBuffer.get_nowait()
|
|
295
|
+
except Exception as e:
|
|
296
|
+
continue
|
|
297
|
+
|
|
298
|
+
self._processDataPackage(data, buf, sensor)
|
|
299
|
+
self._rawDataBuffer.task_done()
|
|
300
|
+
|
|
301
|
+
while self._is_running and self.isDataTransfering and not buf.empty():
|
|
302
|
+
sensorData: SensorData = None
|
|
303
|
+
try:
|
|
304
|
+
sensorData = buf.get_nowait()
|
|
305
|
+
except Exception as e:
|
|
306
|
+
break
|
|
307
|
+
if sensorData != None and callback != None:
|
|
308
|
+
try:
|
|
309
|
+
asyncio.get_event_loop().run_in_executor(None, callback, sensor, sensorData)
|
|
310
|
+
except Exception as e:
|
|
311
|
+
print(e)
|
|
312
|
+
|
|
313
|
+
buf.task_done()
|
|
291
314
|
|
|
292
315
|
def _processDataPackage(self, data: bytes, buf: Queue[SensorData], sensor):
|
|
293
316
|
v = data[0]
|
|
@@ -366,7 +389,7 @@ class SensorProfileDataCtx:
|
|
|
366
389
|
# print(lostLog)
|
|
367
390
|
if sensor._event_loop != None and sensor._on_error_callback != None:
|
|
368
391
|
try:
|
|
369
|
-
|
|
392
|
+
asyncio.get_event_loop().run_in_executor(None, sensor._on_error_callback, sensor, lostLog)
|
|
370
393
|
except Exception as e:
|
|
371
394
|
pass
|
|
372
395
|
|
|
@@ -518,277 +541,7 @@ class SensorProfileDataCtx:
|
|
|
518
541
|
for sensorDataResult in sensorDataList:
|
|
519
542
|
buf.put(sensorDataResult)
|
|
520
543
|
|
|
521
|
-
def
|
|
522
|
-
crc8Table = [
|
|
523
|
-
0x00,
|
|
524
|
-
0x07,
|
|
525
|
-
0x0E,
|
|
526
|
-
0x09,
|
|
527
|
-
0x1C,
|
|
528
|
-
0x1B,
|
|
529
|
-
0x12,
|
|
530
|
-
0x15,
|
|
531
|
-
0x38,
|
|
532
|
-
0x3F,
|
|
533
|
-
0x36,
|
|
534
|
-
0x31,
|
|
535
|
-
0x24,
|
|
536
|
-
0x23,
|
|
537
|
-
0x2A,
|
|
538
|
-
0x2D,
|
|
539
|
-
0x70,
|
|
540
|
-
0x77,
|
|
541
|
-
0x7E,
|
|
542
|
-
0x79,
|
|
543
|
-
0x6C,
|
|
544
|
-
0x6B,
|
|
545
|
-
0x62,
|
|
546
|
-
0x65,
|
|
547
|
-
0x48,
|
|
548
|
-
0x4F,
|
|
549
|
-
0x46,
|
|
550
|
-
0x41,
|
|
551
|
-
0x54,
|
|
552
|
-
0x53,
|
|
553
|
-
0x5A,
|
|
554
|
-
0x5D,
|
|
555
|
-
0xE0,
|
|
556
|
-
0xE7,
|
|
557
|
-
0xEE,
|
|
558
|
-
0xE9,
|
|
559
|
-
0xFC,
|
|
560
|
-
0xFB,
|
|
561
|
-
0xF2,
|
|
562
|
-
0xF5,
|
|
563
|
-
0xD8,
|
|
564
|
-
0xDF,
|
|
565
|
-
0xD6,
|
|
566
|
-
0xD1,
|
|
567
|
-
0xC4,
|
|
568
|
-
0xC3,
|
|
569
|
-
0xCA,
|
|
570
|
-
0xCD,
|
|
571
|
-
0x90,
|
|
572
|
-
0x97,
|
|
573
|
-
0x9E,
|
|
574
|
-
0x99,
|
|
575
|
-
0x8C,
|
|
576
|
-
0x8B,
|
|
577
|
-
0x82,
|
|
578
|
-
0x85,
|
|
579
|
-
0xA8,
|
|
580
|
-
0xAF,
|
|
581
|
-
0xA6,
|
|
582
|
-
0xA1,
|
|
583
|
-
0xB4,
|
|
584
|
-
0xB3,
|
|
585
|
-
0xBA,
|
|
586
|
-
0xBD,
|
|
587
|
-
0xC7,
|
|
588
|
-
0xC0,
|
|
589
|
-
0xC9,
|
|
590
|
-
0xCE,
|
|
591
|
-
0xDB,
|
|
592
|
-
0xDC,
|
|
593
|
-
0xD5,
|
|
594
|
-
0xD2,
|
|
595
|
-
0xFF,
|
|
596
|
-
0xF8,
|
|
597
|
-
0xF1,
|
|
598
|
-
0xF6,
|
|
599
|
-
0xE3,
|
|
600
|
-
0xE4,
|
|
601
|
-
0xED,
|
|
602
|
-
0xEA,
|
|
603
|
-
0xB7,
|
|
604
|
-
0xB0,
|
|
605
|
-
0xB9,
|
|
606
|
-
0xBE,
|
|
607
|
-
0xAB,
|
|
608
|
-
0xAC,
|
|
609
|
-
0xA5,
|
|
610
|
-
0xA2,
|
|
611
|
-
0x8F,
|
|
612
|
-
0x88,
|
|
613
|
-
0x81,
|
|
614
|
-
0x86,
|
|
615
|
-
0x93,
|
|
616
|
-
0x94,
|
|
617
|
-
0x9D,
|
|
618
|
-
0x9A,
|
|
619
|
-
0x27,
|
|
620
|
-
0x20,
|
|
621
|
-
0x29,
|
|
622
|
-
0x2E,
|
|
623
|
-
0x3B,
|
|
624
|
-
0x3C,
|
|
625
|
-
0x35,
|
|
626
|
-
0x32,
|
|
627
|
-
0x1F,
|
|
628
|
-
0x18,
|
|
629
|
-
0x11,
|
|
630
|
-
0x16,
|
|
631
|
-
0x03,
|
|
632
|
-
0x04,
|
|
633
|
-
0x0D,
|
|
634
|
-
0x0A,
|
|
635
|
-
0x57,
|
|
636
|
-
0x50,
|
|
637
|
-
0x59,
|
|
638
|
-
0x5E,
|
|
639
|
-
0x4B,
|
|
640
|
-
0x4C,
|
|
641
|
-
0x45,
|
|
642
|
-
0x42,
|
|
643
|
-
0x6F,
|
|
644
|
-
0x68,
|
|
645
|
-
0x61,
|
|
646
|
-
0x66,
|
|
647
|
-
0x73,
|
|
648
|
-
0x74,
|
|
649
|
-
0x7D,
|
|
650
|
-
0x7A,
|
|
651
|
-
0x89,
|
|
652
|
-
0x8E,
|
|
653
|
-
0x87,
|
|
654
|
-
0x80,
|
|
655
|
-
0x95,
|
|
656
|
-
0x92,
|
|
657
|
-
0x9B,
|
|
658
|
-
0x9C,
|
|
659
|
-
0xB1,
|
|
660
|
-
0xB6,
|
|
661
|
-
0xBF,
|
|
662
|
-
0xB8,
|
|
663
|
-
0xAD,
|
|
664
|
-
0xAA,
|
|
665
|
-
0xA3,
|
|
666
|
-
0xA4,
|
|
667
|
-
0xF9,
|
|
668
|
-
0xFE,
|
|
669
|
-
0xF7,
|
|
670
|
-
0xF0,
|
|
671
|
-
0xE5,
|
|
672
|
-
0xE2,
|
|
673
|
-
0xEB,
|
|
674
|
-
0xEC,
|
|
675
|
-
0xC1,
|
|
676
|
-
0xC6,
|
|
677
|
-
0xCF,
|
|
678
|
-
0xC8,
|
|
679
|
-
0xDD,
|
|
680
|
-
0xDA,
|
|
681
|
-
0xD3,
|
|
682
|
-
0xD4,
|
|
683
|
-
0x69,
|
|
684
|
-
0x6E,
|
|
685
|
-
0x67,
|
|
686
|
-
0x60,
|
|
687
|
-
0x75,
|
|
688
|
-
0x72,
|
|
689
|
-
0x7B,
|
|
690
|
-
0x7C,
|
|
691
|
-
0x51,
|
|
692
|
-
0x56,
|
|
693
|
-
0x5F,
|
|
694
|
-
0x58,
|
|
695
|
-
0x4D,
|
|
696
|
-
0x4A,
|
|
697
|
-
0x43,
|
|
698
|
-
0x44,
|
|
699
|
-
0x19,
|
|
700
|
-
0x1E,
|
|
701
|
-
0x17,
|
|
702
|
-
0x10,
|
|
703
|
-
0x05,
|
|
704
|
-
0x02,
|
|
705
|
-
0x0B,
|
|
706
|
-
0x0C,
|
|
707
|
-
0x21,
|
|
708
|
-
0x26,
|
|
709
|
-
0x2F,
|
|
710
|
-
0x28,
|
|
711
|
-
0x3D,
|
|
712
|
-
0x3A,
|
|
713
|
-
0x33,
|
|
714
|
-
0x34,
|
|
715
|
-
0x4E,
|
|
716
|
-
0x49,
|
|
717
|
-
0x40,
|
|
718
|
-
0x47,
|
|
719
|
-
0x52,
|
|
720
|
-
0x55,
|
|
721
|
-
0x5C,
|
|
722
|
-
0x5B,
|
|
723
|
-
0x76,
|
|
724
|
-
0x71,
|
|
725
|
-
0x78,
|
|
726
|
-
0x7F,
|
|
727
|
-
0x6A,
|
|
728
|
-
0x6D,
|
|
729
|
-
0x64,
|
|
730
|
-
0x63,
|
|
731
|
-
0x3E,
|
|
732
|
-
0x39,
|
|
733
|
-
0x30,
|
|
734
|
-
0x37,
|
|
735
|
-
0x22,
|
|
736
|
-
0x25,
|
|
737
|
-
0x2C,
|
|
738
|
-
0x2B,
|
|
739
|
-
0x06,
|
|
740
|
-
0x01,
|
|
741
|
-
0x08,
|
|
742
|
-
0x0F,
|
|
743
|
-
0x1A,
|
|
744
|
-
0x1D,
|
|
745
|
-
0x14,
|
|
746
|
-
0x13,
|
|
747
|
-
0xAE,
|
|
748
|
-
0xA9,
|
|
749
|
-
0xA0,
|
|
750
|
-
0xA7,
|
|
751
|
-
0xB2,
|
|
752
|
-
0xB5,
|
|
753
|
-
0xBC,
|
|
754
|
-
0xBB,
|
|
755
|
-
0x96,
|
|
756
|
-
0x91,
|
|
757
|
-
0x98,
|
|
758
|
-
0x9F,
|
|
759
|
-
0x8A,
|
|
760
|
-
0x8D,
|
|
761
|
-
0x84,
|
|
762
|
-
0x83,
|
|
763
|
-
0xDE,
|
|
764
|
-
0xD9,
|
|
765
|
-
0xD0,
|
|
766
|
-
0xD7,
|
|
767
|
-
0xC2,
|
|
768
|
-
0xC5,
|
|
769
|
-
0xCC,
|
|
770
|
-
0xCB,
|
|
771
|
-
0xE6,
|
|
772
|
-
0xE1,
|
|
773
|
-
0xE8,
|
|
774
|
-
0xEF,
|
|
775
|
-
0xFA,
|
|
776
|
-
0xFD,
|
|
777
|
-
0xF4,
|
|
778
|
-
0xF3,
|
|
779
|
-
]
|
|
780
|
-
crc8 = 0
|
|
781
|
-
len_data = len(data)
|
|
782
|
-
|
|
783
|
-
for i in range(len_data):
|
|
784
|
-
crc8 ^= data[i]
|
|
785
|
-
crc8 = crc8Table[crc8]
|
|
786
|
-
|
|
787
|
-
return crc8
|
|
788
|
-
|
|
789
|
-
async def processUniversalData(
|
|
790
|
-
self, buf: Queue[SensorData], event_loop: asyncio.AbstractEventLoop, cmd_loop: asyncio.AbstractEventLoop, sensor, callback
|
|
791
|
-
):
|
|
544
|
+
async def processUniversalData(self, buf: Queue[SensorData], sensor, callback):
|
|
792
545
|
|
|
793
546
|
while self._is_running:
|
|
794
547
|
while self._is_running and self._rawDataBuffer.empty():
|
|
@@ -820,7 +573,7 @@ class SensorProfileDataCtx:
|
|
|
820
573
|
index += 1
|
|
821
574
|
continue
|
|
822
575
|
crc = self._concatDataBuffer[index + 1 + n + 1]
|
|
823
|
-
calc_crc =
|
|
576
|
+
calc_crc = utils.calc_crc8(self._concatDataBuffer[index + 2 : index + 2 + n])
|
|
824
577
|
if crc != calc_crc:
|
|
825
578
|
index += 1
|
|
826
579
|
continue
|
|
@@ -833,9 +586,9 @@ class SensorProfileDataCtx:
|
|
|
833
586
|
sensorData = buf.get_nowait()
|
|
834
587
|
except Exception as e:
|
|
835
588
|
break
|
|
836
|
-
if
|
|
589
|
+
if sensorData != None and callback != None:
|
|
837
590
|
try:
|
|
838
|
-
|
|
591
|
+
asyncio.get_event_loop().run_in_executor(None, callback, sensor, sensorData)
|
|
839
592
|
except Exception as e:
|
|
840
593
|
print(e)
|
|
841
594
|
|
|
@@ -851,13 +604,12 @@ class SensorProfileDataCtx:
|
|
|
851
604
|
index += 1
|
|
852
605
|
continue
|
|
853
606
|
crc = self._concatDataBuffer[index + 1 + n + 1]
|
|
854
|
-
calc_crc =
|
|
607
|
+
calc_crc = utils.calc_crc8(self._concatDataBuffer[index + 2 : index + 2 + n])
|
|
855
608
|
if crc != calc_crc:
|
|
856
609
|
index += 1
|
|
857
610
|
continue
|
|
858
611
|
data_package = bytes(self._concatDataBuffer[index + 2 : index + 2 + n])
|
|
859
|
-
|
|
860
|
-
cmd_loop.call_soon_threadsafe(self.gForce._on_cmd_response, None, data_package)
|
|
612
|
+
asyncio.get_event_loop().run_in_executor(None, self.gForce._on_cmd_response, None, data_package)
|
|
861
613
|
last_cut = index = index + 2 + n
|
|
862
614
|
|
|
863
615
|
else:
|
|
@@ -865,3 +617,5 @@ class SensorProfileDataCtx:
|
|
|
865
617
|
|
|
866
618
|
if last_cut > 0:
|
|
867
619
|
self._concatDataBuffer = self._concatDataBuffer[last_cut + 1 :]
|
|
620
|
+
last_cut = -1
|
|
621
|
+
index = 0
|
|
@@ -40,11 +40,17 @@ class DeviceInfo:
|
|
|
40
40
|
self.HardwareVersion = ""
|
|
41
41
|
self.FirmwareVersion = ""
|
|
42
42
|
self.EmgChannelCount = 0
|
|
43
|
+
self.EmgSampleRate = 0
|
|
43
44
|
self.EegChannelCount = 0
|
|
45
|
+
self.EegSampleRate = 0
|
|
44
46
|
self.EcgChannelCount = 0
|
|
47
|
+
self.EcgSampleRate = 0
|
|
45
48
|
self.AccChannelCount = 0
|
|
49
|
+
self.AccSampleRate = 0
|
|
46
50
|
self.GyroChannelCount = 0
|
|
51
|
+
self.GyroSampleRate = 0
|
|
47
52
|
self.BrthChannelCount = 0
|
|
53
|
+
self.BrthSampleRate = 0
|
|
48
54
|
self.MTUSize = 0
|
|
49
55
|
|
|
50
56
|
|