sensor-sdk 0.1.2__tar.gz → 0.1.5__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.
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/PKG-INFO +2 -1
- sensor_sdk-0.1.5/sensor/__init__.py +20 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor/bleak_host.py +57 -25
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor/bleak_process.py +30 -9
- sensor_sdk-0.1.5/sensor/fb/DataType.py +32 -0
- sensor_sdk-0.1.5/sensor/fb/Sample.py +49 -0
- sensor_sdk-0.1.5/sensor/fb/SensorData.py +296 -0
- sensor_sdk-0.1.5/sensor/fb/__init__.py +0 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor/gforce.py +11 -1
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor/sdk_log.py +93 -5
- sensor_sdk-0.1.5/sensor/sensor_data.py +241 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor/sensor_data_context.py +298 -136
- sensor_sdk-0.1.5/sensor/sensor_data_pool.py +110 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor/sensor_utils.py +28 -10
- sensor_sdk-0.1.5/sensor/winrt_high_throughput.py +104 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor_sdk.egg-info/PKG-INFO +2 -1
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor_sdk.egg-info/SOURCES.txt +6 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor_sdk.egg-info/requires.txt +1 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/setup.py +2 -2
- sensor_sdk-0.1.2/sensor/__init__.py +0 -4
- sensor_sdk-0.1.2/sensor/sensor_data.py +0 -103
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/LICENSE.txt +0 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/README.md +0 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor/sensor_controller.py +0 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor/sensor_device.py +0 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor/sensor_profile.py +0 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor_sdk.egg-info/dependency_links.txt +0 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor_sdk.egg-info/top_level.txt +0 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/sensor_sdk.egg-info/zip-safe +0 -0
- {sensor_sdk-0.1.2 → sensor_sdk-0.1.5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sensor-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Python sdk for Synchroni
|
|
5
5
|
Home-page: https://github.com/oymotion/SynchroniSDKPython
|
|
6
6
|
Author: Martin Ye
|
|
@@ -11,6 +11,7 @@ License-File: LICENSE.txt
|
|
|
11
11
|
Requires-Dist: numpy
|
|
12
12
|
Requires-Dist: setuptools
|
|
13
13
|
Requires-Dist: bleak>=3.0.2
|
|
14
|
+
Requires-Dist: flatbuffers>=25.0.0
|
|
14
15
|
Dynamic: author
|
|
15
16
|
Dynamic: author-email
|
|
16
17
|
Dynamic: description
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from sensor.sensor_controller import SensorController, SensorControllerInstance
|
|
2
|
+
from sensor.sensor_profile import SensorProfile
|
|
3
|
+
from sensor.sensor_device import BLEDevice, DeviceInfo, DeviceStateEx
|
|
4
|
+
from sensor.sensor_data import DataType, Sample, SensorData
|
|
5
|
+
from sensor.winrt_high_throughput import apply as _apply_winrt_high_throughput_patch
|
|
6
|
+
|
|
7
|
+
# Windows 下尝试给 bleak WinRT backend 打高吞吐率连接参数补丁
|
|
8
|
+
_apply_winrt_high_throughput_patch()
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"SensorController",
|
|
12
|
+
"SensorControllerInstance",
|
|
13
|
+
"SensorProfile",
|
|
14
|
+
"BLEDevice",
|
|
15
|
+
"DeviceInfo",
|
|
16
|
+
"DeviceStateEx",
|
|
17
|
+
"DataType",
|
|
18
|
+
"Sample",
|
|
19
|
+
"SensorData",
|
|
20
|
+
]
|
|
@@ -17,7 +17,8 @@ class BleakHost:
|
|
|
17
17
|
def __init__(self):
|
|
18
18
|
self._cmd_queue = multiprocessing.Queue(maxsize=50)
|
|
19
19
|
self._result_queue = multiprocessing.Queue(maxsize=sensor_utils.BLEAK_RESULT_QUEUE_MAXSIZE)
|
|
20
|
-
self.
|
|
20
|
+
self._data_queue = multiprocessing.Queue(maxsize=sensor_utils.BLEAK_DATA_QUEUE_MAXSIZE)
|
|
21
|
+
self._bleak_process = BleakProcess(self._cmd_queue, self._result_queue, self._data_queue, SdkLog.get_log_path())
|
|
21
22
|
self._started = False
|
|
22
23
|
|
|
23
24
|
|
|
@@ -69,6 +70,7 @@ class BleakHost:
|
|
|
69
70
|
try:
|
|
70
71
|
self._cmd_queue.close()
|
|
71
72
|
self._result_queue.close()
|
|
73
|
+
self._data_queue.close()
|
|
72
74
|
except Exception as e:
|
|
73
75
|
SdkLog.exception(_TAG, "Error closing queues")
|
|
74
76
|
|
|
@@ -125,38 +127,68 @@ class BleakHost:
|
|
|
125
127
|
|
|
126
128
|
async def _consume_results(self):
|
|
127
129
|
|
|
130
|
+
def _try_get(q, timeout):
|
|
131
|
+
try:
|
|
132
|
+
return q.get(True, timeout)
|
|
133
|
+
except queue.Empty:
|
|
134
|
+
return None
|
|
135
|
+
|
|
128
136
|
while not getattr(self, '_should_exit', False):
|
|
129
137
|
try:
|
|
138
|
+
# Prioritize control/result messages; data messages are drained in batch below.
|
|
130
139
|
msg = await asyncio.get_event_loop().run_in_executor(
|
|
131
|
-
None, self._result_queue
|
|
140
|
+
None, _try_get, self._result_queue, 0.02
|
|
132
141
|
)
|
|
133
|
-
except queue.Empty:
|
|
134
|
-
continue
|
|
135
142
|
except Exception:
|
|
143
|
+
msg = None
|
|
144
|
+
|
|
145
|
+
if msg is None:
|
|
146
|
+
try:
|
|
147
|
+
msg = await asyncio.get_event_loop().run_in_executor(
|
|
148
|
+
None, _try_get, self._data_queue, 0.02
|
|
149
|
+
)
|
|
150
|
+
except Exception:
|
|
151
|
+
msg = None
|
|
152
|
+
|
|
153
|
+
if msg is None:
|
|
154
|
+
await asyncio.sleep(0.001)
|
|
136
155
|
continue
|
|
137
156
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
except Exception as e:
|
|
144
|
-
SdkLog.exception(_TAG, "Unexpected error")
|
|
145
|
-
elif msg_type == "devices":
|
|
146
|
-
if self.on_scan_result is not None:
|
|
147
|
-
try:
|
|
148
|
-
self.on_scan_result(msg)
|
|
149
|
-
except Exception as e:
|
|
150
|
-
SdkLog.exception(_TAG, "Unexpected error")
|
|
151
|
-
elif msg_type == "command_result":
|
|
152
|
-
self._handle_command_result(msg)
|
|
153
|
-
elif msg_type in ("state_changed", "power_changed", "sensor_data", "error"):
|
|
154
|
-
if self.on_device_message is not None:
|
|
155
|
-
device_mac = msg.get("device_mac")
|
|
157
|
+
self._dispatch_message(msg)
|
|
158
|
+
|
|
159
|
+
# Batch drain both queues to catch up quickly and reduce per-get overhead.
|
|
160
|
+
for q in (self._result_queue, self._data_queue):
|
|
161
|
+
while True:
|
|
156
162
|
try:
|
|
157
|
-
self.
|
|
158
|
-
except
|
|
159
|
-
|
|
163
|
+
self._dispatch_message(q.get_nowait())
|
|
164
|
+
except queue.Empty:
|
|
165
|
+
break
|
|
166
|
+
except Exception:
|
|
167
|
+
break
|
|
168
|
+
|
|
169
|
+
def _dispatch_message(self, msg):
|
|
170
|
+
msg_type = msg.get("type")
|
|
171
|
+
if msg_type == "scan_once_result":
|
|
172
|
+
if self.on_scan_once_result is not None:
|
|
173
|
+
try:
|
|
174
|
+
self.on_scan_once_result(msg)
|
|
175
|
+
except Exception as e:
|
|
176
|
+
SdkLog.exception(_TAG, "Unexpected error")
|
|
177
|
+
elif msg_type == "devices":
|
|
178
|
+
if self.on_scan_result is not None:
|
|
179
|
+
try:
|
|
180
|
+
self.on_scan_result(msg)
|
|
181
|
+
except Exception as e:
|
|
182
|
+
SdkLog.exception(_TAG, "Unexpected error")
|
|
183
|
+
elif msg_type == "command_result":
|
|
184
|
+
self._handle_command_result(msg)
|
|
185
|
+
elif msg_type in ("state_changed", "power_changed", "sensor_data", "error"):
|
|
186
|
+
if self.on_device_message is not None:
|
|
187
|
+
device_mac = msg.get("device_mac")
|
|
188
|
+
try:
|
|
189
|
+
self.on_device_message(device_mac, msg)
|
|
190
|
+
except Exception as e:
|
|
191
|
+
SdkLog.exception(_TAG, "Unexpected error")
|
|
160
192
|
|
|
161
193
|
def _handle_command_result(self, msg):
|
|
162
194
|
|
|
@@ -72,11 +72,13 @@ class BleakProcess(multiprocessing.Process):
|
|
|
72
72
|
self,
|
|
73
73
|
cmd_queue: multiprocessing.Queue,
|
|
74
74
|
result_queue: multiprocessing.Queue,
|
|
75
|
+
data_queue: multiprocessing.Queue,
|
|
75
76
|
log_path: str = None,
|
|
76
77
|
):
|
|
77
78
|
super().__init__(daemon=True)
|
|
78
79
|
self.cmd_queue = cmd_queue
|
|
79
80
|
self.result_queue = result_queue
|
|
81
|
+
self.data_queue = data_queue
|
|
80
82
|
self._log_path = log_path
|
|
81
83
|
self._scanner = None
|
|
82
84
|
self._is_scanning = False
|
|
@@ -141,15 +143,23 @@ class BleakProcess(multiprocessing.Process):
|
|
|
141
143
|
|
|
142
144
|
def _flush_msg_queue(self):
|
|
143
145
|
|
|
146
|
+
def _route_and_put(msg):
|
|
147
|
+
msg_type = msg.get("type")
|
|
148
|
+
if msg_type == "sensor_data":
|
|
149
|
+
try:
|
|
150
|
+
self.data_queue.put_nowait(msg)
|
|
151
|
+
except queue.Full:
|
|
152
|
+
pass
|
|
153
|
+
elif msg_type in self._DROPABLE_MSG_TYPES:
|
|
154
|
+
self.result_queue.put_nowait(msg)
|
|
155
|
+
else:
|
|
156
|
+
# Use a short timeout during shutdown so the child process can exit cleanly.
|
|
157
|
+
self.result_queue.put(msg, timeout=2.0)
|
|
158
|
+
|
|
144
159
|
while True:
|
|
145
160
|
try:
|
|
146
161
|
msg = self._msg_queue.get_nowait()
|
|
147
|
-
|
|
148
|
-
if msg_type in self._DROPABLE_MSG_TYPES:
|
|
149
|
-
self.result_queue.put_nowait(msg)
|
|
150
|
-
else:
|
|
151
|
-
# Use a short timeout during shutdown so the child process can exit cleanly.
|
|
152
|
-
self.result_queue.put(msg, timeout=2.0)
|
|
162
|
+
_route_and_put(msg)
|
|
153
163
|
except queue.Empty:
|
|
154
164
|
break
|
|
155
165
|
except queue.Full:
|
|
@@ -170,6 +180,7 @@ class BleakProcess(multiprocessing.Process):
|
|
|
170
180
|
async def _publisher_task(self):
|
|
171
181
|
# Throttle queue-full logs to avoid blocking stdout on Windows.
|
|
172
182
|
_last_queue_full_log = 0.0
|
|
183
|
+
_last_data_queue_full_log = 0.0
|
|
173
184
|
|
|
174
185
|
while True:
|
|
175
186
|
msg = None
|
|
@@ -177,7 +188,17 @@ class BleakProcess(multiprocessing.Process):
|
|
|
177
188
|
try:
|
|
178
189
|
msg = self._msg_queue.get_nowait()
|
|
179
190
|
msg_type = msg.get("type")
|
|
180
|
-
if msg_type
|
|
191
|
+
if msg_type == "sensor_data":
|
|
192
|
+
# High-frequency data: use a dedicated drop-capable queue so it cannot
|
|
193
|
+
# block control/result messages in the main result queue.
|
|
194
|
+
try:
|
|
195
|
+
self.data_queue.put_nowait(msg)
|
|
196
|
+
except queue.Full:
|
|
197
|
+
now = time.time()
|
|
198
|
+
if now - _last_data_queue_full_log >= 2.0:
|
|
199
|
+
_last_data_queue_full_log = now
|
|
200
|
+
SdkLog.w(_TAG, "Data queue is full, dropping sensor_data")
|
|
201
|
+
elif msg_type in self._DROPABLE_MSG_TYPES:
|
|
181
202
|
self.result_queue.put_nowait(msg)
|
|
182
203
|
else:
|
|
183
204
|
# Use a short timeout for important messages so the publisher does not stall.
|
|
@@ -845,9 +866,9 @@ class BleakProcess(multiprocessing.Process):
|
|
|
845
866
|
|
|
846
867
|
try:
|
|
847
868
|
if ctx.isUniversalStream:
|
|
848
|
-
await ctx.
|
|
869
|
+
await ctx._processUniversalData(local_buf, on_data, on_error)
|
|
849
870
|
else:
|
|
850
|
-
await ctx.
|
|
871
|
+
await ctx._process_data(local_buf, on_data, on_error)
|
|
851
872
|
except asyncio.CancelledError as e:
|
|
852
873
|
SdkLog.exception(_TAG, "Data loop cancelled")
|
|
853
874
|
except Exception as e:
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# automatically generated by the FlatBuffers compiler, do not modify
|
|
2
|
+
|
|
3
|
+
# namespace: fb
|
|
4
|
+
|
|
5
|
+
# BLE 数据通知类型,与 SensorSDKCXX src/SensorProfileImpl.h 中的 NotifyDataType 保持一致
|
|
6
|
+
class DataType(object):
|
|
7
|
+
NONE = 0
|
|
8
|
+
NTF_ACC_DATA = 1
|
|
9
|
+
NTF_GYO_DATA = 2
|
|
10
|
+
NTF_MAG_DATA = 3
|
|
11
|
+
NTF_EULER_DATA = 4
|
|
12
|
+
NTF_QUAT_FLOAT_DATA = 5
|
|
13
|
+
NTF_ROTA_DATA = 6
|
|
14
|
+
NTF_EMG_GEST_DATA = 7
|
|
15
|
+
NTF_EMG_ADC_DATA = 8
|
|
16
|
+
NTF_HID_MOUSE = 9
|
|
17
|
+
NTF_HID_JOYSTICK = 10
|
|
18
|
+
NTF_DEV_STATUS = 11
|
|
19
|
+
NTF_LOG_DATA = 12
|
|
20
|
+
NTF_MAG_ANGLE_DATA = 13
|
|
21
|
+
NTF_MOT_CURRENT_DATA = 14
|
|
22
|
+
NTF_NEUCIR_STATUS = 15
|
|
23
|
+
NTF_EEG = 16
|
|
24
|
+
NTF_ECG = 17
|
|
25
|
+
NTF_IMPEDANCE = 18
|
|
26
|
+
NTF_IMU = 19
|
|
27
|
+
NTF_ADS = 20
|
|
28
|
+
NTF_BRTH = 21
|
|
29
|
+
NTF_IMPEDANCE_EXT = 22
|
|
30
|
+
NTF_SPO2 = 23
|
|
31
|
+
NTF_PPG = 24
|
|
32
|
+
NTF_PARTIAL_DATA = 255
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# automatically generated by the FlatBuffers compiler, do not modify
|
|
2
|
+
|
|
3
|
+
# namespace: fb
|
|
4
|
+
|
|
5
|
+
import flatbuffers
|
|
6
|
+
from flatbuffers.compat import import_numpy
|
|
7
|
+
np = import_numpy()
|
|
8
|
+
|
|
9
|
+
# 单个采样点,内存紧凑的 struct
|
|
10
|
+
class Sample(object):
|
|
11
|
+
__slots__ = ['_tab']
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
def SizeOf(cls):
|
|
15
|
+
return 32
|
|
16
|
+
|
|
17
|
+
# Sample
|
|
18
|
+
def Init(self, buf, pos):
|
|
19
|
+
self._tab = flatbuffers.table.Table(buf, pos)
|
|
20
|
+
|
|
21
|
+
# Sample
|
|
22
|
+
def TimeStampInMs(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
|
|
23
|
+
# Sample
|
|
24
|
+
def ChannelIndex(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4))
|
|
25
|
+
# Sample
|
|
26
|
+
def SampleIndex(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(8))
|
|
27
|
+
# Sample
|
|
28
|
+
def RawData(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(12))
|
|
29
|
+
# Sample
|
|
30
|
+
def Data(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(16))
|
|
31
|
+
# Sample
|
|
32
|
+
def Impedance(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(20))
|
|
33
|
+
# Sample
|
|
34
|
+
def Saturation(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(24))
|
|
35
|
+
# Sample
|
|
36
|
+
def IsLost(self): return self._tab.Get(flatbuffers.number_types.BoolFlags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(28))
|
|
37
|
+
|
|
38
|
+
def CreateSample(builder, timeStampInMs, channelIndex, sampleIndex, rawData, data, impedance, saturation, isLost):
|
|
39
|
+
builder.Prep(4, 32)
|
|
40
|
+
builder.Pad(3)
|
|
41
|
+
builder.PrependBool(isLost)
|
|
42
|
+
builder.PrependFloat32(saturation)
|
|
43
|
+
builder.PrependFloat32(impedance)
|
|
44
|
+
builder.PrependFloat32(data)
|
|
45
|
+
builder.PrependInt32(rawData)
|
|
46
|
+
builder.PrependInt32(sampleIndex)
|
|
47
|
+
builder.PrependInt32(channelIndex)
|
|
48
|
+
builder.PrependInt32(timeStampInMs)
|
|
49
|
+
return builder.Offset()
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# automatically generated by the FlatBuffers compiler, do not modify
|
|
2
|
+
|
|
3
|
+
# namespace: fb
|
|
4
|
+
|
|
5
|
+
import flatbuffers
|
|
6
|
+
from flatbuffers.compat import import_numpy
|
|
7
|
+
np = import_numpy()
|
|
8
|
+
|
|
9
|
+
# SensorData 统一数据表
|
|
10
|
+
# samples 为一维扁平数组,按通道顺序存放;samples_per_channel 记录每个通道的 sample 数量。
|
|
11
|
+
class SensorData(object):
|
|
12
|
+
__slots__ = ['_tab']
|
|
13
|
+
|
|
14
|
+
@classmethod
|
|
15
|
+
def GetRootAs(cls, buf, offset=0):
|
|
16
|
+
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
|
17
|
+
x = SensorData()
|
|
18
|
+
x.Init(buf, n + offset)
|
|
19
|
+
return x
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def GetRootAsSensorData(cls, buf, offset=0):
|
|
23
|
+
"""This method is deprecated. Please switch to GetRootAs."""
|
|
24
|
+
return cls.GetRootAs(buf, offset)
|
|
25
|
+
# SensorData
|
|
26
|
+
def Init(self, buf, pos):
|
|
27
|
+
self._tab = flatbuffers.table.Table(buf, pos)
|
|
28
|
+
|
|
29
|
+
# SensorData
|
|
30
|
+
def DeviceMac(self):
|
|
31
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
|
32
|
+
if o != 0:
|
|
33
|
+
return self._tab.String(o + self._tab.Pos)
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
# SensorData
|
|
37
|
+
def DataType(self):
|
|
38
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
|
39
|
+
if o != 0:
|
|
40
|
+
return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
|
|
41
|
+
return 0
|
|
42
|
+
|
|
43
|
+
# SensorData
|
|
44
|
+
def LastPackageCounter(self):
|
|
45
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
|
|
46
|
+
if o != 0:
|
|
47
|
+
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
48
|
+
return 0
|
|
49
|
+
|
|
50
|
+
# SensorData
|
|
51
|
+
def LastPackageIndex(self):
|
|
52
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
|
|
53
|
+
if o != 0:
|
|
54
|
+
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
55
|
+
return 0
|
|
56
|
+
|
|
57
|
+
# SensorData
|
|
58
|
+
def LostPackageCount(self):
|
|
59
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
|
|
60
|
+
if o != 0:
|
|
61
|
+
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
62
|
+
return 0
|
|
63
|
+
|
|
64
|
+
# SensorData
|
|
65
|
+
def ResolutionBits(self):
|
|
66
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
|
|
67
|
+
if o != 0:
|
|
68
|
+
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
69
|
+
return 0
|
|
70
|
+
|
|
71
|
+
# SensorData
|
|
72
|
+
def ResolutionSigned(self):
|
|
73
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
|
|
74
|
+
if o != 0:
|
|
75
|
+
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
76
|
+
return 0
|
|
77
|
+
|
|
78
|
+
# SensorData
|
|
79
|
+
def SampleRate(self):
|
|
80
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
|
|
81
|
+
if o != 0:
|
|
82
|
+
return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
|
|
83
|
+
return 0.0
|
|
84
|
+
|
|
85
|
+
# SensorData
|
|
86
|
+
def ChannelCount(self):
|
|
87
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
|
|
88
|
+
if o != 0:
|
|
89
|
+
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
90
|
+
return 0
|
|
91
|
+
|
|
92
|
+
# SensorData
|
|
93
|
+
def ChannelMask(self):
|
|
94
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
|
|
95
|
+
if o != 0:
|
|
96
|
+
return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
|
|
97
|
+
return 0
|
|
98
|
+
|
|
99
|
+
# SensorData
|
|
100
|
+
def MinPackageSampleCount(self):
|
|
101
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
|
|
102
|
+
if o != 0:
|
|
103
|
+
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
104
|
+
return 0
|
|
105
|
+
|
|
106
|
+
# SensorData
|
|
107
|
+
def PackageSampleCount(self):
|
|
108
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
|
|
109
|
+
if o != 0:
|
|
110
|
+
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
111
|
+
return 0
|
|
112
|
+
|
|
113
|
+
# SensorData
|
|
114
|
+
def PackageIndexLength(self):
|
|
115
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(28))
|
|
116
|
+
if o != 0:
|
|
117
|
+
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
|
118
|
+
return 0
|
|
119
|
+
|
|
120
|
+
# SensorData
|
|
121
|
+
def K(self):
|
|
122
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
|
|
123
|
+
if o != 0:
|
|
124
|
+
return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
|
|
125
|
+
return 0.0
|
|
126
|
+
|
|
127
|
+
# SensorData
|
|
128
|
+
def Samples(self, j):
|
|
129
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
|
|
130
|
+
if o != 0:
|
|
131
|
+
x = self._tab.Vector(o)
|
|
132
|
+
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 32
|
|
133
|
+
from sensor.fb.Sample import Sample
|
|
134
|
+
obj = Sample()
|
|
135
|
+
obj.Init(self._tab.Bytes, x)
|
|
136
|
+
return obj
|
|
137
|
+
return None
|
|
138
|
+
|
|
139
|
+
# SensorData
|
|
140
|
+
def SamplesLength(self):
|
|
141
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
|
|
142
|
+
if o != 0:
|
|
143
|
+
return self._tab.VectorLen(o)
|
|
144
|
+
return 0
|
|
145
|
+
|
|
146
|
+
# SensorData
|
|
147
|
+
def SamplesIsNone(self):
|
|
148
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
|
|
149
|
+
return o == 0
|
|
150
|
+
|
|
151
|
+
# SensorData
|
|
152
|
+
def SamplesPerChannel(self, j):
|
|
153
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
|
|
154
|
+
if o != 0:
|
|
155
|
+
a = self._tab.Vector(o)
|
|
156
|
+
return self._tab.Get(flatbuffers.number_types.Int32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
|
|
157
|
+
return 0
|
|
158
|
+
|
|
159
|
+
# SensorData
|
|
160
|
+
def SamplesPerChannelAsNumpy(self):
|
|
161
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
|
|
162
|
+
if o != 0:
|
|
163
|
+
return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int32Flags, o)
|
|
164
|
+
return 0
|
|
165
|
+
|
|
166
|
+
# SensorData
|
|
167
|
+
def SamplesPerChannelLength(self):
|
|
168
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
|
|
169
|
+
if o != 0:
|
|
170
|
+
return self._tab.VectorLen(o)
|
|
171
|
+
return 0
|
|
172
|
+
|
|
173
|
+
# SensorData
|
|
174
|
+
def SamplesPerChannelIsNone(self):
|
|
175
|
+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
|
|
176
|
+
return o == 0
|
|
177
|
+
|
|
178
|
+
def SensorDataStart(builder):
|
|
179
|
+
builder.StartObject(16)
|
|
180
|
+
|
|
181
|
+
def Start(builder):
|
|
182
|
+
SensorDataStart(builder)
|
|
183
|
+
|
|
184
|
+
def SensorDataAddDeviceMac(builder, deviceMac):
|
|
185
|
+
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(deviceMac), 0)
|
|
186
|
+
|
|
187
|
+
def AddDeviceMac(builder, deviceMac):
|
|
188
|
+
SensorDataAddDeviceMac(builder, deviceMac)
|
|
189
|
+
|
|
190
|
+
def SensorDataAddDataType(builder, dataType):
|
|
191
|
+
builder.PrependUint8Slot(1, dataType, 0)
|
|
192
|
+
|
|
193
|
+
def AddDataType(builder, dataType):
|
|
194
|
+
SensorDataAddDataType(builder, dataType)
|
|
195
|
+
|
|
196
|
+
def SensorDataAddLastPackageCounter(builder, lastPackageCounter):
|
|
197
|
+
builder.PrependInt32Slot(2, lastPackageCounter, 0)
|
|
198
|
+
|
|
199
|
+
def AddLastPackageCounter(builder, lastPackageCounter):
|
|
200
|
+
SensorDataAddLastPackageCounter(builder, lastPackageCounter)
|
|
201
|
+
|
|
202
|
+
def SensorDataAddLastPackageIndex(builder, lastPackageIndex):
|
|
203
|
+
builder.PrependInt32Slot(3, lastPackageIndex, 0)
|
|
204
|
+
|
|
205
|
+
def AddLastPackageIndex(builder, lastPackageIndex):
|
|
206
|
+
SensorDataAddLastPackageIndex(builder, lastPackageIndex)
|
|
207
|
+
|
|
208
|
+
def SensorDataAddLostPackageCount(builder, lostPackageCount):
|
|
209
|
+
builder.PrependInt32Slot(4, lostPackageCount, 0)
|
|
210
|
+
|
|
211
|
+
def AddLostPackageCount(builder, lostPackageCount):
|
|
212
|
+
SensorDataAddLostPackageCount(builder, lostPackageCount)
|
|
213
|
+
|
|
214
|
+
def SensorDataAddResolutionBits(builder, resolutionBits):
|
|
215
|
+
builder.PrependInt32Slot(5, resolutionBits, 0)
|
|
216
|
+
|
|
217
|
+
def AddResolutionBits(builder, resolutionBits):
|
|
218
|
+
SensorDataAddResolutionBits(builder, resolutionBits)
|
|
219
|
+
|
|
220
|
+
def SensorDataAddResolutionSigned(builder, resolutionSigned):
|
|
221
|
+
builder.PrependInt32Slot(6, resolutionSigned, 0)
|
|
222
|
+
|
|
223
|
+
def AddResolutionSigned(builder, resolutionSigned):
|
|
224
|
+
SensorDataAddResolutionSigned(builder, resolutionSigned)
|
|
225
|
+
|
|
226
|
+
def SensorDataAddSampleRate(builder, sampleRate):
|
|
227
|
+
builder.PrependFloat32Slot(7, sampleRate, 0.0)
|
|
228
|
+
|
|
229
|
+
def AddSampleRate(builder, sampleRate):
|
|
230
|
+
SensorDataAddSampleRate(builder, sampleRate)
|
|
231
|
+
|
|
232
|
+
def SensorDataAddChannelCount(builder, channelCount):
|
|
233
|
+
builder.PrependInt32Slot(8, channelCount, 0)
|
|
234
|
+
|
|
235
|
+
def AddChannelCount(builder, channelCount):
|
|
236
|
+
SensorDataAddChannelCount(builder, channelCount)
|
|
237
|
+
|
|
238
|
+
def SensorDataAddChannelMask(builder, channelMask):
|
|
239
|
+
builder.PrependUint64Slot(9, channelMask, 0)
|
|
240
|
+
|
|
241
|
+
def AddChannelMask(builder, channelMask):
|
|
242
|
+
SensorDataAddChannelMask(builder, channelMask)
|
|
243
|
+
|
|
244
|
+
def SensorDataAddMinPackageSampleCount(builder, minPackageSampleCount):
|
|
245
|
+
builder.PrependInt32Slot(10, minPackageSampleCount, 0)
|
|
246
|
+
|
|
247
|
+
def AddMinPackageSampleCount(builder, minPackageSampleCount):
|
|
248
|
+
SensorDataAddMinPackageSampleCount(builder, minPackageSampleCount)
|
|
249
|
+
|
|
250
|
+
def SensorDataAddPackageSampleCount(builder, packageSampleCount):
|
|
251
|
+
builder.PrependInt32Slot(11, packageSampleCount, 0)
|
|
252
|
+
|
|
253
|
+
def AddPackageSampleCount(builder, packageSampleCount):
|
|
254
|
+
SensorDataAddPackageSampleCount(builder, packageSampleCount)
|
|
255
|
+
|
|
256
|
+
def SensorDataAddPackageIndexLength(builder, packageIndexLength):
|
|
257
|
+
builder.PrependInt32Slot(12, packageIndexLength, 0)
|
|
258
|
+
|
|
259
|
+
def AddPackageIndexLength(builder, packageIndexLength):
|
|
260
|
+
SensorDataAddPackageIndexLength(builder, packageIndexLength)
|
|
261
|
+
|
|
262
|
+
def SensorDataAddK(builder, k):
|
|
263
|
+
builder.PrependFloat64Slot(13, k, 0.0)
|
|
264
|
+
|
|
265
|
+
def AddK(builder, k):
|
|
266
|
+
SensorDataAddK(builder, k)
|
|
267
|
+
|
|
268
|
+
def SensorDataAddSamples(builder, samples):
|
|
269
|
+
builder.PrependUOffsetTRelativeSlot(14, flatbuffers.number_types.UOffsetTFlags.py_type(samples), 0)
|
|
270
|
+
|
|
271
|
+
def AddSamples(builder, samples):
|
|
272
|
+
SensorDataAddSamples(builder, samples)
|
|
273
|
+
|
|
274
|
+
def SensorDataStartSamplesVector(builder, numElems):
|
|
275
|
+
return builder.StartVector(32, numElems, 4)
|
|
276
|
+
|
|
277
|
+
def StartSamplesVector(builder, numElems):
|
|
278
|
+
return SensorDataStartSamplesVector(builder, numElems)
|
|
279
|
+
|
|
280
|
+
def SensorDataAddSamplesPerChannel(builder, samplesPerChannel):
|
|
281
|
+
builder.PrependUOffsetTRelativeSlot(15, flatbuffers.number_types.UOffsetTFlags.py_type(samplesPerChannel), 0)
|
|
282
|
+
|
|
283
|
+
def AddSamplesPerChannel(builder, samplesPerChannel):
|
|
284
|
+
SensorDataAddSamplesPerChannel(builder, samplesPerChannel)
|
|
285
|
+
|
|
286
|
+
def SensorDataStartSamplesPerChannelVector(builder, numElems):
|
|
287
|
+
return builder.StartVector(4, numElems, 4)
|
|
288
|
+
|
|
289
|
+
def StartSamplesPerChannelVector(builder, numElems):
|
|
290
|
+
return SensorDataStartSamplesPerChannelVector(builder, numElems)
|
|
291
|
+
|
|
292
|
+
def SensorDataEnd(builder):
|
|
293
|
+
return builder.EndObject()
|
|
294
|
+
|
|
295
|
+
def End(builder):
|
|
296
|
+
return SensorDataEnd(builder)
|
|
File without changes
|
|
@@ -680,7 +680,13 @@ class GForce:
|
|
|
680
680
|
has_res=True,
|
|
681
681
|
)
|
|
682
682
|
)
|
|
683
|
-
|
|
683
|
+
# 硬件版本定义:temp[2]=SYS_HARDWARE_REV_ADDR, temp[3]=SYS_HARDWARE_TYPE_ADDR
|
|
684
|
+
# 响应数据中前两个字节分别为硬件版本号和硬件类型
|
|
685
|
+
if len(buf) >= 2:
|
|
686
|
+
return f"{buf[0]}.{buf[1]}"
|
|
687
|
+
if len(buf) == 1:
|
|
688
|
+
return str(buf[0])
|
|
689
|
+
return "0"
|
|
684
690
|
|
|
685
691
|
async def get_model_number(self) -> str:
|
|
686
692
|
buf = await self._send_request(
|
|
@@ -727,6 +733,8 @@ class GForce:
|
|
|
727
733
|
has_res=True,
|
|
728
734
|
)
|
|
729
735
|
)
|
|
736
|
+
if buf is None or len(buf) == 0:
|
|
737
|
+
return -1
|
|
730
738
|
return int.from_bytes(buf, byteorder="big")
|
|
731
739
|
|
|
732
740
|
async def get_temperature(self) -> int:
|
|
@@ -736,6 +744,8 @@ class GForce:
|
|
|
736
744
|
has_res=True,
|
|
737
745
|
)
|
|
738
746
|
)
|
|
747
|
+
if buf is None or len(buf) == 0:
|
|
748
|
+
return -1
|
|
739
749
|
return int.from_bytes(buf, byteorder="big")
|
|
740
750
|
|
|
741
751
|
async def power_off(self) -> None:
|