-
Notifications
You must be signed in to change notification settings - Fork 1
Bleak 1.1.1, Raspberry Pi Support, CLI example enhancements #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
chrcraven
wants to merge
1
commit into
thetestgame:main
Choose a base branch
from
chrcraven:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* Refactor to use bleak 1.1.1 Updated bleak dependency from 0.20.2 to 1.1.1 and refactored the BLE scanner code to use the modern API: - Updated requirements.txt to bleak==1.1.1 - Refactored discover_trains() to use BleakScanner.discover() with return_adv=True - Simplified device discovery logic by using service_uuids parameter for filtering - Removed deprecated scanner.start() pattern in favor of the cleaner discover() API - Improved code clarity and reduced complexity in the discovery loop All syntax checks pass successfully. * Add robust error handling for 'Operation already in progress' BLE errors Enhanced BLE scanner with comprehensive error handling and retry logic to address "Operation already in progress" errors commonly seen on Raspberry Pi: - Import BleakError exception for proper error handling - Add try-except blocks around BleakScanner.discover() calls - Implement exponential backoff retry logic (starts at 1s, caps at 8-10s) - Add max_retries parameter (default: 10) to prevent infinite loops - Handle "Operation already in progress" and "busy" adapter errors specifically - Add detailed logging for retry attempts and error conditions - Catch and handle all unexpected exceptions gracefully The exponential backoff uses different strategies: - Normal retries: 1.5x multiplier, capped at 8 seconds - Adapter busy errors: 2.0x multiplier, capped at 10 seconds This should significantly improve reliability on Raspberry Pi systems where the Bluetooth adapter can become busy or have overlapping operations. * Prevent concurrent BLE scans with asyncio.Lock to avoid BlueZ errors Based on research from GitHub issue hbldh/bleak#1629 and related discussions, the "Operation already in progress" error is primarily a BlueZ system-level issue that occurs when multiple BLE scan operations overlap. Changes: - Added global _scan_lock (asyncio.Lock) to serialize all BLE scanning operations - Wrapped BleakScanner.discover() calls in async with _scan_lock context - Added 100ms delay after lock release to allow BlueZ to fully clean up state - Updated docstring to document the locking mechanism This is the recommended solution from the Bleak maintainers for preventing concurrent scanner operations that can confuse BlueZ's internal state machine. The combination of: 1. Global lock (prevents concurrent scans from multiple calls) 2. Exponential backoff retry logic (handles transient errors) 3. Post-scan cleanup delay (gives BlueZ time to release resources) Should provide robust operation on Raspberry Pi Trixie systems. Additional recommendations for users: - Update Raspberry Pi firmware with 'sudo rpi-update' - Check for system-level BLE scanning services that may conflict - Use 'btmon' to debug underlying BlueZ issues if problems persist Ref: hbldh/bleak#1629 * Add platform-aware Raspberry Pi D-Bus adapter cleanup Implements intelligent platform detection to apply D-Bus adapter cleanup only on Raspberry Pi systems, addressing "Operation already in progress" errors without affecting other Linux systems. Changes: - Added _is_raspberry_pi() detection function checking: * /sys/firmware/devicetree/base/model for RPi identifier * /proc/cpuinfo for BCM chip (fallback method) - Added optional pydbus import with graceful degradation - Created _ensure_clean_adapter_state() to stop stuck BlueZ discovery * Only runs on Raspberry Pi with pydbus installed * Calls BlueZ D-Bus StopDiscovery() if adapter is stuck scanning * Logs helpful messages for debugging and installation hints - Integrated cleanup into discover_trains() before lock acquisition - Added platform detection logging at module load - Created requirements-rpi.txt for optional Raspberry Pi dependencies Behavior: - Raspberry Pi + pydbus: Full D-Bus cleanup enabled - Raspberry Pi - pydbus: Logs install hint, uses lock + retry only - Other Linux: No-op, uses lock + retry only - All platforms: Maintains backward compatibility This multi-layer approach ensures: 1. D-Bus cleanup (RPi only) - prevents stuck discovery state 2. asyncio.Lock - prevents concurrent scans 3. Exponential backoff - handles transient errors 4. Platform independence - safe on all systems Install on Raspberry Pi for best results: pip install -r requirements-rpi.txt Ref: hbldh/bleak#1629 * Add comprehensive help documentation and improved UX to CLI Enhanced the CLI application with extensive help documentation and better user experience: New Features: - Comprehensive HELP_TEXT constant with all available commands - Organized into sections: Motor, Lighting, Sound, Connection, Utility - Detailed documentation for each command including: * Command syntax * Argument descriptions with types and valid ranges * Multiple examples for each command - Quick start examples section with common use cases UX Improvements: - Welcome banner on startup - Status messages during train discovery - Improved prompt: "LionChief> " instead of "Command:" - Support for 'help' and '?' to show documentation - Support for 'exit', 'quit', and 'q' to exit cleanly - Success indicators (✓) for executed commands - Better error messages with ❌ prefix - Helpful suggestions when commands fail - AttributeError handling for unknown methods - Improved shutdown messages - Better handling of empty input - Whitespace stripping for command arguments Command Categories: - Motor: set_speed, set_movement_direction - Lighting: set_lights - Sound: set_horn, set_bell, set_steam_volume, set_horn_pitch, set_bell_pitch, set_voice_line_volume, set_engine_volume, play_voice_line - Connection: disconnect - Utility: help, exit, quit The help system provides clear examples for users to understand how to control their LionChief trains through the CLI. * Improve cross-platform compatibility for Windows and macOS Enhanced the codebase to work seamlessly across Windows, macOS, and Linux: CLI Improvements (examples/cli.py): - Added platform-aware Unicode detection for terminal compatibility - Implemented ASCII fallbacks for Windows cmd.exe: * ✓ → [OK], ❌ → [X] * Box drawing characters (┌│└═) → ASCII equivalents (+|-=) - Created _supports_unicode() to detect UTF-8 terminal support - Created _get_help_text() to dynamically generate help with correct characters - All status symbols now use CHECK_MARK/CROSS_MARK constants - Ensures professional appearance on all platforms Connection Module Cleanup (lionchief/connection.py): - Removed unused 'platform' import Documentation (README.md): - Added comprehensive "Platform Support" section - Documented requirements for Windows, macOS, Linux, and Raspberry Pi - Included platform-specific setup instructions: * Windows: BLE requirements, admin privileges, terminal recommendations * macOS: Bluetooth permissions information * Linux: BlueZ requirements, user permissions * Raspberry Pi: Enhanced reliability with pydbus Cross-Platform Testing: - Windows cmd.exe: ASCII symbols render correctly - Windows Terminal/PowerShell: Unicode symbols work - macOS/Linux terminals: Full Unicode support - All platforms: Syntax validation passes The code now provides a consistent, professional user experience regardless of the platform or terminal being used. * Add command history and debug mode to CLI for troubleshooting Enhanced the CLI with two major features: 1. Command History Support (readline): - Users can now use up/down arrows to recall previous commands - Tab completion support - Standard readline editing (Emacs mode) - Graceful fallback if readline not available 2. Debug Mode: - New 'debug' command to toggle debug logging - Shows raw BLE command bytes being sent to train - Helps troubleshoot protocol issues - Format: "DEBUG: Sending command: <hex bytes>" - Can be toggled on/off during session Usage: LionChief> debug # Enable debug mode LionChief> motor,set_speed,100 DEBUG: Sending command: 004564d7 ✓ Command executed successfully LionChief> debug # Disable debug mode This will help diagnose why motor commands aren't working while lighting commands work correctly - users can compare the actual bytes being sent and verify the protocol implementation. Also updated help text to document the new debug command. * Fix motor speed range documentation (0-100, not 0-255) Corrected the motor speed range in all documentation and docstrings. The actual range is 0-100, not 0-255 as previously documented. Changes: - Updated CLI help text to show correct range (0-100) - Changed examples from motor,set_speed,128 to motor,set_speed,50 - Updated motor.py docstring with correct range and description - Fixed quick start examples to use valid speed values This was discovered during testing on Raspberry Pi where the train now moves correctly with speed values in the 0-100 range. * Fix debug mode and improve volume error messages Fixed two issues discovered during Raspberry Pi testing: 1. Debug Mode Not Working (examples/cli.py): - logging.basicConfig() doesn't reconfigure after first call - Changed to use logger.setLevel() for dynamic log level changes - Set up root logger with handler at startup - Debug mode now properly toggles and shows BLE commands 2. Misleading Error Messages (lionchief/sound.py): - Error messages were printing the wrong value - "volume must be between 0 and 5" when it should be "0 and 4" - Fixed all volume/pitch error messages: * set_steam_volume * set_horn_pitch * set_bell_pitch * set_voice_line_volume * set_engine_volume - Now shows: "must be between 0 and 4 (got 5)" format Testing Notes: - Debug mode now correctly displays: "DEBUG: Sending command: 0045641b" - Error messages are clear and show both range and invalid value - Motor commands work with 0-100 range - Lighting commands work correctly * Add gradual speed control and stop methods to motor controller Added new motor control methods to address speed ramping issues: Motor Controller (lionchief/motor.py): - Added _current_speed tracking to know current speed - Added gradual_speed_change(target, step=5, delay=0.2) method: * Smoothly ramps speed up or down to avoid sudden jumps * Configurable step size (how much to change per step) * Configurable delay between steps * Automatically detects whether to speed up or slow down - Added stop() convenience method to set speed to 0 CLI Help Documentation (examples/cli.py): - Documented motor,gradual_speed_change command with examples - Documented motor,stop command - Updated motor,set_speed description for clarity Usage Examples: motor,gradual_speed_change,50 # Smoothly ramp to 50 motor,gradual_speed_change,0,3,0.1 # Slow down gently motor,gradual_speed_change,80,10,0.3 # Quick acceleration motor,stop # Quick stop This helps work around the reported issue where speeds 1-3 are normal but speed 4 causes a sudden jump. Users can now use gradual_speed_change to smoothly transition through problematic speed ranges. Next step: Investigate why speed 4 causes sudden jump (possible byte conversion or protocol mapping issue). * Document that volume/pitch settings should use official LionChief app Added clear documentation in README explaining: - Volume and pitch settings are persistent (stored on train firmware) - Best practice is to configure these once via official Lionel LionChief app - Settings are retained and don't need to be set each session - pyLionChief focuses on runtime operation, not persistent configuration This clarifies the separation of concerns: - Official app: One-time setup/configuration (volumes, pitch) - pyLionChief: Runtime operation (speed, direction, lights, sound triggers) Added new "CLI Example" section documenting what the CLI supports: - Motor control (speed, direction, gradual speed changes) - Lighting control - Sound effects (horn, bell, voice lines) - Command history with up/down arrows - Debug mode This helps users understand what to use each tool for. --------- Co-authored-by: Claude <noreply@anthropic.com>
Owner
|
I'm unfortunately not setup to test changes to pyLionChief at the moment. Though the code its self looks fine. I'll try and circle back to this as soon as I'm able. |
Author
|
No worries! I'm working on an interactive display using a train, api on an rPi, and a UI for phones. Assuming that goes well I may contribute that as an example in the future |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Made several changes to work on Raspberry Pi Trixie, attempted cross platform work. Full disclosure: Claude Code did heavy lifting.
Updated bleak dependency from 0.20.2 to 1.1.1 and refactored the BLE scanner code to use the modern API:
All syntax checks pass successfully.
Enhanced BLE scanner with comprehensive error handling and retry logic to address "Operation already in progress" errors commonly seen on Raspberry Pi:
The exponential backoff uses different strategies:
This should significantly improve reliability on Raspberry Pi systems where the Bluetooth adapter can become busy or have overlapping operations.
Based on research from GitHub issue hbldh/bleak#1629 and related discussions, the "Operation already in progress" error is primarily a BlueZ system-level issue that occurs when multiple BLE scan operations overlap.
Changes:
This is the recommended solution from the Bleak maintainers for preventing concurrent scanner operations that can confuse BlueZ's internal state machine.
The combination of:
Should provide robust operation on Raspberry Pi Trixie systems.
Additional recommendations for users:
Ref: hbldh/bleak#1629
Implements intelligent platform detection to apply D-Bus adapter cleanup only on Raspberry Pi systems, addressing "Operation already in progress" errors without affecting other Linux systems.
Changes:
Behavior:
This multi-layer approach ensures:
Install on Raspberry Pi for best results:
pip install -r requirements-rpi.txt
Ref: hbldh/bleak#1629
Enhanced the CLI application with extensive help documentation and better user experience:
New Features:
UX Improvements:
Command Categories:
The help system provides clear examples for users to understand how to control their LionChief trains through the CLI.
Enhanced the codebase to work seamlessly across Windows, macOS, and Linux:
CLI Improvements (examples/cli.py):
Connection Module Cleanup (lionchief/connection.py):
Documentation (README.md):
Cross-Platform Testing:
The code now provides a consistent, professional user experience regardless of the platform or terminal being used.
Enhanced the CLI with two major features:
Command History Support (readline):
Debug Mode:
Usage:
LionChief> debug # Enable debug mode
LionChief> motor,set_speed,100
DEBUG: Sending command: 004564d7
✓ Command executed successfully
LionChief> debug # Disable debug mode
This will help diagnose why motor commands aren't working while lighting commands work correctly - users can compare the actual bytes being sent and verify the protocol implementation.
Also updated help text to document the new debug command.
Corrected the motor speed range in all documentation and docstrings. The actual range is 0-100, not 0-255 as previously documented.
Changes:
This was discovered during testing on Raspberry Pi where the train now moves correctly with speed values in the 0-100 range.
Fixed two issues discovered during Raspberry Pi testing:
Debug Mode Not Working (examples/cli.py):
Misleading Error Messages (lionchief/sound.py):
Testing Notes:
Added new motor control methods to address speed ramping issues:
Motor Controller (lionchief/motor.py):
CLI Help Documentation (examples/cli.py):
Usage Examples:
motor,gradual_speed_change,50 # Smoothly ramp to 50
motor,gradual_speed_change,0,3,0.1 # Slow down gently
motor,gradual_speed_change,80,10,0.3 # Quick acceleration
motor,stop # Quick stop
This helps work around the reported issue where speeds 1-3 are normal but speed 4 causes a sudden jump. Users can now use gradual_speed_change to smoothly transition through problematic speed ranges.
Next step: Investigate why speed 4 causes sudden jump (possible byte conversion or protocol mapping issue).
Added clear documentation in README explaining:
This clarifies the separation of concerns:
Added new "CLI Example" section documenting what the CLI supports:
This helps users understand what to use each tool for.