Skip to content

Conversation

@Fede654
Copy link

@Fede654 Fede654 commented Oct 29, 2025

Summary

This PR fixes two critical bugs that prevent core muselsl functionality from working on certain systems.

Bug 1: Bluetoothctl EOF Handling (muselsl/stream.py)

Problem: muselsl list fails with ValueError: Unexpected error when scanning on systems where bluetoothctl exits cleanly with EOF instead of timing out.

Root Cause: The code treated pexpect.EOF as an error condition, but bluetoothctl scan on may exit cleanly after starting the scan (which continues at the Bluetooth stack level). Both EOF and TIMEOUT are valid completion conditions.

Fix:

  • Handle both pexpect.EOF and pexpect.TIMEOUT as normal scan completion
  • Add explicit process termination cleanup
  • Add error handling for verbose output decoding

Impact: Enables device discovery on systems where bluetoothctl exits immediately (tested on Debian 12, Python 3.13).

Bug 2: Record Filename Directory Creation (muselsl/record.py)

Problem: muselsl record -f filename.csv fails with FileNotFoundError: [Errno 2] No such file or directory: '' when using simple filenames without directory paths.

Root Cause: When os.path.dirname('file.csv') returns an empty string, the code attempts os.makedirs(''), which raises an exception.

Fix: Added check to skip directory creation when dirname() returns empty string (applied to both _save() and record_direct() functions).

Impact: Allows users to record with simple filenames like test.csv in the current directory, while preserving existing behavior for paths with directories.

Testing

✅ Verified on Debian 12, Python 3.13
✅ Device discovery works with muselsl list
✅ Recording works with simple filenames: muselsl record -f test.csv
✅ Recording works with directory paths: muselsl record -f data/test.csv
✅ No regression in existing functionality

Related Issues

Changes

  • muselsl/stream.py: Lines 90-106 - Fixed EOF handling in _list_muses_bluetoothctl()
  • muselsl/record.py: Lines 152, 266 - Added empty string check before os.makedirs()

Both changes are minimal, safe, and maintain backward compatibility.


🤖 Generated with Claude Code

Fede654 and others added 3 commits October 29, 2025 17:52
## Bug 1: Bluetoothctl EOF handling (stream.py)
- **Issue**: `muselsl list` fails on systems where bluetoothctl exits with EOF
- **Fix**: Handle both EOF and TIMEOUT as normal scan completion conditions
- **Impact**: Enables device discovery on affected systems (Debian 12, Python 3.13+)

The original code treated pexpect.EOF as an error condition, but bluetoothctl
may exit cleanly after starting the scan, which is a normal behavior. The scan
continues at the Bluetooth stack level even after the process exits.

## Bug 2: Record filename directory creation (record.py)
- **Issue**: `muselsl record -f file.csv` fails for simple filenames
- **Fix**: Skip directory creation when dirname() returns empty string
- **Impact**: Allows recording to current directory with simple filenames

When os.path.dirname('file.csv') returns '', attempting os.makedirs('')
raises FileNotFoundError. Added check to skip directory creation for empty
dirname, preserving original behavior for paths with directories.

## Testing
- Tested on Debian 12, Python 3.13
- Verified device discovery with `muselsl list`
- Verified recording with simple filenames and directory paths
- No regression in existing functionality

Fixes issues related to alexandrebarachant#208, alexandrebarachant#191

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Remove Linux-specific pinning to pylsl==1.10.5
- Allow modern pylsl versions (>=1.16.2)
- Fixes version conflicts with projects using newer LSL features
- Consistent behavior across all platforms
Previously, LSL stream names were hardcoded to 'Muse' regardless of the
--name CLI parameter. This prevented running multiple Muse devices
simultaneously, as they would all publish to the same stream name.

Changes:
- Use --name parameter value for LSL stream name if provided
- Apply to all stream types: EEG, PPG, ACC, GYRO
- Fallback to 'Muse' if --name not specified (backward compatibility)
- Add debug output showing the stream name being used

This enables multi-device setups like:
  muselsl stream --address XX:XX:XX:XX:XX:01 --name Muse_1
  muselsl stream --address XX:XX:XX:XX:XX:02 --name Muse_2

Each device will now publish to its own uniquely named LSL stream.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant