joycon-lib


Namejoycon-lib JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryA Python library for reading button and stick input from Nintendo Joy-Con controllers
upload_time2025-09-07 21:46:30
maintainerNone
docs_urlNone
authorDexmate AI
requires_python<3.14,>=3.10
licenseNone
keywords joycon nintendo controller gamepad input evdev linux
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Joy-Con Python Library

A Linux-based Python library for reading and decoding button information from Nintendo Joy-Con controllers using the evdev interface.

> **Note:** This library currently only supports Linux. Windows and macOS support would require implementing HID or other platform-specific backends.

## Features

- **Linux Support** - Works on Linux with the evdev interface
- **Evdev Backend** - Direct communication with Joy-Con controllers via Linux input subsystem
- **Real-time Input** - Read button states and analog sticks in real-time
- **Multiple Controllers** - Support for left, right, and Pro controllers
- **Dual Joy-Con Mode** - Use two Joy-Cons as a single controller
- **Event System** - Register callbacks for button press/release events
- **Polling Mode** - Continuous input monitoring at configurable rates
- **Clean API** - Simple, intuitive interface with Google-style docstrings
- **Low Latency** - Optimized for minimal input lag with device grabbing and efficient event reading

## Requirements

- Python 3.10 or higher
- Linux operating system
- Bluetooth-connected Joy-Con controllers
- Dependencies installed automatically:
  - `evdev` (Linux event device interface)

## Installation


```bash
pip install joycon-lib
```


### Prerequisites - Bluetooth Setup

#### Linux Setup

Before using the library, you need to set up your Linux system:

**1. Enable the hid_nintendo kernel driver (REQUIRED):**

```bash
# Load the driver - this is required for Joy-Con support
sudo modprobe hid_nintendo

# To load automatically on boot (recommended):
echo "hid_nintendo" | sudo tee /etc/modules-load.d/hid_nintendo.conf
```

> **Note:** Without the `hid_nintendo` driver, Joy-Con controllers won't be recognized as input devices.

**2. Add udev rules for non-root access (RECOMMENDED):**

Without these rules, you'll need to run your Python scripts with `sudo`.

```bash
# Create udev rules file
sudo tee /etc/udev/rules.d/50-joycon.rules << 'EOF'
# Nintendo Joy-Con (L/R) and Pro Controller
KERNEL=="event*", ATTRS{name}=="*Joy-Con*", MODE="0666"
KERNEL=="event*", ATTRS{name}=="*Pro Controller*", MODE="0666"
EOF

# Reload and apply rules
sudo udevadm control --reload-rules
sudo udevadm trigger
```

**3. Connect Joy-Con via Bluetooth:**
```bash
# Open Bluetooth control
bluetoothctl

# In bluetoothctl:
power on
agent on
default-agent
scan on

# Press sync button on Joy-Con (small button between SL/SR)
# Wait for Joy-Con to appear, note the MAC address

pair XX:XX:XX:XX:XX:XX
trust XX:XX:XX:XX:XX:XX
connect XX:XX:XX:XX:XX:XX

# Exit bluetoothctl
exit
```

Or you can use the GUI to connect to the Joy-Con device via Bluetooth.

## Quick Start

### Basic Usage

```python
from joycon_lib import JoyCon, Button
import time

# Create and connect to Joy-Con
joycon = JoyCon(use_backend='evdev')  # Linux only
joycon.connect()  # Auto-finds first available Joy-Con

# Read button states
while True:
    buttons = joycon.read_buttons()
    if buttons.is_pressed(Button.A):
        print("A button pressed!")
    time.sleep(0.016)  # ~60 FPS

# Disconnect when done
joycon.disconnect()
```

### Dual Joy-Con Mode

```python
from joycon_lib import DualJoyCon, Button
import time

# Create dual Joy-Con controller
dual = DualJoyCon(use_backend='evdev')  # Linux only
dual.connect(auto_find=True)  # Auto-finds and connects both Joy-Cons

# Start polling
dual.start_polling(rate=60)

# Read from both controllers as one
while True:
    buttons = dual.get_button_state()  # Combined buttons from both
    left_stick, right_stick = dual.get_sticks()  # Both analog sticks
    
    if buttons.is_pressed(Button.A):
        print("A pressed!")
    if buttons.is_pressed(Button.L) and buttons.is_pressed(Button.R):
        print("L+R combo!")
    
    time.sleep(0.016)

dual.disconnect()
```

## Running Examples

### Quick Test

```bash
# Run the library's built-in test
python -m joycon_lib
```

### Example Scripts

The `examples/` directory contains various demonstration scripts:

| Script | Description |
|--------|-------------|
| `example_stick.py` | Test analog stick input |
| `example_dual.py` | Use both Joy-Cons independently |
| `example_evdev.py` | Test evdev backend (Linux only) |

```bash
cd examples/
python example_dual.py  # Start with the interactive demo
```

## API Reference

### Core Classes

#### `JoyCon`

Main interface for single Joy-Con interaction.

**Methods:**
- `connect(device_path=None, device_type=None)` - Connect to a Joy-Con (evdev backend)
- `disconnect()` - Disconnect from the Joy-Con
- `read_buttons()` - Read current button state from device
- `get_button_state()` - Get current button state without reading
- `get_left_stick()` - Get left analog stick state
- `get_right_stick()` - Get right analog stick state
- `start_polling(rate=60)` - Start continuous polling
- `stop_polling()` - Stop polling
- `register_callback(event_type, callback)` - Register event callback
- `list_devices()` - List all available Joy-Con devices
- `get_device_info()` - Get information about connected device

#### `DualJoyCon`

Manages two Joy-Cons as a single controller.

**Methods:**
- `connect(auto_find=True, left_path=None, right_path=None)` - Connect to both Joy-Cons
- `disconnect()` - Disconnect both controllers
- `read_input()` - Read input from both Joy-Cons and combine
- `get_button_state()` - Get combined button state without reading
- `get_left_stick()` - Get left analog stick position
- `get_right_stick()` - Get right analog stick position
- `get_sticks()` - Get both analog stick positions as tuple
- `start_polling(rate=60)` - Start polling both controllers
- `stop_polling()` - Stop polling
- `is_connected()` - Check connection status of both Joy-Cons

#### `ButtonState`

Represents the current state of all buttons.

**Methods:**
- `is_pressed(button)` - Check if button is currently pressed
- `is_released(button)` - Check if button is currently released
- `just_pressed(button)` - Check if button was just pressed this frame
- `just_released(button)` - Check if button was just released this frame
- `get_pressed_names()` - Get list of pressed button names
- `to_dict()` - Convert button state to dictionary

### Button Mappings

| Controller | Buttons |
|------------|---------|
| **Right Joy-Con** | `Y`, `X`, `B`, `A`, `SR_RIGHT`, `SL_RIGHT`, `R`, `ZR`, `PLUS`, `R_STICK`, `HOME` |
| **Left Joy-Con** | `UP`, `DOWN`, `LEFT`, `RIGHT`, `SR_LEFT`, `SL_LEFT`, `L`, `ZL`, `MINUS`, `L_STICK`, `CAPTURE` |
| **Pro Controller** | All of the above |

#### `StickState`

Represents analog stick position and provides utility methods.

**Methods:**
- `get_angle()` - Get stick angle in degrees (0-360)
- `get_magnitude()` - Get displacement from center (0.0-1.0)
- `is_centered(deadzone=0.1)` - Check if stick is centered
- `get_direction_4way()` - Get 4-way directional input
- `get_direction_8way()` - Get 8-way directional input

**Attributes:**
- `x` - X-axis value (-1.0 to 1.0)
- `y` - Y-axis value (-1.0 to 1.0)
- `raw_x` - Raw X value from controller
- `raw_y` - Raw Y value from controller

## Troubleshooting

### Common Issues

**Joy-Con not detected:**
- Ensure Joy-Con is paired via Bluetooth
- Check battery level
- Try re-pairing the controller
- On Linux, verify udev rules are installed

**Permission denied errors (Linux):**
- Add udev rules as shown in setup
- Run with `sudo` (not recommended)
- Ensure `hid_nintendo` kernel module is loaded

**Connection drops:**
- Keep Joy-Con within Bluetooth range
- Check for interference from other devices
- Ensure Joy-Con firmware is up to date

## License

MIT License - See [LICENSE](LICENSE) file for details

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "joycon-lib",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<3.14,>=3.10",
    "maintainer_email": null,
    "keywords": "joycon, nintendo, controller, gamepad, input, evdev, linux",
    "author": "Dexmate AI",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/85/1f/37bbe787b01f8bd55d6cdd62a6c46fdf374772ad1c8cae0e13be834e5983/joycon_lib-1.0.0.tar.gz",
    "platform": null,
    "description": "# Joy-Con Python Library\n\nA Linux-based Python library for reading and decoding button information from Nintendo Joy-Con controllers using the evdev interface.\n\n> **Note:** This library currently only supports Linux. Windows and macOS support would require implementing HID or other platform-specific backends.\n\n## Features\n\n- **Linux Support** - Works on Linux with the evdev interface\n- **Evdev Backend** - Direct communication with Joy-Con controllers via Linux input subsystem\n- **Real-time Input** - Read button states and analog sticks in real-time\n- **Multiple Controllers** - Support for left, right, and Pro controllers\n- **Dual Joy-Con Mode** - Use two Joy-Cons as a single controller\n- **Event System** - Register callbacks for button press/release events\n- **Polling Mode** - Continuous input monitoring at configurable rates\n- **Clean API** - Simple, intuitive interface with Google-style docstrings\n- **Low Latency** - Optimized for minimal input lag with device grabbing and efficient event reading\n\n## Requirements\n\n- Python 3.10 or higher\n- Linux operating system\n- Bluetooth-connected Joy-Con controllers\n- Dependencies installed automatically:\n  - `evdev` (Linux event device interface)\n\n## Installation\n\n\n```bash\npip install joycon-lib\n```\n\n\n### Prerequisites - Bluetooth Setup\n\n#### Linux Setup\n\nBefore using the library, you need to set up your Linux system:\n\n**1. Enable the hid_nintendo kernel driver (REQUIRED):**\n\n```bash\n# Load the driver - this is required for Joy-Con support\nsudo modprobe hid_nintendo\n\n# To load automatically on boot (recommended):\necho \"hid_nintendo\" | sudo tee /etc/modules-load.d/hid_nintendo.conf\n```\n\n> **Note:** Without the `hid_nintendo` driver, Joy-Con controllers won't be recognized as input devices.\n\n**2. Add udev rules for non-root access (RECOMMENDED):**\n\nWithout these rules, you'll need to run your Python scripts with `sudo`.\n\n```bash\n# Create udev rules file\nsudo tee /etc/udev/rules.d/50-joycon.rules << 'EOF'\n# Nintendo Joy-Con (L/R) and Pro Controller\nKERNEL==\"event*\", ATTRS{name}==\"*Joy-Con*\", MODE=\"0666\"\nKERNEL==\"event*\", ATTRS{name}==\"*Pro Controller*\", MODE=\"0666\"\nEOF\n\n# Reload and apply rules\nsudo udevadm control --reload-rules\nsudo udevadm trigger\n```\n\n**3. Connect Joy-Con via Bluetooth:**\n```bash\n# Open Bluetooth control\nbluetoothctl\n\n# In bluetoothctl:\npower on\nagent on\ndefault-agent\nscan on\n\n# Press sync button on Joy-Con (small button between SL/SR)\n# Wait for Joy-Con to appear, note the MAC address\n\npair XX:XX:XX:XX:XX:XX\ntrust XX:XX:XX:XX:XX:XX\nconnect XX:XX:XX:XX:XX:XX\n\n# Exit bluetoothctl\nexit\n```\n\nOr you can use the GUI to connect to the Joy-Con device via Bluetooth.\n\n## Quick Start\n\n### Basic Usage\n\n```python\nfrom joycon_lib import JoyCon, Button\nimport time\n\n# Create and connect to Joy-Con\njoycon = JoyCon(use_backend='evdev')  # Linux only\njoycon.connect()  # Auto-finds first available Joy-Con\n\n# Read button states\nwhile True:\n    buttons = joycon.read_buttons()\n    if buttons.is_pressed(Button.A):\n        print(\"A button pressed!\")\n    time.sleep(0.016)  # ~60 FPS\n\n# Disconnect when done\njoycon.disconnect()\n```\n\n### Dual Joy-Con Mode\n\n```python\nfrom joycon_lib import DualJoyCon, Button\nimport time\n\n# Create dual Joy-Con controller\ndual = DualJoyCon(use_backend='evdev')  # Linux only\ndual.connect(auto_find=True)  # Auto-finds and connects both Joy-Cons\n\n# Start polling\ndual.start_polling(rate=60)\n\n# Read from both controllers as one\nwhile True:\n    buttons = dual.get_button_state()  # Combined buttons from both\n    left_stick, right_stick = dual.get_sticks()  # Both analog sticks\n    \n    if buttons.is_pressed(Button.A):\n        print(\"A pressed!\")\n    if buttons.is_pressed(Button.L) and buttons.is_pressed(Button.R):\n        print(\"L+R combo!\")\n    \n    time.sleep(0.016)\n\ndual.disconnect()\n```\n\n## Running Examples\n\n### Quick Test\n\n```bash\n# Run the library's built-in test\npython -m joycon_lib\n```\n\n### Example Scripts\n\nThe `examples/` directory contains various demonstration scripts:\n\n| Script | Description |\n|--------|-------------|\n| `example_stick.py` | Test analog stick input |\n| `example_dual.py` | Use both Joy-Cons independently |\n| `example_evdev.py` | Test evdev backend (Linux only) |\n\n```bash\ncd examples/\npython example_dual.py  # Start with the interactive demo\n```\n\n## API Reference\n\n### Core Classes\n\n#### `JoyCon`\n\nMain interface for single Joy-Con interaction.\n\n**Methods:**\n- `connect(device_path=None, device_type=None)` - Connect to a Joy-Con (evdev backend)\n- `disconnect()` - Disconnect from the Joy-Con\n- `read_buttons()` - Read current button state from device\n- `get_button_state()` - Get current button state without reading\n- `get_left_stick()` - Get left analog stick state\n- `get_right_stick()` - Get right analog stick state\n- `start_polling(rate=60)` - Start continuous polling\n- `stop_polling()` - Stop polling\n- `register_callback(event_type, callback)` - Register event callback\n- `list_devices()` - List all available Joy-Con devices\n- `get_device_info()` - Get information about connected device\n\n#### `DualJoyCon`\n\nManages two Joy-Cons as a single controller.\n\n**Methods:**\n- `connect(auto_find=True, left_path=None, right_path=None)` - Connect to both Joy-Cons\n- `disconnect()` - Disconnect both controllers\n- `read_input()` - Read input from both Joy-Cons and combine\n- `get_button_state()` - Get combined button state without reading\n- `get_left_stick()` - Get left analog stick position\n- `get_right_stick()` - Get right analog stick position\n- `get_sticks()` - Get both analog stick positions as tuple\n- `start_polling(rate=60)` - Start polling both controllers\n- `stop_polling()` - Stop polling\n- `is_connected()` - Check connection status of both Joy-Cons\n\n#### `ButtonState`\n\nRepresents the current state of all buttons.\n\n**Methods:**\n- `is_pressed(button)` - Check if button is currently pressed\n- `is_released(button)` - Check if button is currently released\n- `just_pressed(button)` - Check if button was just pressed this frame\n- `just_released(button)` - Check if button was just released this frame\n- `get_pressed_names()` - Get list of pressed button names\n- `to_dict()` - Convert button state to dictionary\n\n### Button Mappings\n\n| Controller | Buttons |\n|------------|---------|\n| **Right Joy-Con** | `Y`, `X`, `B`, `A`, `SR_RIGHT`, `SL_RIGHT`, `R`, `ZR`, `PLUS`, `R_STICK`, `HOME` |\n| **Left Joy-Con** | `UP`, `DOWN`, `LEFT`, `RIGHT`, `SR_LEFT`, `SL_LEFT`, `L`, `ZL`, `MINUS`, `L_STICK`, `CAPTURE` |\n| **Pro Controller** | All of the above |\n\n#### `StickState`\n\nRepresents analog stick position and provides utility methods.\n\n**Methods:**\n- `get_angle()` - Get stick angle in degrees (0-360)\n- `get_magnitude()` - Get displacement from center (0.0-1.0)\n- `is_centered(deadzone=0.1)` - Check if stick is centered\n- `get_direction_4way()` - Get 4-way directional input\n- `get_direction_8way()` - Get 8-way directional input\n\n**Attributes:**\n- `x` - X-axis value (-1.0 to 1.0)\n- `y` - Y-axis value (-1.0 to 1.0)\n- `raw_x` - Raw X value from controller\n- `raw_y` - Raw Y value from controller\n\n## Troubleshooting\n\n### Common Issues\n\n**Joy-Con not detected:**\n- Ensure Joy-Con is paired via Bluetooth\n- Check battery level\n- Try re-pairing the controller\n- On Linux, verify udev rules are installed\n\n**Permission denied errors (Linux):**\n- Add udev rules as shown in setup\n- Run with `sudo` (not recommended)\n- Ensure `hid_nintendo` kernel module is loaded\n\n**Connection drops:**\n- Keep Joy-Con within Bluetooth range\n- Check for interference from other devices\n- Ensure Joy-Con firmware is up to date\n\n## License\n\nMIT License - See [LICENSE](LICENSE) file for details\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A Python library for reading button and stick input from Nintendo Joy-Con controllers",
    "version": "1.0.0",
    "project_urls": null,
    "split_keywords": [
        "joycon",
        " nintendo",
        " controller",
        " gamepad",
        " input",
        " evdev",
        " linux"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2b651efeb9504018dca5056880135604b8c1ac7e97f732c5e4491c24778f4e9e",
                "md5": "a88ebd263ad02d5202c864ea5e768893",
                "sha256": "88d73663eed81b00bf65a0a1634649b8bc522fd2b208f5d58e3920c6fd7d21c8"
            },
            "downloads": -1,
            "filename": "joycon_lib-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "a88ebd263ad02d5202c864ea5e768893",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<3.14,>=3.10",
            "size": 19254,
            "upload_time": "2025-09-07T21:46:29",
            "upload_time_iso_8601": "2025-09-07T21:46:29.654374Z",
            "url": "https://files.pythonhosted.org/packages/2b/65/1efeb9504018dca5056880135604b8c1ac7e97f732c5e4491c24778f4e9e/joycon_lib-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "851f37bbe787b01f8bd55d6cdd62a6c46fdf374772ad1c8cae0e13be834e5983",
                "md5": "55c26daf14cd1c542d85e6988b23d95c",
                "sha256": "744cf888aad76da4ee867873141b1e408b0c547cb4e34cd3485d88b809f289fa"
            },
            "downloads": -1,
            "filename": "joycon_lib-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "55c26daf14cd1c542d85e6988b23d95c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<3.14,>=3.10",
            "size": 19294,
            "upload_time": "2025-09-07T21:46:30",
            "upload_time_iso_8601": "2025-09-07T21:46:30.760518Z",
            "url": "https://files.pythonhosted.org/packages/85/1f/37bbe787b01f8bd55d6cdd62a6c46fdf374772ad1c8cae0e13be834e5983/joycon_lib-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-07 21:46:30",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "joycon-lib"
}
        
Elapsed time: 0.99102s