sensor-sdk 1.3.3__py3-none-win_amd64.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.
sensor/__init__.py ADDED
@@ -0,0 +1,34 @@
1
+ from sensor.sensor_controller import SensorController
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 import _dll
6
+ from sensor._dll import dll_path
7
+ from sensor._sync import submit
8
+
9
+ __version__ = "1.3.3"
10
+
11
+ def capi_version() -> int:
12
+ return _dll.load_dll().sen_capi_version()
13
+
14
+ def __getattr__(name):
15
+ if name == "SensorControllerInstance":
16
+ from sensor.sensor_controller import SensorControllerInstance
17
+ return SensorControllerInstance
18
+ raise AttributeError("module %r has no attribute %r" % (__name__, name))
19
+
20
+ __all__ = [
21
+ "SensorController",
22
+ "SensorControllerInstance",
23
+ "SensorProfile",
24
+ "BLEDevice",
25
+ "DeviceInfo",
26
+ "DeviceStateEx",
27
+ "DataType",
28
+ "Sample",
29
+ "SensorData",
30
+ "dll_path",
31
+ "capi_version",
32
+ "submit",
33
+ "__version__",
34
+ ]
sensor/_dll.py ADDED
@@ -0,0 +1,381 @@
1
+ import ctypes
2
+ import os
3
+ import platform
4
+ import sys
5
+ import warnings
6
+ from pathlib import Path
7
+
8
+ SEN_CAPI_VERSION = 20
9
+
10
+ def _library_name():
11
+ if sys.platform == "win32":
12
+ return "sensor.dll"
13
+ if sys.platform == "darwin":
14
+ return "libsensor.dylib"
15
+ return "libsensor.so"
16
+
17
+ def _candidate_paths():
18
+ env = os.environ.get("SENSOR_SDK_CAPI_DLL")
19
+ if env:
20
+ yield env
21
+ name = _library_name()
22
+ pkg_dir = os.path.dirname(os.path.abspath(__file__))
23
+ yield os.path.join(pkg_dir, "bin", name)
24
+ repo_root = Path(pkg_dir).resolve().parents[2]
25
+ if sys.platform == "win32":
26
+ base = repo_root / "lib" / "windows"
27
+ yield str(base / "x64" / "Debug" / name)
28
+ yield str(base / "x64" / "Release" / name)
29
+ yield str(base / "Win32" / "Debug" / "sensor32.dll")
30
+ yield str(base / "Win32" / "Release" / "sensor32.dll")
31
+ elif sys.platform == "darwin":
32
+ yield str(repo_root / "lib" / "mac" / "Debug" / name)
33
+ yield str(repo_root / "lib" / "mac" / "Release" / name)
34
+ else:
35
+ machine = platform.machine().lower()
36
+ arch_dir = {"amd64": "x86_64", "aarch64": "arm64"}.get(machine, machine)
37
+ base = repo_root / "lib" / "linux" / arch_dir
38
+ for config in ("Debug", "Release"):
39
+ for suffix in ("_x86", "_x64", "_arm64"):
40
+ yield str(base / config / ("libsensor%s.so" % suffix))
41
+
42
+ _dll = None
43
+ _dll_path = None
44
+
45
+ def _expose_bumble_glue(loaded_path):
46
+ repo_root = Path(os.path.dirname(os.path.abspath(__file__))).resolve().parents[2]
47
+ helper = repo_root / "helper"
48
+ if not helper.is_dir():
49
+ return
50
+ try:
51
+ Path(loaded_path).resolve().relative_to(repo_root / "lib")
52
+ except ValueError:
53
+ return
54
+ p = str(helper)
55
+ if p not in sys.path:
56
+ sys.path.append(p)
57
+
58
+ def load_dll():
59
+ global _dll, _dll_path
60
+ if _dll is not None:
61
+ return _dll
62
+ errors = []
63
+ for path in _candidate_paths():
64
+ try:
65
+ _dll = ctypes.CDLL(path)
66
+ _dll_path = path
67
+ _declare(_dll)
68
+ lib_version = _dll.sen_capi_version()
69
+ if lib_version != SEN_CAPI_VERSION:
70
+ warnings.warn(
71
+ "the sensor binding was built for SEN_CAPI_VERSION %d but %s "
72
+ "reports %d; rebuild the library or update the binding"
73
+ % (SEN_CAPI_VERSION, path, lib_version))
74
+ _expose_bumble_glue(path)
75
+ return _dll
76
+ except OSError as e:
77
+ errors.append("%s: %s" % (path, e))
78
+ raise OSError(
79
+ "cannot load the sensor SDK library; tried:\n " + "\n ".join(errors)
80
+ + "\nSet SENSOR_SDK_CAPI_DLL to the library path."
81
+ )
82
+
83
+ def dll_path():
84
+ load_dll()
85
+ return _dll_path
86
+
87
+ class sen_sample_t(ctypes.Structure):
88
+ _fields_ = [
89
+ ("absTimeStampInSec", ctypes.c_double),
90
+ ("channelIndex", ctypes.c_int32),
91
+ ("sampleIndex", ctypes.c_int32),
92
+ ("rawData", ctypes.c_int32),
93
+ ("data", ctypes.c_float),
94
+ ("impedance", ctypes.c_float),
95
+ ("saturation", ctypes.c_float),
96
+ ("isLost", ctypes.c_uint8),
97
+ ("_reserved", ctypes.c_uint8 * 7),
98
+ ]
99
+
100
+ class sen_data_info_t(ctypes.Structure):
101
+ _fields_ = [
102
+ ("deviceMac", ctypes.c_char * 18),
103
+ ("dataType", ctypes.c_int32),
104
+ ("lostPackageCount", ctypes.c_int32),
105
+ ("sampleRate", ctypes.c_float),
106
+ ("channelCount", ctypes.c_int32),
107
+ ("channelMask", ctypes.c_uint64),
108
+ ("sampleCount", ctypes.c_int32),
109
+ ("startTimeStamp", ctypes.c_uint32),
110
+ ("delay", ctypes.c_uint32),
111
+ ("startTimeSec", ctypes.c_double),
112
+ ("deviceName", ctypes.c_char * 32),
113
+ ]
114
+
115
+ class sen_data_view_t(ctypes.Structure):
116
+ _fields_ = [
117
+ ("startSampleIndex", ctypes.c_int32),
118
+ ("startTimeStamp", ctypes.c_uint32),
119
+ ("info", ctypes.POINTER(sen_data_info_t)),
120
+ ("samples", ctypes.POINTER(sen_sample_t)),
121
+ ("samplesBytes", ctypes.c_size_t),
122
+ ]
123
+
124
+ class sen_ble_device_t(ctypes.Structure):
125
+ _fields_ = [
126
+ ("name", ctypes.c_char * 32),
127
+ ("mac", ctypes.c_char * 18),
128
+ ("rssi", ctypes.c_int16),
129
+ ]
130
+
131
+ class sen_device_info_t(ctypes.Structure):
132
+ _fields_ = [
133
+ ("structSize", ctypes.c_uint32),
134
+ ("deviceName", ctypes.c_char * 32),
135
+ ("modelName", ctypes.c_char * 32),
136
+ ("hardwareVersion", ctypes.c_char * 32),
137
+ ("firmwareVersion", ctypes.c_char * 32),
138
+ ("MTUSize", ctypes.c_uint16),
139
+ ("isMTUFine", ctypes.c_uint8),
140
+ ("EMGGain", ctypes.c_uint8),
141
+ ("EEGGain", ctypes.c_uint8),
142
+ ("ECGGain", ctypes.c_uint8),
143
+ ("EMGChannelCount", ctypes.c_uint8),
144
+ ("EEGChannelCount", ctypes.c_uint8),
145
+ ("ECGChannelCount", ctypes.c_uint8),
146
+ ("BRTHChannelCount", ctypes.c_uint8),
147
+ ("AccChannelCount", ctypes.c_uint8),
148
+ ("GyroChannelCount", ctypes.c_uint8),
149
+ ("MagAngleChannelCount", ctypes.c_uint8),
150
+ ("EMGSampleRate", ctypes.c_uint16),
151
+ ("EEGSampleRate", ctypes.c_uint16),
152
+ ("ECGSampleRate", ctypes.c_uint16),
153
+ ("BRTHSampleRate", ctypes.c_uint16),
154
+ ("AccSampleRate", ctypes.c_uint16),
155
+ ("GyroSampleRate", ctypes.c_uint16),
156
+ ("MagAngleSampleRate", ctypes.c_uint16),
157
+ ("ImuChannelCount", ctypes.c_uint8),
158
+ ("ImuSampleRate", ctypes.c_uint16),
159
+ ("EulerChannelCount", ctypes.c_uint8),
160
+ ("EulerSampleRate", ctypes.c_uint16),
161
+ ("QuatChannelCount", ctypes.c_uint8),
162
+ ("QuatSampleRate", ctypes.c_uint16),
163
+ ("PpgChannelCount", ctypes.c_uint8),
164
+ ("PpgSampleRate", ctypes.c_uint16),
165
+ ("Spo2ChannelCount", ctypes.c_uint8),
166
+ ("Spo2SampleRate", ctypes.c_uint16),
167
+ ("ImpeChannelCount", ctypes.c_uint8),
168
+ ("ImpeSampleRate", ctypes.c_uint16),
169
+ ("EmgMaxSampleRate", ctypes.c_uint16),
170
+ ("EegMaxSampleRate", ctypes.c_uint16),
171
+ ("EcgMaxSampleRate", ctypes.c_uint16),
172
+ ("ConnectionIntervalMs", ctypes.c_double),
173
+ ("PeripheralLatency", ctypes.c_int32),
174
+ ("SupervisionTimeoutMs", ctypes.c_int32),
175
+ ("backend", ctypes.c_char * 16),
176
+ ("GestChannelCount", ctypes.c_uint8),
177
+ ("GestSampleRate", ctypes.c_uint16),
178
+ ]
179
+
180
+ SEN_BIN_MAX_SENSOR_DATAS = 14
181
+
182
+ class sen_bin_sensor_data_config_t(ctypes.Structure):
183
+ _fields_ = [
184
+ ("sampleRate", ctypes.c_double),
185
+ ("k", ctypes.c_double),
186
+ ("channelMask", ctypes.c_uint64),
187
+ ("dataType", ctypes.c_int32),
188
+ ("typeIndex", ctypes.c_uint8),
189
+ ("channelCount", ctypes.c_uint8),
190
+ ("packageIndexLength", ctypes.c_uint8),
191
+ ("resolutionBits", ctypes.c_uint8),
192
+ ("resolutionSigned", ctypes.c_uint8),
193
+ ("rawDataBias", ctypes.c_int8),
194
+ ("packageSampleCount", ctypes.c_uint16),
195
+ ("minPackageSampleCount", ctypes.c_uint16),
196
+ ]
197
+
198
+ class sen_bin_file_info_t(ctypes.Structure):
199
+ _fields_ = [
200
+ ("structSize", ctypes.c_uint32),
201
+ ("mac", ctypes.c_char * 18),
202
+ ("deviceName", ctypes.c_char * 32),
203
+ ("durationSec", ctypes.c_double),
204
+ ("valid", ctypes.c_uint8),
205
+ ("_reserved", ctypes.c_uint8 * 7),
206
+ ("deviceInfo", sen_device_info_t),
207
+ ("configVersion", ctypes.c_uint32),
208
+ ("chipType", ctypes.c_int32),
209
+ ("isUniversalStream", ctypes.c_uint8),
210
+ ("isNewEmg", ctypes.c_uint8),
211
+ ("isContainQat6", ctypes.c_uint8),
212
+ ("ppgModel", ctypes.c_uint8),
213
+ ("featureMap", ctypes.c_int64),
214
+ ("notifyDataFlag", ctypes.c_int64),
215
+ ("sensorDataCount", ctypes.c_uint32),
216
+ ("sensorDatas", sen_bin_sensor_data_config_t * SEN_BIN_MAX_SENSOR_DATAS),
217
+ ("firstDataTsMs", ctypes.c_uint64),
218
+ ("lastDataTsMs", ctypes.c_uint64),
219
+ ]
220
+
221
+ _sen_scan_result_cb = ctypes.CFUNCTYPE(
222
+ None, ctypes.c_void_p, ctypes.POINTER(sen_ble_device_t), ctypes.c_size_t)
223
+ _sen_enable_changed_cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_int)
224
+ _sen_data_cb = ctypes.CFUNCTYPE(
225
+ None, ctypes.c_void_p, ctypes.c_void_p,
226
+ ctypes.POINTER(sen_data_view_t), ctypes.c_size_t)
227
+ _sen_state_cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int)
228
+ _sen_error_cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_char_p)
229
+ _sen_power_cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int)
230
+ _sen_auto_reconnect_answer_cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_int)
231
+ _sen_auto_reconnect_cb = ctypes.CFUNCTYPE(
232
+ None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int,
233
+ _sen_auto_reconnect_answer_cb, ctypes.c_void_p)
234
+ _sen_device_info_update_cb = ctypes.CFUNCTYPE(
235
+ None, ctypes.c_void_p, ctypes.c_void_p, ctypes.POINTER(sen_device_info_t))
236
+ _sen_data_transfer_state_cb = ctypes.CFUNCTYPE(
237
+ None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int)
238
+
239
+ _sen_completion_cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_int, ctypes.c_char_p)
240
+ _sen_param_cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p)
241
+ _sen_battery_cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_int, ctypes.c_char_p)
242
+ _sen_info_cb = ctypes.CFUNCTYPE(
243
+ None, ctypes.c_void_p, ctypes.POINTER(sen_device_info_t), ctypes.c_char_p)
244
+ _sen_multi_result_cb = ctypes.CFUNCTYPE(
245
+ None, ctypes.c_void_p, ctypes.POINTER(ctypes.c_char_p),
246
+ ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_char_p), ctypes.c_size_t)
247
+
248
+ class sen_profile_cbs_t(ctypes.Structure):
249
+ _fields_ = [
250
+ ("structSize", ctypes.c_uint32),
251
+ ("onData", _sen_data_cb),
252
+ ("onStateChange", _sen_state_cb),
253
+ ("onError", _sen_error_cb),
254
+ ("onPowerChange", _sen_power_cb),
255
+ ("onAutoReconnect", _sen_auto_reconnect_cb),
256
+ ("onDeviceInfoUpdate", _sen_device_info_update_cb),
257
+ ("onDataTransferStateChange", _sen_data_transfer_state_cb),
258
+ ]
259
+
260
+ class sen_controller_cbs_t(ctypes.Structure):
261
+ _fields_ = [
262
+ ("structSize", ctypes.c_uint32),
263
+ ("onScanResult", _sen_scan_result_cb),
264
+ ("onEnableChanged", _sen_enable_changed_cb),
265
+ ]
266
+
267
+ def _declare(dll):
268
+ P_CTRL = ctypes.c_void_p
269
+ P_PROF = ctypes.c_void_p
270
+ c_str = ctypes.c_char_p
271
+ c_size = ctypes.c_size_t
272
+
273
+ dll.sen_terminate.restype = None
274
+ dll.sen_terminate.argtypes = []
275
+ dll.sen_capi_version.restype = ctypes.c_uint32
276
+ dll.sen_capi_version.argtypes = []
277
+ dll.sen_controller_create.restype = P_CTRL
278
+ dll.sen_controller_create.argtypes = []
279
+ dll.sen_controller_destroy.restype = None
280
+ dll.sen_controller_destroy.argtypes = [P_CTRL]
281
+ dll.sen_controller_set_callbacks.restype = None
282
+ dll.sen_controller_set_callbacks.argtypes = [P_CTRL, ctypes.POINTER(sen_controller_cbs_t), ctypes.c_void_p]
283
+
284
+ dll.sen_controller_is_enable.restype = ctypes.c_int
285
+ dll.sen_controller_is_enable.argtypes = [P_CTRL]
286
+ dll.sen_controller_is_scanning.restype = ctypes.c_int
287
+ dll.sen_controller_is_scanning.argtypes = [P_CTRL]
288
+ dll.sen_controller_start_scan.restype = ctypes.c_int
289
+ dll.sen_controller_start_scan.argtypes = [P_CTRL, ctypes.c_int]
290
+ dll.sen_controller_stop_scan.restype = ctypes.c_int
291
+ dll.sen_controller_stop_scan.argtypes = [P_CTRL]
292
+ dll.sen_controller_scan_once.restype = None
293
+ dll.sen_controller_scan_once.argtypes = [P_CTRL, ctypes.c_int, _sen_scan_result_cb, ctypes.c_void_p]
294
+
295
+ dll.sen_controller_require_sensor.restype = P_PROF
296
+ dll.sen_controller_require_sensor.argtypes = [P_CTRL, c_str]
297
+ dll.sen_controller_get_sensor.restype = P_PROF
298
+ dll.sen_controller_get_sensor.argtypes = [P_CTRL, c_str]
299
+ dll.sen_controller_get_sensors.restype = c_size
300
+ dll.sen_controller_get_sensors.argtypes = [P_CTRL, ctypes.POINTER(P_PROF), c_size]
301
+ dll.sen_controller_get_connected_sensors.restype = c_size
302
+ dll.sen_controller_get_connected_sensors.argtypes = [P_CTRL, ctypes.POINTER(P_PROF), c_size]
303
+
304
+ dll.sen_controller_get_bin_file_info.restype = ctypes.c_int
305
+ dll.sen_controller_get_bin_file_info.argtypes = [P_CTRL, c_str, ctypes.POINTER(sen_bin_file_info_t)]
306
+ dll.sen_controller_replay_bin_file.restype = P_PROF
307
+ dll.sen_controller_replay_bin_file.argtypes = [P_CTRL, c_str, c_str, ctypes.c_int, ctypes.c_uint32]
308
+ dll.sen_controller_multi_replay_bin_file.restype = c_size
309
+ dll.sen_controller_multi_replay_bin_file.argtypes = [
310
+ P_CTRL, ctypes.POINTER(c_str), ctypes.POINTER(c_str), c_size,
311
+ ctypes.c_int, ctypes.c_uint32, ctypes.POINTER(P_PROF)]
312
+ dll.sen_controller_pause_bin_replay.restype = None
313
+ dll.sen_controller_pause_bin_replay.argtypes = [P_CTRL, c_str, c_str, c_size]
314
+ dll.sen_controller_resume_bin_replay.restype = None
315
+ dll.sen_controller_resume_bin_replay.argtypes = [P_CTRL, c_str, c_str, c_size]
316
+ dll.sen_controller_stop_bin_replay.restype = None
317
+ dll.sen_controller_stop_bin_replay.argtypes = [P_CTRL, c_str, c_str, c_size]
318
+ dll.sen_controller_parse_bin_to_csv.restype = None
319
+ dll.sen_controller_parse_bin_to_csv.argtypes = [P_CTRL, c_str, c_str, _sen_param_cb, ctypes.c_void_p]
320
+
321
+ dll.sen_controller_get_version.restype = None
322
+ dll.sen_controller_get_version.argtypes = [P_CTRL, c_str, c_size]
323
+
324
+ dll.sen_controller_get_param.restype = None
325
+ dll.sen_controller_get_param.argtypes = [P_CTRL, c_str, _sen_param_cb, ctypes.c_void_p]
326
+ dll.sen_controller_set_param.restype = None
327
+ dll.sen_controller_set_param.argtypes = [P_CTRL, c_str, c_str, _sen_param_cb, ctypes.c_void_p]
328
+
329
+ dll.sen_controller_log.restype = None
330
+ dll.sen_controller_log.argtypes = [P_CTRL, c_str, c_str]
331
+
332
+ dll.sen_controller_on_suspend.restype = None
333
+ dll.sen_controller_on_suspend.argtypes = [P_CTRL]
334
+
335
+ dll.sen_controller_check_setup_dongle.restype = None
336
+ dll.sen_controller_check_setup_dongle.argtypes = [P_CTRL, _sen_param_cb, ctypes.c_void_p]
337
+
338
+ dll.sen_controller_multi_start_data.restype = None
339
+ dll.sen_controller_multi_start_data.argtypes = [P_CTRL, ctypes.POINTER(P_PROF), c_size, ctypes.c_int, ctypes.c_int, ctypes.c_int, _sen_multi_result_cb, ctypes.c_void_p]
340
+ dll.sen_controller_multi_stop_data.restype = None
341
+ dll.sen_controller_multi_stop_data.argtypes = [P_CTRL, ctypes.POINTER(P_PROF), c_size, ctypes.c_int, _sen_multi_result_cb, ctypes.c_void_p]
342
+
343
+ dll.sen_profile_set_callbacks.restype = None
344
+ dll.sen_profile_set_callbacks.argtypes = [P_PROF, ctypes.POINTER(sen_profile_cbs_t), ctypes.c_void_p]
345
+ dll.sen_profile_get_device.restype = None
346
+ dll.sen_profile_get_device.argtypes = [P_PROF, ctypes.POINTER(sen_ble_device_t)]
347
+ dll.sen_profile_get_state.restype = ctypes.c_int
348
+ dll.sen_profile_get_state.argtypes = [P_PROF]
349
+ dll.sen_profile_connect.restype = None
350
+ dll.sen_profile_connect.argtypes = [P_PROF, _sen_completion_cb, ctypes.c_void_p]
351
+ dll.sen_profile_disconnect.restype = None
352
+ dll.sen_profile_disconnect.argtypes = [P_PROF, _sen_completion_cb, ctypes.c_void_p]
353
+ dll.sen_profile_has_init.restype = ctypes.c_int
354
+ dll.sen_profile_has_init.argtypes = [P_PROF]
355
+ dll.sen_profile_has_start_data_notification.restype = ctypes.c_int
356
+ dll.sen_profile_has_start_data_notification.argtypes = [P_PROF]
357
+
358
+ dll.sen_profile_init.restype = None
359
+ dll.sen_profile_init.argtypes = [P_PROF, ctypes.c_int, ctypes.c_int, ctypes.c_int, _sen_completion_cb, ctypes.c_void_p]
360
+ dll.sen_profile_start_data.restype = None
361
+ dll.sen_profile_start_data.argtypes = [P_PROF, ctypes.c_int, _sen_completion_cb, ctypes.c_void_p]
362
+ dll.sen_profile_stop_data.restype = None
363
+ dll.sen_profile_stop_data.argtypes = [P_PROF, ctypes.c_int, _sen_completion_cb, ctypes.c_void_p]
364
+
365
+ dll.sen_profile_get_battery_level.restype = None
366
+ dll.sen_profile_get_battery_level.argtypes = [P_PROF, ctypes.c_int, _sen_battery_cb, ctypes.c_void_p]
367
+ dll.sen_profile_fetch_device_info.restype = None
368
+ dll.sen_profile_fetch_device_info.argtypes = [P_PROF, ctypes.c_int, _sen_info_cb, ctypes.c_void_p]
369
+ dll.sen_profile_get_device_info.restype = None
370
+ dll.sen_profile_get_device_info.argtypes = [P_PROF, ctypes.POINTER(sen_device_info_t)]
371
+
372
+ dll.sen_profile_set_param.restype = None
373
+ dll.sen_profile_set_param.argtypes = [P_PROF, ctypes.c_int, c_str, c_str, _sen_param_cb, ctypes.c_void_p]
374
+ dll.sen_profile_get_param.restype = None
375
+ dll.sen_profile_get_param.argtypes = [P_PROF, ctypes.c_int, c_str, _sen_param_cb, ctypes.c_void_p]
376
+
377
+ dll.sen_profile_set_auto_reconnect.restype = None
378
+ dll.sen_profile_set_auto_reconnect.argtypes = [P_PROF, ctypes.c_int]
379
+
380
+ dll.sen_profile_log.restype = None
381
+ dll.sen_profile_log.argtypes = [P_PROF, c_str, c_str]
sensor/_sync.py ADDED
@@ -0,0 +1,85 @@
1
+ import asyncio
2
+ import queue
3
+ import threading
4
+ import traceback
5
+ from concurrent.futures import Future
6
+ from concurrent.futures import TimeoutError as FuturesTimeoutError
7
+
8
+ _loop = None
9
+ _thread = None
10
+ _lock = threading.Lock()
11
+
12
+ def _run(loop):
13
+ asyncio.set_event_loop(loop)
14
+ loop.run_forever()
15
+
16
+ def get_loop():
17
+ global _loop, _thread
18
+ with _lock:
19
+ if _loop is None:
20
+ loop = asyncio.new_event_loop()
21
+ t = threading.Thread(target=_run, args=(loop,),
22
+ name="sensor-sync-loop", daemon=True)
23
+ t.start()
24
+ _loop = loop
25
+ _thread = t
26
+ return _loop
27
+
28
+ def is_loop_thread():
29
+ t = _thread
30
+ return t is not None and threading.get_ident() == t.ident
31
+
32
+ _assumed_cmd_timeout_ms = 10000
33
+
34
+ def effective_timeout_ms(timeout_ms):
35
+ return timeout_ms if timeout_ms > 0 else _assumed_cmd_timeout_ms
36
+
37
+ def note_cmd_timeout_ms(v):
38
+ global _assumed_cmd_timeout_ms
39
+ try:
40
+ v = int(v)
41
+ except (TypeError, ValueError):
42
+ return
43
+ if v > 0:
44
+ _assumed_cmd_timeout_ms = v
45
+
46
+ def run_sync(coro, timeout):
47
+ if is_loop_thread():
48
+ coro.close()
49
+ raise RuntimeError("blocking sync call from the sensor sync thread")
50
+ return asyncio.run_coroutine_threadsafe(coro, get_loop()).result(timeout)
51
+
52
+ class _Runner:
53
+ def __init__(self):
54
+ self._q = queue.Queue()
55
+ self._thread = threading.Thread(target=self._run, name="sensor-runner",
56
+ daemon=True)
57
+ self._thread.start()
58
+
59
+ def _run(self):
60
+ while True:
61
+ fn, fut = self._q.get()
62
+ if fn is None:
63
+ return
64
+ if not fut.set_running_or_notify_cancel():
65
+ continue
66
+ try:
67
+ fut.set_result(fn())
68
+ except BaseException as e:
69
+ fut.set_exception(e)
70
+ traceback.print_exc()
71
+
72
+ def submit(self, fn, *args, **kwargs):
73
+ fut = Future()
74
+ self._q.put((lambda: fn(*args, **kwargs), fut))
75
+ return fut
76
+
77
+ _runner = None
78
+ _runner_lock = threading.Lock()
79
+
80
+ def submit(fn, *args, **kwargs):
81
+ global _runner
82
+ with _runner_lock:
83
+ if _runner is None:
84
+ _runner = _Runner()
85
+ return _runner.submit(fn, *args, **kwargs)
sensor/bin/sensor.dll ADDED
Binary file
Binary file
@@ -0,0 +1,4 @@
1
+ import os
2
+
3
+ def get_hook_dirs():
4
+ return [os.path.dirname(os.path.abspath(__file__))]
@@ -0,0 +1,3 @@
1
+ from PyInstaller.utils.hooks import collect_data_files
2
+
3
+ datas = collect_data_files("sensor", includes=["bin/*"])