rpi-controls - RPi’s GPIO buttons
The rpicontrols package simplifies interactions with physical buttons connected to GPIO pins on a Raspberry Pi.
It abstracts away the complexity of monitoring the state of GPIO pins to detect events such as presses, clicks, double clicks… User code can subscribe to those high-level events the same way it would with most UI frameworks.
from rpicontrols import Controller, Button, PullType, make_controller
# Initialize the button controller. A single instance can handle as many buttons as needed.
controller: Controller = make_controller()
# Create the button, connected to pin 22.
button: Button = controller.make_button(
input_pin_id=22, # Id of the GPIO pin the button switch is connected to.
input=Button.InputType.PRESSED_WHEN_OFF, # Depends on the physical wiring of the button.
pull=PullType.UP # Whether to enable pull-up or pull-down resistor. Use PullType.NONE to disable.
)
# Define a callback to run when button is clicked.
async def on_click_callback(button: Button) -> None:
print(f'Button {button.name} clicked!')
# Run some IO-bound task without blocking.
# Other event handlers may run while waiting.
await asyncio.sleep(2)
# Subscribe to the click event.
button.add_on_click(on_click_callback)
# Start controller main loop. Use controller.start_in_thread() for the non-blocking version.
controller.run()
from rpicontrols import Controller, Button, PullType, make_controller
# Initialize the button controller. A single instance can handle as many buttons as needed.
controller: Controller = make_controller()
# Create the button, connected to pin 22.
button: Button = controller.make_button(
input_pin_id=22, # Id of the GPIO pin the button switch is connected to.
input=Button.InputType.PRESSED_WHEN_OFF, # Depends on the physical wiring of the button.
pull=PullType.UP # Whether to enable pull-up or pull-down resistor. Use PullType.NONE to disable.
)
# Define a callback to run when button is clicked.
def on_click_callback(button: Button) -> None:
print(f'Button {button.name} clicked!')
# Subscribe to the click event.
button.add_on_click(on_click_callback)
# Start controller main loop. Use controller.start_in_thread() for the non-blocking version.
controller.run()
As shown in the example above, event handlers can be either synchronous or asynchronous functions.
Synchronous handlers can only run one at a time. One handler must finish its execution for another to be executed, so long-running synchronous handlers are discouraged.
On the contrary, asynchronous handlers can run concurrently, in the sense that one handler can run while another is awaiting an IO-bound task.
In all cases, event handlers are all run on the same thread.
Summary
|
Creates a new instance of a button controller. |
|
Represents the object managing all buttons. |
|
Defines the various steps in a controller lifecycle. |
|
Represents a button connected to the GPIO. |
Functions
- rpicontrols.make_controller(gpio_driver=None)
Creates a new instance of a button controller. One instance of a controller is required to work with any number of buttons, so a call to this function is mandatory when initializing the client code.
- Parameters
gpio_driver (Optional[rpicontrols.gpio_driver.GpioDriver]) – object abstracting access to the GPIO, defaults to None in which case an implementation based on RPi.GPIO will be used (see
rpicontrols.rpi_gpio_driver.RpiGpioDriver). This parameter is unlikely to require a different value in a production context. It is mostly here to help mocking the GPIO access when testing.- Return type
A new controller, accepting button declaration and ready to be started.
Controller Object
- class rpicontrols.Controller(driver)
Represents the object managing all buttons. It monitors the state of the GPIO and calls event callbacks on buttons when appropriate.
- Parameters
driver (gpio_driver.GpioDriver) –
- class Status(value)
Defines the various steps in a controller lifecycle.
- READY = 'ready'
Controller is waiting for being started, either with
Controller.run()orController.start_in_thread()
- RUNNING = 'running'
Controller has been started and is monitoring GPIO. This is the active state of the controller, during which button events can be raised.
- STOPPED = 'stopped'
Controller is at full stop and all event callbacks have returned. Controller cannot be started again.
- STOPPING = 'stopping'
Controller is being shut down. No new events will be raised at this point because GPIO is no longer monitored, but ongoing callbacks may still need to finish.
- property buttons: Iterable[rpicontrols.controller.Button]
Gets the collection of buttons that have been registered using
make_button().
- delete_button(button)
Removes the button from the controller. The controller will stop monitoring this button events and will not update its status anymore. Call this method to save resources if this button is not useful anymore. It is not required to delete all buttons before deleting this controller.
- Parameters
button (rpicontrols.controller.Button) –
- Return type
None
- make_button(input_pin_id, input, pull, name=None, bounce_time=0)
Creates a new button connected to pins of the GPIO.
- Parameters
input_pin_id (int) – id of the input pin the button is connected to. Its meaning depends on the selected GPIO driver. The default driver is
rpicontrols.rpi_gpio_driver.RpiGpioDriverwhich usesRPi.GPIO.BOARDunless otherwise specified.input (rpicontrols.controller.Button.InputType) – value describing the button physical behavior with respect to the electrical wiring. It helps the controller tell when the button is considered pressed or released, depending on the state of the GPIO.
pull (rpicontrols.gpio_driver.PullType) – whether built-in pull-up or pull-down should be used for this button. Those are resistors integrated in the Raspberry Pi’s circuits that can be used to make sure GPIO pins are always at a predictable potential. The appropriate value is dependent on how the physical button or switch has been wired to the GPIO. See Wikipedia for more information.
name (Optional[str]) – optional name, used for documentation and logging purposes. If unset, a default unique name will be assigned.
bounce_time (int) – timespan after a GPIO rising or falling edge during which new edges should be ignored. This is meant to avoid unwanted edge detections due to the transient instability of switches when they change state. The appropriate value depends on the actual physical switch or button in use.
- Return type
- run()
Runs the engine controlling the GPIO.
This method blocks until the controller is stopped. See also
start_in_thread()for a non-blocking version of this start method.- Return type
None
- start_in_thread()
Runs the engine controlling the GPIO in its own thread.
- Return type
None
- property status: rpicontrols.controller.Controller.Status
Gets the current status of this controller.
- stop(wait=False)
Stops this controller.
Attempting to stop a controller that is already stopped does nothing. Otherwise, calling this method on a controller that is in a status different from
Controller.Status.RUNNINGraises an exception.- Parameters
wait (bool) – whether to block until the controller has actually stopped. If False, the method returns quicker but there is no guarantee that the controller has actually reached the
Status.STOPPEDstatus.- Return type
None
- stop_on_signals(signals=[<Signals.SIGINT: 2>, <Signals.SIGTERM: 15>])
Registers a handler to stop this controller when specific signals are caught.
- Parameters
signals (Iterable[signal.Signals]) – list of signals that should stop this controller.
Button Objects
- class rpicontrols.Button(input_pin_id, input_type, name=None)
Represents a button connected to the GPIO.
This object holds the current state of the button and the event handlers to be called when events are raised.
- Parameters
input_pin_id (int) –
input_type (Button.InputType) –
name (Optional[str]) –
- AsyncEventHandler
Represents the type for asynchronous event handlers.
alias of
Callable[[Button],Coroutine[Any,Any,Any]]
- EventHandler
Represents the type for all kinds of event handlers (synchronous or asynchronous).
alias of
Union[Callable[[Button],None],Callable[[Button],Coroutine[Any,Any,Any]]]
- EventHandlerList
Represents the type for lists of event handlers (synchronous or asynchronous).
alias of
List[Union[Callable[[Button],None],Callable[[Button],Coroutine[Any,Any,Any]]]]
- class InputType(value)
Defines the various physical behaviors of a button with respect to the wiring of its corresponding GPIO pins.
- PRESSED_WHEN_OFF = 2
The button is detected as pressed when its GPIO input pin is off.
- PRESSED_WHEN_ON = 1
The button is detected as pressed when its GPIO input pin is on.
- SyncEventHandler
Represents the type for synchronous event handlers.
alias of
Callable[[Button],None]
- add_on_click(func)
Adds a handler of the click event. This handler will be called whenever the button is pressed and released once. If a second click happens before
double_click_timeoutexpires, this event is not raised. The double click event is raised instead.- Parameters
func (EventHandler) –
- Return type
None
- add_on_double_click(func)
Adds a handler of the double click event. This handler will be called whenever the button is pressed and released twice within a period of time at most equal to
double_click_timeout.- Parameters
func (EventHandler) –
- Return type
None
- add_on_long_press(func)
Adds a handler of the long press event. This handler will be called whenever the button has been kept in its pressed state for a period of time equal to
long_press_timeoutseconds.- Parameters
func (EventHandler) –
- Return type
None
- add_on_press(func)
Adds a handler of the press event. This handler will be called whenever the button is pressed.
- Parameters
func (EventHandler) –
- Return type
None
- add_on_release(func)
Adds a handler of the release event. This handler will be called whenever the button is released after having been pressed.
- Parameters
func (EventHandler) –
- Return type
None
- double_click_timeout: float
Period of time in seconds that defines the double click speed. For a double click to be detected, two clicks must occur so that the number of elapsed seconds between the first press and the second release is at most equal to this timeout. This timeout has an indirect impact on the detection of the click events: since no click event is raised when a double click occurs, the controller must wait for this double click timeout to expire once a first click has been detected before the actual click event can be raised.
- property input_type: InputType
Returns a value indicating the physical status of the button with respect to GPIO status.
- long_press_timeout: float
Number of consecutive seconds the button must be pressed for the long pressed event to be raised.
- property long_pressed: bool
Returns a value indicating whether the button is currently pressed and has been so for least a period of time at least equal to
long_press_timeout.
- property name: str
Informational name of this button. This name is used mainly for logging purposes.
- property pin_id: int
Id of the input pin the button is connected to. See
Controller.make_button()for more info on its meaning.
- property pressed: bool
Returns a value indicating whether the button is currently pressed.
- remove_on_click(func)
Removes a handler of the click event.
- Parameters
func (EventHandler) –
- Return type
None
- remove_on_double_click(func)
Removes a handler of the double click event.
- Parameters
func (EventHandler) –
- Return type
None
- remove_on_long_press(func)
Removes a handler of the long press event.
- Parameters
func (EventHandler) –
- Return type
None
- remove_on_press(func)
Removes a handler of the press event.
- Parameters
func (EventHandler) –
- Return type
None
- remove_on_release(func)
Removes a handler of the release event.
- Parameters
func (EventHandler) –
- Return type
None
GPIO Drivers
- class rpicontrols.rpi_gpio_driver.RpiGpioDriver(mode: int = RPi.GPIO.BOARD)
Implementation of the GPIO driver interface based on RPi.GPIO. This is the default driver for button controllers.
- Parameters
mode – value describing the meaning of GPIO pin numbers. Refer to RPi.GPIO documentation for more information.