Skip to main content
Loss of provenance

A previous release had provenance metadata, but this release does not. View details.

signalino

Native Python API for Signalino EEG devices. It connects directly over USB, Bluetooth Classic or Bluetooth LE and decodes the Signalino S4CP control protocol and stable 33-byte OpenBCI-compatible EEG frames.

This package does not depend on BrainFlow. Applications that specifically need the BrainFlow API can install the separate brainflow-signalino integration.

Signalino is research software. It is not a medical device and must not be used for diagnosis or patient monitoring.

New in 0.2.1

Linux can now discover paired HC-06/Signalino devices and connect directly over Bluetooth Classic, without creating /dev/rfcomm0 or running Signalino Suite. This also works with Conda Python builds that lack Bluetooth socket address support, using the system Python for connection setup. Existing macOS, USB and BLE paths are preserved. Pair the HC-06 first and close other clients.

Upgrade with python -m pip install --upgrade signalino. See CHANGELOG.md for release details.

Installation

python -m pip install signalino

Python 3.10 or newer is supported on macOS, Linux and Windows. Optional integrations are installed separately:

python -m pip install "signalino[lsl]"
python -m pip install "signalino[mne]"
python -m pip install "signalino[viewer]"

USB

import time

from signalino import Signalino

with Signalino.usb() as device:
    print(device.info.name, device.info.hardware)
    device.start_streaming()
    time.sleep(2)
    eeg_uv = device.get_data()

print(eeg_uv.shape)  # (8, approximately 500)

Signalino.usb() chooses the most probable port. Select it explicitly when several boards are connected:

device = Signalino.usb("/dev/cu.usbmodem1101")  # macOS
device = Signalino.usb("/dev/ttyACM0")  # Linux
device = Signalino.usb("COM3")  # Windows

Bluetooth Classic

Pair the HC-06 (or equivalent serial Bluetooth module) with the computer first:

with Signalino.bluetooth_classic() as device:
    device.start_streaming()

The package finds likely paired serial ports automatically. An explicit port can also be passed to Signalino.bluetooth_classic(port).

On macOS, Classic Bluetooth uses the native RFCOMM helper installed with Signalino Suite. Its location can instead be supplied through the SIGNALINO_CLASSIC_CONNECT environment variable. Linux normally exposes /dev/rfcomm0; Windows exposes a paired COM port.

Bluetooth LE

with Signalino.ble("Signalino-852960") as device:
    device.start_streaming()

Use Signalino.ble() when only one Signalino is advertising. With several units in the room, select one by advertised name or address:

Signalino.ble(name="Signalino-852960")
Signalino.ble(address="AA:BB:CC:12:34:56")

Data and losses

get_data() returns microvolts as a NumPy array shaped (channels, samples). It consumes the oldest samples by default. Use clear=False to inspect without consuming:

latest = device.get_data(250, clear=False)
batch = device.get_data_batch()
print(batch.samples_uv, batch.timestamps)

print(device.stats.received_samples)
print(device.stats.lost_samples)
print(device.stats.loss_percent)

The package validates frame headers and footers, recovers alignment after corrupt input, and uses the 8-bit sample counter to detect losses and duplicates. Buffers are bounded and LSL does not consume data requested by get_data().

Battery, impedance and sensors

battery = device.battery()
print(battery.volts, battery.percent, battery.charging)

impedance = device.impedance()
print(impedance.kiloohms)

auxiliary = device.get_auxiliary_data()
print(auxiliary.raw_values, auxiliary.packet_types)

Normal EEG acquisition pauses while impedances are measured and resumes automatically afterward. USB and Bluetooth Classic share control and binary data on one serial channel, so battery queries on those transports also require streaming to be stopped. BLE has separate control and EEG characteristics.

Hardware, firmware, available sensors and capabilities are reported by the physical unit through device.info; they are not inferred from a board number.

S4CP control

High-level operations use S4CP internally. Documented low-level commands remain available for diagnostics:

print(device.command("STS;"))
device.command("SRC1;SMP250;GAN24;")

Control replies are compact strings such as STS SRC=1 REC=0 SMP=250 ...;. The EEG data plane remains the 33-byte OpenBCI-compatible frame.

LSL

device.start_streaming()
stream = device.start_lsl()
print(stream.name, stream.source_id)

The LSL outlet contains eight float32 EEG channels in microvolts and closes automatically when acquisition stops.

MNE

raw = device.to_mne(clear=False)
print(raw.info["sfreq"])

MNE stores EEG in volts; conversion from Signalino microvolts is automatic.

Examples

The examples/ directory contains minimal USB, BLE and Bluetooth Classic programs, an LSL publisher, impedance acquisition, MNE conversion, a rolling viewer, and a Classic Bluetooth loss measurement.

For local development:

python -m pip install -e ".[dev,all]"
ruff check .
ruff format --check .
pytest --cov=signalino
python -m build
twine check dist/*

License

MIT. Copyright Scignals 2026.

Linux Bluetooth Classic without a serial port

On Linux, Signalino.bluetooth_classic() now falls back to paired BlueZ devices when no serial port exists. It opens RFCOMM channel 1 directly; /dev/rfcomm0, root privileges and a running Suite are not required. Pair the HC-06 in Linux Bluetooth settings first and close other clients before connecting.

with Signalino.bluetooth_classic(address="98:D3:91:FD:3D:CE") as device:
    device.start_streaming()

Omit address for automatic selection, or pass a serial port as before. Multiple candidates require an explicit address. Linux needs bluetoothctl; Conda builds without Bluetooth socket address support also use /usr/bin/python3 briefly to open the socket and pass its descriptor. Acquisition remains in the calling Python process. Other platforms keep their existing serial/bridge behavior.

Metadata

Release files for signalino 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Loss of provenance

These files do not have provenance metadata, despite files in a prior release including this data.

We recommend further investigation before installing these files. View details.

Source distribution (sdist)

Source distribution for signalino 0.2.1
File Size Uploaded Provenance Actions
signalino-0.2.1.tar.gz 38.0 kB Without provenance Details for signalino-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for signalino 0.2.1
File Interpreter ABI Platform Actions
signalino-0.2.1-py3-none-any.whl Python 3 none any Details for signalino-0.2.1-py3-none-any.whl

Total release size: 65.7 kB

Release files / signalino-0.2.1.tar.gz

Loss of provenance

This file belongs to a release without provenance metadata, despite a prior release including this data.

We recommend further investigation before installing this file. View details.

Download URL signalino-0.2.1.tar.gz
Size 38.0 kB
Tags Source
SHA-256 checksum
How to use checksums
9e0a5370ae67ff374c340ff133f066881541425ec088a72444f1221d2cb67631
BLAKE2b-256 checksum
How to use checksums
db95c358cbe014a96b03f722d576d5b7b4e90ed89583d27c4878af3595384d56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.8

Release files / signalino-0.2.1-py3-none-any.whl

Loss of provenance

This file belongs to a release without provenance metadata, despite a prior release including this data.

We recommend further investigation before installing this file. View details.

Download URL signalino-0.2.1-py3-none-any.whl
Size 27.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
035a4ff05c567560a7ae4e32ad3b280d69b750b421883a6f1f70aef82a69f874
BLAKE2b-256 checksum
How to use checksums
59774de5a949c0d638103325865862134cb71d315d86d446e1581415f82f34a3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.8

Security for signalino 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Loss of provenance

A previous release of these files had provenance metadata, but this release does not.

While this could reflect a routine change by the project maintainers, it may also indicate that the release files have been compromised.

Release comparison

  • Removed 0.1.3 2 files With provenance
  • Added 0.2.1 2 files Without provenance

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page