sensor-sdk 0.0.15__py3-none-any.whl → 0.0.16__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sensor-sdk might be problematic. Click here for more details.

sensor/gforce.py CHANGED
@@ -728,6 +728,17 @@ class GForce:
728
728
  )
729
729
  )
730
730
 
731
+ async def set_package_id(self, switchStatus):
732
+ body = [switchStatus == True]
733
+ body = bytes(body)
734
+ ret = await self._send_request(
735
+ Request(
736
+ cmd=Command.PACKAGE_ID_CONTROL,
737
+ body=body,
738
+ has_res=True,
739
+ )
740
+ )
741
+
731
742
  async def set_log_level(self, logLevel):
732
743
  body = [0xFF & logLevel]
733
744
  body = bytes(body)
sensor/sensor_data.py CHANGED
@@ -38,6 +38,7 @@ class Sample:
38
38
  class DataType(IntEnum):
39
39
  NTF_ACC = 0x1 # 加速度,用于标识加速度传感器采集的数据
40
40
  NTF_GYRO = 0x2 # 陀螺仪,用于标识陀螺仪传感器采集的数据
41
+ NTF_EMG = 0x8 # EMG,用于标识肌电传感器采集的数据
41
42
  NTF_EEG = 0x10 # EEG,用于标识脑电传感器采集的数据
42
43
  NTF_ECG = 0x11 # ECG,用于标识心电传感器采集的数据
43
44
  NTF_IMPEDANCE = (0x12,) # 阻抗数据
@@ -8,7 +8,7 @@ from typing import Deque, List
8
8
  from concurrent.futures import ThreadPoolExecutor
9
9
  import csv
10
10
  from sensor import utils
11
- from sensor.gforce import DataSubscription, GForce
11
+ from sensor.gforce import DataSubscription, GForce, SamplingRate
12
12
  from sensor.sensor_data import DataType, Sample, SensorData
13
13
 
14
14
  from enum import Enum, IntEnum
@@ -22,7 +22,8 @@ class SensorDataType(IntEnum):
22
22
  DATA_TYPE_ACC = 2
23
23
  DATA_TYPE_GYRO = 3
24
24
  DATA_TYPE_BRTH = 4
25
- DATA_TYPE_COUNT = 5
25
+ DATA_TYPE_EMG = 5
26
+ DATA_TYPE_COUNT = 6
26
27
 
27
28
 
28
29
  # 枚举 FeatureMaps 的 Python 实现
@@ -114,6 +115,31 @@ class SensorProfileDataCtx:
114
115
  def hasConcatBLE(self):
115
116
  return (self.featureMap & FeatureMaps.GFD_FEAT_CONCAT_BLE.value) != 0
116
117
 
118
+ async def initEMG(self, packageCount: int) -> int:
119
+ config = await self.gForce.get_emg_raw_data_config()
120
+ data = SensorData()
121
+ data.deviceMac = self.deviceMac
122
+ data.dataType = DataType.NTF_EMG
123
+ data.sampleRate = 500
124
+ data.resolutionBits = 0
125
+ data.channelCount = 8
126
+ data.channelMask = config.channel_mask
127
+ data.minPackageSampleCount = packageCount
128
+ data.packageSampleCount = 8
129
+ data.K = 4000000.0 / 8388607.0
130
+ data.clear()
131
+ self.sensorDatas[SensorDataType.DATA_TYPE_EMG] = data
132
+ self.notifyDataFlag |= DataSubscription.EMG_RAW
133
+
134
+ config.fs = SamplingRate.HZ_500
135
+ config.channel_mask = 255
136
+ config.resolution = 8
137
+ config.batch_len = 128
138
+ await self.gForce.set_emg_raw_data_config(config)
139
+
140
+ await self.gForce.set_package_id(True)
141
+ return data.channelCount
142
+
117
143
  async def initEEG(self, packageCount: int) -> int:
118
144
  config = await self.gForce.get_eeg_raw_data_config()
119
145
  cap = await self.gForce.get_eeg_raw_data_cap()
@@ -234,23 +260,23 @@ class SensorProfileDataCtx:
234
260
  if self.hasImpedance():
235
261
  self.notifyDataFlag |= DataSubscription.DNF_IMPEDANCE
236
262
 
237
- if self.hasEEG() & (self.init_map["NTF_EEG"] == "ON"):
238
- # print("initEEG")
263
+ if self.hasEMG() and (self.init_map["NTF_EMG"] == "ON"):
264
+ info.EmgChannelCount = await self.initEMG(packageCount)
265
+ info.EmgSampleRate = self.sensorDatas[SensorDataType.DATA_TYPE_EMG].sampleRate
266
+
267
+ if self.hasEEG() and (self.init_map["NTF_EEG"] == "ON"):
239
268
  info.EegChannelCount = await self.initEEG(packageCount)
240
269
  info.EegSampleRate = self.sensorDatas[SensorDataType.DATA_TYPE_EEG].sampleRate
241
270
 
242
- if self.hasECG() & (self.init_map["NTF_ECG"] == "ON"):
243
- # print("initECG")
271
+ if self.hasECG() and (self.init_map["NTF_ECG"] == "ON"):
244
272
  info.EcgChannelCount = await self.initECG(packageCount)
245
273
  info.EcgSampleRate = self.sensorDatas[SensorDataType.DATA_TYPE_ECG].sampleRate
246
274
 
247
- if self.hasBrth() & (self.init_map["NTF_BRTH"] == "ON"):
248
- # print("initBrth")
275
+ if self.hasBrth() and (self.init_map["NTF_BRTH"] == "ON"):
249
276
  info.BrthChannelCount = await self.initBrth(packageCount)
250
277
  info.BrthSampleRate = self.sensorDatas[SensorDataType.DATA_TYPE_BRTH].sampleRate
251
278
 
252
- if self.hasIMU() & (self.init_map["NTF_IMU"] == "ON"):
253
- # print("initIMU")
279
+ if self.hasIMU() and (self.init_map["NTF_IMU"] == "ON"):
254
280
  imuChannelCount = await self.initIMU(packageCount)
255
281
  info.AccChannelCount = imuChannelCount
256
282
  info.GyroChannelCount = imuChannelCount
@@ -374,7 +400,7 @@ class SensorProfileDataCtx:
374
400
  buf.task_done()
375
401
 
376
402
  def _processDataPackage(self, data: bytes, buf: Queue[SensorData], sensor):
377
- v = data[0]
403
+ v = data[0] & 0x7F
378
404
  if v == DataType.NTF_IMPEDANCE:
379
405
  offset = 1
380
406
  # packageIndex = ((data[offset + 1] & 0xff) << 8) | (data[offset] & 0xff)
@@ -397,7 +423,10 @@ class SensorProfileDataCtx:
397
423
 
398
424
  self.impedanceData = impedanceData
399
425
  self.saturationData = saturationData
400
-
426
+ elif v == DataType.NTF_EMG:
427
+ sensor_data = self.sensorDatas[SensorDataType.DATA_TYPE_EMG]
428
+ if self.checkReadSamples(sensor, data, sensor_data, 3, 0):
429
+ self.sendSensorData(sensor_data, buf)
401
430
  elif v == DataType.NTF_EEG:
402
431
  sensor_data = self.sensorDatas[SensorDataType.DATA_TYPE_EEG]
403
432
  if self.checkReadSamples(sensor, data, sensor_data, 3, 0):
@@ -421,7 +450,7 @@ class SensorProfileDataCtx:
421
450
 
422
451
  def checkReadSamples(self, sensor, data: bytes, sensorData: SensorData, dataOffset: int, dataGap: int):
423
452
  offset = 1
424
- v = data[0]
453
+
425
454
  if not self._is_data_transfering:
426
455
  return False
427
456
  try:
@@ -453,8 +482,9 @@ class SensorProfileDataCtx:
453
482
  asyncio.get_event_loop().run_in_executor(None, sensor._on_error_callback, sensor, lostLog)
454
483
  except Exception as e:
455
484
  pass
485
+ if lostSampleCount < 100:
486
+ self.readSamples(data, sensorData, 0, dataGap, lostSampleCount)
456
487
 
457
- self.readSamples(data, sensorData, 0, dataGap, lostSampleCount)
458
488
  if newPackageIndex == 0:
459
489
  sensorData.lastPackageIndex = 65535
460
490
  else:
@@ -469,6 +499,12 @@ class SensorProfileDataCtx:
469
499
  return False
470
500
  return True
471
501
 
502
+ def transTrainData(self, data: int):
503
+ xout = data >> 4
504
+ exp = data & 0x0000000F
505
+ xout = xout << exp
506
+ return xout
507
+
472
508
  def readSamples(
473
509
  self,
474
510
  data: bytes,
@@ -536,6 +572,10 @@ class SensorProfileDataCtx:
536
572
  rawData = (data[offset] << 16) | (data[offset + 1] << 8) | data[offset + 2]
537
573
  rawData -= 8388608
538
574
  offset += 3
575
+ elif sensorData.resolutionBits == 0:
576
+ rawData = struct.unpack_from("<h", data, offset)[0]
577
+ offset += 2
578
+ rawData = self.transTrainData(rawData)
539
579
 
540
580
  converted = rawData * K
541
581
  dataItem.rawData = rawData
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sensor-sdk
3
- Version: 0.0.15
3
+ Version: 0.0.16
4
4
  Summary: Python sdk for Synchroni
5
5
  Home-page: https://github.com/oymotion/SynchroniSDKPython
6
6
  Author: Martin Ye
7
7
  Author-email: yecq_82@hotmail.com
8
- Requires-Python: >=3.8.0
8
+ Requires-Python: >=3.9.0
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE.txt
11
11
  Requires-Dist: numpy
@@ -0,0 +1,14 @@
1
+ sensor/__init__.py,sha256=L1VyAP0EDEnJIMeMTzp4iXHSRUUHyHScF_GIl3iYKRI,123
2
+ sensor/gforce.py,sha256=gpetzJD0b4zezCMdhzodjjj55eb2C37ApeiNIYzRf1Q,26078
3
+ sensor/sensor_controller.py,sha256=qnM9mVwpJn9PCnxlvbgWFeaLktqVnmaquZgasYGEHqs,9451
4
+ sensor/sensor_data.py,sha256=vKreLHZs7WbQcnfqHiLLfHQ3cCmvD1K2xl2WUQg8vv0,4005
5
+ sensor/sensor_data_context.py,sha256=FpZlgEq98MPRR3SGOy4LimXaiU3SBVuxtDCbSMPro1M,30560
6
+ sensor/sensor_device.py,sha256=eO1vaqjxCc2UCPBoKXqlk6o498uRyWt6IYs7r7wXSD0,3042
7
+ sensor/sensor_profile.py,sha256=NJsPr9l4VB9zAjfkaD28chGnJiSCnYAGFdkkN9Wyky0,19669
8
+ sensor/utils.py,sha256=BudTD083ucGxcTXfmksF-2gLRi_i-k7tMytruLUUKJc,6503
9
+ sensor_sdk-0.0.16.dist-info/LICENSE.txt,sha256=8CSivOpub3IuXODTyqBRI91AxouJZk02YrcKuOAkWu8,1111
10
+ sensor_sdk-0.0.16.dist-info/METADATA,sha256=dxmSp_3HYa2gUxk9bpCeqsynksYfw1Km-SeIhsTtsFc,9825
11
+ sensor_sdk-0.0.16.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
12
+ sensor_sdk-0.0.16.dist-info/top_level.txt,sha256=Ftq49B6bH0Ffdc7c8LkcyakHo6lsg_snlBbpEUoILSk,7
13
+ sensor_sdk-0.0.16.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
14
+ sensor_sdk-0.0.16.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- sensor/__init__.py,sha256=L1VyAP0EDEnJIMeMTzp4iXHSRUUHyHScF_GIl3iYKRI,123
2
- sensor/gforce.py,sha256=wZ4aEFtrgeR8LsL7tm6VSsjvIVcWbfQhwAVfADveNkg,25761
3
- sensor/sensor_controller.py,sha256=qnM9mVwpJn9PCnxlvbgWFeaLktqVnmaquZgasYGEHqs,9451
4
- sensor/sensor_data.py,sha256=Hu7Ql0LgQ7V24xYZhaLrKPwU4KWZeWE655v8Gy8xphY,3934
5
- sensor/sensor_data_context.py,sha256=rxttt7f1BQOM2lUFys_po4BICdVl-NmIHKfnqGKs5XE,28815
6
- sensor/sensor_device.py,sha256=eO1vaqjxCc2UCPBoKXqlk6o498uRyWt6IYs7r7wXSD0,3042
7
- sensor/sensor_profile.py,sha256=NJsPr9l4VB9zAjfkaD28chGnJiSCnYAGFdkkN9Wyky0,19669
8
- sensor/utils.py,sha256=BudTD083ucGxcTXfmksF-2gLRi_i-k7tMytruLUUKJc,6503
9
- sensor_sdk-0.0.15.dist-info/LICENSE.txt,sha256=8CSivOpub3IuXODTyqBRI91AxouJZk02YrcKuOAkWu8,1111
10
- sensor_sdk-0.0.15.dist-info/METADATA,sha256=D2Zk6zQPs3XrYYVdt_ROBT-PNZaIi_EhCgFZ9iqtwb4,9825
11
- sensor_sdk-0.0.15.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
12
- sensor_sdk-0.0.15.dist-info/top_level.txt,sha256=Ftq49B6bH0Ffdc7c8LkcyakHo6lsg_snlBbpEUoILSk,7
13
- sensor_sdk-0.0.15.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
14
- sensor_sdk-0.0.15.dist-info/RECORD,,