Skip to main content

Advanced Topics

Advanced features and configurations for power users and developers.

Lua Plugin System

Extend SiFi Bridge functionality with custom Lua scripts.

Creating a Plugin

Plugins are Lua 5.4 scripts that can hook into SiFi Bridge events.

Basic Plugin Structure:

-- my_plugin.lua
local plugin = {}

function plugin.on_device_connected(device)
print("Device connected: " .. device.name)
end

function plugin.on_data_received(data)
print("Received: " .. tostring(data.value))
end

function plugin.on_device_disconnected(device)
print("Device disconnected: " .. device.name)
end

return plugin

Loading a Plugin

sifibridge> plugin load /path/to/my_plugin.lua
✓ Plugin loaded: my_plugin.lua

Available Plugin Hooks

on_device_connected

Called when a device connects successfully.

function plugin.on_device_connected(device)
-- device: {name, mac, status, battery}
print("Connected to " .. device.name)
end

on_device_disconnected

Called when a device disconnects.

function plugin.on_device_disconnected(device)
print("Disconnected from " .. device.name)
end

on_data_received

Called each time data is received from a sensor.

function plugin.on_data_received(data)
-- data: {sensor, timestamp, values}
if data.sensor == "ppg" then
print("PPG Red: " .. data.values.red)
end
end

on_command_executed

Called when a command completes.

function plugin.on_command_executed(result)
-- result: {command, success, message}
print("Command " .. result.command .. ": " .. tostring(result.success))
end

Example: Data Logging Plugin

-- log_plugin.lua: Log all data with timestamps
local plugin = {}
local log_file = io.open("data.log", "a")

function plugin.on_device_connected(device)
log_file:write("[CONNECT] " .. device.name .. " at " .. os.date() .. "\n")
log_file:flush()
end

function plugin.on_data_received(data)
local entry = string.format("[DATA] %s: %s\n",
data.timestamp,
data.sensor
)
log_file:write(entry)

if log_file:seek() > 1000000 then -- Rotate at 1MB
log_file:close()
os.rename("data.log", "data.log." .. os.time())
log_file = io.open("data.log", "a")
end

log_file:flush()
end

function plugin.on_device_disconnected(device)
log_file:write("[DISCONNECT] " .. device.name .. "\n")
log_file:close()
end

return plugin

Configuration Files

Global Configuration

Create a configuration file at ~/.sifibridge/config.toml:

# Device Discovery
[discovery]
ble_scan_timeout = 10 # seconds
serial_ports = ["/dev/ttyUSB0", "/dev/ttyUSB1"]

# Data Collection
[acquisition]
csv_output_dir = "/home/user/data"
auto_timestamp = true
buffer_size = 1024

# Network
[network]
lsl_enabled = true
tcp_default_port = 5000
udp_default_port = 5001

# Logging
[logging]
level = "info" # debug, info, warn, error
file = "/home/user/.sifibridge/sifibridge.log"

Per-Device Configuration

Store device-specific settings:

[device.AA:BB:CC:DD:EE:FF]
name = "my_device"
auto_connect = true

[device.AA:BB:CC:DD:EE:FF.sensors]
ppg_enabled = true
ppg_sensitivity = 128
ppg_current = 100

imu_enabled = true
imu_sample_rate = 100

ecg_enabled = false
eda_enabled = false

Command-Line Options

Batch Processing

Execute multiple commands without interactive REPL:

sifibridge -c "scan; connect 0; show; exit"

Scripts

Create script files with one command per line:

# commands.sifi
scan
connect 0
command start-acquisition
# Wait would be: sleep 10
command stop-acquisition
command export-csv output.csv
disconnect
exit

Execute the script:

sifibridge < commands.sifi

Or with redirection:

sifibridge < commands.sifi > log.txt 2>&1

Environment Variables

Control SiFi Bridge behavior via environment variables:

# Logging
export RUST_LOG=debug
export SIFI_LOG_FILE=/tmp/sifibridge.log

# Bluetooth
export SIFI_BLE_TIMEOUT=15

# CSV output
export SIFI_CSV_DIR=/mnt/data

sifibridge

Automation & Integration

Systemd Service

Create a systemd service for continuous data collection:

# /etc/systemd/system/sifibridge.service
[Unit]
Description=SiFi Bridge Data Collection
After=network.target

[Service]
Type=simple
User=sifi
WorkingDirectory=/home/sifi/data
ExecStart=/usr/local/bin/sifibridge -c "connect AA:BB:CC:DD:EE:FF; command start-acquisition"
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable sifibridge
sudo systemctl start sifibridge
sudo systemctl status sifibridge

Cron Jobs

Schedule periodic data collection:

# Collect data every hour
0 * * * * /usr/local/bin/sifibridge -c "connect 0; command export-csv /data/$(date +\%Y\%m\%d_\%H\%M).csv; disconnect"

# Daily device health check
0 0 * * * /usr/local/bin/sifibridge -c "connect 0; show > /var/log/sifibridge_health.log; disconnect"

Performance Optimization

Memory Management

For long-running data collection:

[acquisition]
# Buffer size affects memory usage (samples)
buffer_size = 512

# Flush to disk more frequently
auto_flush_interval = 60 # seconds

CPU Usage

Reduce CPU load:

sifibridge> command start-acquisition --low-power
✓ Acquisition started in low-power mode

Reduces:

  • Data processing overhead
  • Network stream rate
  • Logging frequency

Disk I/O

Optimize CSV writes:

[acquisition]
# Write in larger batches
batch_write_size = 1000

# Compress archived data
enable_compression = true

Advanced Data Processing

Real-time Analysis

Stream data directly to analysis tools:

# Stream to Python for analysis
sifibridge -c "connect 0; command start-acquisition --output tcp --host localhost --port 5000" &

# In another terminal:
python3 analyze.py

analyze.py:

import socket
import json

sock = socket.socket()
sock.connect(('localhost', 5000))

for _ in range(1000):
data_json = sock.recv(1024).decode()
data = json.loads(data_json)

if data['sensor'] == 'ppg':
# Calculate heart rate in real-time
heart_rate = process_ppg(data['data'])
print(f"Heart rate: {heart_rate} bpm")

Batch Processing Pipeline

#!/bin/bash
# Process all CSV files and generate reports

for csv_file in *.csv; do
echo "Processing $csv_file..."

# Analyze with Python
python3 analyze.py "$csv_file"

# Generate plots
python3 plot.py "$csv_file"

# Archive
tar czf "${csv_file%.csv}.tar.gz" "$csv_file"
done

Troubleshooting Advanced Issues

Memory Leaks

Monitor memory usage:

# Watch memory in real-time
watch -n 1 'ps aux | grep sifibridge'

If memory grows unbounded:

  • Check plugin for memory leaks
  • Reduce buffer size
  • Enable periodic flushing

High CPU Usage

Profile with built-in diagnostics:

sifibridge> diagnostic cpu
CPU Usage: 45%
Thread 1 (device_read): 20%
Thread 2 (data_process): 15%
Thread 3 (csv_write): 10%

Reduce load by:

  • Lowering sample rates
  • Disabling unused sensors
  • Using --low-power mode