Source code for crappy.inout.gpio_switch

# coding: utf-8

from typing import Union
import logging

from .meta_inout import InOut
from .._global import OptionalModule

try:
  import RPi.GPIO as GPIO
except (ModuleNotFoundError, ImportError):
  GPIO = OptionalModule("RPi.GPIO")

try:
  import board
except (ModuleNotFoundError, ImportError):
  board = OptionalModule('board', 'Blinka is necessary to access the GPIO')

try:
  import digitalio
except (ImportError, ModuleNotFoundError):
  digitalio = OptionalModule('digitalio',
                             'Blinka is necessary to access the GPIOs')

gpio_switch_backends = ['Pi4', 'blinka']


[docs] class GPIOSwitch(InOut): """This class can drive a GPIO high or low on a single board computer. When the command value is `1` the GPIO is turned high, when the command is `0` it is turned low. Any value other than `0` and `1` raises an error. .. versionadded:: 1.4.0 .. versionchanged:: 2.0.0 renamed from *Gpio_switch* to *GPIOSwitch* """
[docs] def __init__(self, pin_out: Union[int, str], backend: str) -> None: """Checks the validity of the arguments. Args: pin_out: The GPIO pin to be controlled. On Raspberry Pi, should be an :obj:`int` corresponding to a GPIO in BCM convention. With the `'blinka'` backend, should be a string holding the name of the pin. Refer to blinka's specific documentation for each board for more information. backend: Should be one of : :: 'Pi4', 'blinka' The `'Pi4'` backend only works on the Raspberry Pis. The `'blinka'` backend requires installing :mod:`Adafruit-Blinka`, but this module is compatible with and maintained on a wide variety of boards. .. versionadded:: 1.5.10 .. versionadded:: 1.5.10 *ft232h_ser_num* argument .. versionremoved:: 2.0.0 *ft232h_ser_num* argument """ self._pin_out = None # Checking that the backend is valid if not isinstance(backend, str) or backend not in gpio_switch_backends: raise ValueError("backend should be in {}".format(gpio_switch_backends)) self._backend = backend # Checking that the given pin is valid for the selected backend if backend == 'blinka' and not hasattr(board, pin_out): raise TypeError(f'{pin_out} is not a valid pin using the blinka backend ' f'on this board !') elif backend == 'Pi4' and (not isinstance(pin_out, int) or pin_out not in range(2, 28)): raise ValueError('pin_out should be an integer between 2 and 28 when ' 'using the Pi4 backend !') super().__init__() # Instantiating the pin object if backend == 'Pi4': self._pin_out = pin_out elif backend == 'blinka': self._pin_out = digitalio.DigitalInOut(getattr(board, pin_out))
[docs] def open(self) -> None: """Initializes the GPIO.""" if self._backend == 'Pi4': self.log(logging.INFO, "Setting up the GPIOs") GPIO.setmode(GPIO.BCM) GPIO.setup(self._pin_out, GPIO.OUT) elif self._backend == 'blinka': self._pin_out.direction = digitalio.Direction.OUTPUT
[docs] def set_cmd(self, *cmd: int) -> None: """Drives the GPIO according to the command. Args: cmd: 1 for driving the GPIO high, 0 for driving it low. """ if cmd[0] not in [0, 1]: raise ValueError("The GPIO input can only be 0 or 1") if self._backend == 'Pi4': GPIO.output(self._pin_out, cmd[0]) elif self._backend == 'blinka': self._pin_out.value = cmd[0]
[docs] def close(self) -> None: """Releases the GPIO.""" if self._backend == 'Pi4': self.log(logging.INFO, "Cleaning up the GPIOs") GPIO.cleanup() elif self._backend == 'blinka' and self._pin_out is not None: self._pin_out.deinit()