SiFi Bridge Python
SiFi Bridge Python is a Python API for controlling SiFi Labs biosensor devices programmatically. Build custom applications, automate experiments, and integrate physiological data into your research workflow.
Features
- Object-Oriented API - Clean, Pythonic interface for device control
- Real-Time Data Streaming - Sensor packets delivered as Python dicts with per-sample timestamps
- Flexible Configuration - Per-sensor sampling rate, filtering, and gain controlled programmatically
- Multiple Output Formats - Stream over stdout, TCP, UDP, or Lab Streaming Layer (LSL)
- Multi-Device Support - Manage multiple SiFi devices from a single bridge instance
- Easy Integration - Works seamlessly with NumPy, Pandas, scikit-learn, NeuroKit2, and ML frameworks
Installation
Install via pip:
pip install sifi_bridge_py
Or from source:
git clone https://github.com/SiFiLabs/sifi-bridge-py.git
cd sifi-bridge-py
pip install -e .
See the Installation Guide for detailed instructions.
Quick Start
Connect to a device and stream ECG data in just a few lines:
import sifi_bridge_py as sbp
# Create bridge and connect to the first available SiFi device.
# Pass a DeviceType or a MAC/UUID to target a specific unit.
sb = sbp.SifiBridge()
sb.connect()
# Configure ECG sensor: 500 Hz, 0–30 Hz bandpass, 50 Hz mains notch
# (use 60 in North America).
sb.configure_ecg(state=True, fs=500, mains_notch=50,
bandpass=True, flo=0, fhi=30)
sb.start()
# Read 10 ECG packets.
for _ in range(10):
packet = sb.get_ecg()
print(f"ECG data: {packet['data']['ecg'][:5]}...")
# Cleanup.
sb.stop()
sb.disconnect()
See the Quick Start Guide for more examples.
Use Cases
Data Collection
import time
import sifi_bridge_py as sbp
sb = sbp.SifiBridge()
sb.connect()
sb.configure_sensors(ecg=True, emg=True, imu=True)
sb.start()
# Collect packets for 60 seconds and route them by packet_type.
ecg, emg, imu = [], [], []
t0 = time.time()
while time.time() - t0 < 60:
pkt = sb.get_data(timeout=1.0)
if not pkt:
continue
if pkt['packet_type'] == 'ecg':
ecg.append(pkt)
elif pkt['packet_type'] == 'emg':
emg.append(pkt)
elif pkt['packet_type'] == 'imu':
imu.append(pkt)
sb.stop()
sb.disconnect()
Real-Time Analysis
import numpy as np
import sifi_bridge_py as sbp
sb = sbp.SifiBridge()
sb.connect()
sb.configure_sensors(ecg=True)
sb.configure_ecg(state=True, fs=500)
sb.start()
while True:
packet = sb.get_ecg()
ecg_data = np.array(packet['data']['ecg'])
# Your analysis here, e.g. R-peak detection, HR estimation, ...
Lab Streaming Layer (LSL)
# Stream to LSL for integration with LabRecorder, OpenViBE, BCILAB,
# pylsl scripts, etc. Each enabled sensor becomes its own LSL outlet.
sb = sbp.SifiBridge(use_lsl=True)
sb.connect()
sb.configure_sensors(ecg=True, emg=True)
sb.start()
Network Streaming (TCP/UDP)
# Push every sensor packet as JSON over TCP. The bridge acts as a TCP
# CLIENT and connects out to the address you specify, so a TCP server
# must already be listening at host:port.
sb = sbp.SifiBridge(publishers="tcp://127.0.0.1:9001")
sb.connect()
sb.configure_sensors(ecg=True)
sb.start()
Machine Learning Integration
import pandas as pd
import sifi_bridge_py as sbp
sb = sbp.SifiBridge()
sb.connect()
sb.configure_sensors(emg=True)
sb.configure_emg(state=True, fs=2000)
sb.start()
# Collect 1000 EMG packets and turn them into a DataFrame.
data_buffer = []
for _ in range(1000):
packet = sb.get_emg()
data_buffer.extend(packet['data']['emg'])
df = pd.DataFrame({'emg': data_buffer})
# Train your model ...
Key Concepts
Device Connection
Connect to devices by type, by address, or auto-connect to the first available unit:
# Auto-connect to any SiFi device in range.
sb.connect()
# Connect to a BioPoint v1.3 specifically.
sb.connect(sbp.DeviceType.BIOPOINT_V1_3)
# Connect by MAC (Windows / Linux) or UUID (macOS).
sb.connect("AA:BB:CC:DD:EE:FF")
# List devices first, then connect.
devices = sb.list_devices(sbp.ListSources.BLE)
sb.connect(devices[0])
Sensor Configuration
Two layers: configure_sensors() is the on/off switch for each sensor
family, and the per-sensor configure_* methods set sampling rate,
filtering, and gain.
# Enable only the sensors you need.
sb.configure_sensors(ecg=True, emg=True, imu=True)
# ECG: 500 Hz, 0–30 Hz bandpass, 50 Hz mains notch.
sb.configure_ecg(state=True, fs=500, mains_notch=50,
bandpass=True, flo=0, fhi=30)
# EMG: 2 kHz, 20–450 Hz bandpass.
sb.configure_emg(state=True, fs=2000, mains_notch=50,
bandpass=True, flo=20, fhi=450)
# PPG: per-LED current in mA (1–50) and photodiode sensitivity.
sb.configure_ppg(state=True, fs=100, ir=7, red=7, green=9, blue=9,
sens=sbp.PpgSensitivity.MEDIUM)
# IMU: accelerometer range in g, gyroscope range in deg/s.
sb.configure_imu(state=True, fs=100, accel_range=2, gyro_range=250)
Data Acquisition
Multiple ways to get data, depending on whether you want any packet or a specific sensor:
# Get any packet (event packets, status packets, sensor packets, ...).
packet = sb.get_data()
# Get the next packet of a specific sensor type.
ecg = sb.get_ecg()
emg = sb.get_emg()
imu = sb.get_imu()
ppg = sb.get_ppg()
# Non-blocking / bounded read.
packet = sb.get_data(timeout=1.0)
Device Commands
Control LEDs, vibration motor, and event markers:
# LED control.
sb.send_command(sbp.DeviceCommand.OPEN_LED_1)
sb.send_command(sbp.DeviceCommand.CLOSE_LED_1)
# Vibration motor — set intensity (1–10), then start / stop.
sb.set_motor_intensity(5)
sb.send_command(sbp.DeviceCommand.START_MOTOR)
sb.send_command(sbp.DeviceCommand.STOP_MOTOR)
# Event markers. send_event() injects an event packet into the data
# stream — it comes back with packet_type='event' and a device-side
# timestamp, just like a sensor packet.
sb.send_event()
Comparison with CLI
| Feature | Python API | CLI |
|---|---|---|
| Use Case | Custom applications, automation | Interactive exploration, quick data collection |
| Coding Required | Yes | No |
| Integration | Seamless with NumPy, Pandas, ML | Export over LSL, TCP, UDP |
| Flexibility | Full programmatic control | Command-based |
| Best For | Developers, researchers with coding | Researchers without coding, quick tests |
Both interfaces use the same underlying library and offer the same capabilities.
Support
- API Reference - Complete method documentation
- Email: support@sifilabs.com
- GitHub Issues: Report bugs