sensor-sdk 0.0.3__py3-none-any.whl → 0.0.4__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/sensor_controller.py +52 -26
- sensor/sensor_data.py +44 -41
- sensor/sensor_data_context.py +376 -93
- sensor/sensor_device.py +34 -34
- sensor/sensor_profile.py +121 -66
- sensor/utils.py +7 -5
- {sensor_sdk-0.0.3.dist-info → sensor_sdk-0.0.4.dist-info}/METADATA +1 -1
- sensor_sdk-0.0.4.dist-info/RECORD +14 -0
- sensor_sdk-0.0.3.dist-info/RECORD +0 -14
- {sensor_sdk-0.0.3.dist-info → sensor_sdk-0.0.4.dist-info}/LICENSE.txt +0 -0
- {sensor_sdk-0.0.3.dist-info → sensor_sdk-0.0.4.dist-info}/WHEEL +0 -0
- {sensor_sdk-0.0.3.dist-info → sensor_sdk-0.0.4.dist-info}/top_level.txt +0 -0
- {sensor_sdk-0.0.3.dist-info → sensor_sdk-0.0.4.dist-info}/zip-safe +0 -0
sensor/sensor_data_context.py
CHANGED
|
@@ -11,6 +11,7 @@ from enum import Enum, IntEnum
|
|
|
11
11
|
from sensor.sensor_device import DeviceInfo
|
|
12
12
|
from sensor.utils import timer
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
class SensorDataType(IntEnum):
|
|
15
16
|
DATA_TYPE_EEG = 0
|
|
16
17
|
DATA_TYPE_ECG = 1
|
|
@@ -19,6 +20,7 @@ class SensorDataType(IntEnum):
|
|
|
19
20
|
DATA_TYPE_BRTH = 4
|
|
20
21
|
DATA_TYPE_COUNT = 5
|
|
21
22
|
|
|
23
|
+
|
|
22
24
|
# 枚举 FeatureMaps 的 Python 实现
|
|
23
25
|
class FeatureMaps(Enum):
|
|
24
26
|
GFD_FEAT_EMG = 0x000002000
|
|
@@ -34,8 +36,8 @@ class FeatureMaps(Enum):
|
|
|
34
36
|
class SensorProfileDataCtx:
|
|
35
37
|
def __init__(self, gForce: GForce, deviceMac: str, buf: Queue[bytes]):
|
|
36
38
|
self.featureMap = 0
|
|
37
|
-
self.notifyDataFlag:DataSubscription = 0
|
|
38
|
-
|
|
39
|
+
self.notifyDataFlag: DataSubscription = 0
|
|
40
|
+
|
|
39
41
|
self.gForce = gForce
|
|
40
42
|
self.deviceMac = deviceMac
|
|
41
43
|
self._device_info: DeviceInfo = None
|
|
@@ -75,30 +77,32 @@ class SensorProfileDataCtx:
|
|
|
75
77
|
:return: bool: 如果传感器正在进行数据传输,返回 True;否则返回 False。
|
|
76
78
|
"""
|
|
77
79
|
return self._is_data_transfering
|
|
80
|
+
|
|
78
81
|
def hasInit(self):
|
|
79
82
|
return self.featureMap != 0 and self.notifyDataFlag != 0
|
|
83
|
+
|
|
80
84
|
def hasEMG(self):
|
|
81
85
|
return (self.featureMap & FeatureMaps.GFD_FEAT_EMG.value) != 0
|
|
82
86
|
|
|
83
87
|
def hasEEG(self):
|
|
84
88
|
return (self.featureMap & FeatureMaps.GFD_FEAT_EEG.value) != 0
|
|
85
|
-
|
|
89
|
+
|
|
86
90
|
def hasECG(self):
|
|
87
91
|
return (self.featureMap & FeatureMaps.GFD_FEAT_ECG.value) != 0
|
|
88
92
|
|
|
89
93
|
def hasImpedance(self):
|
|
90
94
|
return (self.featureMap & FeatureMaps.GFD_FEAT_IMPEDANCE.value) != 0
|
|
91
|
-
|
|
95
|
+
|
|
92
96
|
def hasIMU(self):
|
|
93
97
|
return (self.featureMap & FeatureMaps.GFD_FEAT_IMU.value) != 0
|
|
94
|
-
|
|
98
|
+
|
|
95
99
|
def hasBrth(self):
|
|
96
100
|
return (self.featureMap & FeatureMaps.GFD_FEAT_BRTH.value) != 0
|
|
97
101
|
|
|
98
102
|
def hasConcatBLE(self):
|
|
99
103
|
return (self.featureMap & FeatureMaps.GFD_FEAT_CONCAT_BLE.value) != 0
|
|
100
|
-
|
|
101
|
-
async def initEEG(self,packageCount:int)-> int:
|
|
104
|
+
|
|
105
|
+
async def initEEG(self, packageCount: int) -> int:
|
|
102
106
|
config = await self.gForce.get_eeg_raw_data_config()
|
|
103
107
|
cap = await self.gForce.get_eeg_raw_data_cap()
|
|
104
108
|
data = SensorData()
|
|
@@ -115,8 +119,8 @@ class SensorProfileDataCtx:
|
|
|
115
119
|
self.sensorDatas[SensorDataType.DATA_TYPE_EEG] = data
|
|
116
120
|
self.notifyDataFlag |= DataSubscription.DNF_EEG
|
|
117
121
|
return data.channelCount
|
|
118
|
-
|
|
119
|
-
async def initECG(self,packageCount:int)-> int:
|
|
122
|
+
|
|
123
|
+
async def initECG(self, packageCount: int) -> int:
|
|
120
124
|
config = await self.gForce.get_ecg_raw_data_config()
|
|
121
125
|
data = SensorData()
|
|
122
126
|
data.deviceMac = self.deviceMac
|
|
@@ -131,9 +135,9 @@ class SensorProfileDataCtx:
|
|
|
131
135
|
data.clear()
|
|
132
136
|
self.sensorDatas[SensorDataType.DATA_TYPE_ECG] = data
|
|
133
137
|
self.notifyDataFlag |= DataSubscription.DNF_ECG
|
|
134
|
-
return data.channelCount
|
|
135
|
-
|
|
136
|
-
async def initIMU(self,packageCount:int)-> int:
|
|
138
|
+
return data.channelCount
|
|
139
|
+
|
|
140
|
+
async def initIMU(self, packageCount: int) -> int:
|
|
137
141
|
config = await self.gForce.get_imu_raw_data_config()
|
|
138
142
|
data = SensorData()
|
|
139
143
|
data.deviceMac = self.deviceMac
|
|
@@ -163,9 +167,9 @@ class SensorProfileDataCtx:
|
|
|
163
167
|
|
|
164
168
|
self.notifyDataFlag |= DataSubscription.DNF_IMU
|
|
165
169
|
|
|
166
|
-
return data.channelCount
|
|
170
|
+
return data.channelCount
|
|
167
171
|
|
|
168
|
-
async def initBrth(self,packageCount:int)-> int:
|
|
172
|
+
async def initBrth(self, packageCount: int) -> int:
|
|
169
173
|
config = await self.gForce.get_brth_raw_data_config()
|
|
170
174
|
data = SensorData()
|
|
171
175
|
data.deviceMac = self.deviceMac
|
|
@@ -180,19 +184,19 @@ class SensorProfileDataCtx:
|
|
|
180
184
|
data.clear()
|
|
181
185
|
self.sensorDatas[SensorDataType.DATA_TYPE_BRTH] = data
|
|
182
186
|
self.notifyDataFlag |= DataSubscription.DNF_ECG
|
|
183
|
-
return data.channelCount
|
|
184
|
-
|
|
185
|
-
async def initDataTransfer(self,isGetFeature:bool)-> int:
|
|
186
|
-
if
|
|
187
|
-
self.featureMap =
|
|
188
|
-
if
|
|
187
|
+
return data.channelCount
|
|
188
|
+
|
|
189
|
+
async def initDataTransfer(self, isGetFeature: bool) -> int:
|
|
190
|
+
if isGetFeature:
|
|
191
|
+
self.featureMap = await self.gForce.get_feature_map()
|
|
192
|
+
if self.hasImpedance():
|
|
189
193
|
self.notifyDataFlag |= DataSubscription.DNF_IMPEDANCE
|
|
190
194
|
return self.featureMap
|
|
191
195
|
else:
|
|
192
196
|
await self.gForce.set_subscription(self.notifyDataFlag)
|
|
193
197
|
return self.notifyDataFlag
|
|
194
|
-
|
|
195
|
-
async def fetchDeviceInfo(self)->DeviceInfo:
|
|
198
|
+
|
|
199
|
+
async def fetchDeviceInfo(self) -> DeviceInfo:
|
|
196
200
|
info = DeviceInfo()
|
|
197
201
|
info.MTUSize = self.gForce.client.mtu_size
|
|
198
202
|
info.DeviceName = await self.gForce.get_device_name()
|
|
@@ -200,46 +204,46 @@ class SensorProfileDataCtx:
|
|
|
200
204
|
info.HardwareVersion = await self.gForce.get_hardware_revision()
|
|
201
205
|
info.FirmwareVersion = await self.gForce.get_firmware_revision()
|
|
202
206
|
return info
|
|
203
|
-
|
|
204
|
-
async def init(self, packageCount:int)->bool:
|
|
207
|
+
|
|
208
|
+
async def init(self, packageCount: int) -> bool:
|
|
205
209
|
try:
|
|
206
210
|
info = await self.fetchDeviceInfo()
|
|
207
|
-
|
|
211
|
+
|
|
208
212
|
await self.initDataTransfer(True)
|
|
209
213
|
|
|
210
|
-
if
|
|
214
|
+
if self.hasImpedance():
|
|
211
215
|
self.notifyDataFlag |= DataSubscription.DNF_IMPEDANCE
|
|
212
216
|
|
|
213
|
-
if
|
|
214
|
-
info.EegChannelCount = await self.initEEG(packageCount)
|
|
217
|
+
if self.hasEEG():
|
|
218
|
+
info.EegChannelCount = await self.initEEG(packageCount)
|
|
215
219
|
|
|
216
|
-
if
|
|
217
|
-
info.EcgChannelCount = await self.initECG(packageCount)
|
|
220
|
+
if self.hasECG():
|
|
221
|
+
info.EcgChannelCount = await self.initECG(packageCount)
|
|
218
222
|
|
|
219
|
-
if
|
|
220
|
-
info.BrthChannelCount = await self.initBrth(packageCount)
|
|
223
|
+
if self.hasBrth():
|
|
224
|
+
info.BrthChannelCount = await self.initBrth(packageCount)
|
|
221
225
|
|
|
222
|
-
if
|
|
226
|
+
if self.hasIMU():
|
|
223
227
|
imuChannelCount = await self.initIMU(packageCount)
|
|
224
228
|
info.AccChannelCount = imuChannelCount
|
|
225
229
|
info.GyroChannelCount = imuChannelCount
|
|
226
230
|
|
|
227
231
|
self._device_info = info
|
|
228
232
|
|
|
229
|
-
if
|
|
233
|
+
if not self.isUniversalStream:
|
|
230
234
|
await self.initDataTransfer(False)
|
|
231
235
|
|
|
232
236
|
return True
|
|
233
237
|
except Exception as e:
|
|
234
238
|
print(e)
|
|
235
239
|
return False
|
|
236
|
-
|
|
240
|
+
|
|
237
241
|
async def start_streaming(self) -> bool:
|
|
238
|
-
if
|
|
242
|
+
if self._is_data_transfering:
|
|
239
243
|
return True
|
|
240
244
|
self._is_data_transfering = True
|
|
241
245
|
self._rawDataBuffer.queue.clear()
|
|
242
|
-
if
|
|
246
|
+
if not self.isUniversalStream:
|
|
243
247
|
await self.gForce.start_streaming(self._rawDataBuffer)
|
|
244
248
|
return True
|
|
245
249
|
else:
|
|
@@ -247,12 +251,12 @@ class SensorProfileDataCtx:
|
|
|
247
251
|
return True
|
|
248
252
|
|
|
249
253
|
async def stop_streaming(self) -> bool:
|
|
250
|
-
if
|
|
254
|
+
if not self._is_data_transfering:
|
|
251
255
|
return True
|
|
252
|
-
|
|
256
|
+
|
|
253
257
|
self._is_data_transfering = False
|
|
254
258
|
|
|
255
|
-
if
|
|
259
|
+
if not self.isUniversalStream:
|
|
256
260
|
await self.gForce.stop_streaming()
|
|
257
261
|
return True
|
|
258
262
|
else:
|
|
@@ -268,7 +272,7 @@ class SensorProfileDataCtx:
|
|
|
268
272
|
self._processDataPackage(data, buf)
|
|
269
273
|
self._rawDataBuffer.task_done()
|
|
270
274
|
|
|
271
|
-
def _processDataPackage(self,data: bytes, buf: Queue[SensorData]):
|
|
275
|
+
def _processDataPackage(self, data: bytes, buf: Queue[SensorData]):
|
|
272
276
|
v = data[0]
|
|
273
277
|
if v == DataType.NTF_IMPEDANCE:
|
|
274
278
|
offset = 1
|
|
@@ -280,14 +284,14 @@ class SensorProfileDataCtx:
|
|
|
280
284
|
|
|
281
285
|
dataCount = (len(data) - 3) // 4 // 2
|
|
282
286
|
for index in range(dataCount):
|
|
283
|
-
impedance_bytes = data[offset:offset + 4]
|
|
284
|
-
impedance = int.from_bytes(impedance_bytes, byteorder=
|
|
287
|
+
impedance_bytes = data[offset : offset + 4]
|
|
288
|
+
impedance = int.from_bytes(impedance_bytes, byteorder="little")
|
|
285
289
|
offset += 4
|
|
286
290
|
impedanceData.append(impedance)
|
|
287
291
|
|
|
288
292
|
for index in range(dataCount):
|
|
289
|
-
saturation_bytes = data[offset:offset + 4]
|
|
290
|
-
saturation = int.from_bytes(saturation_bytes, byteorder=
|
|
293
|
+
saturation_bytes = data[offset : offset + 4]
|
|
294
|
+
saturation = int.from_bytes(saturation_bytes, byteorder="little")
|
|
291
295
|
offset += 4
|
|
292
296
|
saturationData.append(saturation / 10) # firmware value range 0 - 1000
|
|
293
297
|
|
|
@@ -295,34 +299,36 @@ class SensorProfileDataCtx:
|
|
|
295
299
|
self.saturationData = saturationData
|
|
296
300
|
|
|
297
301
|
elif v == DataType.NTF_EEG:
|
|
298
|
-
sensor_data = self.sensorDatas[SensorDataType.DATA_TYPE_EEG]
|
|
302
|
+
sensor_data = self.sensorDatas[SensorDataType.DATA_TYPE_EEG]
|
|
299
303
|
if self.checkReadSamples(data, sensor_data, 3, 0):
|
|
300
304
|
self.sendSensorData(sensor_data, buf)
|
|
301
305
|
elif v == DataType.NTF_ECG:
|
|
302
|
-
sensor_data = self.sensorDatas[SensorDataType.DATA_TYPE_ECG]
|
|
306
|
+
sensor_data = self.sensorDatas[SensorDataType.DATA_TYPE_ECG]
|
|
303
307
|
if self.checkReadSamples(data, sensor_data, 3, 0):
|
|
304
308
|
self.sendSensorData(sensor_data, buf)
|
|
305
309
|
elif v == DataType.NTF_BRTH:
|
|
306
|
-
sensor_data = self.sensorDatas[SensorDataType.DATA_TYPE_BRTH]
|
|
310
|
+
sensor_data = self.sensorDatas[SensorDataType.DATA_TYPE_BRTH]
|
|
307
311
|
if self.checkReadSamples(data, sensor_data, 3, 0):
|
|
308
312
|
self.sendSensorData(sensor_data, buf)
|
|
309
313
|
elif v == DataType.NTF_IMU:
|
|
310
|
-
sensor_data_acc = self.sensorDatas[SensorDataType.DATA_TYPE_ACC]
|
|
314
|
+
sensor_data_acc = self.sensorDatas[SensorDataType.DATA_TYPE_ACC]
|
|
311
315
|
if self.checkReadSamples(data, sensor_data_acc, 3, 6):
|
|
312
316
|
self.sendSensorData(sensor_data_acc, buf)
|
|
313
317
|
|
|
314
|
-
sensor_data_gyro = self.sensorDatas[SensorDataType.DATA_TYPE_GYRO]
|
|
318
|
+
sensor_data_gyro = self.sensorDatas[SensorDataType.DATA_TYPE_GYRO]
|
|
315
319
|
if self.checkReadSamples(data, sensor_data_gyro, 9, 6):
|
|
316
320
|
self.sendSensorData(sensor_data_gyro, buf)
|
|
317
321
|
|
|
318
|
-
def checkReadSamples(
|
|
322
|
+
def checkReadSamples(
|
|
323
|
+
self, data: bytes, sensorData: SensorData, dataOffset: int, dataGap: int
|
|
324
|
+
):
|
|
319
325
|
offset = 1
|
|
320
326
|
v = data[0]
|
|
321
327
|
if not self._is_data_transfering:
|
|
322
328
|
return False
|
|
323
329
|
try:
|
|
324
330
|
|
|
325
|
-
packageIndex = ((data[offset + 1] &
|
|
331
|
+
packageIndex = ((data[offset + 1] & 0xFF) << 8) | (data[offset] & 0xFF)
|
|
326
332
|
offset += 2
|
|
327
333
|
newPackageIndex = packageIndex
|
|
328
334
|
lastPackageIndex = sensorData.lastPackageIndex
|
|
@@ -334,14 +340,18 @@ class SensorProfileDataCtx:
|
|
|
334
340
|
|
|
335
341
|
deltaPackageIndex = packageIndex - lastPackageIndex
|
|
336
342
|
if deltaPackageIndex > 1:
|
|
337
|
-
lostSampleCount = sensorData.packageSampleCount * (
|
|
338
|
-
|
|
343
|
+
lostSampleCount = sensorData.packageSampleCount * (
|
|
344
|
+
deltaPackageIndex - 1
|
|
345
|
+
)
|
|
346
|
+
print(
|
|
347
|
+
f"lost dataType {sensorData.dataType} -> data {sensorData.deviceMac} {lostSampleCount}"
|
|
348
|
+
)
|
|
339
349
|
self.readSamples(data, sensorData, 0, dataGap, lostSampleCount)
|
|
340
350
|
if newPackageIndex == 0:
|
|
341
351
|
sensorData.lastPackageIndex = 65535
|
|
342
352
|
else:
|
|
343
353
|
sensorData.lastPackageIndex = newPackageIndex - 1
|
|
344
|
-
sensorData.lastPackageCounter +=
|
|
354
|
+
sensorData.lastPackageCounter += deltaPackageIndex - 1
|
|
345
355
|
|
|
346
356
|
self.readSamples(data, sensorData, dataOffset, dataGap, 0)
|
|
347
357
|
sensorData.lastPackageIndex = newPackageIndex
|
|
@@ -349,8 +359,15 @@ class SensorProfileDataCtx:
|
|
|
349
359
|
except Exception:
|
|
350
360
|
return False
|
|
351
361
|
return True
|
|
352
|
-
|
|
353
|
-
def readSamples(
|
|
362
|
+
|
|
363
|
+
def readSamples(
|
|
364
|
+
self,
|
|
365
|
+
data: bytes,
|
|
366
|
+
sensorData: SensorData,
|
|
367
|
+
offset: int,
|
|
368
|
+
dataGap: int,
|
|
369
|
+
lostSampleCount: int,
|
|
370
|
+
):
|
|
354
371
|
sampleCount = sensorData.packageSampleCount
|
|
355
372
|
sampleInterval = 1000 // sensorData.sampleRate
|
|
356
373
|
if lostSampleCount > 0:
|
|
@@ -368,13 +385,17 @@ class SensorProfileDataCtx:
|
|
|
368
385
|
channelSamples.append([])
|
|
369
386
|
|
|
370
387
|
for sampleIndex in range(sampleCount):
|
|
371
|
-
for channelIndex, impedanceChannelIndex in enumerate(
|
|
388
|
+
for channelIndex, impedanceChannelIndex in enumerate(
|
|
389
|
+
range(sensorData.channelCount)
|
|
390
|
+
):
|
|
372
391
|
if (sensorData.channelMask & (1 << channelIndex)) != 0:
|
|
373
392
|
samples = channelSamples[channelIndex]
|
|
374
393
|
impedance = 0.0
|
|
375
394
|
saturation = 0.0
|
|
376
395
|
if sensorData.dataType == DataType.NTF_ECG:
|
|
377
|
-
impedanceChannelIndex = self.sensorDatas[
|
|
396
|
+
impedanceChannelIndex = self.sensorDatas[
|
|
397
|
+
SensorDataType.DATA_TYPE_EEG
|
|
398
|
+
].channelCount
|
|
378
399
|
impedance = _impedanceData[impedanceChannelIndex]
|
|
379
400
|
saturation = _saturationData[impedanceChannelIndex]
|
|
380
401
|
impedanceChannelIndex += 1
|
|
@@ -396,10 +417,18 @@ class SensorProfileDataCtx:
|
|
|
396
417
|
rawData -= 128
|
|
397
418
|
offset += 1
|
|
398
419
|
elif sensorData.resolutionBits == 16:
|
|
399
|
-
rawData = int.from_bytes(
|
|
420
|
+
rawData = int.from_bytes(
|
|
421
|
+
data[offset : offset + 2],
|
|
422
|
+
byteorder="little",
|
|
423
|
+
signed=True,
|
|
424
|
+
)
|
|
400
425
|
offset += 2
|
|
401
426
|
elif sensorData.resolutionBits == 24:
|
|
402
|
-
rawData = (
|
|
427
|
+
rawData = (
|
|
428
|
+
(data[offset] << 16)
|
|
429
|
+
| (data[offset + 1] << 8)
|
|
430
|
+
| data[offset + 2]
|
|
431
|
+
)
|
|
403
432
|
rawData -= 8388608
|
|
404
433
|
offset += 3
|
|
405
434
|
|
|
@@ -428,7 +457,7 @@ class SensorProfileDataCtx:
|
|
|
428
457
|
if realSampleCount < sensorData.minPackageSampleCount:
|
|
429
458
|
return
|
|
430
459
|
|
|
431
|
-
sensorData.channelSamples = []
|
|
460
|
+
sensorData.channelSamples = []
|
|
432
461
|
batchCount = realSampleCount // sensorData.minPackageSampleCount
|
|
433
462
|
# leftSampleSize = realSampleCount - sensorData.minPackageSampleCount * batchCount
|
|
434
463
|
|
|
@@ -468,25 +497,264 @@ class SensorProfileDataCtx:
|
|
|
468
497
|
for sensorDataResult in sensorDataList:
|
|
469
498
|
buf.put(sensorDataResult)
|
|
470
499
|
|
|
471
|
-
|
|
472
|
-
def calc_crc8(self,data):
|
|
500
|
+
def calc_crc8(self, data):
|
|
473
501
|
crc8Table = [
|
|
474
|
-
0x00,
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
502
|
+
0x00,
|
|
503
|
+
0x07,
|
|
504
|
+
0x0E,
|
|
505
|
+
0x09,
|
|
506
|
+
0x1C,
|
|
507
|
+
0x1B,
|
|
508
|
+
0x12,
|
|
509
|
+
0x15,
|
|
510
|
+
0x38,
|
|
511
|
+
0x3F,
|
|
512
|
+
0x36,
|
|
513
|
+
0x31,
|
|
514
|
+
0x24,
|
|
515
|
+
0x23,
|
|
516
|
+
0x2A,
|
|
517
|
+
0x2D,
|
|
518
|
+
0x70,
|
|
519
|
+
0x77,
|
|
520
|
+
0x7E,
|
|
521
|
+
0x79,
|
|
522
|
+
0x6C,
|
|
523
|
+
0x6B,
|
|
524
|
+
0x62,
|
|
525
|
+
0x65,
|
|
526
|
+
0x48,
|
|
527
|
+
0x4F,
|
|
528
|
+
0x46,
|
|
529
|
+
0x41,
|
|
530
|
+
0x54,
|
|
531
|
+
0x53,
|
|
532
|
+
0x5A,
|
|
533
|
+
0x5D,
|
|
534
|
+
0xE0,
|
|
535
|
+
0xE7,
|
|
536
|
+
0xEE,
|
|
537
|
+
0xE9,
|
|
538
|
+
0xFC,
|
|
539
|
+
0xFB,
|
|
540
|
+
0xF2,
|
|
541
|
+
0xF5,
|
|
542
|
+
0xD8,
|
|
543
|
+
0xDF,
|
|
544
|
+
0xD6,
|
|
545
|
+
0xD1,
|
|
546
|
+
0xC4,
|
|
547
|
+
0xC3,
|
|
548
|
+
0xCA,
|
|
549
|
+
0xCD,
|
|
550
|
+
0x90,
|
|
551
|
+
0x97,
|
|
552
|
+
0x9E,
|
|
553
|
+
0x99,
|
|
554
|
+
0x8C,
|
|
555
|
+
0x8B,
|
|
556
|
+
0x82,
|
|
557
|
+
0x85,
|
|
558
|
+
0xA8,
|
|
559
|
+
0xAF,
|
|
560
|
+
0xA6,
|
|
561
|
+
0xA1,
|
|
562
|
+
0xB4,
|
|
563
|
+
0xB3,
|
|
564
|
+
0xBA,
|
|
565
|
+
0xBD,
|
|
566
|
+
0xC7,
|
|
567
|
+
0xC0,
|
|
568
|
+
0xC9,
|
|
569
|
+
0xCE,
|
|
570
|
+
0xDB,
|
|
571
|
+
0xDC,
|
|
572
|
+
0xD5,
|
|
573
|
+
0xD2,
|
|
574
|
+
0xFF,
|
|
575
|
+
0xF8,
|
|
576
|
+
0xF1,
|
|
577
|
+
0xF6,
|
|
578
|
+
0xE3,
|
|
579
|
+
0xE4,
|
|
580
|
+
0xED,
|
|
581
|
+
0xEA,
|
|
582
|
+
0xB7,
|
|
583
|
+
0xB0,
|
|
584
|
+
0xB9,
|
|
585
|
+
0xBE,
|
|
586
|
+
0xAB,
|
|
587
|
+
0xAC,
|
|
588
|
+
0xA5,
|
|
589
|
+
0xA2,
|
|
590
|
+
0x8F,
|
|
591
|
+
0x88,
|
|
592
|
+
0x81,
|
|
593
|
+
0x86,
|
|
594
|
+
0x93,
|
|
595
|
+
0x94,
|
|
596
|
+
0x9D,
|
|
597
|
+
0x9A,
|
|
598
|
+
0x27,
|
|
599
|
+
0x20,
|
|
600
|
+
0x29,
|
|
601
|
+
0x2E,
|
|
602
|
+
0x3B,
|
|
603
|
+
0x3C,
|
|
604
|
+
0x35,
|
|
605
|
+
0x32,
|
|
606
|
+
0x1F,
|
|
607
|
+
0x18,
|
|
608
|
+
0x11,
|
|
609
|
+
0x16,
|
|
610
|
+
0x03,
|
|
611
|
+
0x04,
|
|
612
|
+
0x0D,
|
|
613
|
+
0x0A,
|
|
614
|
+
0x57,
|
|
615
|
+
0x50,
|
|
616
|
+
0x59,
|
|
617
|
+
0x5E,
|
|
618
|
+
0x4B,
|
|
619
|
+
0x4C,
|
|
620
|
+
0x45,
|
|
621
|
+
0x42,
|
|
622
|
+
0x6F,
|
|
623
|
+
0x68,
|
|
624
|
+
0x61,
|
|
625
|
+
0x66,
|
|
626
|
+
0x73,
|
|
627
|
+
0x74,
|
|
628
|
+
0x7D,
|
|
629
|
+
0x7A,
|
|
630
|
+
0x89,
|
|
631
|
+
0x8E,
|
|
632
|
+
0x87,
|
|
633
|
+
0x80,
|
|
634
|
+
0x95,
|
|
635
|
+
0x92,
|
|
636
|
+
0x9B,
|
|
637
|
+
0x9C,
|
|
638
|
+
0xB1,
|
|
639
|
+
0xB6,
|
|
640
|
+
0xBF,
|
|
641
|
+
0xB8,
|
|
642
|
+
0xAD,
|
|
643
|
+
0xAA,
|
|
644
|
+
0xA3,
|
|
645
|
+
0xA4,
|
|
646
|
+
0xF9,
|
|
647
|
+
0xFE,
|
|
648
|
+
0xF7,
|
|
649
|
+
0xF0,
|
|
650
|
+
0xE5,
|
|
651
|
+
0xE2,
|
|
652
|
+
0xEB,
|
|
653
|
+
0xEC,
|
|
654
|
+
0xC1,
|
|
655
|
+
0xC6,
|
|
656
|
+
0xCF,
|
|
657
|
+
0xC8,
|
|
658
|
+
0xDD,
|
|
659
|
+
0xDA,
|
|
660
|
+
0xD3,
|
|
661
|
+
0xD4,
|
|
662
|
+
0x69,
|
|
663
|
+
0x6E,
|
|
664
|
+
0x67,
|
|
665
|
+
0x60,
|
|
666
|
+
0x75,
|
|
667
|
+
0x72,
|
|
668
|
+
0x7B,
|
|
669
|
+
0x7C,
|
|
670
|
+
0x51,
|
|
671
|
+
0x56,
|
|
672
|
+
0x5F,
|
|
673
|
+
0x58,
|
|
674
|
+
0x4D,
|
|
675
|
+
0x4A,
|
|
676
|
+
0x43,
|
|
677
|
+
0x44,
|
|
678
|
+
0x19,
|
|
679
|
+
0x1E,
|
|
680
|
+
0x17,
|
|
681
|
+
0x10,
|
|
682
|
+
0x05,
|
|
683
|
+
0x02,
|
|
684
|
+
0x0B,
|
|
685
|
+
0x0C,
|
|
686
|
+
0x21,
|
|
687
|
+
0x26,
|
|
688
|
+
0x2F,
|
|
689
|
+
0x28,
|
|
690
|
+
0x3D,
|
|
691
|
+
0x3A,
|
|
692
|
+
0x33,
|
|
693
|
+
0x34,
|
|
694
|
+
0x4E,
|
|
695
|
+
0x49,
|
|
696
|
+
0x40,
|
|
697
|
+
0x47,
|
|
698
|
+
0x52,
|
|
699
|
+
0x55,
|
|
700
|
+
0x5C,
|
|
701
|
+
0x5B,
|
|
702
|
+
0x76,
|
|
703
|
+
0x71,
|
|
704
|
+
0x78,
|
|
705
|
+
0x7F,
|
|
706
|
+
0x6A,
|
|
707
|
+
0x6D,
|
|
708
|
+
0x64,
|
|
709
|
+
0x63,
|
|
710
|
+
0x3E,
|
|
711
|
+
0x39,
|
|
712
|
+
0x30,
|
|
713
|
+
0x37,
|
|
714
|
+
0x22,
|
|
715
|
+
0x25,
|
|
716
|
+
0x2C,
|
|
717
|
+
0x2B,
|
|
718
|
+
0x06,
|
|
719
|
+
0x01,
|
|
720
|
+
0x08,
|
|
721
|
+
0x0F,
|
|
722
|
+
0x1A,
|
|
723
|
+
0x1D,
|
|
724
|
+
0x14,
|
|
725
|
+
0x13,
|
|
726
|
+
0xAE,
|
|
727
|
+
0xA9,
|
|
728
|
+
0xA0,
|
|
729
|
+
0xA7,
|
|
730
|
+
0xB2,
|
|
731
|
+
0xB5,
|
|
732
|
+
0xBC,
|
|
733
|
+
0xBB,
|
|
734
|
+
0x96,
|
|
735
|
+
0x91,
|
|
736
|
+
0x98,
|
|
737
|
+
0x9F,
|
|
738
|
+
0x8A,
|
|
739
|
+
0x8D,
|
|
740
|
+
0x84,
|
|
741
|
+
0x83,
|
|
742
|
+
0xDE,
|
|
743
|
+
0xD9,
|
|
744
|
+
0xD0,
|
|
745
|
+
0xD7,
|
|
746
|
+
0xC2,
|
|
747
|
+
0xC5,
|
|
748
|
+
0xCC,
|
|
749
|
+
0xCB,
|
|
750
|
+
0xE6,
|
|
751
|
+
0xE1,
|
|
752
|
+
0xE8,
|
|
753
|
+
0xEF,
|
|
754
|
+
0xFA,
|
|
755
|
+
0xFD,
|
|
756
|
+
0xF4,
|
|
757
|
+
0xF3,
|
|
490
758
|
]
|
|
491
759
|
crc8 = 0
|
|
492
760
|
len_data = len(data)
|
|
@@ -496,11 +764,14 @@ class SensorProfileDataCtx:
|
|
|
496
764
|
crc8 = crc8Table[crc8]
|
|
497
765
|
|
|
498
766
|
return crc8
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
767
|
+
|
|
768
|
+
def processUniversalData(
|
|
769
|
+
self, buf: Queue[SensorData], loop: asyncio.AbstractEventLoop, sensor, callback
|
|
770
|
+
):
|
|
771
|
+
|
|
772
|
+
while self._is_running:
|
|
502
773
|
try:
|
|
503
|
-
while
|
|
774
|
+
while self._is_running and not self._rawDataBuffer.empty():
|
|
504
775
|
data = self._rawDataBuffer.get_nowait()
|
|
505
776
|
self._concatDataBuffer.extend(data)
|
|
506
777
|
self._rawDataBuffer.task_done()
|
|
@@ -524,22 +795,28 @@ class SensorProfileDataCtx:
|
|
|
524
795
|
index += 1
|
|
525
796
|
continue
|
|
526
797
|
crc = self._concatDataBuffer[index + 1 + n + 1]
|
|
527
|
-
calc_crc = self.calc_crc8(
|
|
798
|
+
calc_crc = self.calc_crc8(
|
|
799
|
+
self._concatDataBuffer[index + 2 : index + 2 + n]
|
|
800
|
+
)
|
|
528
801
|
if crc != calc_crc:
|
|
529
802
|
index += 1
|
|
530
803
|
continue
|
|
531
804
|
if self._is_data_transfering:
|
|
532
|
-
data_package = bytes(
|
|
805
|
+
data_package = bytes(
|
|
806
|
+
self._concatDataBuffer[index + 2 : index + 2 + n]
|
|
807
|
+
)
|
|
533
808
|
self._processDataPackage(data_package, buf)
|
|
534
|
-
while
|
|
809
|
+
while self._is_running and self.isDataTransfering:
|
|
535
810
|
sensorData: SensorData = None
|
|
536
811
|
try:
|
|
537
812
|
sensorData = buf.get_nowait()
|
|
538
813
|
except Exception as e:
|
|
539
814
|
break
|
|
540
|
-
if
|
|
815
|
+
if sensorData != None and callback != None:
|
|
541
816
|
try:
|
|
542
|
-
loop.call_soon_threadsafe(
|
|
817
|
+
loop.call_soon_threadsafe(
|
|
818
|
+
callback, sensor, sensorData
|
|
819
|
+
)
|
|
543
820
|
except Exception as e:
|
|
544
821
|
print(e)
|
|
545
822
|
|
|
@@ -555,15 +832,21 @@ class SensorProfileDataCtx:
|
|
|
555
832
|
index += 1
|
|
556
833
|
continue
|
|
557
834
|
crc = self._concatDataBuffer[index + 1 + n + 1]
|
|
558
|
-
calc_crc = self.calc_crc8(
|
|
835
|
+
calc_crc = self.calc_crc8(
|
|
836
|
+
self._concatDataBuffer[index + 2 : index + 2 + n]
|
|
837
|
+
)
|
|
559
838
|
if crc != calc_crc:
|
|
560
839
|
index += 1
|
|
561
840
|
continue
|
|
562
|
-
data_package = bytes(
|
|
563
|
-
|
|
841
|
+
data_package = bytes(
|
|
842
|
+
self._concatDataBuffer[index + 2 : index + 2 + n]
|
|
843
|
+
)
|
|
844
|
+
loop.call_soon_threadsafe(
|
|
845
|
+
self.gForce._on_cmd_response, None, data_package
|
|
846
|
+
)
|
|
564
847
|
last_cut = index = index + 2 + n
|
|
565
848
|
else:
|
|
566
849
|
index += 1
|
|
567
850
|
|
|
568
851
|
if last_cut > 0:
|
|
569
|
-
self._concatDataBuffer = self._concatDataBuffer[last_cut + 1:]
|
|
852
|
+
self._concatDataBuffer = self._concatDataBuffer[last_cut + 1 :]
|