sensor-sdk 0.0.69__tar.gz → 0.0.71__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.
Files changed (21) hide show
  1. {sensor_sdk-0.0.69/sensor_sdk.egg-info → sensor_sdk-0.0.71}/PKG-INFO +1 -1
  2. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor/bleak_process.py +12 -12
  3. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor/gforce.py +5 -3
  4. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor/sensor_data.py +103 -105
  5. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor/sensor_data_context.py +1488 -1409
  6. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71/sensor_sdk.egg-info}/PKG-INFO +1 -1
  7. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/setup.py +1 -1
  8. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/LICENSE.txt +0 -0
  9. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/README.md +0 -0
  10. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor/__init__.py +0 -0
  11. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor/bleak_host.py +0 -0
  12. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor/sensor_controller.py +0 -0
  13. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor/sensor_device.py +0 -0
  14. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor/sensor_profile.py +0 -0
  15. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor/sensor_utils.py +0 -0
  16. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor_sdk.egg-info/SOURCES.txt +0 -0
  17. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor_sdk.egg-info/dependency_links.txt +0 -0
  18. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor_sdk.egg-info/requires.txt +0 -0
  19. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor_sdk.egg-info/top_level.txt +0 -0
  20. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/sensor_sdk.egg-info/zip-safe +0 -0
  21. {sensor_sdk-0.0.69 → sensor_sdk-0.0.71}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sensor-sdk
3
- Version: 0.0.69
3
+ Version: 0.0.71
4
4
  Summary: Python sdk for Synchroni
5
5
  Home-page: https://github.com/oymotion/SynchroniSDKPython
6
6
  Author: Martin Ye
@@ -96,7 +96,7 @@ class BleakProcess(multiprocessing.Process):
96
96
  self._gforce_event_loop = None
97
97
  self._gforce_event_thread = None
98
98
 
99
- # 可被丢弃的消息类型:这些消息高频且允许丢失,队列满时直接丢弃最新的一条
99
+ # Message types that can be dropped when the result queue is full.
100
100
  _DROPABLE_MSG_TYPES = ("sensor_data", "devices", "scan_once_result", "error")
101
101
 
102
102
  def _publish(self, msg_type: str, **kwargs):
@@ -104,16 +104,16 @@ class BleakProcess(multiprocessing.Process):
104
104
  try:
105
105
  msg = {"type": msg_type, **kwargs}
106
106
 
107
- # 对所有消息类型都做一层内存保护,防止子进程内部队列无限增长导致内存耗尽
107
+ # Memory guard: prevent the internal message queue from growing without bound.
108
108
  if self._msg_queue.qsize() > sensor_utils.BLEAK_RESULT_QUEUE_MAXSIZE:
109
109
  if msg_type in self._DROPABLE_MSG_TYPES:
110
110
  return
111
- # 对于不可丢弃的消息,尝试丢弃一条最旧的可丢弃消息以腾出空间
111
+ # For non-droppable messages, try to evict one old droppable message.
112
112
  try:
113
113
  old_msg = self._msg_queue.get_nowait()
114
114
  old_type = old_msg.get("type")
115
115
  if old_type not in self._DROPABLE_MSG_TYPES:
116
- # 如果最旧的消息也不可丢弃,把它放回去
116
+ # If the oldest message is also non-droppable, put it back.
117
117
  self._msg_queue.put_nowait(old_msg)
118
118
  except queue.Empty:
119
119
  pass
@@ -123,7 +123,7 @@ class BleakProcess(multiprocessing.Process):
123
123
  try:
124
124
  self._msg_queue.put_nowait(msg)
125
125
  except queue.Full:
126
- # 如果队列仍是满的,对不可丢弃的消息使用短时阻塞 put,避免重要消息丢失
126
+ # If still full, use a short blocking put for important messages.
127
127
  if msg_type not in self._DROPABLE_MSG_TYPES:
128
128
  try:
129
129
  self._msg_queue.put(msg, timeout=1.0)
@@ -142,12 +142,12 @@ class BleakProcess(multiprocessing.Process):
142
142
  if msg_type in self._DROPABLE_MSG_TYPES:
143
143
  self.result_queue.put_nowait(msg)
144
144
  else:
145
- # 退出时重要消息只等待较短时间,避免子进程无法正常结束
145
+ # Use a short timeout during shutdown so the child process can exit cleanly.
146
146
  self.result_queue.put(msg, timeout=2.0)
147
147
  except queue.Empty:
148
148
  break
149
149
  except queue.Full:
150
- # 队列满时丢弃一条最旧的可丢弃消息,给重要消息腾出空间
150
+ # Drop one old droppable message to make room for important messages.
151
151
  try:
152
152
  old_msg = self._msg_queue.get_nowait()
153
153
  old_type = old_msg.get("type")
@@ -161,7 +161,7 @@ class BleakProcess(multiprocessing.Process):
161
161
  break
162
162
 
163
163
  async def _publisher_task(self):
164
- # 用于限制 "Result queue is full" 的打印频率,避免在 Windows 上大量输出阻塞 stdout
164
+ # Throttle queue-full logs to avoid blocking stdout on Windows.
165
165
  _last_queue_full_log = 0.0
166
166
 
167
167
  while True:
@@ -173,7 +173,7 @@ class BleakProcess(multiprocessing.Process):
173
173
  if msg_type in self._DROPABLE_MSG_TYPES:
174
174
  self.result_queue.put_nowait(msg)
175
175
  else:
176
- # 重要消息使用较短 timeout,避免 publisher_task 长期阻塞
176
+ # Use a short timeout for important messages so the publisher does not stall.
177
177
  self.result_queue.put(msg, timeout=2.0)
178
178
  except queue.Empty:
179
179
  if self._should_exit:
@@ -182,15 +182,15 @@ class BleakProcess(multiprocessing.Process):
182
182
  except queue.Full as e:
183
183
  if msg is not None:
184
184
  if msg_type not in self._DROPABLE_MSG_TYPES:
185
- # 重要消息重新放回队列头部,稍后重试
185
+ # Put important messages back so they can be retried later.
186
186
  try:
187
187
  self._msg_queue.put_nowait(msg)
188
188
  except queue.Full:
189
189
  pass
190
190
  else:
191
- # 可丢弃消息直接丢弃,避免内存无限增长
191
+ # Droppable messages are discarded to avoid unbounded memory growth.
192
192
  pass
193
- # 2 秒最多打印一次,避免队列满时刷屏阻塞 stdout
193
+ # Log at most once every 2 seconds to prevent stdout flooding.
194
194
  now = time.time()
195
195
  if now - _last_queue_full_log >= 2.0:
196
196
  _last_queue_full_log = now
@@ -157,6 +157,8 @@ class DataSubscription(IntEnum):
157
157
  # Device Log On
158
158
  LOG = (0x00000800,)
159
159
 
160
+ DNF_TYPE_GEST_EXT = (0x00001000,)
161
+
160
162
  DNF_MAG_ANGLE_EXT = (0x00002000,)
161
163
 
162
164
  DNF_EEG = (0x00010000,)
@@ -505,8 +507,8 @@ class GForce:
505
507
  try:
506
508
  q.put_nowait(bytes(bs))
507
509
  except queue.Full:
508
- # 队列满时只丢弃最旧的一部分数据,而不是全部清空,
509
- # 避免一次性丢失过多原始数据包
510
+ # Drop only a few oldest items instead of clearing the whole queue
511
+ # to avoid losing too many raw data packets at once.
510
512
  dropped = 0
511
513
  while dropped < 16 and not q.empty():
512
514
  try:
@@ -579,7 +581,7 @@ class GForce:
579
581
  try:
580
582
  q.put_nowait(bytes(bs))
581
583
  except queue.Full:
582
- # 队列满时只丢弃最旧的一部分数据,而不是全部清空
584
+ # Drop only a few oldest items instead of clearing the whole queue.
583
585
  dropped = 0
584
586
  while dropped < 16 and not q.empty():
585
587
  try:
@@ -1,105 +1,103 @@
1
- from enum import Enum, IntEnum
2
- from typing import Dict, List
3
-
4
-
5
-
6
-
7
- class Sample:
8
- # """
9
- # Initialize a Sample instance.
10
-
11
-
12
-
13
-
14
-
15
-
16
- # """
17
- # def __init__(self, data: int, impedance: int, saturation: int, sample_index: int, is_lost: bool):
18
- # self.data = data
19
- # self.impedance = impedance
20
- # self.saturation = saturation
21
- # self.sampleIndex = sample_index
22
- # self.isLost = is_lost
23
-
24
- def __init__(self):
25
- self.rawData = 0
26
- self.data = 0
27
- self.impedance = 0
28
- self.saturation = 0
29
- self.sampleIndex = 0
30
- self.isLost = False
31
- self.timeStampInMs = 0
32
- self.channelIndex = 0
33
-
34
-
35
-
36
-
37
- class DataType(IntEnum):
38
- NTF_ACC = 0x1
39
- NTF_GYRO = 0x2
40
- NTF_EULER_DATA = 0x4
41
- NTF_QUATERNION = 0x5
42
- NTF_EMG = 0x8
43
- NTF_MAG_ANGLE_DATA = 0x0D
44
- NTF_EEG = 0x10
45
- NTF_ECG = 0x11
46
- NTF_IMPEDANCE = 0x12
47
- NTF_IMU = 0x13
48
- NTF_ADS = 0x14
49
- NTF_BRTH = 0x15
50
- NTF_IMPEDANCE_EXT = 0x16
51
- NTF_PPG = 0x18
52
- NTF_SPO2 = 0x17
53
-
54
-
55
-
56
-
57
-
58
- class SensorData:
59
- # """
60
- # Initialize a SensorData instance.
61
-
62
- # :param device_mac: The MAC address of the device.
63
- # :param data_type: The type of data being collected.
64
- # :param sample_rate: The rate at which samples are collected.
65
- # :param channel_count: The number of channels in the data.
66
- # :param package_sample_count: The number of samples in the package.
67
- # :param channel_samples: A list of lists containing the sample data for each channel.
68
- # """
69
- # def __init__(self, device_mac: str, data_type: DataType, sample_rate: int, channel_count: int,
70
- # package_sample_count: int, channel_samples: List[List[Sample]]):
71
- # self.deviceMac = device_mac
72
- # self.dataType = data_type
73
- # self.sampleRate = sample_rate
74
- # self.channelCount = channel_count
75
- # self.packageSampleCount = package_sample_count
76
- # self.channelSamples = channel_samples
77
- # self.lastPackageCounter = 0
78
- # self.lastPackageIndex = 0
79
- # self.resolutionBits = 0
80
- # self.channelMask = 0
81
- # self.minPackageSampleCount = 0
82
- # self.K = 0
83
-
84
- def __init__(self):
85
- self.deviceMac = ""
86
- self.dataType = DataType.NTF_EEG
87
- self.sampleRate = 0
88
- self.channelCount = 0
89
- self.packageSampleCount = 0
90
- self.packageIndexLength = 2
91
- self.channelSamples: List[List[Sample]] = list()
92
- self.lastPackageCounter = 0
93
- self.lastPackageIndex = 0
94
- self.lostPackageCount = 0
95
- self.resolutionBits = 0
96
- self.resolutionSigned = 0
97
- self.channelMask = 0
98
- self.minPackageSampleCount = 0
99
- self.K = 0
100
-
101
- def clear(self):
102
- self.channelSamples.clear()
103
- self.lastPackageCounter = -1
104
- self.lastPackageIndex = 0
105
- self.lostPackageCount = 0
1
+ from enum import Enum, IntEnum
2
+ from typing import Dict, List
3
+
4
+
5
+
6
+
7
+ class Sample:
8
+ # """
9
+ # Initialize a Sample instance.
10
+
11
+
12
+
13
+
14
+
15
+
16
+ # """
17
+ # def __init__(self, data: int, impedance: int, saturation: int, sample_index: int, is_lost: bool):
18
+ # self.data = data
19
+ # self.impedance = impedance
20
+ # self.saturation = saturation
21
+ # self.sampleIndex = sample_index
22
+ # self.isLost = is_lost
23
+
24
+ def __init__(self):
25
+ self.rawData = 0
26
+ self.data = 0
27
+ self.impedance = 0
28
+ self.saturation = 0
29
+ self.sampleIndex = 0
30
+ self.isLost = False
31
+ self.timeStampInMs = 0
32
+ self.channelIndex = 0
33
+
34
+
35
+
36
+
37
+ class DataType(IntEnum):
38
+ NTF_ACC = 0x1
39
+ NTF_GYRO = 0x2
40
+ NTF_EULER_DATA = 0x4
41
+ NTF_QUATERNION = 0x5
42
+ NTF_GEST = 0x07
43
+ NTF_EMG = 0x8
44
+ NTF_MAG_ANGLE_DATA = 0x0D
45
+ NTF_EEG = 0x10
46
+ NTF_ECG = 0x11
47
+ NTF_IMPEDANCE = 0x12
48
+ NTF_IMU = 0x13
49
+ NTF_ADS = 0x14
50
+ NTF_BRTH = 0x15
51
+ NTF_IMPEDANCE_EXT = 0x16
52
+ NTF_SPO2 = 0x17
53
+ NTF_PPG = 0x18
54
+
55
+
56
+ class SensorData:
57
+ # """
58
+ # Initialize a SensorData instance.
59
+
60
+ # :param device_mac: The MAC address of the device.
61
+ # :param data_type: The type of data being collected.
62
+ # :param sample_rate: The rate at which samples are collected.
63
+ # :param channel_count: The number of channels in the data.
64
+ # :param package_sample_count: The number of samples in the package.
65
+ # :param channel_samples: A list of lists containing the sample data for each channel.
66
+ # """
67
+ # def __init__(self, device_mac: str, data_type: DataType, sample_rate: int, channel_count: int,
68
+ # package_sample_count: int, channel_samples: List[List[Sample]]):
69
+ # self.deviceMac = device_mac
70
+ # self.dataType = data_type
71
+ # self.sampleRate = sample_rate
72
+ # self.channelCount = channel_count
73
+ # self.packageSampleCount = package_sample_count
74
+ # self.channelSamples = channel_samples
75
+ # self.lastPackageCounter = 0
76
+ # self.lastPackageIndex = 0
77
+ # self.resolutionBits = 0
78
+ # self.channelMask = 0
79
+ # self.minPackageSampleCount = 0
80
+ # self.K = 0
81
+
82
+ def __init__(self):
83
+ self.deviceMac = ""
84
+ self.dataType = DataType.NTF_EEG
85
+ self.sampleRate = 0
86
+ self.channelCount = 0
87
+ self.packageSampleCount = 0
88
+ self.packageIndexLength = 2
89
+ self.channelSamples: List[List[Sample]] = list()
90
+ self.lastPackageCounter = 0
91
+ self.lastPackageIndex = 0
92
+ self.lostPackageCount = 0
93
+ self.resolutionBits = 0
94
+ self.resolutionSigned = 0
95
+ self.channelMask = 0
96
+ self.minPackageSampleCount = 0
97
+ self.K = 0
98
+
99
+ def clear(self):
100
+ self.channelSamples.clear()
101
+ self.lastPackageCounter = -1
102
+ self.lastPackageIndex = 0
103
+ self.lostPackageCount = 0