sensor-sdk 0.0.4__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/gforce.py +73 -46
- sensor/sensor_controller.py +76 -47
- sensor/sensor_data_context.py +69 -61
- sensor/sensor_profile.py +147 -113
- sensor/utils.py +51 -8
- {sensor_sdk-0.0.4.dist-info → sensor_sdk-0.0.6.dist-info}/METADATA +14 -2
- sensor_sdk-0.0.6.dist-info/RECORD +14 -0
- sensor_sdk-0.0.4.dist-info/RECORD +0 -14
- {sensor_sdk-0.0.4.dist-info → sensor_sdk-0.0.6.dist-info}/LICENSE.txt +0 -0
- {sensor_sdk-0.0.4.dist-info → sensor_sdk-0.0.6.dist-info}/WHEEL +0 -0
- {sensor_sdk-0.0.4.dist-info → sensor_sdk-0.0.6.dist-info}/top_level.txt +0 -0
- {sensor_sdk-0.0.4.dist-info → sensor_sdk-0.0.6.dist-info}/zip-safe +0 -0
sensor/sensor_profile.py
CHANGED
|
@@ -13,6 +13,7 @@ from bleak import (
|
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
import sensor
|
|
16
|
+
from sensor import utils
|
|
16
17
|
from sensor.gforce import GForce
|
|
17
18
|
from sensor.sensor_data import DataType, Sample, SensorData
|
|
18
19
|
import asyncio
|
|
@@ -20,7 +21,7 @@ import threading
|
|
|
20
21
|
|
|
21
22
|
from sensor.sensor_data_context import SensorProfileDataCtx
|
|
22
23
|
from sensor.sensor_device import BLEDevice, DeviceInfo, DeviceStateEx
|
|
23
|
-
from sensor.utils import start_loop,
|
|
24
|
+
from sensor.utils import async_call, start_loop, sync_call, async_exec, timer
|
|
24
25
|
from contextlib import suppress
|
|
25
26
|
from dataclasses import dataclass
|
|
26
27
|
|
|
@@ -44,6 +45,7 @@ class SensorProfile:
|
|
|
44
45
|
self,
|
|
45
46
|
device: bleak.BLEDevice,
|
|
46
47
|
adv: bleak.AdvertisementData,
|
|
48
|
+
mac: str,
|
|
47
49
|
gforce_event_loop: asyncio.AbstractEventLoop,
|
|
48
50
|
):
|
|
49
51
|
"""
|
|
@@ -52,7 +54,7 @@ class SensorProfile:
|
|
|
52
54
|
:param device (BLEDevice): 蓝牙设备对象,包含设备的名称、地址和信号强度等信息。
|
|
53
55
|
"""
|
|
54
56
|
self._detail_device = device
|
|
55
|
-
self._device = BLEDevice(device.name,
|
|
57
|
+
self._device = BLEDevice(device.name, mac, adv.rssi)
|
|
56
58
|
self._device_state = DeviceStateEx.Disconnected
|
|
57
59
|
self._on_state_changed: Callable[["SensorProfile", DeviceStateEx], None] = None
|
|
58
60
|
self._on_error_callback: Callable[["SensorProfile", str], None] = None
|
|
@@ -76,15 +78,13 @@ class SensorProfile:
|
|
|
76
78
|
self._destroy()
|
|
77
79
|
|
|
78
80
|
def _destroy(self):
|
|
79
|
-
if
|
|
80
|
-
self._device_state == DeviceStateEx.Connected
|
|
81
|
-
or self._device_state == DeviceStateEx.Ready
|
|
82
|
-
):
|
|
81
|
+
if self._device_state == DeviceStateEx.Connected or self._device_state == DeviceStateEx.Ready:
|
|
83
82
|
self.disconnect()
|
|
84
83
|
if self._data_event_loop != None:
|
|
85
84
|
try:
|
|
86
85
|
self._data_event_loop.stop()
|
|
87
86
|
self._data_event_loop.close()
|
|
87
|
+
self._data_event_loop = None
|
|
88
88
|
self._data_event_thread.join()
|
|
89
89
|
except Exception as e:
|
|
90
90
|
pass
|
|
@@ -92,6 +92,7 @@ class SensorProfile:
|
|
|
92
92
|
try:
|
|
93
93
|
self._event_loop.stop()
|
|
94
94
|
self._event_loop.close()
|
|
95
|
+
self._event_loop = None
|
|
95
96
|
self._event_thread.join()
|
|
96
97
|
except Exception as e:
|
|
97
98
|
pass
|
|
@@ -108,11 +109,9 @@ class SensorProfile:
|
|
|
108
109
|
def _set_device_state(self, newState: DeviceStateEx):
|
|
109
110
|
if self._device_state != newState:
|
|
110
111
|
self._device_state = newState
|
|
111
|
-
if self._on_state_changed != None:
|
|
112
|
+
if self._event_loop != None and self._on_state_changed != None:
|
|
112
113
|
try:
|
|
113
|
-
self._event_loop.call_soon_threadsafe(
|
|
114
|
-
self._on_state_changed, self, newState
|
|
115
|
-
)
|
|
114
|
+
self._event_loop.call_soon_threadsafe(self._on_state_changed, self, newState)
|
|
116
115
|
except Exception as e:
|
|
117
116
|
print(e)
|
|
118
117
|
pass
|
|
@@ -158,9 +157,7 @@ class SensorProfile:
|
|
|
158
157
|
return self._on_state_changed
|
|
159
158
|
|
|
160
159
|
@onStateChanged.setter
|
|
161
|
-
def onStateChanged(
|
|
162
|
-
self, callback: Callable[["SensorProfile", DeviceStateEx], None]
|
|
163
|
-
):
|
|
160
|
+
def onStateChanged(self, callback: Callable[["SensorProfile", DeviceStateEx], None]):
|
|
164
161
|
"""
|
|
165
162
|
设置状态变化的回调函数。
|
|
166
163
|
|
|
@@ -223,17 +220,48 @@ class SensorProfile:
|
|
|
223
220
|
self._on_power_changed = callback
|
|
224
221
|
|
|
225
222
|
async def _connect(self) -> bool:
|
|
226
|
-
if
|
|
227
|
-
self.
|
|
228
|
-
|
|
229
|
-
|
|
223
|
+
if self._event_thread == None:
|
|
224
|
+
self._event_loop = asyncio.new_event_loop()
|
|
225
|
+
self._event_thread = threading.Thread(target=start_loop, args=(self._event_loop,))
|
|
226
|
+
self._event_thread.daemon = True
|
|
227
|
+
self._event_thread.name = self._device.Name + " event"
|
|
228
|
+
self._event_thread.start()
|
|
229
|
+
self._data_buffer: Queue[SensorData] = Queue()
|
|
230
|
+
self._raw_data_buf: Queue[bytes] = Queue()
|
|
231
|
+
|
|
232
|
+
if self._gforce == None:
|
|
233
|
+
if self._adv.service_data.get(SERVICE_GUID) != None:
|
|
234
|
+
# print("OYM_SERVICE:" + self._detail_device.name)
|
|
235
|
+
self._gforce = GForce(
|
|
236
|
+
self._detail_device,
|
|
237
|
+
OYM_CMD_NOTIFY_CHAR_UUID,
|
|
238
|
+
OYM_DATA_NOTIFY_CHAR_UUID,
|
|
239
|
+
False,
|
|
240
|
+
)
|
|
241
|
+
elif self._adv.service_data.get(RFSTAR_SERVICE_GUID) != None:
|
|
242
|
+
# print("RFSTAR_SERVICE:" + self._detail_device.name)
|
|
243
|
+
self._gforce = GForce(self._detail_device, RFSTAR_CMD_UUID, RFSTAR_DATA_UUID, True)
|
|
244
|
+
self._data_event_loop = asyncio.new_event_loop()
|
|
245
|
+
self._data_event_thread = threading.Thread(target=start_loop, args=(self._data_event_loop,))
|
|
246
|
+
self._data_event_thread.daemon = True
|
|
247
|
+
self._data_event_thread.name = self._detail_device.name + " data"
|
|
248
|
+
self._data_event_thread.start()
|
|
249
|
+
else:
|
|
250
|
+
print("Invalid device service uuid:" + self._detail_device.name + str(self._adv))
|
|
251
|
+
return False
|
|
252
|
+
|
|
253
|
+
if self._data_ctx == None and self._gforce != None:
|
|
254
|
+
self._data_ctx = SensorProfileDataCtx(self._gforce, self._device.Address, self._raw_data_buf)
|
|
255
|
+
if self._data_ctx.isUniversalStream:
|
|
256
|
+
async_exec(self._data_event_loop, self._process_universal_data())
|
|
257
|
+
|
|
258
|
+
if self.deviceState == DeviceStateEx.Connected or self.deviceState == DeviceStateEx.Ready:
|
|
230
259
|
return True
|
|
231
260
|
self._set_device_state(DeviceStateEx.Connecting)
|
|
232
261
|
|
|
233
262
|
def handle_disconnect(_: BleakClient):
|
|
234
|
-
self.stopDataNotification()
|
|
235
263
|
self._data_ctx.close()
|
|
236
|
-
time.sleep(1)
|
|
264
|
+
time.sleep(0.1)
|
|
237
265
|
self._data_buffer.queue.clear()
|
|
238
266
|
self._data_ctx = None
|
|
239
267
|
self._gforce = None
|
|
@@ -244,10 +272,11 @@ class SensorProfile:
|
|
|
244
272
|
|
|
245
273
|
if self._gforce.client.is_connected:
|
|
246
274
|
self._set_device_state(DeviceStateEx.Connected)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
275
|
+
self._set_device_state(DeviceStateEx.Ready)
|
|
276
|
+
# if self._gforce.client.mtu_size >= 80:
|
|
277
|
+
# self._set_device_state(DeviceStateEx.Ready)
|
|
278
|
+
# else:
|
|
279
|
+
# self.disconnect()
|
|
251
280
|
else:
|
|
252
281
|
self._set_device_state(DeviceStateEx.Disconnected)
|
|
253
282
|
|
|
@@ -260,55 +289,17 @@ class SensorProfile:
|
|
|
260
289
|
:return: bool: 如果连接成功,返回 True;否则返回 False。
|
|
261
290
|
|
|
262
291
|
"""
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
self._event_thread = threading.Thread(
|
|
266
|
-
target=start_loop, args=(self._event_loop,)
|
|
267
|
-
)
|
|
268
|
-
self._event_thread.daemon = True
|
|
269
|
-
self._event_thread.name = self._device.Name + " event"
|
|
270
|
-
self._event_thread.start()
|
|
271
|
-
self._data_buffer: Queue[SensorData] = Queue()
|
|
272
|
-
self._raw_data_buf: Queue[bytes] = Queue()
|
|
292
|
+
result = sync_call(self._gforce_event_loop, self._connect())
|
|
293
|
+
return result
|
|
273
294
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
self._gforce = GForce(
|
|
278
|
-
self._detail_device,
|
|
279
|
-
OYM_CMD_NOTIFY_CHAR_UUID,
|
|
280
|
-
OYM_DATA_NOTIFY_CHAR_UUID,
|
|
281
|
-
False,
|
|
282
|
-
)
|
|
283
|
-
elif self._adv.service_data.get(RFSTAR_SERVICE_GUID) != None:
|
|
284
|
-
# print("RFSTAR_SERVICE:" + self._detail_device.name)
|
|
285
|
-
self._gforce = GForce(
|
|
286
|
-
self._detail_device, RFSTAR_CMD_UUID, RFSTAR_DATA_UUID, True
|
|
287
|
-
)
|
|
288
|
-
self._data_event_loop = asyncio.new_event_loop()
|
|
289
|
-
self._data_event_thread = threading.Thread(
|
|
290
|
-
target=start_loop, args=(self._data_event_loop,)
|
|
291
|
-
)
|
|
292
|
-
self._data_event_thread.daemon = True
|
|
293
|
-
self._data_event_thread.name = self._detail_device.name + " data"
|
|
294
|
-
self._data_event_thread.start()
|
|
295
|
-
else:
|
|
296
|
-
print(
|
|
297
|
-
"Invalid device service uuid:"
|
|
298
|
-
+ self._detail_device.name
|
|
299
|
-
+ str(self._adv)
|
|
300
|
-
)
|
|
301
|
-
return False
|
|
295
|
+
async def asyncConnect(self) -> bool:
|
|
296
|
+
"""
|
|
297
|
+
连接传感器。
|
|
302
298
|
|
|
303
|
-
|
|
304
|
-
self._data_ctx = SensorProfileDataCtx(
|
|
305
|
-
self._gforce, self._device.Address, self._raw_data_buf
|
|
306
|
-
)
|
|
307
|
-
if self._data_ctx.isUniversalStream:
|
|
308
|
-
timer(self._data_event_loop, 0, self._process_universal_data())
|
|
299
|
+
:return: bool: 如果连接成功,返回 True;否则返回 False。
|
|
309
300
|
|
|
310
|
-
|
|
311
|
-
return
|
|
301
|
+
"""
|
|
302
|
+
return await async_call(self._gforce_event_loop, self._connect())
|
|
312
303
|
|
|
313
304
|
async def _waitForDisconnect(self) -> bool:
|
|
314
305
|
while self.deviceState != DeviceStateEx.Disconnected:
|
|
@@ -316,16 +307,13 @@ class SensorProfile:
|
|
|
316
307
|
return True
|
|
317
308
|
|
|
318
309
|
async def _disconnect(self) -> bool:
|
|
319
|
-
if
|
|
320
|
-
self.deviceState != DeviceStateEx.Connected
|
|
321
|
-
and self.deviceState != DeviceStateEx.Ready
|
|
322
|
-
):
|
|
310
|
+
if self.deviceState != DeviceStateEx.Connected and self.deviceState != DeviceStateEx.Ready:
|
|
323
311
|
return True
|
|
324
312
|
if self._data_ctx == None:
|
|
325
313
|
return False
|
|
326
314
|
self._set_device_state(DeviceStateEx.Disconnecting)
|
|
327
315
|
await self._gforce.disconnect()
|
|
328
|
-
await asyncio.wait_for(self._waitForDisconnect(),
|
|
316
|
+
await asyncio.wait_for(self._waitForDisconnect(), utils._TIMEOUT)
|
|
329
317
|
return True
|
|
330
318
|
|
|
331
319
|
def disconnect(self) -> bool:
|
|
@@ -335,46 +323,37 @@ class SensorProfile:
|
|
|
335
323
|
:return: bool: 如果断开连接成功,返回 True;否则返回 False。
|
|
336
324
|
|
|
337
325
|
"""
|
|
338
|
-
return
|
|
326
|
+
return sync_call(self._gforce_event_loop, self._disconnect())
|
|
327
|
+
|
|
328
|
+
async def asyncDisconnect(self) -> bool:
|
|
329
|
+
"""
|
|
330
|
+
断开传感器连接。
|
|
331
|
+
|
|
332
|
+
:return: bool: 如果断开连接成功,返回 True;否则返回 False。
|
|
333
|
+
|
|
334
|
+
"""
|
|
335
|
+
return await async_call(self._gforce_event_loop, self._disconnect())
|
|
339
336
|
|
|
340
337
|
async def _process_data(self):
|
|
341
338
|
while self._data_ctx._is_running and self._data_ctx.isDataTransfering:
|
|
342
|
-
self._data_ctx.process_data(self._data_buffer)
|
|
339
|
+
self._data_ctx.process_data(self._data_buffer, self)
|
|
343
340
|
while self._data_ctx._is_running and self._data_ctx.isDataTransfering:
|
|
344
341
|
sensorData: SensorData = None
|
|
345
342
|
try:
|
|
346
343
|
sensorData = self._data_buffer.get_nowait()
|
|
347
344
|
except Exception as e:
|
|
348
345
|
break
|
|
349
|
-
if sensorData != None and self._on_data_callback != None:
|
|
346
|
+
if self._event_loop != None and sensorData != None and self._on_data_callback != None:
|
|
350
347
|
try:
|
|
351
|
-
self._event_loop.call_soon_threadsafe(
|
|
352
|
-
self._on_data_callback, self, sensorData
|
|
353
|
-
)
|
|
348
|
+
self._event_loop.call_soon_threadsafe(self._on_data_callback, self, sensorData)
|
|
354
349
|
except Exception as e:
|
|
355
350
|
print(e)
|
|
356
351
|
self._data_buffer.task_done()
|
|
357
352
|
|
|
358
353
|
async def _process_universal_data(self):
|
|
359
|
-
self._data_ctx.processUniversalData(
|
|
360
|
-
self._data_buffer, self._event_loop, self, self._on_data_callback
|
|
361
|
-
)
|
|
354
|
+
self._data_ctx.processUniversalData(self._data_buffer, self._event_loop, self, self._on_data_callback)
|
|
362
355
|
|
|
363
356
|
async def _startDataNotification(self) -> bool:
|
|
364
|
-
result = await self._data_ctx.start_streaming()
|
|
365
|
-
self._data_buffer.queue.clear()
|
|
366
|
-
self._data_ctx.clear()
|
|
367
|
-
if not self._data_ctx.isUniversalStream:
|
|
368
|
-
timer(self._data_event_loop, 0, self._process_data())
|
|
369
|
-
return result
|
|
370
|
-
|
|
371
|
-
def startDataNotification(self) -> bool:
|
|
372
|
-
"""
|
|
373
|
-
开始数据通知。
|
|
374
|
-
|
|
375
|
-
:return: bool: 如果开始数据通知成功,返回 True;否则返回 False。
|
|
376
|
-
|
|
377
|
-
"""
|
|
378
357
|
if self.deviceState != DeviceStateEx.Ready:
|
|
379
358
|
return False
|
|
380
359
|
if self._data_ctx == None:
|
|
@@ -387,26 +366,37 @@ class SensorProfile:
|
|
|
387
366
|
|
|
388
367
|
if self._data_event_loop == None:
|
|
389
368
|
self._data_event_loop = asyncio.new_event_loop()
|
|
390
|
-
self._data_event_thread = threading.Thread(
|
|
391
|
-
target=start_loop, args=(self._data_event_loop,)
|
|
392
|
-
)
|
|
369
|
+
self._data_event_thread = threading.Thread(target=start_loop, args=(self._data_event_loop,))
|
|
393
370
|
self._data_event_thread.daemon = True
|
|
394
371
|
self._data_event_thread.name = self.BLEDevice.Name + " data"
|
|
395
372
|
self._data_event_thread.start()
|
|
396
373
|
|
|
397
|
-
|
|
374
|
+
result = await self._data_ctx.start_streaming()
|
|
375
|
+
self._data_buffer.queue.clear()
|
|
376
|
+
self._data_ctx.clear()
|
|
377
|
+
if not self._data_ctx.isUniversalStream:
|
|
378
|
+
async_exec(self._data_event_loop, self._process_data())
|
|
379
|
+
return result
|
|
380
|
+
|
|
381
|
+
def startDataNotification(self) -> bool:
|
|
382
|
+
"""
|
|
383
|
+
开始数据通知。
|
|
398
384
|
|
|
399
|
-
|
|
385
|
+
:return: bool: 如果开始数据通知成功,返回 True;否则返回 False。
|
|
400
386
|
|
|
401
|
-
|
|
387
|
+
"""
|
|
388
|
+
return sync_call(self._gforce_event_loop, self._startDataNotification())
|
|
402
389
|
|
|
403
|
-
def
|
|
390
|
+
async def asyncStartDataNotification(self) -> bool:
|
|
404
391
|
"""
|
|
405
|
-
|
|
392
|
+
开始数据通知。
|
|
406
393
|
|
|
407
|
-
:return: bool:
|
|
394
|
+
:return: bool: 如果开始数据通知成功,返回 True;否则返回 False。
|
|
408
395
|
|
|
409
396
|
"""
|
|
397
|
+
return await async_call(self._gforce_event_loop, self._startDataNotification())
|
|
398
|
+
|
|
399
|
+
async def _stopDataNotification(self) -> bool:
|
|
410
400
|
if self.deviceState != DeviceStateEx.Ready:
|
|
411
401
|
return False
|
|
412
402
|
if self._data_ctx == None:
|
|
@@ -417,16 +407,32 @@ class SensorProfile:
|
|
|
417
407
|
if not self._data_ctx.isDataTransfering:
|
|
418
408
|
return True
|
|
419
409
|
|
|
420
|
-
return
|
|
410
|
+
return not await self._data_ctx.stop_streaming()
|
|
411
|
+
|
|
412
|
+
def stopDataNotification(self) -> bool:
|
|
413
|
+
"""
|
|
414
|
+
停止数据通知。
|
|
415
|
+
|
|
416
|
+
:return: bool: 如果停止数据通知成功,返回 True;否则返回 False。
|
|
417
|
+
|
|
418
|
+
"""
|
|
419
|
+
return sync_call(self._gforce_event_loop, self._stopDataNotification())
|
|
420
|
+
|
|
421
|
+
async def asyncStopDataNotification(self) -> bool:
|
|
422
|
+
"""
|
|
423
|
+
停止数据通知。
|
|
424
|
+
|
|
425
|
+
:return: bool: 如果停止数据通知成功,返回 True;否则返回 False。
|
|
426
|
+
|
|
427
|
+
"""
|
|
428
|
+
return await async_call(self._gforce_event_loop, self._stopDataNotification())
|
|
421
429
|
|
|
422
430
|
async def _refresh_power(self):
|
|
423
431
|
self._power = await self._gforce.get_battery_level()
|
|
424
432
|
|
|
425
|
-
if self._on_power_changed != None:
|
|
433
|
+
if self._event_loop != None and self._on_power_changed != None:
|
|
426
434
|
try:
|
|
427
|
-
self._event_loop.call_soon_threadsafe(
|
|
428
|
-
self._on_power_changed, self, self._power
|
|
429
|
-
)
|
|
435
|
+
self._event_loop.call_soon_threadsafe(self._on_power_changed, self, self._power)
|
|
430
436
|
except Exception as e:
|
|
431
437
|
print(e)
|
|
432
438
|
|
|
@@ -465,10 +471,26 @@ class SensorProfile:
|
|
|
465
471
|
:return: bool: 初始化结果。True 表示成功,False 表示失败。
|
|
466
472
|
|
|
467
473
|
"""
|
|
468
|
-
return
|
|
474
|
+
return sync_call(
|
|
469
475
|
self._gforce_event_loop,
|
|
470
|
-
0,
|
|
471
476
|
self._init(packageSampleCount, powerRefreshInterval),
|
|
477
|
+
120,
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
async def asyncInit(self, packageSampleCount: int, powerRefreshInterval: int) -> bool:
|
|
481
|
+
"""
|
|
482
|
+
初始化数据采集。
|
|
483
|
+
|
|
484
|
+
:param packageSampleCount (int): 数据包中的样本数量。
|
|
485
|
+
:param powerRefreshInterval (int): 电量刷新间隔。
|
|
486
|
+
|
|
487
|
+
:return: bool: 初始化结果。True 表示成功,False 表示失败。
|
|
488
|
+
|
|
489
|
+
"""
|
|
490
|
+
return await async_call(
|
|
491
|
+
self._gforce_event_loop,
|
|
492
|
+
self._init(packageSampleCount, powerRefreshInterval),
|
|
493
|
+
120,
|
|
472
494
|
)
|
|
473
495
|
|
|
474
496
|
def getBatteryLevel(self) -> int:
|
|
@@ -502,3 +524,15 @@ class SensorProfile:
|
|
|
502
524
|
|
|
503
525
|
"""
|
|
504
526
|
return ""
|
|
527
|
+
|
|
528
|
+
async def AsyncSetParam(self, key: str, value: str) -> str:
|
|
529
|
+
"""
|
|
530
|
+
设置传感器的参数。
|
|
531
|
+
|
|
532
|
+
:param key (str): 参数的键。
|
|
533
|
+
:param value (str): 参数的值。
|
|
534
|
+
|
|
535
|
+
:return: str: 设置参数的结果。
|
|
536
|
+
|
|
537
|
+
"""
|
|
538
|
+
return ""
|
sensor/utils.py
CHANGED
|
@@ -1,30 +1,73 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import platform
|
|
3
|
+
import queue
|
|
2
4
|
import signal
|
|
5
|
+
import time
|
|
3
6
|
|
|
7
|
+
_terminated = False
|
|
8
|
+
_TIMEOUT = 10
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
|
|
11
|
+
async def delay(_time: float, function) -> any:
|
|
12
|
+
await asyncio.sleep(_time)
|
|
8
13
|
return await function
|
|
9
14
|
|
|
10
15
|
|
|
11
|
-
def timer(_loop: asyncio.AbstractEventLoop,
|
|
16
|
+
def timer(_loop: asyncio.AbstractEventLoop, _delay: float, function):
|
|
17
|
+
if _loop == None:
|
|
18
|
+
return
|
|
19
|
+
try:
|
|
20
|
+
asyncio.run_coroutine_threadsafe(delay(_delay, function), _loop)
|
|
21
|
+
except Exception as e:
|
|
22
|
+
print(e)
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
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:
|
|
37
|
+
if _loop == None:
|
|
38
|
+
return
|
|
39
|
+
|
|
12
40
|
try:
|
|
13
|
-
asyncio.run_coroutine_threadsafe(
|
|
41
|
+
f = asyncio.run_coroutine_threadsafe(asyncio.wait_for(function, _timeout), _loop)
|
|
42
|
+
return f.result(timeout=_timeout)
|
|
14
43
|
except Exception as e:
|
|
15
44
|
print(e)
|
|
16
45
|
pass
|
|
17
46
|
|
|
18
47
|
|
|
19
|
-
def
|
|
48
|
+
async def async_call(_loop: asyncio.AbstractEventLoop, function, _timeout=_TIMEOUT) -> any:
|
|
49
|
+
if _loop == None:
|
|
50
|
+
return
|
|
51
|
+
|
|
20
52
|
try:
|
|
21
|
-
f = asyncio.run_coroutine_threadsafe(
|
|
22
|
-
return f.result()
|
|
53
|
+
f = asyncio.run_coroutine_threadsafe(asyncio.wait_for(function, _timeout), _loop)
|
|
23
54
|
except Exception as e:
|
|
24
55
|
print(e)
|
|
25
56
|
pass
|
|
26
57
|
|
|
58
|
+
while not _terminated and not f.done():
|
|
59
|
+
await asyncio.sleep(0.1)
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
if not f.cancelled():
|
|
63
|
+
return f.result()
|
|
64
|
+
except Exception as e:
|
|
65
|
+
print(e)
|
|
66
|
+
return
|
|
67
|
+
|
|
27
68
|
|
|
28
69
|
def start_loop(loop: asyncio.BaseEventLoop):
|
|
70
|
+
if platform.system() == "Darwin":
|
|
71
|
+
asyncio.get_running_loop = asyncio.get_event_loop
|
|
29
72
|
asyncio.set_event_loop(loop)
|
|
30
73
|
loop.run_forever()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sensor-sdk
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.6
|
|
4
4
|
Summary: Python sdk for Synchroni
|
|
5
5
|
Home-page: https://github.com/oymotion/SynchroniSDKPython
|
|
6
6
|
Author: Martin Ye
|
|
@@ -71,6 +71,12 @@ success = SensorControllerInstance.startScan(6000)
|
|
|
71
71
|
|
|
72
72
|
returns true if start scan success, periodInMS means onDeviceCallback will be called every periodInMS
|
|
73
73
|
|
|
74
|
+
Use `def scan(period_in_ms: int) -> list[BLEDevice]` to scan once time
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
bleDevices = SensorControllerInstance.scan(6000)
|
|
78
|
+
```
|
|
79
|
+
|
|
74
80
|
### 3. Stop scan
|
|
75
81
|
|
|
76
82
|
Use `def stopScan() -> None` to stop scan
|
|
@@ -125,7 +131,7 @@ sensorProfiles = SensorControllerInstance.getConnectedSensors()
|
|
|
125
131
|
|
|
126
132
|
### 9. Get Connected BLE Devices
|
|
127
133
|
|
|
128
|
-
Use `def getConnectedDevices() -> list[
|
|
134
|
+
Use `def getConnectedDevices() -> list[BLEDevice]` to get connected BLE Devices.
|
|
129
135
|
|
|
130
136
|
```python
|
|
131
137
|
bleDevices = SensorControllerInstance.getConnectedDevices()
|
|
@@ -343,3 +349,9 @@ batteryPower = sensorProfile.getBatteryLevel()
|
|
|
343
349
|
```
|
|
344
350
|
|
|
345
351
|
Please check console.py in examples directory
|
|
352
|
+
|
|
353
|
+
## Async methods
|
|
354
|
+
|
|
355
|
+
all methods start with async is async methods, they has same params and return result as sync methods.
|
|
356
|
+
|
|
357
|
+
Please check async_console.py in examples directory
|
|
@@ -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=ZVOHV6_NiwGMPAf4BXqlxEHsDrynUBr0rcgqmbJT5oc,24586
|
|
3
|
-
sensor/sensor_controller.py,sha256=UcFsbkXbJsknkVARADB_wT0ZGIDVjHfBFMsmxglF1_0,8334
|
|
4
|
-
sensor/sensor_data.py,sha256=Hu7Ql0LgQ7V24xYZhaLrKPwU4KWZeWE655v8Gy8xphY,3934
|
|
5
|
-
sensor/sensor_data_context.py,sha256=fcGEYWOu5x9UGZ-psvKVKA-nxAKfA8vqMEeA4LjsxAA,27978
|
|
6
|
-
sensor/sensor_device.py,sha256=LCjBzm2TuOh2KpHsFTjm1sF8hzwvS22LhF_ueAct0Jo,2848
|
|
7
|
-
sensor/sensor_profile.py,sha256=NuWYSVGrHWA8y2Goi9UyNyZ3bXE8unKrQ560q8looNw,17873
|
|
8
|
-
sensor/utils.py,sha256=LPLnLTOrrsLnVkL65L10PLtqpjgMYkomyVenRc7pUUo,744
|
|
9
|
-
sensor_sdk-0.0.4.dist-info/LICENSE.txt,sha256=8CSivOpub3IuXODTyqBRI91AxouJZk02YrcKuOAkWu8,1111
|
|
10
|
-
sensor_sdk-0.0.4.dist-info/METADATA,sha256=EYBnMeflySNLB1qxF0OtqRx-xW-FiUo_CFAB89w4el8,8055
|
|
11
|
-
sensor_sdk-0.0.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
12
|
-
sensor_sdk-0.0.4.dist-info/top_level.txt,sha256=Ftq49B6bH0Ffdc7c8LkcyakHo6lsg_snlBbpEUoILSk,7
|
|
13
|
-
sensor_sdk-0.0.4.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
14
|
-
sensor_sdk-0.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|