sensor-sdk 0.0.8__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.8 → sensor-sdk-0.0.10}/PKG-INFO +1 -1
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor/gforce.py +18 -11
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor/sensor_controller.py +23 -25
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor/sensor_data_context.py +33 -285
- {sensor-sdk-0.0.8 → 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.8 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/PKG-INFO +1 -1
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/setup.py +1 -1
- sensor-sdk-0.0.8/sensor/utils.py +0 -73
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/LICENSE.txt +0 -0
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/README.md +0 -0
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor/__init__.py +0 -0
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor/sensor_data.py +0 -0
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor/sensor_device.py +0 -0
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/SOURCES.txt +0 -0
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/dependency_links.txt +0 -0
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/requires.txt +0 -0
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/top_level.txt +0 -0
- {sensor-sdk-0.0.8 → sensor-sdk-0.0.10}/sensor_sdk.egg-info/zip-safe +0 -0
- {sensor-sdk-0.0.8 → 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,6 +5,7 @@ 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
|
|
|
@@ -284,14 +285,32 @@ class SensorProfileDataCtx:
|
|
|
284
285
|
await self.gForce.set_subscription(0)
|
|
285
286
|
return True
|
|
286
287
|
|
|
287
|
-
def process_data(self, buf: Queue[SensorData], sensor):
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
except Exception as e:
|
|
291
|
-
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)
|
|
292
291
|
|
|
293
|
-
|
|
294
|
-
|
|
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()
|
|
295
314
|
|
|
296
315
|
def _processDataPackage(self, data: bytes, buf: Queue[SensorData], sensor):
|
|
297
316
|
v = data[0]
|
|
@@ -370,7 +389,7 @@ class SensorProfileDataCtx:
|
|
|
370
389
|
# print(lostLog)
|
|
371
390
|
if sensor._event_loop != None and sensor._on_error_callback != None:
|
|
372
391
|
try:
|
|
373
|
-
|
|
392
|
+
asyncio.get_event_loop().run_in_executor(None, sensor._on_error_callback, sensor, lostLog)
|
|
374
393
|
except Exception as e:
|
|
375
394
|
pass
|
|
376
395
|
|
|
@@ -522,277 +541,7 @@ class SensorProfileDataCtx:
|
|
|
522
541
|
for sensorDataResult in sensorDataList:
|
|
523
542
|
buf.put(sensorDataResult)
|
|
524
543
|
|
|
525
|
-
def
|
|
526
|
-
crc8Table = [
|
|
527
|
-
0x00,
|
|
528
|
-
0x07,
|
|
529
|
-
0x0E,
|
|
530
|
-
0x09,
|
|
531
|
-
0x1C,
|
|
532
|
-
0x1B,
|
|
533
|
-
0x12,
|
|
534
|
-
0x15,
|
|
535
|
-
0x38,
|
|
536
|
-
0x3F,
|
|
537
|
-
0x36,
|
|
538
|
-
0x31,
|
|
539
|
-
0x24,
|
|
540
|
-
0x23,
|
|
541
|
-
0x2A,
|
|
542
|
-
0x2D,
|
|
543
|
-
0x70,
|
|
544
|
-
0x77,
|
|
545
|
-
0x7E,
|
|
546
|
-
0x79,
|
|
547
|
-
0x6C,
|
|
548
|
-
0x6B,
|
|
549
|
-
0x62,
|
|
550
|
-
0x65,
|
|
551
|
-
0x48,
|
|
552
|
-
0x4F,
|
|
553
|
-
0x46,
|
|
554
|
-
0x41,
|
|
555
|
-
0x54,
|
|
556
|
-
0x53,
|
|
557
|
-
0x5A,
|
|
558
|
-
0x5D,
|
|
559
|
-
0xE0,
|
|
560
|
-
0xE7,
|
|
561
|
-
0xEE,
|
|
562
|
-
0xE9,
|
|
563
|
-
0xFC,
|
|
564
|
-
0xFB,
|
|
565
|
-
0xF2,
|
|
566
|
-
0xF5,
|
|
567
|
-
0xD8,
|
|
568
|
-
0xDF,
|
|
569
|
-
0xD6,
|
|
570
|
-
0xD1,
|
|
571
|
-
0xC4,
|
|
572
|
-
0xC3,
|
|
573
|
-
0xCA,
|
|
574
|
-
0xCD,
|
|
575
|
-
0x90,
|
|
576
|
-
0x97,
|
|
577
|
-
0x9E,
|
|
578
|
-
0x99,
|
|
579
|
-
0x8C,
|
|
580
|
-
0x8B,
|
|
581
|
-
0x82,
|
|
582
|
-
0x85,
|
|
583
|
-
0xA8,
|
|
584
|
-
0xAF,
|
|
585
|
-
0xA6,
|
|
586
|
-
0xA1,
|
|
587
|
-
0xB4,
|
|
588
|
-
0xB3,
|
|
589
|
-
0xBA,
|
|
590
|
-
0xBD,
|
|
591
|
-
0xC7,
|
|
592
|
-
0xC0,
|
|
593
|
-
0xC9,
|
|
594
|
-
0xCE,
|
|
595
|
-
0xDB,
|
|
596
|
-
0xDC,
|
|
597
|
-
0xD5,
|
|
598
|
-
0xD2,
|
|
599
|
-
0xFF,
|
|
600
|
-
0xF8,
|
|
601
|
-
0xF1,
|
|
602
|
-
0xF6,
|
|
603
|
-
0xE3,
|
|
604
|
-
0xE4,
|
|
605
|
-
0xED,
|
|
606
|
-
0xEA,
|
|
607
|
-
0xB7,
|
|
608
|
-
0xB0,
|
|
609
|
-
0xB9,
|
|
610
|
-
0xBE,
|
|
611
|
-
0xAB,
|
|
612
|
-
0xAC,
|
|
613
|
-
0xA5,
|
|
614
|
-
0xA2,
|
|
615
|
-
0x8F,
|
|
616
|
-
0x88,
|
|
617
|
-
0x81,
|
|
618
|
-
0x86,
|
|
619
|
-
0x93,
|
|
620
|
-
0x94,
|
|
621
|
-
0x9D,
|
|
622
|
-
0x9A,
|
|
623
|
-
0x27,
|
|
624
|
-
0x20,
|
|
625
|
-
0x29,
|
|
626
|
-
0x2E,
|
|
627
|
-
0x3B,
|
|
628
|
-
0x3C,
|
|
629
|
-
0x35,
|
|
630
|
-
0x32,
|
|
631
|
-
0x1F,
|
|
632
|
-
0x18,
|
|
633
|
-
0x11,
|
|
634
|
-
0x16,
|
|
635
|
-
0x03,
|
|
636
|
-
0x04,
|
|
637
|
-
0x0D,
|
|
638
|
-
0x0A,
|
|
639
|
-
0x57,
|
|
640
|
-
0x50,
|
|
641
|
-
0x59,
|
|
642
|
-
0x5E,
|
|
643
|
-
0x4B,
|
|
644
|
-
0x4C,
|
|
645
|
-
0x45,
|
|
646
|
-
0x42,
|
|
647
|
-
0x6F,
|
|
648
|
-
0x68,
|
|
649
|
-
0x61,
|
|
650
|
-
0x66,
|
|
651
|
-
0x73,
|
|
652
|
-
0x74,
|
|
653
|
-
0x7D,
|
|
654
|
-
0x7A,
|
|
655
|
-
0x89,
|
|
656
|
-
0x8E,
|
|
657
|
-
0x87,
|
|
658
|
-
0x80,
|
|
659
|
-
0x95,
|
|
660
|
-
0x92,
|
|
661
|
-
0x9B,
|
|
662
|
-
0x9C,
|
|
663
|
-
0xB1,
|
|
664
|
-
0xB6,
|
|
665
|
-
0xBF,
|
|
666
|
-
0xB8,
|
|
667
|
-
0xAD,
|
|
668
|
-
0xAA,
|
|
669
|
-
0xA3,
|
|
670
|
-
0xA4,
|
|
671
|
-
0xF9,
|
|
672
|
-
0xFE,
|
|
673
|
-
0xF7,
|
|
674
|
-
0xF0,
|
|
675
|
-
0xE5,
|
|
676
|
-
0xE2,
|
|
677
|
-
0xEB,
|
|
678
|
-
0xEC,
|
|
679
|
-
0xC1,
|
|
680
|
-
0xC6,
|
|
681
|
-
0xCF,
|
|
682
|
-
0xC8,
|
|
683
|
-
0xDD,
|
|
684
|
-
0xDA,
|
|
685
|
-
0xD3,
|
|
686
|
-
0xD4,
|
|
687
|
-
0x69,
|
|
688
|
-
0x6E,
|
|
689
|
-
0x67,
|
|
690
|
-
0x60,
|
|
691
|
-
0x75,
|
|
692
|
-
0x72,
|
|
693
|
-
0x7B,
|
|
694
|
-
0x7C,
|
|
695
|
-
0x51,
|
|
696
|
-
0x56,
|
|
697
|
-
0x5F,
|
|
698
|
-
0x58,
|
|
699
|
-
0x4D,
|
|
700
|
-
0x4A,
|
|
701
|
-
0x43,
|
|
702
|
-
0x44,
|
|
703
|
-
0x19,
|
|
704
|
-
0x1E,
|
|
705
|
-
0x17,
|
|
706
|
-
0x10,
|
|
707
|
-
0x05,
|
|
708
|
-
0x02,
|
|
709
|
-
0x0B,
|
|
710
|
-
0x0C,
|
|
711
|
-
0x21,
|
|
712
|
-
0x26,
|
|
713
|
-
0x2F,
|
|
714
|
-
0x28,
|
|
715
|
-
0x3D,
|
|
716
|
-
0x3A,
|
|
717
|
-
0x33,
|
|
718
|
-
0x34,
|
|
719
|
-
0x4E,
|
|
720
|
-
0x49,
|
|
721
|
-
0x40,
|
|
722
|
-
0x47,
|
|
723
|
-
0x52,
|
|
724
|
-
0x55,
|
|
725
|
-
0x5C,
|
|
726
|
-
0x5B,
|
|
727
|
-
0x76,
|
|
728
|
-
0x71,
|
|
729
|
-
0x78,
|
|
730
|
-
0x7F,
|
|
731
|
-
0x6A,
|
|
732
|
-
0x6D,
|
|
733
|
-
0x64,
|
|
734
|
-
0x63,
|
|
735
|
-
0x3E,
|
|
736
|
-
0x39,
|
|
737
|
-
0x30,
|
|
738
|
-
0x37,
|
|
739
|
-
0x22,
|
|
740
|
-
0x25,
|
|
741
|
-
0x2C,
|
|
742
|
-
0x2B,
|
|
743
|
-
0x06,
|
|
744
|
-
0x01,
|
|
745
|
-
0x08,
|
|
746
|
-
0x0F,
|
|
747
|
-
0x1A,
|
|
748
|
-
0x1D,
|
|
749
|
-
0x14,
|
|
750
|
-
0x13,
|
|
751
|
-
0xAE,
|
|
752
|
-
0xA9,
|
|
753
|
-
0xA0,
|
|
754
|
-
0xA7,
|
|
755
|
-
0xB2,
|
|
756
|
-
0xB5,
|
|
757
|
-
0xBC,
|
|
758
|
-
0xBB,
|
|
759
|
-
0x96,
|
|
760
|
-
0x91,
|
|
761
|
-
0x98,
|
|
762
|
-
0x9F,
|
|
763
|
-
0x8A,
|
|
764
|
-
0x8D,
|
|
765
|
-
0x84,
|
|
766
|
-
0x83,
|
|
767
|
-
0xDE,
|
|
768
|
-
0xD9,
|
|
769
|
-
0xD0,
|
|
770
|
-
0xD7,
|
|
771
|
-
0xC2,
|
|
772
|
-
0xC5,
|
|
773
|
-
0xCC,
|
|
774
|
-
0xCB,
|
|
775
|
-
0xE6,
|
|
776
|
-
0xE1,
|
|
777
|
-
0xE8,
|
|
778
|
-
0xEF,
|
|
779
|
-
0xFA,
|
|
780
|
-
0xFD,
|
|
781
|
-
0xF4,
|
|
782
|
-
0xF3,
|
|
783
|
-
]
|
|
784
|
-
crc8 = 0
|
|
785
|
-
len_data = len(data)
|
|
786
|
-
|
|
787
|
-
for i in range(len_data):
|
|
788
|
-
crc8 ^= data[i]
|
|
789
|
-
crc8 = crc8Table[crc8]
|
|
790
|
-
|
|
791
|
-
return crc8
|
|
792
|
-
|
|
793
|
-
async def processUniversalData(
|
|
794
|
-
self, buf: Queue[SensorData], event_loop: asyncio.AbstractEventLoop, cmd_loop: asyncio.AbstractEventLoop, sensor, callback
|
|
795
|
-
):
|
|
544
|
+
async def processUniversalData(self, buf: Queue[SensorData], sensor, callback):
|
|
796
545
|
|
|
797
546
|
while self._is_running:
|
|
798
547
|
while self._is_running and self._rawDataBuffer.empty():
|
|
@@ -824,7 +573,7 @@ class SensorProfileDataCtx:
|
|
|
824
573
|
index += 1
|
|
825
574
|
continue
|
|
826
575
|
crc = self._concatDataBuffer[index + 1 + n + 1]
|
|
827
|
-
calc_crc =
|
|
576
|
+
calc_crc = utils.calc_crc8(self._concatDataBuffer[index + 2 : index + 2 + n])
|
|
828
577
|
if crc != calc_crc:
|
|
829
578
|
index += 1
|
|
830
579
|
continue
|
|
@@ -837,9 +586,9 @@ class SensorProfileDataCtx:
|
|
|
837
586
|
sensorData = buf.get_nowait()
|
|
838
587
|
except Exception as e:
|
|
839
588
|
break
|
|
840
|
-
if
|
|
589
|
+
if sensorData != None and callback != None:
|
|
841
590
|
try:
|
|
842
|
-
|
|
591
|
+
asyncio.get_event_loop().run_in_executor(None, callback, sensor, sensorData)
|
|
843
592
|
except Exception as e:
|
|
844
593
|
print(e)
|
|
845
594
|
|
|
@@ -855,13 +604,12 @@ class SensorProfileDataCtx:
|
|
|
855
604
|
index += 1
|
|
856
605
|
continue
|
|
857
606
|
crc = self._concatDataBuffer[index + 1 + n + 1]
|
|
858
|
-
calc_crc =
|
|
607
|
+
calc_crc = utils.calc_crc8(self._concatDataBuffer[index + 2 : index + 2 + n])
|
|
859
608
|
if crc != calc_crc:
|
|
860
609
|
index += 1
|
|
861
610
|
continue
|
|
862
611
|
data_package = bytes(self._concatDataBuffer[index + 2 : index + 2 + n])
|
|
863
|
-
|
|
864
|
-
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)
|
|
865
613
|
last_cut = index = index + 2 + n
|
|
866
614
|
|
|
867
615
|
else:
|
|
@@ -2,28 +2,23 @@
|
|
|
2
2
|
# 该枚举类定义了设备的各种状态,用于表示设备在不同操作阶段的状态信息
|
|
3
3
|
from enum import Enum, IntEnum
|
|
4
4
|
from queue import Queue
|
|
5
|
-
import struct
|
|
6
5
|
import time
|
|
7
|
-
from typing import Callable,
|
|
6
|
+
from typing import Callable, Optional
|
|
8
7
|
|
|
9
8
|
import bleak
|
|
10
9
|
from bleak import (
|
|
11
10
|
BleakClient,
|
|
12
|
-
BleakGATTCharacteristic,
|
|
13
11
|
)
|
|
14
12
|
|
|
15
|
-
import sensor
|
|
16
13
|
from sensor import utils
|
|
17
14
|
from sensor.gforce import GForce
|
|
18
|
-
from sensor.sensor_data import
|
|
15
|
+
from sensor.sensor_data import SensorData
|
|
19
16
|
import asyncio
|
|
20
|
-
|
|
17
|
+
|
|
21
18
|
|
|
22
19
|
from sensor.sensor_data_context import SensorProfileDataCtx
|
|
23
20
|
from sensor.sensor_device import BLEDevice, DeviceInfo, DeviceStateEx
|
|
24
|
-
from sensor.utils import async_call,
|
|
25
|
-
from contextlib import suppress
|
|
26
|
-
from dataclasses import dataclass
|
|
21
|
+
from sensor.utils import async_call, sync_call, async_exec, timer
|
|
27
22
|
|
|
28
23
|
SERVICE_GUID = "0000ffd0-0000-1000-8000-00805f9b34fb"
|
|
29
24
|
OYM_CMD_NOTIFY_CHAR_UUID = "f000ffe1-0451-4000-b000-000000000000"
|
|
@@ -46,7 +41,6 @@ class SensorProfile:
|
|
|
46
41
|
device: bleak.BLEDevice,
|
|
47
42
|
adv: bleak.AdvertisementData,
|
|
48
43
|
mac: str,
|
|
49
|
-
gforce_event_loop: asyncio.AbstractEventLoop,
|
|
50
44
|
):
|
|
51
45
|
"""
|
|
52
46
|
初始化 SensorProfile 类的实例。
|
|
@@ -66,9 +60,7 @@ class SensorProfile:
|
|
|
66
60
|
self._data_ctx: SensorProfileDataCtx = None
|
|
67
61
|
self._gforce: GForce = None
|
|
68
62
|
self._data_event_loop: asyncio.AbstractEventLoop = None
|
|
69
|
-
self._gforce_event_loop: asyncio.AbstractEventLoop = gforce_event_loop
|
|
70
63
|
self._event_loop: asyncio.AbstractEventLoop = None
|
|
71
|
-
self._event_thread = None
|
|
72
64
|
|
|
73
65
|
def __del__(self) -> None:
|
|
74
66
|
"""
|
|
@@ -85,7 +77,6 @@ class SensorProfile:
|
|
|
85
77
|
self._data_event_loop.stop()
|
|
86
78
|
self._data_event_loop.close()
|
|
87
79
|
self._data_event_loop = None
|
|
88
|
-
self._data_event_thread.join()
|
|
89
80
|
except Exception as e:
|
|
90
81
|
pass
|
|
91
82
|
if self._event_loop != None:
|
|
@@ -93,7 +84,6 @@ class SensorProfile:
|
|
|
93
84
|
self._event_loop.stop()
|
|
94
85
|
self._event_loop.close()
|
|
95
86
|
self._event_loop = None
|
|
96
|
-
self._event_thread.join()
|
|
97
87
|
except Exception as e:
|
|
98
88
|
pass
|
|
99
89
|
|
|
@@ -111,7 +101,7 @@ class SensorProfile:
|
|
|
111
101
|
self._device_state = newState
|
|
112
102
|
if self._event_loop != None and self._on_state_changed != None:
|
|
113
103
|
try:
|
|
114
|
-
|
|
104
|
+
asyncio.get_event_loop().run_in_executor(None, self._on_state_changed, self, newState)
|
|
115
105
|
except Exception as e:
|
|
116
106
|
print(e)
|
|
117
107
|
pass
|
|
@@ -220,12 +210,11 @@ class SensorProfile:
|
|
|
220
210
|
self._on_power_changed = callback
|
|
221
211
|
|
|
222
212
|
async def _connect(self) -> bool:
|
|
223
|
-
if
|
|
213
|
+
if utils._terminated:
|
|
214
|
+
return False
|
|
215
|
+
|
|
216
|
+
if self._event_loop == None:
|
|
224
217
|
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
218
|
self._data_buffer: Queue[SensorData] = Queue()
|
|
230
219
|
self._raw_data_buf: Queue[bytes] = Queue()
|
|
231
220
|
|
|
@@ -242,10 +231,6 @@ class SensorProfile:
|
|
|
242
231
|
# print("RFSTAR_SERVICE:" + self._detail_device.name)
|
|
243
232
|
self._gforce = GForce(self._detail_device, RFSTAR_CMD_UUID, RFSTAR_DATA_UUID, True)
|
|
244
233
|
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
234
|
else:
|
|
250
235
|
print("Invalid device service uuid:" + self._detail_device.name + str(self._adv))
|
|
251
236
|
return False
|
|
@@ -253,24 +238,25 @@ class SensorProfile:
|
|
|
253
238
|
if self._data_ctx == None and self._gforce != None:
|
|
254
239
|
self._data_ctx = SensorProfileDataCtx(self._gforce, self._device.Address, self._raw_data_buf)
|
|
255
240
|
if self._data_ctx.isUniversalStream:
|
|
256
|
-
async_exec(self.
|
|
241
|
+
async_exec(self._process_universal_data())
|
|
257
242
|
|
|
258
243
|
if self.deviceState == DeviceStateEx.Connected or self.deviceState == DeviceStateEx.Ready:
|
|
259
244
|
return True
|
|
260
245
|
self._set_device_state(DeviceStateEx.Connecting)
|
|
261
246
|
|
|
262
247
|
def handle_disconnect(_: BleakClient):
|
|
263
|
-
self._data_ctx
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
248
|
+
if self._data_ctx != None:
|
|
249
|
+
self._data_ctx.close()
|
|
250
|
+
time.sleep(1)
|
|
251
|
+
self._data_buffer.queue.clear()
|
|
252
|
+
self._data_ctx = None
|
|
253
|
+
self._gforce = None
|
|
268
254
|
self._set_device_state(DeviceStateEx.Disconnected)
|
|
269
255
|
pass
|
|
270
256
|
|
|
271
257
|
await self._gforce.connect(handle_disconnect, self._raw_data_buf)
|
|
272
258
|
|
|
273
|
-
if self._gforce.client.is_connected:
|
|
259
|
+
if self._gforce != None and self._gforce.client.is_connected:
|
|
274
260
|
self._set_device_state(DeviceStateEx.Connected)
|
|
275
261
|
self._set_device_state(DeviceStateEx.Ready)
|
|
276
262
|
# if self._gforce.client.mtu_size >= 80:
|
|
@@ -289,7 +275,7 @@ class SensorProfile:
|
|
|
289
275
|
:return: bool: 如果连接成功,返回 True;否则返回 False。
|
|
290
276
|
|
|
291
277
|
"""
|
|
292
|
-
result = sync_call(self.
|
|
278
|
+
result = sync_call(self._connect())
|
|
293
279
|
return result
|
|
294
280
|
|
|
295
281
|
async def asyncConnect(self) -> bool:
|
|
@@ -299,7 +285,7 @@ class SensorProfile:
|
|
|
299
285
|
:return: bool: 如果连接成功,返回 True;否则返回 False。
|
|
300
286
|
|
|
301
287
|
"""
|
|
302
|
-
return await async_call(self.
|
|
288
|
+
return await async_call(self._connect())
|
|
303
289
|
|
|
304
290
|
async def _waitForDisconnect(self) -> bool:
|
|
305
291
|
while self.deviceState != DeviceStateEx.Disconnected:
|
|
@@ -314,6 +300,7 @@ class SensorProfile:
|
|
|
314
300
|
self._set_device_state(DeviceStateEx.Disconnecting)
|
|
315
301
|
await self._gforce.disconnect()
|
|
316
302
|
await asyncio.wait_for(self._waitForDisconnect(), utils._TIMEOUT)
|
|
303
|
+
|
|
317
304
|
return True
|
|
318
305
|
|
|
319
306
|
def disconnect(self) -> bool:
|
|
@@ -323,7 +310,7 @@ class SensorProfile:
|
|
|
323
310
|
:return: bool: 如果断开连接成功,返回 True;否则返回 False。
|
|
324
311
|
|
|
325
312
|
"""
|
|
326
|
-
return sync_call(self.
|
|
313
|
+
return sync_call(self._disconnect())
|
|
327
314
|
|
|
328
315
|
async def asyncDisconnect(self) -> bool:
|
|
329
316
|
"""
|
|
@@ -332,28 +319,13 @@ class SensorProfile:
|
|
|
332
319
|
:return: bool: 如果断开连接成功,返回 True;否则返回 False。
|
|
333
320
|
|
|
334
321
|
"""
|
|
335
|
-
return await async_call(self.
|
|
322
|
+
return await async_call(self._disconnect())
|
|
336
323
|
|
|
337
324
|
async def _process_data(self):
|
|
338
|
-
|
|
339
|
-
self._data_ctx.process_data(self._data_buffer, self)
|
|
340
|
-
while self._data_ctx._is_running and self._data_ctx.isDataTransfering:
|
|
341
|
-
sensorData: SensorData = None
|
|
342
|
-
try:
|
|
343
|
-
sensorData = self._data_buffer.get_nowait()
|
|
344
|
-
except Exception as e:
|
|
345
|
-
break
|
|
346
|
-
if self._event_loop != None and sensorData != None and self._on_data_callback != None:
|
|
347
|
-
try:
|
|
348
|
-
self._event_loop.call_soon_threadsafe(self._on_data_callback, self, sensorData)
|
|
349
|
-
except Exception as e:
|
|
350
|
-
print(e)
|
|
351
|
-
self._data_buffer.task_done()
|
|
325
|
+
await self._data_ctx.process_data(self._data_buffer, self, self._on_data_callback)
|
|
352
326
|
|
|
353
327
|
async def _process_universal_data(self):
|
|
354
|
-
await self._data_ctx.processUniversalData(
|
|
355
|
-
self._data_buffer, self._event_loop, self._gforce_event_loop, self, self._on_data_callback
|
|
356
|
-
)
|
|
328
|
+
await self._data_ctx.processUniversalData(self._data_buffer, self, self._on_data_callback)
|
|
357
329
|
|
|
358
330
|
async def _startDataNotification(self) -> bool:
|
|
359
331
|
if self.deviceState != DeviceStateEx.Ready:
|
|
@@ -368,16 +340,12 @@ class SensorProfile:
|
|
|
368
340
|
|
|
369
341
|
if self._data_event_loop == None:
|
|
370
342
|
self._data_event_loop = asyncio.new_event_loop()
|
|
371
|
-
self._data_event_thread = threading.Thread(target=start_loop, args=(self._data_event_loop,))
|
|
372
|
-
self._data_event_thread.daemon = True
|
|
373
|
-
self._data_event_thread.name = self.BLEDevice.Name + " data"
|
|
374
|
-
self._data_event_thread.start()
|
|
375
343
|
|
|
376
344
|
result = await self._data_ctx.start_streaming()
|
|
377
345
|
self._data_buffer.queue.clear()
|
|
378
346
|
self._data_ctx.clear()
|
|
379
347
|
if not self._data_ctx.isUniversalStream:
|
|
380
|
-
async_exec(self.
|
|
348
|
+
async_exec(self._process_data())
|
|
381
349
|
return result
|
|
382
350
|
|
|
383
351
|
def startDataNotification(self) -> bool:
|
|
@@ -387,7 +355,7 @@ class SensorProfile:
|
|
|
387
355
|
:return: bool: 如果开始数据通知成功,返回 True;否则返回 False。
|
|
388
356
|
|
|
389
357
|
"""
|
|
390
|
-
return sync_call(self.
|
|
358
|
+
return sync_call(self._startDataNotification())
|
|
391
359
|
|
|
392
360
|
async def asyncStartDataNotification(self) -> bool:
|
|
393
361
|
"""
|
|
@@ -396,7 +364,7 @@ class SensorProfile:
|
|
|
396
364
|
:return: bool: 如果开始数据通知成功,返回 True;否则返回 False。
|
|
397
365
|
|
|
398
366
|
"""
|
|
399
|
-
return await async_call(self.
|
|
367
|
+
return await async_call(self._startDataNotification())
|
|
400
368
|
|
|
401
369
|
async def _stopDataNotification(self) -> bool:
|
|
402
370
|
if self.deviceState != DeviceStateEx.Ready:
|
|
@@ -418,7 +386,7 @@ class SensorProfile:
|
|
|
418
386
|
:return: bool: 如果停止数据通知成功,返回 True;否则返回 False。
|
|
419
387
|
|
|
420
388
|
"""
|
|
421
|
-
return sync_call(self.
|
|
389
|
+
return sync_call(self._stopDataNotification())
|
|
422
390
|
|
|
423
391
|
async def asyncStopDataNotification(self) -> bool:
|
|
424
392
|
"""
|
|
@@ -427,23 +395,19 @@ class SensorProfile:
|
|
|
427
395
|
:return: bool: 如果停止数据通知成功,返回 True;否则返回 False。
|
|
428
396
|
|
|
429
397
|
"""
|
|
430
|
-
return await async_call(self.
|
|
398
|
+
return await async_call(self._stopDataNotification())
|
|
431
399
|
|
|
432
400
|
async def _refresh_power(self):
|
|
433
|
-
|
|
401
|
+
while not utils._terminated and self.deviceState == DeviceStateEx.Ready:
|
|
402
|
+
await asyncio.sleep(self._power_interval / 1000)
|
|
434
403
|
|
|
435
|
-
|
|
436
|
-
try:
|
|
437
|
-
self._event_loop.call_soon_threadsafe(self._on_power_changed, self, self._power)
|
|
438
|
-
except Exception as e:
|
|
439
|
-
print(e)
|
|
404
|
+
self._power = await self._gforce.get_battery_level()
|
|
440
405
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
)
|
|
406
|
+
if self._event_loop != None and self._on_power_changed != None:
|
|
407
|
+
try:
|
|
408
|
+
asyncio.get_event_loop().run_in_executor(None, self._on_power_changed, self, self._power)
|
|
409
|
+
except Exception as e:
|
|
410
|
+
print(e)
|
|
447
411
|
|
|
448
412
|
async def _init(self, packageSampleCount: int, powerRefreshInterval: int) -> bool:
|
|
449
413
|
if self.deviceState != DeviceStateEx.Ready:
|
|
@@ -455,11 +419,7 @@ class SensorProfile:
|
|
|
455
419
|
|
|
456
420
|
if await self._data_ctx.init(packageSampleCount):
|
|
457
421
|
self._power_interval = powerRefreshInterval
|
|
458
|
-
|
|
459
|
-
self._gforce_event_loop,
|
|
460
|
-
self._power_interval / 1000,
|
|
461
|
-
self._refresh_power(),
|
|
462
|
-
)
|
|
422
|
+
utils.async_exec(self._refresh_power())
|
|
463
423
|
|
|
464
424
|
return self._data_ctx.hasInit()
|
|
465
425
|
|
|
@@ -474,7 +434,6 @@ class SensorProfile:
|
|
|
474
434
|
|
|
475
435
|
"""
|
|
476
436
|
return sync_call(
|
|
477
|
-
self._gforce_event_loop,
|
|
478
437
|
self._init(packageSampleCount, powerRefreshInterval),
|
|
479
438
|
20,
|
|
480
439
|
)
|
|
@@ -490,7 +449,6 @@ class SensorProfile:
|
|
|
490
449
|
|
|
491
450
|
"""
|
|
492
451
|
return await async_call(
|
|
493
|
-
self._gforce_event_loop,
|
|
494
452
|
self._init(packageSampleCount, powerRefreshInterval),
|
|
495
453
|
20,
|
|
496
454
|
)
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import platform
|
|
3
|
+
import queue
|
|
4
|
+
import signal
|
|
5
|
+
import threading
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
_terminated = False
|
|
9
|
+
_TIMEOUT = 10
|
|
10
|
+
running_tasks = set()
|
|
11
|
+
_runloop: asyncio.AbstractEventLoop = None
|
|
12
|
+
_event_thread: threading.Thread = None
|
|
13
|
+
_needCloseRunloop = False
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def checkRunLoop():
|
|
17
|
+
global _runloop, _needCloseRunloop, _event_thread
|
|
18
|
+
if _runloop == None:
|
|
19
|
+
try:
|
|
20
|
+
_runloop = asyncio.get_running_loop()
|
|
21
|
+
except Exception as e:
|
|
22
|
+
_needCloseRunloop = True
|
|
23
|
+
_runloop = asyncio.new_event_loop()
|
|
24
|
+
_event_thread = threading.Thread(target=start_loop, args=(_runloop,))
|
|
25
|
+
_event_thread.daemon = True
|
|
26
|
+
_event_thread.name = "SensorController event"
|
|
27
|
+
_event_thread.start()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def Terminate():
|
|
31
|
+
global _runloop, _needCloseRunloop, _event_thread
|
|
32
|
+
if _needCloseRunloop:
|
|
33
|
+
try:
|
|
34
|
+
_runloop.stop()
|
|
35
|
+
_runloop.close()
|
|
36
|
+
except Exception as e:
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
async def delay(_time: float, function) -> any:
|
|
41
|
+
try:
|
|
42
|
+
await asyncio.sleep(_time)
|
|
43
|
+
except Exception as e:
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
return await function
|
|
48
|
+
except Exception as e:
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def timer(_delay: float, function):
|
|
53
|
+
checkRunLoop()
|
|
54
|
+
task: asyncio.Future = None
|
|
55
|
+
try:
|
|
56
|
+
task = asyncio.run_coroutine_threadsafe(delay(_delay, function), _runloop)
|
|
57
|
+
running_tasks.add(task)
|
|
58
|
+
task.add_done_callback(lambda t: running_tasks.remove(t))
|
|
59
|
+
except Exception as e:
|
|
60
|
+
print(e)
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def async_exec(function):
|
|
65
|
+
checkRunLoop()
|
|
66
|
+
task: asyncio.Future = None
|
|
67
|
+
try:
|
|
68
|
+
task = asyncio.run_coroutine_threadsafe(function, _runloop)
|
|
69
|
+
running_tasks.add(task)
|
|
70
|
+
task.add_done_callback(lambda t: running_tasks.remove(t))
|
|
71
|
+
except Exception as e:
|
|
72
|
+
print(e)
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def sync_call(function, _timeout=_TIMEOUT) -> any:
|
|
77
|
+
checkRunLoop()
|
|
78
|
+
task: asyncio.Future = None
|
|
79
|
+
try:
|
|
80
|
+
task = asyncio.run_coroutine_threadsafe(asyncio.wait_for(function, _timeout), _runloop)
|
|
81
|
+
running_tasks.add(task)
|
|
82
|
+
task.add_done_callback(lambda t: running_tasks.remove(t))
|
|
83
|
+
return task.result(timeout=_timeout)
|
|
84
|
+
except Exception as e:
|
|
85
|
+
print(e)
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
async def async_call(function, _timeout=_TIMEOUT) -> any:
|
|
90
|
+
checkRunLoop()
|
|
91
|
+
task: asyncio.Future = None
|
|
92
|
+
try:
|
|
93
|
+
task = asyncio.run_coroutine_threadsafe(asyncio.wait_for(function, _timeout), _runloop)
|
|
94
|
+
running_tasks.add(task)
|
|
95
|
+
task.add_done_callback(lambda t: running_tasks.remove(t))
|
|
96
|
+
except Exception as e:
|
|
97
|
+
print(e)
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
while not _terminated and not task.done():
|
|
101
|
+
await asyncio.sleep(0.1)
|
|
102
|
+
|
|
103
|
+
try:
|
|
104
|
+
if not task.cancelled():
|
|
105
|
+
return task.result()
|
|
106
|
+
except Exception as e:
|
|
107
|
+
print(e)
|
|
108
|
+
return
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def start_loop(loop: asyncio.BaseEventLoop):
|
|
112
|
+
asyncio.set_event_loop(loop)
|
|
113
|
+
loop.run_forever()
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def calc_crc8(data):
|
|
117
|
+
crc8Table = [
|
|
118
|
+
0x00,
|
|
119
|
+
0x07,
|
|
120
|
+
0x0E,
|
|
121
|
+
0x09,
|
|
122
|
+
0x1C,
|
|
123
|
+
0x1B,
|
|
124
|
+
0x12,
|
|
125
|
+
0x15,
|
|
126
|
+
0x38,
|
|
127
|
+
0x3F,
|
|
128
|
+
0x36,
|
|
129
|
+
0x31,
|
|
130
|
+
0x24,
|
|
131
|
+
0x23,
|
|
132
|
+
0x2A,
|
|
133
|
+
0x2D,
|
|
134
|
+
0x70,
|
|
135
|
+
0x77,
|
|
136
|
+
0x7E,
|
|
137
|
+
0x79,
|
|
138
|
+
0x6C,
|
|
139
|
+
0x6B,
|
|
140
|
+
0x62,
|
|
141
|
+
0x65,
|
|
142
|
+
0x48,
|
|
143
|
+
0x4F,
|
|
144
|
+
0x46,
|
|
145
|
+
0x41,
|
|
146
|
+
0x54,
|
|
147
|
+
0x53,
|
|
148
|
+
0x5A,
|
|
149
|
+
0x5D,
|
|
150
|
+
0xE0,
|
|
151
|
+
0xE7,
|
|
152
|
+
0xEE,
|
|
153
|
+
0xE9,
|
|
154
|
+
0xFC,
|
|
155
|
+
0xFB,
|
|
156
|
+
0xF2,
|
|
157
|
+
0xF5,
|
|
158
|
+
0xD8,
|
|
159
|
+
0xDF,
|
|
160
|
+
0xD6,
|
|
161
|
+
0xD1,
|
|
162
|
+
0xC4,
|
|
163
|
+
0xC3,
|
|
164
|
+
0xCA,
|
|
165
|
+
0xCD,
|
|
166
|
+
0x90,
|
|
167
|
+
0x97,
|
|
168
|
+
0x9E,
|
|
169
|
+
0x99,
|
|
170
|
+
0x8C,
|
|
171
|
+
0x8B,
|
|
172
|
+
0x82,
|
|
173
|
+
0x85,
|
|
174
|
+
0xA8,
|
|
175
|
+
0xAF,
|
|
176
|
+
0xA6,
|
|
177
|
+
0xA1,
|
|
178
|
+
0xB4,
|
|
179
|
+
0xB3,
|
|
180
|
+
0xBA,
|
|
181
|
+
0xBD,
|
|
182
|
+
0xC7,
|
|
183
|
+
0xC0,
|
|
184
|
+
0xC9,
|
|
185
|
+
0xCE,
|
|
186
|
+
0xDB,
|
|
187
|
+
0xDC,
|
|
188
|
+
0xD5,
|
|
189
|
+
0xD2,
|
|
190
|
+
0xFF,
|
|
191
|
+
0xF8,
|
|
192
|
+
0xF1,
|
|
193
|
+
0xF6,
|
|
194
|
+
0xE3,
|
|
195
|
+
0xE4,
|
|
196
|
+
0xED,
|
|
197
|
+
0xEA,
|
|
198
|
+
0xB7,
|
|
199
|
+
0xB0,
|
|
200
|
+
0xB9,
|
|
201
|
+
0xBE,
|
|
202
|
+
0xAB,
|
|
203
|
+
0xAC,
|
|
204
|
+
0xA5,
|
|
205
|
+
0xA2,
|
|
206
|
+
0x8F,
|
|
207
|
+
0x88,
|
|
208
|
+
0x81,
|
|
209
|
+
0x86,
|
|
210
|
+
0x93,
|
|
211
|
+
0x94,
|
|
212
|
+
0x9D,
|
|
213
|
+
0x9A,
|
|
214
|
+
0x27,
|
|
215
|
+
0x20,
|
|
216
|
+
0x29,
|
|
217
|
+
0x2E,
|
|
218
|
+
0x3B,
|
|
219
|
+
0x3C,
|
|
220
|
+
0x35,
|
|
221
|
+
0x32,
|
|
222
|
+
0x1F,
|
|
223
|
+
0x18,
|
|
224
|
+
0x11,
|
|
225
|
+
0x16,
|
|
226
|
+
0x03,
|
|
227
|
+
0x04,
|
|
228
|
+
0x0D,
|
|
229
|
+
0x0A,
|
|
230
|
+
0x57,
|
|
231
|
+
0x50,
|
|
232
|
+
0x59,
|
|
233
|
+
0x5E,
|
|
234
|
+
0x4B,
|
|
235
|
+
0x4C,
|
|
236
|
+
0x45,
|
|
237
|
+
0x42,
|
|
238
|
+
0x6F,
|
|
239
|
+
0x68,
|
|
240
|
+
0x61,
|
|
241
|
+
0x66,
|
|
242
|
+
0x73,
|
|
243
|
+
0x74,
|
|
244
|
+
0x7D,
|
|
245
|
+
0x7A,
|
|
246
|
+
0x89,
|
|
247
|
+
0x8E,
|
|
248
|
+
0x87,
|
|
249
|
+
0x80,
|
|
250
|
+
0x95,
|
|
251
|
+
0x92,
|
|
252
|
+
0x9B,
|
|
253
|
+
0x9C,
|
|
254
|
+
0xB1,
|
|
255
|
+
0xB6,
|
|
256
|
+
0xBF,
|
|
257
|
+
0xB8,
|
|
258
|
+
0xAD,
|
|
259
|
+
0xAA,
|
|
260
|
+
0xA3,
|
|
261
|
+
0xA4,
|
|
262
|
+
0xF9,
|
|
263
|
+
0xFE,
|
|
264
|
+
0xF7,
|
|
265
|
+
0xF0,
|
|
266
|
+
0xE5,
|
|
267
|
+
0xE2,
|
|
268
|
+
0xEB,
|
|
269
|
+
0xEC,
|
|
270
|
+
0xC1,
|
|
271
|
+
0xC6,
|
|
272
|
+
0xCF,
|
|
273
|
+
0xC8,
|
|
274
|
+
0xDD,
|
|
275
|
+
0xDA,
|
|
276
|
+
0xD3,
|
|
277
|
+
0xD4,
|
|
278
|
+
0x69,
|
|
279
|
+
0x6E,
|
|
280
|
+
0x67,
|
|
281
|
+
0x60,
|
|
282
|
+
0x75,
|
|
283
|
+
0x72,
|
|
284
|
+
0x7B,
|
|
285
|
+
0x7C,
|
|
286
|
+
0x51,
|
|
287
|
+
0x56,
|
|
288
|
+
0x5F,
|
|
289
|
+
0x58,
|
|
290
|
+
0x4D,
|
|
291
|
+
0x4A,
|
|
292
|
+
0x43,
|
|
293
|
+
0x44,
|
|
294
|
+
0x19,
|
|
295
|
+
0x1E,
|
|
296
|
+
0x17,
|
|
297
|
+
0x10,
|
|
298
|
+
0x05,
|
|
299
|
+
0x02,
|
|
300
|
+
0x0B,
|
|
301
|
+
0x0C,
|
|
302
|
+
0x21,
|
|
303
|
+
0x26,
|
|
304
|
+
0x2F,
|
|
305
|
+
0x28,
|
|
306
|
+
0x3D,
|
|
307
|
+
0x3A,
|
|
308
|
+
0x33,
|
|
309
|
+
0x34,
|
|
310
|
+
0x4E,
|
|
311
|
+
0x49,
|
|
312
|
+
0x40,
|
|
313
|
+
0x47,
|
|
314
|
+
0x52,
|
|
315
|
+
0x55,
|
|
316
|
+
0x5C,
|
|
317
|
+
0x5B,
|
|
318
|
+
0x76,
|
|
319
|
+
0x71,
|
|
320
|
+
0x78,
|
|
321
|
+
0x7F,
|
|
322
|
+
0x6A,
|
|
323
|
+
0x6D,
|
|
324
|
+
0x64,
|
|
325
|
+
0x63,
|
|
326
|
+
0x3E,
|
|
327
|
+
0x39,
|
|
328
|
+
0x30,
|
|
329
|
+
0x37,
|
|
330
|
+
0x22,
|
|
331
|
+
0x25,
|
|
332
|
+
0x2C,
|
|
333
|
+
0x2B,
|
|
334
|
+
0x06,
|
|
335
|
+
0x01,
|
|
336
|
+
0x08,
|
|
337
|
+
0x0F,
|
|
338
|
+
0x1A,
|
|
339
|
+
0x1D,
|
|
340
|
+
0x14,
|
|
341
|
+
0x13,
|
|
342
|
+
0xAE,
|
|
343
|
+
0xA9,
|
|
344
|
+
0xA0,
|
|
345
|
+
0xA7,
|
|
346
|
+
0xB2,
|
|
347
|
+
0xB5,
|
|
348
|
+
0xBC,
|
|
349
|
+
0xBB,
|
|
350
|
+
0x96,
|
|
351
|
+
0x91,
|
|
352
|
+
0x98,
|
|
353
|
+
0x9F,
|
|
354
|
+
0x8A,
|
|
355
|
+
0x8D,
|
|
356
|
+
0x84,
|
|
357
|
+
0x83,
|
|
358
|
+
0xDE,
|
|
359
|
+
0xD9,
|
|
360
|
+
0xD0,
|
|
361
|
+
0xD7,
|
|
362
|
+
0xC2,
|
|
363
|
+
0xC5,
|
|
364
|
+
0xCC,
|
|
365
|
+
0xCB,
|
|
366
|
+
0xE6,
|
|
367
|
+
0xE1,
|
|
368
|
+
0xE8,
|
|
369
|
+
0xEF,
|
|
370
|
+
0xFA,
|
|
371
|
+
0xFD,
|
|
372
|
+
0xF4,
|
|
373
|
+
0xF3,
|
|
374
|
+
]
|
|
375
|
+
crc8 = 0
|
|
376
|
+
len_data = len(data)
|
|
377
|
+
|
|
378
|
+
for i in range(len_data):
|
|
379
|
+
crc8 ^= data[i]
|
|
380
|
+
crc8 = crc8Table[crc8]
|
|
381
|
+
|
|
382
|
+
return crc8
|
|
@@ -8,7 +8,7 @@ with open(os.path.join(this_directory, "README.md"), "r", encoding="utf-8") as f
|
|
|
8
8
|
|
|
9
9
|
setup(
|
|
10
10
|
name="sensor-sdk",
|
|
11
|
-
version="0.0.
|
|
11
|
+
version="0.0.10",
|
|
12
12
|
description="Python sdk for Synchroni",
|
|
13
13
|
long_description=long_description,
|
|
14
14
|
long_description_content_type="text/markdown",
|
sensor-sdk-0.0.8/sensor/utils.py
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import platform
|
|
3
|
-
import queue
|
|
4
|
-
import signal
|
|
5
|
-
import time
|
|
6
|
-
|
|
7
|
-
_terminated = False
|
|
8
|
-
_TIMEOUT = 10
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
async def delay(_time: float, function) -> any:
|
|
12
|
-
await asyncio.sleep(_time)
|
|
13
|
-
return await function
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
40
|
-
try:
|
|
41
|
-
f = asyncio.run_coroutine_threadsafe(asyncio.wait_for(function, _timeout), _loop)
|
|
42
|
-
return f.result(timeout=_timeout)
|
|
43
|
-
except Exception as e:
|
|
44
|
-
print(e)
|
|
45
|
-
pass
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
async def async_call(_loop: asyncio.AbstractEventLoop, function, _timeout=_TIMEOUT) -> any:
|
|
49
|
-
if _loop == None:
|
|
50
|
-
return
|
|
51
|
-
|
|
52
|
-
try:
|
|
53
|
-
f = asyncio.run_coroutine_threadsafe(asyncio.wait_for(function, _timeout), _loop)
|
|
54
|
-
except Exception as e:
|
|
55
|
-
print(e)
|
|
56
|
-
pass
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
def start_loop(loop: asyncio.BaseEventLoop):
|
|
70
|
-
if platform.system() == "Darwin":
|
|
71
|
-
asyncio.get_running_loop = asyncio.get_event_loop
|
|
72
|
-
asyncio.set_event_loop(loop)
|
|
73
|
-
loop.run_forever()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|