Synchroni sdk for Python
Synchroni SDK is the software development kit for developers to access Synchroni products.
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
pip install sensor-sdk
Application will obtain bluetooth permission by itself.
from sensor import *
SensorControllerInstance = SensorController()
# register scan listener
if not SensorControllerInstance.hasDeviceFoundCallback:
def on_device_callback(deviceList: List[BLEDevice]):
# return all devices doesn't connected
pass
SensorControllerInstance.onDeviceFoundCallback = on_device_callback
Use def startScan(period_in_ms: int) -> bool
to start scan
success = SensorControllerInstance.startScan(6000)
returns true if start scan success, periodInMS means onDeviceCallback will be called every periodInMS
Use def stopScan() -> None
to stop scan
SensorControllerInstance.stopScan()
Use property isScanning: bool
to check scanning status
isScanning = SensorControllerInstance.isScanning
Use property isEnabled: bool
to check if bluetooth is enabled
isEnabled = SensorControllerInstance.isEnabled
Use def requireSensor(device: BLEDevice) -> SensorProfile | None
to create SensorProfile.
If bleDevice is invalid, result is None.
sensorProfile = SensorControllerInstance.requireSensor(bleDevice)
Use def getSensor(device: BLEDevice) -> SensorProfile | None
to get SensorProfile.
If SensorProfile didn't created, result is None.
sensorProfile = SensorControllerInstance.getSensor(bleDevice)
Use def getConnectedSensors() -> list[SensorProfile]
to get connected SensorProfiles.
sensorProfiles = SensorControllerInstance.getConnectedSensors()
Use def getConnectedDevices() -> list[SensorProfile]
to get connected BLE Devices.
bleDevices = SensorControllerInstance.getConnectedDevices()
Use def terminate()
to terminate sdk
def terminate():
SensorControllerInstance.terminate()
exit()
def main():
signal.signal(signal.SIGINT, lambda signal, frame: terminate())
time.sleep(30)
SensorControllerInstance.terminate()
Please MAKE SURE to call terminate when exit main() or press Ctrl+C
Please register callbacks for SensorProfile
sensorProfile = SensorControllerInstance.requireSensor(bleDevice)
# register callbacks
def on_state_changed(sensor, newState):
# please do logic when device disconnected unexpected
pass
def on_error_callback(sensor, reason):
# called when error occurs
pass
def on_power_changed(sensor, power):
# callback for get battery level of device, power from 0 - 100, -1 is invalid
pass
def on_data_callback(sensor, data):
# called after start data transfer
pass
sensorProfile.onStateChanged = on_state_changed
sensorProfile.onErrorCallback = on_error_callback
sensorProfile.onPowerChanged = on_power_changed
sensorProfile.onDataCallback = on_data_callback
Use def connect() -> bool
to connect.
success = sensorProfile.connect()
Use def disconnect() -> bool
to disconnect.
success = sensorProfile.disconnect()
Use property deviceState: DeviceStateEx
to get device status.
Please send command in 'Ready' state, should be after connect() return True.
deviceStateEx = sensorProfile.deviceState
# deviceStateEx has define:
# class DeviceStateEx(Enum):
# Disconnected = 0
# Connecting = 1
# Connected = 2
# Ready = 3
# Disconnecting = 4
# Invalid = 5
Use property BLEDevice: BLEDevice
to get BLE device of SensorProfile.
bleDevice = sensorProfile.BLEDevice
Use def getDeviceInfo() -> dict | None
to get device info of SensorProfile.
Please call after device in 'Ready' state, return None if it's not connected.
deviceInfo = sensorProfile.getDeviceInfo()
# deviceInfo has defines:
# deviceInfo = {
# "deviceName": str,
# "modelName": str,
# "hardwareVersion": str,
# "firmwareVersion": str,
# "emgChannelCount": int,
# "eegChannelCount": int,
# "ecgChannelCount": int,
# "accChannelCount": int,
# "gyroChannelCount": int,
# "brthChannelCount": int,
# "mtuSize": int
# }
Use def init(packageSampleCount: int, powerRefreshInterval: int) -> bool
.
Please call after device in 'Ready' state, return True if init succeed.
success = sensorProfile.init(5, 60*1000)
packageSampleCount: set sample counts of SensorData.channelSamples in onDataCallback() powerRefreshInterval: callback period for onPowerChanged()
Use property hasInited: bool
to check if init data transfer succeed.
hasInited = sensorProfile.hasInited
Use def startDataNotification() -> bool
to start data notification.
Please call if hasInited return True
success = sensorProfile.startDataNotification()
Data type list:
class DataType(Enum):
NTF_ACC = 0x1 # unit is g
NTF_GYRO = 0x2 # unit is degree/s
NTF_EEG = 0x10 # unit is uV
NTF_ECG = 0x11 # unit is uV
NTF_BRTH = 0x15 # unit is uV
Process data in onDataCallback.
def on_data_callback(sensor, data):
if data.dataType == DataType.NTF_EEG:
pass
elif data.dataType == DataType.NTF_ECG:
pass
# process data as you wish
for oneChannelSamples in data.channelSamples:
for sample in oneChannelSamples:
if sample.isLost:
# do some logic
pass
else:
# draw with sample.data & sample.channelIndex
# print(f"{sample.channelIndex} | {sample.sampleIndex} | {sample.data} | {sample.impedance}")
pass
sensorProfile.onDataCallback = on_data_callback
Use def stopDataNotification() -> bool
to stop data transfer.
success = sensorProfile.stopDataNotification()
Use property isDataTransfering: bool
to check if it's data transfering.
isDataTransfering = sensorProfile.isDataTransfering
Use def getBatteryLevel() -> int
to get battery level. Please call after device in 'Ready' state.
batteryPower = sensorProfile.getBatteryLevel()
# batteryPower is battery level returned, value ranges from 0 to 100, 0 means out of battery, while 100 means full.
Please check console.py in examples directory