Server Features
| Feature | Description |
|---|---|
| 250 Hz streaming | WebSocket (ws://<host>:1616), plain JSON, language-agnostic |
| 8 & 16 channel | PiEEG-8 / PiEEG-16 shields (SPI) and IronBCI / EAREEG headsets (8 ch, Bluetooth LE) |
| Bandpass filter | Butterworth IIR (SOS), per-channel state, adjustable live via WebSocket |
| CSV recording | Start/stop from dashboard or CLI; auto-timestamped; optional duration limit |
| Session annotations | Text notes on any frame; sidecar .annotations.json |
| Terminal monitor | Rich TUI with per-channel sparklines and µV readout; works over SSH |
| Mock mode | Realistic synthetic EEG (alpha rhythm, drift, noise, blink artifacts) |
| Authentication | Optional 6-digit code, rate limiting, HMAC timing-safe verify, HttpOnly cookies |
| VRChat OSC | Band powers via UDP OSC; chatbox + avatar parameters; rolling normalization |
| LSL | Push raw samples to LSL network; discoverable by OpenViBE, MNE, LabRecorder |
| Webhooks | HTTP callbacks on EEG events; IFTTT & Zapier presets; per-rule cooldown |
| Self-diagnostics | pieeg-server doctor checks Pi model, SPI/GPIO, ports, deps, systemd |
| Self-update | Detects pip/git install; checks PyPI or remote; one-click upgrade from dashboard |
| Systemd service | Auto-starts on boot; standard systemctl management |
| Zero-dep GPIO | Direct Linux chardev v1 ioctl; stable ABI since Linux 4.8 |
| Spike rejection | Auto-resets after sustained electrode contact changes |
| Cloud-ready | Dockerfile + Fly.io config for mock-mode demo hosting |
Architecture
hardware.py → SPI/GPIO init, ADS1299 config (PiEEG)
ironbci.py → BLE scan, GATT notifications, ADS1299 parsing (IronBCI)
↓
acquisition.py → 250 Hz read loop (background thread)
↓ pub/sub
├── server.py → WebSocket broadcast
├── recorder.py → CSV writer
├── monitor.py → Terminal sparklines
├── osc_vrchat.py → VRChat OSC bridge
└── lsl.py → Lab Streaming Layer outlet
webhooks.py → event rules + HTTP relay
dashboard.py → HTTP server (React UI)
auth.py → session + WS token management
filters.py → Butterworth bandpass (SOS)
updater.py → version check + upgrade
doctor.py → system diagnosticsData Flow
- Hardware/Mock/BLE → AcquisitionLoop (threaded, 250 Hz)
- Each sample: 8 or 16 channels of float values in µV
- Subscription-based queue system — each subscriber gets its own
asyncio.Queue - Subscribers: WebSocket server, recorder, monitor, OSC, LSL
- WebSocket broadcasts plain JSON to all connected clients
Tech Stack
| Layer | Tech |
|---|---|
| Language | Python 3.10+ (asyncio) |
| WebSocket | websockets library |
| Filter | scipy Butterworth IIR |
| Terminal UI | rich |
| GPIO | Direct /dev/gpiochip ioctl (no dependencies) |
| Dashboard | React 19 + Vite 6 |