sensor-sdk 0.0.5__py3-none-any.whl → 0.0.6__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 +15 -36
- sensor/sensor_data_context.py +14 -44
- sensor/sensor_profile.py +29 -74
- sensor/utils.py +15 -14
- {sensor_sdk-0.0.5.dist-info → sensor_sdk-0.0.6.dist-info}/METADATA +1 -1
- sensor_sdk-0.0.6.dist-info/RECORD +14 -0
- sensor_sdk-0.0.5.dist-info/RECORD +0 -14
- {sensor_sdk-0.0.5.dist-info → sensor_sdk-0.0.6.dist-info}/LICENSE.txt +0 -0
- {sensor_sdk-0.0.5.dist-info → sensor_sdk-0.0.6.dist-info}/WHEEL +0 -0
- {sensor_sdk-0.0.5.dist-info → sensor_sdk-0.0.6.dist-info}/top_level.txt +0 -0
- {sensor_sdk-0.0.5.dist-info → sensor_sdk-0.0.6.dist-info}/zip-safe +0 -0
sensor/sensor_controller.py
CHANGED
|
@@ -9,7 +9,7 @@ from sensor import utils
|
|
|
9
9
|
from sensor.sensor_profile import DeviceStateEx, SensorProfile
|
|
10
10
|
import asyncio
|
|
11
11
|
|
|
12
|
-
from sensor.utils import
|
|
12
|
+
from sensor.utils import async_call, start_loop, sync_call, async_exec, timer
|
|
13
13
|
from bleak import (
|
|
14
14
|
BleakScanner,
|
|
15
15
|
AdvertisementData,
|
|
@@ -38,16 +38,12 @@ class SensorController:
|
|
|
38
38
|
初始化 SensorController 实例。
|
|
39
39
|
"""
|
|
40
40
|
self._event_loop = asyncio.new_event_loop()
|
|
41
|
-
self._event_thread = threading.Thread(
|
|
42
|
-
target=start_loop, args=(self._event_loop,)
|
|
43
|
-
)
|
|
41
|
+
self._event_thread = threading.Thread(target=start_loop, args=(self._event_loop,))
|
|
44
42
|
self._event_thread.daemon = True
|
|
45
43
|
self._event_thread.name = "SensorController event"
|
|
46
44
|
self._event_thread.start()
|
|
47
45
|
self._gforce_event_loop = asyncio.new_event_loop()
|
|
48
|
-
self._gforce_event_thread = threading.Thread(
|
|
49
|
-
target=start_loop, args=(self._gforce_event_loop,)
|
|
50
|
-
)
|
|
46
|
+
self._gforce_event_thread = threading.Thread(target=start_loop, args=(self._gforce_event_loop,))
|
|
51
47
|
self._gforce_event_thread.daemon = True
|
|
52
48
|
self._gforce_event_thread.name = "BLE operation"
|
|
53
49
|
self._gforce_event_thread.start()
|
|
@@ -72,10 +68,7 @@ class SensorController:
|
|
|
72
68
|
def terminate(self):
|
|
73
69
|
utils._terminated = True
|
|
74
70
|
for sensor in self._sensor_profiles.values():
|
|
75
|
-
if
|
|
76
|
-
sensor.deviceState == DeviceStateEx.Connected
|
|
77
|
-
or sensor.deviceState == DeviceStateEx.Ready
|
|
78
|
-
):
|
|
71
|
+
if sensor.deviceState == DeviceStateEx.Connected or sensor.deviceState == DeviceStateEx.Ready:
|
|
79
72
|
sensor._destroy()
|
|
80
73
|
|
|
81
74
|
def _match_device(self, _device: bleak.BLEDevice, adv: AdvertisementData):
|
|
@@ -125,9 +118,7 @@ class SensorController:
|
|
|
125
118
|
return self._device_callback != None
|
|
126
119
|
|
|
127
120
|
@hasDeviceFoundCallback.setter
|
|
128
|
-
def onDeviceFoundCallback(
|
|
129
|
-
self, callback: Callable[[List[sensor_profile.BLEDevice]], None]
|
|
130
|
-
):
|
|
121
|
+
def onDeviceFoundCallback(self, callback: Callable[[List[sensor_profile.BLEDevice]], None]):
|
|
131
122
|
"""
|
|
132
123
|
设置扫描设备回调。
|
|
133
124
|
|
|
@@ -168,9 +159,7 @@ class SensorController:
|
|
|
168
159
|
|
|
169
160
|
async def _async_scan(self, period):
|
|
170
161
|
self._is_scanning = True
|
|
171
|
-
found_devices = await self._scanner.discover(
|
|
172
|
-
timeout=period / 1000, return_adv=True
|
|
173
|
-
)
|
|
162
|
+
found_devices = await self._scanner.discover(timeout=period / 1000, return_adv=True)
|
|
174
163
|
self._is_scanning = False
|
|
175
164
|
return self._process_ble_devices(found_devices)
|
|
176
165
|
|
|
@@ -182,7 +171,7 @@ class SensorController:
|
|
|
182
171
|
|
|
183
172
|
:return: List[sensor_profile.BLEDevice]: BLEDevice列表
|
|
184
173
|
"""
|
|
185
|
-
return
|
|
174
|
+
return sync_call(self._gforce_event_loop, self._async_scan(period))
|
|
186
175
|
|
|
187
176
|
async def asyncScan(self, period) -> List[sensor_profile.BLEDevice]:
|
|
188
177
|
"""
|
|
@@ -192,7 +181,7 @@ class SensorController:
|
|
|
192
181
|
|
|
193
182
|
:return: List[sensor_profile.BLEDevice]: BLEDevice列表
|
|
194
183
|
"""
|
|
195
|
-
return await
|
|
184
|
+
return await async_call(self._gforce_event_loop, self._async_scan(period))
|
|
196
185
|
|
|
197
186
|
async def _device_scan_callback(self, devices: List[sensor_profile.BLEDevice]):
|
|
198
187
|
if self._device_callback:
|
|
@@ -202,14 +191,12 @@ class SensorController:
|
|
|
202
191
|
print(e)
|
|
203
192
|
|
|
204
193
|
if self._is_scanning:
|
|
205
|
-
|
|
194
|
+
async_exec(self._gforce_event_loop, self._startScan())
|
|
206
195
|
|
|
207
196
|
async def _startScan(self) -> bool:
|
|
208
|
-
found_devices = await self._scanner.discover(
|
|
209
|
-
timeout=self._device_callback_period / 1000, return_adv=True
|
|
210
|
-
)
|
|
197
|
+
found_devices = await self._scanner.discover(timeout=self._device_callback_period / 1000, return_adv=True)
|
|
211
198
|
devices = self._process_ble_devices(found_devices)
|
|
212
|
-
|
|
199
|
+
async_exec(self._event_loop, self._device_scan_callback(devices))
|
|
213
200
|
|
|
214
201
|
def startScan(self, periodInMs: int) -> bool:
|
|
215
202
|
"""
|
|
@@ -225,7 +212,7 @@ class SensorController:
|
|
|
225
212
|
self._is_scanning = True
|
|
226
213
|
self._device_callback_period = periodInMs
|
|
227
214
|
|
|
228
|
-
|
|
215
|
+
async_exec(self._gforce_event_loop, self._startScan())
|
|
229
216
|
return True
|
|
230
217
|
|
|
231
218
|
def stopScan(self) -> None:
|
|
@@ -237,9 +224,7 @@ class SensorController:
|
|
|
237
224
|
|
|
238
225
|
self._is_scanning = False
|
|
239
226
|
|
|
240
|
-
def requireSensor(
|
|
241
|
-
self, device: sensor_profile.BLEDevice
|
|
242
|
-
) -> Optional[SensorProfile]:
|
|
227
|
+
def requireSensor(self, device: sensor_profile.BLEDevice) -> Optional[SensorProfile]:
|
|
243
228
|
"""
|
|
244
229
|
根据设备信息获取或创建SensorProfile。
|
|
245
230
|
|
|
@@ -271,10 +256,7 @@ class SensorController:
|
|
|
271
256
|
"""
|
|
272
257
|
sensors: List[SensorProfile] = list()
|
|
273
258
|
for sensor in self._sensor_profiles.values():
|
|
274
|
-
if
|
|
275
|
-
sensor.deviceState == DeviceStateEx.Connected
|
|
276
|
-
or sensor.deviceState == DeviceStateEx.Ready
|
|
277
|
-
):
|
|
259
|
+
if sensor.deviceState == DeviceStateEx.Connected or sensor.deviceState == DeviceStateEx.Ready:
|
|
278
260
|
sensors.append(sensor)
|
|
279
261
|
|
|
280
262
|
return sensors
|
|
@@ -287,10 +269,7 @@ class SensorController:
|
|
|
287
269
|
"""
|
|
288
270
|
devices: List[sensor_profile.BLEDevice] = list()
|
|
289
271
|
for sensor in self._sensor_profiles.values():
|
|
290
|
-
if
|
|
291
|
-
sensor.deviceState == DeviceStateEx.Connected
|
|
292
|
-
or sensor.deviceState == DeviceStateEx.Ready
|
|
293
|
-
):
|
|
272
|
+
if sensor.deviceState == DeviceStateEx.Connected or sensor.deviceState == DeviceStateEx.Ready:
|
|
294
273
|
devices.append(sensor.BLEDevice)
|
|
295
274
|
|
|
296
275
|
return devices
|
sensor/sensor_data_context.py
CHANGED
|
@@ -82,9 +82,7 @@ class SensorProfileDataCtx:
|
|
|
82
82
|
return self._is_data_transfering
|
|
83
83
|
|
|
84
84
|
def hasInit(self):
|
|
85
|
-
return
|
|
86
|
-
not self._is_initing and self.featureMap != 0 and self.notifyDataFlag != 0
|
|
87
|
-
)
|
|
85
|
+
return not self._is_initing and self.featureMap != 0 and self.notifyDataFlag != 0
|
|
88
86
|
|
|
89
87
|
def hasEMG(self):
|
|
90
88
|
return (self.featureMap & FeatureMaps.GFD_FEAT_EMG.value) != 0
|
|
@@ -337,9 +335,7 @@ class SensorProfileDataCtx:
|
|
|
337
335
|
if self.checkReadSamples(sensor, data, sensor_data_gyro, 9, 6):
|
|
338
336
|
self.sendSensorData(sensor_data_gyro, buf)
|
|
339
337
|
|
|
340
|
-
def checkReadSamples(
|
|
341
|
-
self, sensor, data: bytes, sensorData: SensorData, dataOffset: int, dataGap: int
|
|
342
|
-
):
|
|
338
|
+
def checkReadSamples(self, sensor, data: bytes, sensorData: SensorData, dataOffset: int, dataGap: int):
|
|
343
339
|
offset = 1
|
|
344
340
|
v = data[0]
|
|
345
341
|
if not self._is_data_transfering:
|
|
@@ -358,9 +354,7 @@ class SensorProfileDataCtx:
|
|
|
358
354
|
|
|
359
355
|
deltaPackageIndex = packageIndex - lastPackageIndex
|
|
360
356
|
if deltaPackageIndex > 1:
|
|
361
|
-
lostSampleCount = sensorData.packageSampleCount * (
|
|
362
|
-
deltaPackageIndex - 1
|
|
363
|
-
)
|
|
357
|
+
lostSampleCount = sensorData.packageSampleCount * (deltaPackageIndex - 1)
|
|
364
358
|
lostLog = (
|
|
365
359
|
"MSG|LOST SAMPLE|MAC|"
|
|
366
360
|
+ str(sensorData.deviceMac)
|
|
@@ -372,9 +366,7 @@ class SensorProfileDataCtx:
|
|
|
372
366
|
# print(lostLog)
|
|
373
367
|
if sensor._event_loop != None and sensor._on_error_callback != None:
|
|
374
368
|
try:
|
|
375
|
-
sensor._event_loop.call_soon_threadsafe(
|
|
376
|
-
sensor._on_error_callback, sensor, lostLog
|
|
377
|
-
)
|
|
369
|
+
sensor._event_loop.call_soon_threadsafe(sensor._on_error_callback, sensor, lostLog)
|
|
378
370
|
except Exception as e:
|
|
379
371
|
pass
|
|
380
372
|
|
|
@@ -418,18 +410,14 @@ class SensorProfileDataCtx:
|
|
|
418
410
|
channelSamples.append([])
|
|
419
411
|
|
|
420
412
|
for sampleIndex in range(sampleCount):
|
|
421
|
-
for channelIndex, impedanceChannelIndex in enumerate(
|
|
422
|
-
range(sensorData.channelCount)
|
|
423
|
-
):
|
|
413
|
+
for channelIndex, impedanceChannelIndex in enumerate(range(sensorData.channelCount)):
|
|
424
414
|
if (sensorData.channelMask & (1 << channelIndex)) != 0:
|
|
425
415
|
samples = channelSamples[channelIndex]
|
|
426
416
|
impedance = 0.0
|
|
427
417
|
saturation = 0.0
|
|
428
418
|
|
|
429
419
|
if sensorData.dataType == DataType.NTF_ECG:
|
|
430
|
-
impedanceChannelIndex = self.sensorDatas[
|
|
431
|
-
SensorDataType.DATA_TYPE_EEG
|
|
432
|
-
].channelCount
|
|
420
|
+
impedanceChannelIndex = self.sensorDatas[SensorDataType.DATA_TYPE_EEG].channelCount
|
|
433
421
|
|
|
434
422
|
if impedanceChannelIndex < len(_impedanceData):
|
|
435
423
|
impedance = _impedanceData[impedanceChannelIndex]
|
|
@@ -461,11 +449,7 @@ class SensorProfileDataCtx:
|
|
|
461
449
|
)
|
|
462
450
|
offset += 2
|
|
463
451
|
elif sensorData.resolutionBits == 24:
|
|
464
|
-
rawData = (
|
|
465
|
-
(data[offset] << 16)
|
|
466
|
-
| (data[offset + 1] << 8)
|
|
467
|
-
| data[offset + 2]
|
|
468
|
-
)
|
|
452
|
+
rawData = (data[offset] << 16) | (data[offset + 1] << 8) | data[offset + 2]
|
|
469
453
|
rawData -= 8388608
|
|
470
454
|
offset += 3
|
|
471
455
|
|
|
@@ -802,9 +786,7 @@ class SensorProfileDataCtx:
|
|
|
802
786
|
|
|
803
787
|
return crc8
|
|
804
788
|
|
|
805
|
-
def processUniversalData(
|
|
806
|
-
self, buf: Queue[SensorData], loop: asyncio.AbstractEventLoop, sensor, callback
|
|
807
|
-
):
|
|
789
|
+
def processUniversalData(self, buf: Queue[SensorData], loop: asyncio.AbstractEventLoop, sensor, callback):
|
|
808
790
|
|
|
809
791
|
while self._is_running:
|
|
810
792
|
try:
|
|
@@ -832,16 +814,12 @@ class SensorProfileDataCtx:
|
|
|
832
814
|
index += 1
|
|
833
815
|
continue
|
|
834
816
|
crc = self._concatDataBuffer[index + 1 + n + 1]
|
|
835
|
-
calc_crc = self.calc_crc8(
|
|
836
|
-
self._concatDataBuffer[index + 2 : index + 2 + n]
|
|
837
|
-
)
|
|
817
|
+
calc_crc = self.calc_crc8(self._concatDataBuffer[index + 2 : index + 2 + n])
|
|
838
818
|
if crc != calc_crc:
|
|
839
819
|
index += 1
|
|
840
820
|
continue
|
|
841
821
|
if self._is_data_transfering:
|
|
842
|
-
data_package = bytes(
|
|
843
|
-
self._concatDataBuffer[index + 2 : index + 2 + n]
|
|
844
|
-
)
|
|
822
|
+
data_package = bytes(self._concatDataBuffer[index + 2 : index + 2 + n])
|
|
845
823
|
self._processDataPackage(data_package, buf, sensor)
|
|
846
824
|
while self._is_running and self.isDataTransfering:
|
|
847
825
|
sensorData: SensorData = None
|
|
@@ -851,9 +829,7 @@ class SensorProfileDataCtx:
|
|
|
851
829
|
break
|
|
852
830
|
if loop != None and sensorData != None and callback != None:
|
|
853
831
|
try:
|
|
854
|
-
loop.call_soon_threadsafe(
|
|
855
|
-
callback, sensor, sensorData
|
|
856
|
-
)
|
|
832
|
+
loop.call_soon_threadsafe(callback, sensor, sensorData)
|
|
857
833
|
except Exception as e:
|
|
858
834
|
print(e)
|
|
859
835
|
|
|
@@ -869,19 +845,13 @@ class SensorProfileDataCtx:
|
|
|
869
845
|
index += 1
|
|
870
846
|
continue
|
|
871
847
|
crc = self._concatDataBuffer[index + 1 + n + 1]
|
|
872
|
-
calc_crc = self.calc_crc8(
|
|
873
|
-
self._concatDataBuffer[index + 2 : index + 2 + n]
|
|
874
|
-
)
|
|
848
|
+
calc_crc = self.calc_crc8(self._concatDataBuffer[index + 2 : index + 2 + n])
|
|
875
849
|
if crc != calc_crc:
|
|
876
850
|
index += 1
|
|
877
851
|
continue
|
|
878
|
-
data_package = bytes(
|
|
879
|
-
self._concatDataBuffer[index + 2 : index + 2 + n]
|
|
880
|
-
)
|
|
852
|
+
data_package = bytes(self._concatDataBuffer[index + 2 : index + 2 + n])
|
|
881
853
|
if loop != None:
|
|
882
|
-
loop.call_soon_threadsafe(
|
|
883
|
-
self.gForce._on_cmd_response, None, data_package
|
|
884
|
-
)
|
|
854
|
+
loop.call_soon_threadsafe(self.gForce._on_cmd_response, None, data_package)
|
|
885
855
|
last_cut = index = index + 2 + n
|
|
886
856
|
else:
|
|
887
857
|
index += 1
|
sensor/sensor_profile.py
CHANGED
|
@@ -21,7 +21,7 @@ import threading
|
|
|
21
21
|
|
|
22
22
|
from sensor.sensor_data_context import SensorProfileDataCtx
|
|
23
23
|
from sensor.sensor_device import BLEDevice, DeviceInfo, DeviceStateEx
|
|
24
|
-
from sensor.utils import
|
|
24
|
+
from sensor.utils import async_call, start_loop, sync_call, async_exec, timer
|
|
25
25
|
from contextlib import suppress
|
|
26
26
|
from dataclasses import dataclass
|
|
27
27
|
|
|
@@ -78,10 +78,7 @@ class SensorProfile:
|
|
|
78
78
|
self._destroy()
|
|
79
79
|
|
|
80
80
|
def _destroy(self):
|
|
81
|
-
if
|
|
82
|
-
self._device_state == DeviceStateEx.Connected
|
|
83
|
-
or self._device_state == DeviceStateEx.Ready
|
|
84
|
-
):
|
|
81
|
+
if self._device_state == DeviceStateEx.Connected or self._device_state == DeviceStateEx.Ready:
|
|
85
82
|
self.disconnect()
|
|
86
83
|
if self._data_event_loop != None:
|
|
87
84
|
try:
|
|
@@ -114,9 +111,7 @@ class SensorProfile:
|
|
|
114
111
|
self._device_state = newState
|
|
115
112
|
if self._event_loop != None and self._on_state_changed != None:
|
|
116
113
|
try:
|
|
117
|
-
self._event_loop.call_soon_threadsafe(
|
|
118
|
-
self._on_state_changed, self, newState
|
|
119
|
-
)
|
|
114
|
+
self._event_loop.call_soon_threadsafe(self._on_state_changed, self, newState)
|
|
120
115
|
except Exception as e:
|
|
121
116
|
print(e)
|
|
122
117
|
pass
|
|
@@ -162,9 +157,7 @@ class SensorProfile:
|
|
|
162
157
|
return self._on_state_changed
|
|
163
158
|
|
|
164
159
|
@onStateChanged.setter
|
|
165
|
-
def onStateChanged(
|
|
166
|
-
self, callback: Callable[["SensorProfile", DeviceStateEx], None]
|
|
167
|
-
):
|
|
160
|
+
def onStateChanged(self, callback: Callable[["SensorProfile", DeviceStateEx], None]):
|
|
168
161
|
"""
|
|
169
162
|
设置状态变化的回调函数。
|
|
170
163
|
|
|
@@ -229,9 +222,7 @@ class SensorProfile:
|
|
|
229
222
|
async def _connect(self) -> bool:
|
|
230
223
|
if self._event_thread == None:
|
|
231
224
|
self._event_loop = asyncio.new_event_loop()
|
|
232
|
-
self._event_thread = threading.Thread(
|
|
233
|
-
target=start_loop, args=(self._event_loop,)
|
|
234
|
-
)
|
|
225
|
+
self._event_thread = threading.Thread(target=start_loop, args=(self._event_loop,))
|
|
235
226
|
self._event_thread.daemon = True
|
|
236
227
|
self._event_thread.name = self._device.Name + " event"
|
|
237
228
|
self._event_thread.start()
|
|
@@ -249,35 +240,22 @@ class SensorProfile:
|
|
|
249
240
|
)
|
|
250
241
|
elif self._adv.service_data.get(RFSTAR_SERVICE_GUID) != None:
|
|
251
242
|
# print("RFSTAR_SERVICE:" + self._detail_device.name)
|
|
252
|
-
self._gforce = GForce(
|
|
253
|
-
self._detail_device, RFSTAR_CMD_UUID, RFSTAR_DATA_UUID, True
|
|
254
|
-
)
|
|
243
|
+
self._gforce = GForce(self._detail_device, RFSTAR_CMD_UUID, RFSTAR_DATA_UUID, True)
|
|
255
244
|
self._data_event_loop = asyncio.new_event_loop()
|
|
256
|
-
self._data_event_thread = threading.Thread(
|
|
257
|
-
target=start_loop, args=(self._data_event_loop,)
|
|
258
|
-
)
|
|
245
|
+
self._data_event_thread = threading.Thread(target=start_loop, args=(self._data_event_loop,))
|
|
259
246
|
self._data_event_thread.daemon = True
|
|
260
247
|
self._data_event_thread.name = self._detail_device.name + " data"
|
|
261
248
|
self._data_event_thread.start()
|
|
262
249
|
else:
|
|
263
|
-
print(
|
|
264
|
-
"Invalid device service uuid:"
|
|
265
|
-
+ self._detail_device.name
|
|
266
|
-
+ str(self._adv)
|
|
267
|
-
)
|
|
250
|
+
print("Invalid device service uuid:" + self._detail_device.name + str(self._adv))
|
|
268
251
|
return False
|
|
269
252
|
|
|
270
253
|
if self._data_ctx == None and self._gforce != None:
|
|
271
|
-
self._data_ctx = SensorProfileDataCtx(
|
|
272
|
-
self._gforce, self._device.Address, self._raw_data_buf
|
|
273
|
-
)
|
|
254
|
+
self._data_ctx = SensorProfileDataCtx(self._gforce, self._device.Address, self._raw_data_buf)
|
|
274
255
|
if self._data_ctx.isUniversalStream:
|
|
275
|
-
|
|
256
|
+
async_exec(self._data_event_loop, self._process_universal_data())
|
|
276
257
|
|
|
277
|
-
if
|
|
278
|
-
self.deviceState == DeviceStateEx.Connected
|
|
279
|
-
or self.deviceState == DeviceStateEx.Ready
|
|
280
|
-
):
|
|
258
|
+
if self.deviceState == DeviceStateEx.Connected or self.deviceState == DeviceStateEx.Ready:
|
|
281
259
|
return True
|
|
282
260
|
self._set_device_state(DeviceStateEx.Connecting)
|
|
283
261
|
|
|
@@ -311,7 +289,7 @@ class SensorProfile:
|
|
|
311
289
|
:return: bool: 如果连接成功,返回 True;否则返回 False。
|
|
312
290
|
|
|
313
291
|
"""
|
|
314
|
-
result =
|
|
292
|
+
result = sync_call(self._gforce_event_loop, self._connect())
|
|
315
293
|
return result
|
|
316
294
|
|
|
317
295
|
async def asyncConnect(self) -> bool:
|
|
@@ -321,7 +299,7 @@ class SensorProfile:
|
|
|
321
299
|
:return: bool: 如果连接成功,返回 True;否则返回 False。
|
|
322
300
|
|
|
323
301
|
"""
|
|
324
|
-
return await
|
|
302
|
+
return await async_call(self._gforce_event_loop, self._connect())
|
|
325
303
|
|
|
326
304
|
async def _waitForDisconnect(self) -> bool:
|
|
327
305
|
while self.deviceState != DeviceStateEx.Disconnected:
|
|
@@ -329,10 +307,7 @@ class SensorProfile:
|
|
|
329
307
|
return True
|
|
330
308
|
|
|
331
309
|
async def _disconnect(self) -> bool:
|
|
332
|
-
if
|
|
333
|
-
self.deviceState != DeviceStateEx.Connected
|
|
334
|
-
and self.deviceState != DeviceStateEx.Ready
|
|
335
|
-
):
|
|
310
|
+
if self.deviceState != DeviceStateEx.Connected and self.deviceState != DeviceStateEx.Ready:
|
|
336
311
|
return True
|
|
337
312
|
if self._data_ctx == None:
|
|
338
313
|
return False
|
|
@@ -348,7 +323,7 @@ class SensorProfile:
|
|
|
348
323
|
:return: bool: 如果断开连接成功,返回 True;否则返回 False。
|
|
349
324
|
|
|
350
325
|
"""
|
|
351
|
-
return
|
|
326
|
+
return sync_call(self._gforce_event_loop, self._disconnect())
|
|
352
327
|
|
|
353
328
|
async def asyncDisconnect(self) -> bool:
|
|
354
329
|
"""
|
|
@@ -357,7 +332,7 @@ class SensorProfile:
|
|
|
357
332
|
:return: bool: 如果断开连接成功,返回 True;否则返回 False。
|
|
358
333
|
|
|
359
334
|
"""
|
|
360
|
-
return await
|
|
335
|
+
return await async_call(self._gforce_event_loop, self._disconnect())
|
|
361
336
|
|
|
362
337
|
async def _process_data(self):
|
|
363
338
|
while self._data_ctx._is_running and self._data_ctx.isDataTransfering:
|
|
@@ -368,23 +343,15 @@ class SensorProfile:
|
|
|
368
343
|
sensorData = self._data_buffer.get_nowait()
|
|
369
344
|
except Exception as e:
|
|
370
345
|
break
|
|
371
|
-
if
|
|
372
|
-
self._event_loop != None
|
|
373
|
-
and sensorData != None
|
|
374
|
-
and self._on_data_callback != None
|
|
375
|
-
):
|
|
346
|
+
if self._event_loop != None and sensorData != None and self._on_data_callback != None:
|
|
376
347
|
try:
|
|
377
|
-
self._event_loop.call_soon_threadsafe(
|
|
378
|
-
self._on_data_callback, self, sensorData
|
|
379
|
-
)
|
|
348
|
+
self._event_loop.call_soon_threadsafe(self._on_data_callback, self, sensorData)
|
|
380
349
|
except Exception as e:
|
|
381
350
|
print(e)
|
|
382
351
|
self._data_buffer.task_done()
|
|
383
352
|
|
|
384
353
|
async def _process_universal_data(self):
|
|
385
|
-
self._data_ctx.processUniversalData(
|
|
386
|
-
self._data_buffer, self._event_loop, self, self._on_data_callback
|
|
387
|
-
)
|
|
354
|
+
self._data_ctx.processUniversalData(self._data_buffer, self._event_loop, self, self._on_data_callback)
|
|
388
355
|
|
|
389
356
|
async def _startDataNotification(self) -> bool:
|
|
390
357
|
if self.deviceState != DeviceStateEx.Ready:
|
|
@@ -399,9 +366,7 @@ class SensorProfile:
|
|
|
399
366
|
|
|
400
367
|
if self._data_event_loop == None:
|
|
401
368
|
self._data_event_loop = asyncio.new_event_loop()
|
|
402
|
-
self._data_event_thread = threading.Thread(
|
|
403
|
-
target=start_loop, args=(self._data_event_loop,)
|
|
404
|
-
)
|
|
369
|
+
self._data_event_thread = threading.Thread(target=start_loop, args=(self._data_event_loop,))
|
|
405
370
|
self._data_event_thread.daemon = True
|
|
406
371
|
self._data_event_thread.name = self.BLEDevice.Name + " data"
|
|
407
372
|
self._data_event_thread.start()
|
|
@@ -410,7 +375,7 @@ class SensorProfile:
|
|
|
410
375
|
self._data_buffer.queue.clear()
|
|
411
376
|
self._data_ctx.clear()
|
|
412
377
|
if not self._data_ctx.isUniversalStream:
|
|
413
|
-
|
|
378
|
+
async_exec(self._data_event_loop, self._process_data())
|
|
414
379
|
return result
|
|
415
380
|
|
|
416
381
|
def startDataNotification(self) -> bool:
|
|
@@ -420,7 +385,7 @@ class SensorProfile:
|
|
|
420
385
|
:return: bool: 如果开始数据通知成功,返回 True;否则返回 False。
|
|
421
386
|
|
|
422
387
|
"""
|
|
423
|
-
return
|
|
388
|
+
return sync_call(self._gforce_event_loop, self._startDataNotification())
|
|
424
389
|
|
|
425
390
|
async def asyncStartDataNotification(self) -> bool:
|
|
426
391
|
"""
|
|
@@ -429,9 +394,7 @@ class SensorProfile:
|
|
|
429
394
|
:return: bool: 如果开始数据通知成功,返回 True;否则返回 False。
|
|
430
395
|
|
|
431
396
|
"""
|
|
432
|
-
return await
|
|
433
|
-
self._gforce_event_loop, 0, self._startDataNotification()
|
|
434
|
-
)
|
|
397
|
+
return await async_call(self._gforce_event_loop, self._startDataNotification())
|
|
435
398
|
|
|
436
399
|
async def _stopDataNotification(self) -> bool:
|
|
437
400
|
if self.deviceState != DeviceStateEx.Ready:
|
|
@@ -453,7 +416,7 @@ class SensorProfile:
|
|
|
453
416
|
:return: bool: 如果停止数据通知成功,返回 True;否则返回 False。
|
|
454
417
|
|
|
455
418
|
"""
|
|
456
|
-
return
|
|
419
|
+
return sync_call(self._gforce_event_loop, self._stopDataNotification())
|
|
457
420
|
|
|
458
421
|
async def asyncStopDataNotification(self) -> bool:
|
|
459
422
|
"""
|
|
@@ -462,18 +425,14 @@ class SensorProfile:
|
|
|
462
425
|
:return: bool: 如果停止数据通知成功,返回 True;否则返回 False。
|
|
463
426
|
|
|
464
427
|
"""
|
|
465
|
-
return await
|
|
466
|
-
self._gforce_event_loop, 0, self._stopDataNotification()
|
|
467
|
-
)
|
|
428
|
+
return await async_call(self._gforce_event_loop, self._stopDataNotification())
|
|
468
429
|
|
|
469
430
|
async def _refresh_power(self):
|
|
470
431
|
self._power = await self._gforce.get_battery_level()
|
|
471
432
|
|
|
472
433
|
if self._event_loop != None and self._on_power_changed != None:
|
|
473
434
|
try:
|
|
474
|
-
self._event_loop.call_soon_threadsafe(
|
|
475
|
-
self._on_power_changed, self, self._power
|
|
476
|
-
)
|
|
435
|
+
self._event_loop.call_soon_threadsafe(self._on_power_changed, self, self._power)
|
|
477
436
|
except Exception as e:
|
|
478
437
|
print(e)
|
|
479
438
|
|
|
@@ -512,16 +471,13 @@ class SensorProfile:
|
|
|
512
471
|
:return: bool: 初始化结果。True 表示成功,False 表示失败。
|
|
513
472
|
|
|
514
473
|
"""
|
|
515
|
-
return
|
|
474
|
+
return sync_call(
|
|
516
475
|
self._gforce_event_loop,
|
|
517
|
-
0,
|
|
518
476
|
self._init(packageSampleCount, powerRefreshInterval),
|
|
519
477
|
120,
|
|
520
478
|
)
|
|
521
479
|
|
|
522
|
-
async def asyncInit(
|
|
523
|
-
self, packageSampleCount: int, powerRefreshInterval: int
|
|
524
|
-
) -> bool:
|
|
480
|
+
async def asyncInit(self, packageSampleCount: int, powerRefreshInterval: int) -> bool:
|
|
525
481
|
"""
|
|
526
482
|
初始化数据采集。
|
|
527
483
|
|
|
@@ -531,9 +487,8 @@ class SensorProfile:
|
|
|
531
487
|
:return: bool: 初始化结果。True 表示成功,False 表示失败。
|
|
532
488
|
|
|
533
489
|
"""
|
|
534
|
-
return await
|
|
490
|
+
return await async_call(
|
|
535
491
|
self._gforce_event_loop,
|
|
536
|
-
0,
|
|
537
492
|
self._init(packageSampleCount, powerRefreshInterval),
|
|
538
493
|
120,
|
|
539
494
|
)
|
sensor/utils.py
CHANGED
|
@@ -9,8 +9,7 @@ _TIMEOUT = 10
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
async def delay(_time: float, function) -> any:
|
|
12
|
-
|
|
13
|
-
await asyncio.sleep(_time)
|
|
12
|
+
await asyncio.sleep(_time)
|
|
14
13
|
return await function
|
|
15
14
|
|
|
16
15
|
|
|
@@ -24,32 +23,34 @@ def timer(_loop: asyncio.AbstractEventLoop, _delay: float, function):
|
|
|
24
23
|
pass
|
|
25
24
|
|
|
26
25
|
|
|
27
|
-
def
|
|
28
|
-
_loop
|
|
29
|
-
|
|
26
|
+
def async_exec(_loop: asyncio.AbstractEventLoop, function):
|
|
27
|
+
if _loop == None:
|
|
28
|
+
return
|
|
29
|
+
try:
|
|
30
|
+
asyncio.run_coroutine_threadsafe(function, _loop)
|
|
31
|
+
except Exception as e:
|
|
32
|
+
print(e)
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def sync_call(_loop: asyncio.AbstractEventLoop, function, _timeout=_TIMEOUT) -> any:
|
|
30
37
|
if _loop == None:
|
|
31
38
|
return
|
|
32
39
|
|
|
33
40
|
try:
|
|
34
|
-
f = asyncio.run_coroutine_threadsafe(
|
|
35
|
-
asyncio.wait_for(delay(_delay, function), _delay + _timeout), _loop
|
|
36
|
-
)
|
|
41
|
+
f = asyncio.run_coroutine_threadsafe(asyncio.wait_for(function, _timeout), _loop)
|
|
37
42
|
return f.result(timeout=_timeout)
|
|
38
43
|
except Exception as e:
|
|
39
44
|
print(e)
|
|
40
45
|
pass
|
|
41
46
|
|
|
42
47
|
|
|
43
|
-
async def
|
|
44
|
-
_loop: asyncio.AbstractEventLoop, _delay: float, function, _timeout=_TIMEOUT
|
|
45
|
-
) -> any:
|
|
48
|
+
async def async_call(_loop: asyncio.AbstractEventLoop, function, _timeout=_TIMEOUT) -> any:
|
|
46
49
|
if _loop == None:
|
|
47
50
|
return
|
|
48
51
|
|
|
49
52
|
try:
|
|
50
|
-
f = asyncio.run_coroutine_threadsafe(
|
|
51
|
-
asyncio.wait_for(delay(_delay, function), _delay + _timeout), _loop
|
|
52
|
-
)
|
|
53
|
+
f = asyncio.run_coroutine_threadsafe(asyncio.wait_for(function, _timeout), _loop)
|
|
53
54
|
except Exception as e:
|
|
54
55
|
print(e)
|
|
55
56
|
pass
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
sensor/__init__.py,sha256=L1VyAP0EDEnJIMeMTzp4iXHSRUUHyHScF_GIl3iYKRI,123
|
|
2
|
+
sensor/gforce.py,sha256=z-w9POiw5rtj6AgTvwFAI6tZt_5jv_3eSiKt_0jA1Ps,25229
|
|
3
|
+
sensor/sensor_controller.py,sha256=lNi7i3T_aAHEJvv963OvVv_PNAYy_5-BwXD82XNvnGg,10028
|
|
4
|
+
sensor/sensor_data.py,sha256=Hu7Ql0LgQ7V24xYZhaLrKPwU4KWZeWE655v8Gy8xphY,3934
|
|
5
|
+
sensor/sensor_data_context.py,sha256=7GQwthoAH-qJsimWwCf8JcQAP8TivG3X0lwxfyHabo4,28575
|
|
6
|
+
sensor/sensor_device.py,sha256=LCjBzm2TuOh2KpHsFTjm1sF8hzwvS22LhF_ueAct0Jo,2848
|
|
7
|
+
sensor/sensor_profile.py,sha256=SFecXPCauvadRJdssu9iWMgCdxRinTqGlzLAQsZ8-k8,19625
|
|
8
|
+
sensor/utils.py,sha256=ybmByBldCQ_x-sVtjA2mdXWo0QOafPAupfnWAxLrkV0,1773
|
|
9
|
+
sensor_sdk-0.0.6.dist-info/LICENSE.txt,sha256=8CSivOpub3IuXODTyqBRI91AxouJZk02YrcKuOAkWu8,1111
|
|
10
|
+
sensor_sdk-0.0.6.dist-info/METADATA,sha256=JP3HgNyVlwNe2AkT7LMm1PCVAxGtLr4XrdkfHZKBmL0,8374
|
|
11
|
+
sensor_sdk-0.0.6.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
12
|
+
sensor_sdk-0.0.6.dist-info/top_level.txt,sha256=Ftq49B6bH0Ffdc7c8LkcyakHo6lsg_snlBbpEUoILSk,7
|
|
13
|
+
sensor_sdk-0.0.6.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
14
|
+
sensor_sdk-0.0.6.dist-info/RECORD,,
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
sensor/__init__.py,sha256=L1VyAP0EDEnJIMeMTzp4iXHSRUUHyHScF_GIl3iYKRI,123
|
|
2
|
-
sensor/gforce.py,sha256=z-w9POiw5rtj6AgTvwFAI6tZt_5jv_3eSiKt_0jA1Ps,25229
|
|
3
|
-
sensor/sensor_controller.py,sha256=p4AFR_x6qer2PHqbQiVEJOU4xPcqT0WcOvZJJyb946w,10301
|
|
4
|
-
sensor/sensor_data.py,sha256=Hu7Ql0LgQ7V24xYZhaLrKPwU4KWZeWE655v8Gy8xphY,3934
|
|
5
|
-
sensor/sensor_data_context.py,sha256=Mf09kF5SA8jqSgNHZhSHvnV6KXxOuKC1U_unrsBiFd8,29285
|
|
6
|
-
sensor/sensor_device.py,sha256=LCjBzm2TuOh2KpHsFTjm1sF8hzwvS22LhF_ueAct0Jo,2848
|
|
7
|
-
sensor/sensor_profile.py,sha256=40p0YvkzsGcGgOoNePtOIVwiCKRa7B0NyprN1jHXDBA,20384
|
|
8
|
-
sensor/utils.py,sha256=9hcEVjAf9kUbsdgKiKZT0B2QDsBLBx5gocrNdBCYjpE,1707
|
|
9
|
-
sensor_sdk-0.0.5.dist-info/LICENSE.txt,sha256=8CSivOpub3IuXODTyqBRI91AxouJZk02YrcKuOAkWu8,1111
|
|
10
|
-
sensor_sdk-0.0.5.dist-info/METADATA,sha256=hGZJafML055JDFdYkbnEHNElcMgl_J-1ymzKEeL_lRc,8374
|
|
11
|
-
sensor_sdk-0.0.5.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
12
|
-
sensor_sdk-0.0.5.dist-info/top_level.txt,sha256=Ftq49B6bH0Ffdc7c8LkcyakHo6lsg_snlBbpEUoILSk,7
|
|
13
|
-
sensor_sdk-0.0.5.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
14
|
-
sensor_sdk-0.0.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|