pi-controller


Namepi-controller JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryA library for nintendo switch pro controller support with raspberry pi.
upload_time2025-01-08 19:34:49
maintainerNone
docs_urlNone
authorPreciousFood
requires_python>=3.8
licenseNone
keywords pi raspberry pi controller pro controller
VCS
bugtrack_url
requirements evdev
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # PiController
This is a project to connect a nintendo pro controller to a raspberry pi. 
I initially did this with pygame [here](https://github.com/PreciousFood/pro_controller), but this is better suited for the pi. That project is multiplatform though, whereas this makes use of evdev, which is only available on linux. 

# Documentation

## Overview

The `ProController` module provides an abstraction for interfacing with a Nintendo Switch Pro Controller via the `evdev` library in Python. It includes classes and utilities for handling buttons, joysticks, and events, as well as support for vibration feedback.

---

## Table of Contents

1. [Installation](#installation)
2. [Classes](#classes)
   - [ProController](#1-procontroller)
   - [RawJoystick](#2-rawjoystick)
   - [Joystick](#3-joystick)
   - [Key](#1-key)
3. [Additional Functions](#additional-functions)
4. [Usage](#usage)
5. [Examples](#examples)
6. [Requirements](#requirements)

---

## Installation

1. Install the python development headers, a dependency for evdev, the one and only dependency of this library.
    ```bash
    sudo apt install python3-dev
    ```
2. Install pi_controller (inside a virtual environment is recomended)
    ```bash
    pip install pi_controller
    ```
    or clone from github
    ```bash
    git clone https://github.com/PreciousFood/pi_controller.git
    ```

## Classes

### 1. `ProController`
Represents the Nintendo Switch Pro Controller. Handles button and joystick inputs, event processing, and vibration feedback.

#### Initialization:
```python
ProController(index: int, check_controller: bool = True, min_pause_time: float = 0)
```

- `index`: Index of the controller in the list of devices. See [list_devices](#1-list_devices) to figure out what the correct index is.
- `check_controller`: If `True`, validates the controller as a Pro Controller.
- `min_pause_time`: Minimum time between event loops.

#### Attributes:
- `BUTTONS`: Tuple of button names.
- `JOYSTICKS`: Tuple of joystick names.
- `buttons`: List of `Key` objects representing controller buttons.
- `raw_joysticks`: List of `RawJoystick` objects for joystick axes.
- `joysticks`: List of `Joystick` objects for grouped joystick axes.

#### Methods:
- `run()`: Starts the event loop to process input.
- `stop()`: Stops the event loop.
- `button_from_code(code: int) -> Key`: Maps a hardware code to a `Key`.
- `raw_joystick_from_code(code: int) -> RawJoystick`: Maps a hardware code to a `RawJoystick`.

#### Event Handlers:
- `on_key_press(func: Callable[[Key], None])`: Adds a callback for button press events.
- `on_key_release(func: Callable[[Key], None])`: Adds a callback for button release events.
- `on_v_key_press(key: str)`: Adds a callback for a specific button press.
- `on_v_key_release(key: str)`: Adds a callback for a specific button release.
- `on_every_loop(func: Callable)`: Adds a callback for every event loop iteration.
- `on_abs_event(func: Callable[[RawJoystick, int], None])`: Adds a callback for joystick movement events.
- `on_v_abs_event(joystick: str)`: Adds a callback for a specific joystick movement.

#### Vibration:
> Experimental feature, not fully implemented yet
- `rumble(duration: int, strong: int, weak: int, repeat: int = 1)`: Triggers vibration feedback.

#### Properties:
- Button aliases (`a`, `b`, `x`, etc.).
- Joystick aliases (`left_joystick`, `right_joystick`, `dpad).
- D-pad directional properties (`dpad_up`, `dpad_down`, etc.).
>Note: Because of how evdev handles the dpad, it is technically a joystick with values of -1, 0, or 1. The D-pad directional properties handle this to be a simple bool

---

### 2. `RawJoystick`
Represents a raw axis of a joystick.

#### Attributes:
- `name` (str): Name of the axis.
- `code` (int): Hardware code for the axis.
- `value` (int): Current raw value of the axis.
- `max_val` (int): Maximum possible value for the axis.

#### Properties:
- `p_val` (float): Normalized value of the axis (`value / max_val`).

#### Methods:
- `__str__()`: Returns the name of the axis.

---

### 3. `Joystick`
Represents a joystick with two axes (X and Y).

#### Attributes:
- `name` (str): Name of the joystick.
- `x` (`RawJoystick`): X-axis of the joystick.
- `y` (`RawJoystick`): Y-axis of the joystick.

#### Properties:
- `value` (tuple[int, int]): Tuple of raw X and Y values.
- `p_val` (tuple[float, float]): Tuple of normalized X and Y values.

#### Methods:
- `__str__()`: Returns the joystick name.

---

### 1. `Key`
Represents a single button on the controller.

#### Attributes:
- `name` (str): Name of the button.
- `code` (int): Hardware code for the button.
- `pressed` (bool): State of the button (`True` if pressed, `False` otherwise).

#### Methods:
- `__str__()`: Returns the name of the button and whether it is pressed.
- `__bool__()`: Returns the `pressed` state.


## Additional Functions

### 1. list_devices
Lists the names of all available devices, the index of the device you want is the index to pass to `ProController`.

Returns a list of strings.

## Usage

1. **Initialize the Controller:**
   ```python
   from pro_controller import ProController

   pro = ProController(index=0)
   ```

2. **Register Event Handlers:**
   ```python
   @pro.on_key_press
   def on_button_press(key):
       print(f"{key} pressed")
   ```

3. **Start the Event Loop:**
   ```python
   pro.run()
   ```

4. **Stop the Controller:**
   ```python
   pro.stop()
   ```

---

## Examples

### Button Press Example:
```python
pro = ProController(0)

@pro.on_key_press
def handle_press(button):
    print(f"Button {button.name} was pressed!")

pro.run()
```

### Joystick Movement Example:
```python
pro = ProController(0)

@pro.on_abs_event
def handle_joystick(joystick, value):
    print(f"{joystick.name} moved to {value}")

pro.run()
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "pi-controller",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "pi, raspberry pi, controller, pro controller",
    "author": "PreciousFood",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/f2/0f/ef8ba98166050f34492cc3a3aa66bb4c44f120ef808f5885b67ecbb9e413/pi_controller-1.0.0.tar.gz",
    "platform": null,
    "description": "# PiController\nThis is a project to connect a nintendo pro controller to a raspberry pi. \nI initially did this with pygame [here](https://github.com/PreciousFood/pro_controller), but this is better suited for the pi. That project is multiplatform though, whereas this makes use of evdev, which is only available on linux. \n\n# Documentation\n\n## Overview\n\nThe `ProController` module provides an abstraction for interfacing with a Nintendo Switch Pro Controller via the `evdev` library in Python. It includes classes and utilities for handling buttons, joysticks, and events, as well as support for vibration feedback.\n\n---\n\n## Table of Contents\n\n1. [Installation](#installation)\n2. [Classes](#classes)\n   - [ProController](#1-procontroller)\n   - [RawJoystick](#2-rawjoystick)\n   - [Joystick](#3-joystick)\n   - [Key](#1-key)\n3. [Additional Functions](#additional-functions)\n4. [Usage](#usage)\n5. [Examples](#examples)\n6. [Requirements](#requirements)\n\n---\n\n## Installation\n\n1. Install the python development headers, a dependency for evdev, the one and only dependency of this library.\n    ```bash\n    sudo apt install python3-dev\n    ```\n2. Install pi_controller (inside a virtual environment is recomended)\n    ```bash\n    pip install pi_controller\n    ```\n    or clone from github\n    ```bash\n    git clone https://github.com/PreciousFood/pi_controller.git\n    ```\n\n## Classes\n\n### 1. `ProController`\nRepresents the Nintendo Switch Pro Controller. Handles button and joystick inputs, event processing, and vibration feedback.\n\n#### Initialization:\n```python\nProController(index: int, check_controller: bool = True, min_pause_time: float = 0)\n```\n\n- `index`: Index of the controller in the list of devices. See [list_devices](#1-list_devices) to figure out what the correct index is.\n- `check_controller`: If `True`, validates the controller as a Pro Controller.\n- `min_pause_time`: Minimum time between event loops.\n\n#### Attributes:\n- `BUTTONS`: Tuple of button names.\n- `JOYSTICKS`: Tuple of joystick names.\n- `buttons`: List of `Key` objects representing controller buttons.\n- `raw_joysticks`: List of `RawJoystick` objects for joystick axes.\n- `joysticks`: List of `Joystick` objects for grouped joystick axes.\n\n#### Methods:\n- `run()`: Starts the event loop to process input.\n- `stop()`: Stops the event loop.\n- `button_from_code(code: int) -> Key`: Maps a hardware code to a `Key`.\n- `raw_joystick_from_code(code: int) -> RawJoystick`: Maps a hardware code to a `RawJoystick`.\n\n#### Event Handlers:\n- `on_key_press(func: Callable[[Key], None])`: Adds a callback for button press events.\n- `on_key_release(func: Callable[[Key], None])`: Adds a callback for button release events.\n- `on_v_key_press(key: str)`: Adds a callback for a specific button press.\n- `on_v_key_release(key: str)`: Adds a callback for a specific button release.\n- `on_every_loop(func: Callable)`: Adds a callback for every event loop iteration.\n- `on_abs_event(func: Callable[[RawJoystick, int], None])`: Adds a callback for joystick movement events.\n- `on_v_abs_event(joystick: str)`: Adds a callback for a specific joystick movement.\n\n#### Vibration:\n> Experimental feature, not fully implemented yet\n- `rumble(duration: int, strong: int, weak: int, repeat: int = 1)`: Triggers vibration feedback.\n\n#### Properties:\n- Button aliases (`a`, `b`, `x`, etc.).\n- Joystick aliases (`left_joystick`, `right_joystick`, `dpad).\n- D-pad directional properties (`dpad_up`, `dpad_down`, etc.).\n>Note: Because of how evdev handles the dpad, it is technically a joystick with values of -1, 0, or 1. The D-pad directional properties handle this to be a simple bool\n\n---\n\n### 2. `RawJoystick`\nRepresents a raw axis of a joystick.\n\n#### Attributes:\n- `name` (str): Name of the axis.\n- `code` (int): Hardware code for the axis.\n- `value` (int): Current raw value of the axis.\n- `max_val` (int): Maximum possible value for the axis.\n\n#### Properties:\n- `p_val` (float): Normalized value of the axis (`value / max_val`).\n\n#### Methods:\n- `__str__()`: Returns the name of the axis.\n\n---\n\n### 3. `Joystick`\nRepresents a joystick with two axes (X and Y).\n\n#### Attributes:\n- `name` (str): Name of the joystick.\n- `x` (`RawJoystick`): X-axis of the joystick.\n- `y` (`RawJoystick`): Y-axis of the joystick.\n\n#### Properties:\n- `value` (tuple[int, int]): Tuple of raw X and Y values.\n- `p_val` (tuple[float, float]): Tuple of normalized X and Y values.\n\n#### Methods:\n- `__str__()`: Returns the joystick name.\n\n---\n\n### 1. `Key`\nRepresents a single button on the controller.\n\n#### Attributes:\n- `name` (str): Name of the button.\n- `code` (int): Hardware code for the button.\n- `pressed` (bool): State of the button (`True` if pressed, `False` otherwise).\n\n#### Methods:\n- `__str__()`: Returns the name of the button and whether it is pressed.\n- `__bool__()`: Returns the `pressed` state.\n\n\n## Additional Functions\n\n### 1. list_devices\nLists the names of all available devices, the index of the device you want is the index to pass to `ProController`.\n\nReturns a list of strings.\n\n## Usage\n\n1. **Initialize the Controller:**\n   ```python\n   from pro_controller import ProController\n\n   pro = ProController(index=0)\n   ```\n\n2. **Register Event Handlers:**\n   ```python\n   @pro.on_key_press\n   def on_button_press(key):\n       print(f\"{key} pressed\")\n   ```\n\n3. **Start the Event Loop:**\n   ```python\n   pro.run()\n   ```\n\n4. **Stop the Controller:**\n   ```python\n   pro.stop()\n   ```\n\n---\n\n## Examples\n\n### Button Press Example:\n```python\npro = ProController(0)\n\n@pro.on_key_press\ndef handle_press(button):\n    print(f\"Button {button.name} was pressed!\")\n\npro.run()\n```\n\n### Joystick Movement Example:\n```python\npro = ProController(0)\n\n@pro.on_abs_event\ndef handle_joystick(joystick, value):\n    print(f\"{joystick.name} moved to {value}\")\n\npro.run()\n```\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A library for nintendo switch pro controller support with raspberry pi.",
    "version": "1.0.0",
    "project_urls": {
        "Homepage": "https://github.com/PreciousFood/pi_controller"
    },
    "split_keywords": [
        "pi",
        " raspberry pi",
        " controller",
        " pro controller"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2192dd5395b56a3ca9033e511c5128af339e32838194bb9317673429e306d4c7",
                "md5": "c74d55bed8f1f7f6d7126b63e04e83b2",
                "sha256": "5c8f3daa6e62e39594896956274da2999c3dc01549e04eeb429bc5b163b775d0"
            },
            "downloads": -1,
            "filename": "pi_controller-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c74d55bed8f1f7f6d7126b63e04e83b2",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 6965,
            "upload_time": "2025-01-08T19:34:47",
            "upload_time_iso_8601": "2025-01-08T19:34:47.205252Z",
            "url": "https://files.pythonhosted.org/packages/21/92/dd5395b56a3ca9033e511c5128af339e32838194bb9317673429e306d4c7/pi_controller-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f20fef8ba98166050f34492cc3a3aa66bb4c44f120ef808f5885b67ecbb9e413",
                "md5": "e001802faf5a258f4f2cfd653915a034",
                "sha256": "28e70815537a5890343d58efaa38ff35c0f2aa51250c315f6187f70fbaac0b4d"
            },
            "downloads": -1,
            "filename": "pi_controller-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "e001802faf5a258f4f2cfd653915a034",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 7037,
            "upload_time": "2025-01-08T19:34:49",
            "upload_time_iso_8601": "2025-01-08T19:34:49.560647Z",
            "url": "https://files.pythonhosted.org/packages/f2/0f/ef8ba98166050f34492cc3a3aa66bb4c44f120ef808f5885b67ecbb9e413/pi_controller-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-08 19:34:49",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "PreciousFood",
    "github_project": "pi_controller",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "evdev",
            "specs": []
        }
    ],
    "lcname": "pi-controller"
}
        
Elapsed time: 0.51492s