Skip to content

Commit

Permalink
Muse lsl connection timeout argument (#200)
Browse files Browse the repository at this point in the history
* added timeout parameter to BleakDevice in backends.py, added help documentatino for -t argument and timout parser for arguments

* added -t and --timeout argument functionality to stream and record_direct.

* added "timing out after [timeout] seconds" message to connection message

* amended forgotten -t help text in record_direct

---------

Co-authored-by: auAn <auan@Monday-Night.ed.shawcable.net>
Co-authored-by: Dano Morrison <morrisondano@gmail.com>
  • Loading branch information
3 people committed Apr 22, 2024
1 parent ae5f090 commit 524ce0e
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 16 deletions.
2 changes: 2 additions & 0 deletions muselsl/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def main():
-n --name Device name (e.g. Muse-41D2).
-b --backend BLE backend to use. can be auto, bluemuse, gatt or bgapi.
-i --interface The interface to use, 'hci0' for gatt or a com port for bgapi.
-t --timeout Length of timeout before giving up on connecting to an identified device.
-p --ppg Include PPG data
-c --acc Include accelerometer data
-g --gyro Include gyroscope data
Expand All @@ -41,6 +42,7 @@ def main():
-n --name Device name (e.g. Muse-41D2).
-b --backend BLE backend to use. can be auto, bluemuse, gatt or bgapi.
-i --interface The interface to use, 'hci0' for gatt or a com port for bgapi.
-t --timeout Length of timeout before giving up on connecting to an identified device.
''')

parser.add_argument('command', help='Command to run.')
Expand Down
9 changes: 5 additions & 4 deletions muselsl/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ def scan(self, timeout=10):
raise bleak
devices = _wait(bleak.BleakScanner.discover(timeout))
return [{'name':device.name, 'address':device.address} for device in devices]
def connect(self, address):
result = BleakDevice(self, address)
def connect(self, address, connection_timeout=None):
result = BleakDevice(self, address, connection_timeout)
result.connect()
return result

class BleakDevice:
def __init__(self, adapter, address):
def __init__(self, adapter, address, connection_timeout=None):
self._adapter = adapter
self._client = bleak.BleakClient(address)
self._timeout = connection_timeout
self._client = bleak.BleakClient(address, timeout=self._timeout) # <- CRITICAL timeout value HERE
def connect(self):
_wait(self._client.connect())
self._adapter.connected.add(self)
Expand Down
18 changes: 16 additions & 2 deletions muselsl/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ def stream(self):
default=None,
help=
"The interface to use, 'hci0' for gatt or a com port for bgapi.")
parser.add_argument(
"-t",
"--timeout",
dest="timeout",
type=float,
default=10.0,
help="Length of timeout before giving up on connecting to an identified device.")
parser.add_argument("-P",
"--preset",
type=int,
Expand Down Expand Up @@ -104,7 +111,7 @@ def stream(self):
from . import stream

stream(args.address, args.backend, args.interface, args.name, args.ppg,
args.acc, args.gyro, args.disable_eeg, args.preset, args.disable_light)
args.acc, args.gyro, args.disable_eeg, args.preset, args.disable_light, args.timeout)

def record(self):
parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -173,6 +180,13 @@ def record_direct(self):
default=None,
help=
"The interface to use, 'hci0' for gatt or a com port for bgapi.")
parser.add_argument(
"-t",
"--timeout",
dest="timeout",
type=float,
default=10.0,
help="Length of timeout before giving up on connecting to an identified device.")
parser.add_argument(
"-d",
"--duration",
Expand All @@ -190,7 +204,7 @@ def record_direct(self):
args = parser.parse_args(sys.argv[2:])
from . import record_direct
record_direct(args.duration, args.address, args.filename, args.backend,
args.interface, args.name)
args.interface, args.name, args.timeout)

def view(self):
parser = argparse.ArgumentParser(
Expand Down
2 changes: 1 addition & 1 deletion muselsl/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
MUSE_GYRO_SCALE_FACTOR = 0.0074768

MUSE_SCAN_TIMEOUT = 10.5
AUTO_DISCONNECT_DELAY = 3
# AUTO_DISCONNECT_DELAY = 3

LSL_SCAN_TIMEOUT = 5
LSL_BUFFER = 360
Expand Down
8 changes: 5 additions & 3 deletions muselsl/muse.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ def __init__(self,
time_func=time,
name=None,
preset=None,
disable_light=False):
disable_light=False,
timeout=None):
"""Initialize
callback_eeg -- callback for eeg data, function(data, timestamps)
Expand All @@ -45,6 +46,7 @@ def __init__(self,
"""

self.address = address
self.timeout = timeout
self.name = name
self.callback_eeg = callback_eeg
self.callback_telemetry = callback_telemetry
Expand Down Expand Up @@ -76,7 +78,7 @@ def connect(self, interface=None):
else:
logger.info('Connecting to %s: %s...' % (self.name
if self.name else 'Muse',
self.address))
self.address, int(self.timeout)))
if self.backend == 'gatt':
self.interface = self.interface or 'hci0'
self.adapter = pygatt.GATTToolBackend(self.interface)
Expand All @@ -87,7 +89,7 @@ def connect(self, interface=None):
serial_port=self.interface)

self.adapter.start()
self.device = self.adapter.connect(self.address)
self.device = self.adapter.connect(self.address, self.timeout)
if(self.preset != None):
self.select_preset(self.preset)

Expand Down
6 changes: 4 additions & 2 deletions muselsl/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ def record_direct(duration,
filename=None,
backend='auto',
interface=None,
name=None):
name=None,
timeout=None):
if backend == 'bluemuse':
raise (NotImplementedError(
'Direct record not supported with BlueMuse backend. Use record after starting stream instead.'
Expand Down Expand Up @@ -211,7 +212,8 @@ def save_eeg(new_samples, new_timestamps):
eeg_samples.append(new_samples)
timestamps.append(new_timestamps)

muse = Muse(address, save_eeg, backend=backend)
muse = Muse(address, save_eeg, backend=backend, timeout=timeout)
print("Recording direct received", str(timeout), "for timeout!")
muse.connect()
muse.start()

Expand Down
7 changes: 3 additions & 4 deletions muselsl/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from . import backends
from . import helper
from .muse import Muse
from .constants import MUSE_SCAN_TIMEOUT, AUTO_DISCONNECT_DELAY, \
from .constants import MUSE_SCAN_TIMEOUT, \
MUSE_NB_EEG_CHANNELS, MUSE_SAMPLING_EEG_RATE, LSL_EEG_CHUNK, \
MUSE_NB_PPG_CHANNELS, MUSE_SAMPLING_PPG_RATE, LSL_PPG_CHUNK, \
MUSE_NB_ACC_CHANNELS, MUSE_SAMPLING_ACC_RATE, LSL_ACC_CHUNK, \
Expand Down Expand Up @@ -133,7 +133,7 @@ def stream(
eeg_disabled=False,
preset=None,
disable_light=False,
timeout=AUTO_DISCONNECT_DELAY,
timeout=None
):
# If no data types are enabled, we warn the user and return immediately.
if eeg_disabled and not ppg_enabled and not acc_enabled and not gyro_enabled:
Expand Down Expand Up @@ -216,8 +216,7 @@ def push(data, timestamps, outlet):
push_gyro = partial(push, outlet=gyro_outlet) if gyro_enabled else None

muse = Muse(address=address, callback_eeg=push_eeg, callback_ppg=push_ppg, callback_acc=push_acc, callback_gyro=push_gyro,
backend=backend, interface=interface, name=name, preset=preset, disable_light=disable_light)

backend=backend, interface=interface, name=name, preset=preset, disable_light=disable_light, timeout=timeout)
didConnect = muse.connect()

if(didConnect):
Expand Down

0 comments on commit 524ce0e

Please sign in to comment.