CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-gpiozero

A simple interface to GPIO devices with Raspberry Pi

Pending
Overview
Eval results
Files

pin-factories.mddocs/

Pin Factory System

The pin factory system provides an abstracted interface for different GPIO backends, board information, and pin management. This enables GPIO Zero to work with multiple underlying GPIO libraries and provides comprehensive hardware abstraction.

Core Factory Classes

Factory

Abstract base class for all pin factories.

class Factory:
    def __init__(self):
        """
        Abstract base class for pin factories.
        """

    def close(self):
        """Close the factory and release all resources."""

    def reset(self):
        """Reset the factory to its initial state."""

    def pin(self, spec) -> 'Pin':
        """
        Create a pin object for the specified pin.
        
        Parameters:
        - spec: Pin specification (int, str, or PinInfo)
        
        Returns:
        Pin object for the specified pin
        """

    def spi(self, *, port=0, device=0) -> 'SPI':
        """
        Create an SPI interface object.
        
        Parameters:
        - port: int - SPI port number
        - device: int - SPI device (chip select) number
        
        Returns:
        SPI interface object
        """

    def reserve_pins(self, requester, *pins):
        """Reserve pins for exclusive use by requester."""

    def release_pins(self, requester, *pins):
        """Release pin reservations for requester."""

    def release_all(self, requester):
        """Release all pin reservations for requester."""

    @property
    def board_info(self) -> 'BoardInfo':
        """Information about the current board."""

    @property
    def ticks(self) -> int:
        """Current system tick count."""

    def ticks_diff(self, later: int, earlier: int) -> int:
        """Calculate difference between two tick counts."""

Pin

Abstract base class representing a GPIO pin.

class Pin:
    def __init__(self, factory, info):
        """
        Abstract base class for GPIO pins.
        
        Parameters:
        - factory: Factory that created this pin
        - info: PinInfo object describing this pin
        """

    def close(self):
        """Close the pin and release resources."""

    def output_with_state(self, state: bool):
        """Configure pin as output and set initial state."""

    def input_with_pull(self, pull: str):
        """Configure pin as input with pull resistor."""

    @property
    def number(self) -> int:
        """Pin number."""

    @property
    def info(self) -> 'PinInfo':
        """Pin information object."""

    @property
    def factory(self) -> Factory:
        """Factory that created this pin."""

    @property
    def function(self) -> str:
        """Current pin function ('input', 'output', 'alt0', etc.)."""

    @function.setter
    def function(self, value: str): ...

    @property
    def state(self) -> bool:
        """Current pin state (True=HIGH, False=LOW)."""

    @state.setter
    def state(self, value: bool): ...

    @property
    def pull(self) -> str:
        """Current pull resistor setting ('up', 'down', 'floating')."""

    @pull.setter
    def pull(self, value: str): ...

    @property
    def bounce(self) -> float:
        """Bounce time in seconds for edge detection."""

    @bounce.setter
    def bounce(self, value: float): ...

    @property
    def edges(self) -> str:
        """Edge detection setting ('none', 'falling', 'rising', 'both')."""

    @edges.setter
    def edges(self, value: str): ...

    @property
    def frequency(self) -> float:
        """PWM frequency in Hz."""

    @frequency.setter
    def frequency(self, value: float): ...

    @property
    def when_changed(self) -> callable:
        """Callback function for pin state changes."""

    @when_changed.setter
    def when_changed(self, value: callable): ...

SPI

Abstract base class for SPI interfaces.

class SPI:
    def __init__(self, factory, port, device):
        """
        Abstract base class for SPI interfaces.
        
        Parameters:
        - factory: Factory that created this interface
        - port: SPI port number
        - device: SPI device number
        """

    def close(self):
        """Close the SPI interface."""

    def transfer(self, data: list) -> list:
        """
        Transfer data over SPI.
        
        Parameters:
        - data: List of bytes to send
        
        Returns:
        List of bytes received
        """

    @property
    def closed(self) -> bool:
        """Returns True if interface is closed."""

    @property
    def port(self) -> int:
        """SPI port number."""

    @property
    def device(self) -> int:
        """SPI device (chip select) number."""

Board Information Classes

BoardInfo

Information about a GPIO board.

class BoardInfo:
    def __init__(self, headers, **kwargs):
        """
        Information about a GPIO board.
        
        Parameters:
        - headers: Dictionary of HeaderInfo objects
        - **kwargs: Additional board properties
        """

    def find_pin(self, spec) -> list:
        """
        Find pin by specification.
        
        Parameters:
        - spec: Pin specification (number, name, or pattern)
        
        Returns:
        List of (header, pin_info) tuples matching specification
        """

    @property
    def headers(self) -> dict:
        """Dictionary of headers on this board."""

    @property
    def pins(self) -> dict:
        """Dictionary of all pins on this board."""

HeaderInfo

Information about a pin header.

class HeaderInfo:
    def __init__(self, name, rows, columns, **kwargs):
        """
        Information about a pin header.
        
        Parameters:
        - name: Header name
        - rows: Number of rows
        - columns: Number of columns
        - **kwargs: Additional header properties
        """

    @property
    def name(self) -> str:
        """Header name."""

    @property
    def rows(self) -> int:
        """Number of rows in header."""

    @property
    def columns(self) -> int:
        """Number of columns in header."""

    @property
    def pins(self) -> dict:
        """Dictionary of pins in this header."""

PinInfo

Information about a specific pin.

class PinInfo:
    def __init__(self, number, name, **kwargs):
        """
        Information about a specific pin.
        
        Parameters:
        - number: Pin number
        - name: Pin name
        - **kwargs: Additional pin properties
        """

    @property
    def number(self) -> int:
        """Pin number."""

    @property
    def name(self) -> str:
        """Pin name."""

    @property
    def function(self) -> str:
        """Default pin function."""

    @property
    def pull(self) -> str:
        """Default pull resistor setting."""

    @property
    def row(self) -> int:
        """Header row position."""

    @property
    def col(self) -> int:
        """Header column position."""

Raspberry Pi Specific Classes

PiBoardInfo

Board information specific to Raspberry Pi.

class PiBoardInfo(BoardInfo):
    def __init__(self, revision=None, **kwargs):
        """
        Raspberry Pi board information.
        
        Parameters:
        - revision: Pi revision string or None for auto-detect
        - **kwargs: Additional board properties
        """

    @property
    def revision(self) -> str:
        """Pi board revision string."""

    @property
    def model(self) -> str:
        """Pi model name."""

    @property
    def pcb_revision(self) -> str:
        """PCB revision."""

    @property
    def memory(self) -> int:
        """Memory size in MB."""

    @property
    def manufacturer(self) -> str:
        """Board manufacturer."""

    @property
    def storage(self) -> str:
        """Storage type."""

    @property
    def usb(self) -> int:
        """Number of USB ports."""

    @property
    def ethernet(self) -> int:
        """Number of Ethernet ports."""

    @property
    def wifi(self) -> bool:
        """True if WiFi is available."""

    @property
    def bluetooth(self) -> bool:
        """True if Bluetooth is available."""

    @property
    def csi(self) -> int:
        """Number of CSI camera connectors."""

    @property
    def dsi(self) -> int:
        """Number of DSI display connectors."""

pi_info Function

def pi_info(revision=None) -> PiBoardInfo:
    """
    Return board information for current or specified Pi revision.
    
    Parameters:
    - revision: str or None - Pi revision string or None for current Pi
    
    Returns:
    PiBoardInfo object for the specified Pi
    """

Device Configuration

Setting Pin Factory

# Global pin factory configuration
from gpiozero import Device
from gpiozero.pins.pigpio import PiGPIOFactory

Device.pin_factory = PiGPIOFactory()

Per-Device Pin Factory

# Individual device pin factory
from gpiozero import LED
from gpiozero.pins.native import NativeFactory

led = LED(17, pin_factory=NativeFactory())

Available Pin Factories

GPIO Zero includes several pin factory implementations:

Default Factory (Auto-Detection)

The default factory automatically selects the best available backend:

  1. lgpio - Preferred modern library
  2. RPi.GPIO - Classic library
  3. pigpio - High-performance library
  4. native - Pure Python fallback

Specific Factories

Native Factory

from gpiozero.pins.native import NativeFactory
Device.pin_factory = NativeFactory()

Pure Python implementation, works on any Pi but limited functionality.

RPi.GPIO Factory

from gpiozero.pins.rpigpio import RPiGPIOFactory  
Device.pin_factory = RPiGPIOFactory()

Uses RPi.GPIO library, good compatibility but limited PWM.

pigpio Factory

from gpiozero.pins.pigpio import PiGPIOFactory
Device.pin_factory = PiGPIOFactory()

High-performance library with accurate timing and hardware PWM.

lgpio Factory

from gpiozero.pins.lgpio import LGPIOFactory
Device.pin_factory = LGPIOFactory()

Modern replacement for pigpio with similar features.

Mock Factory

For testing and development without hardware:

from gpiozero.pins.mock import MockFactory
Device.pin_factory = MockFactory()

Usage Examples

Board Information

from gpiozero import Device

# Get current board info
board = Device.pin_factory.board_info
print(f"Board: {board.model}")
print(f"Revision: {board.revision}")
print(f"Memory: {board.memory}MB")

# Find pins by name
gpio17_pins = board.find_pin("GPIO17")
for header, pin_info in gpio17_pins:
    print(f"Pin {pin_info.number}: {pin_info.name}")

# List all pins
for pin_num, pin_info in board.pins.items():
    print(f"Pin {pin_num}: {pin_info.name}")

Pin Factory Selection

from gpiozero import LED, Device
from gpiozero.pins.pigpio import PiGPIOFactory
from gpiozero.pins.rpigpio import RPiGPIOFactory

# Set global pin factory
Device.pin_factory = PiGPIOFactory()

# All devices now use pigpio
led1 = LED(17)
led2 = LED(18)

# Override for specific device
led3 = LED(19, pin_factory=RPiGPIOFactory())

Remote GPIO

from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOFactory

# Connect to remote Pi
remote_factory = PiGPIOFactory(host='192.168.1.100', port=8888)
led = LED(17, pin_factory=remote_factory)

led.on()

Mock Pin Testing

from gpiozero import LED, Button
from gpiozero.pins.mock import MockFactory, MockPWMPin

# Set up mock factory
mock_factory = MockFactory()
Device.pin_factory = mock_factory

# Create devices (no hardware needed)
led = LED(17)
button = Button(2)

# Simulate hardware
mock_factory.pin(17).drive_high()  # Simulate LED on
mock_factory.pin(2).drive_low()    # Simulate button press

# Check device states
print(f"LED is {'on' if led.is_lit else 'off'}")
print(f"Button is {'pressed' if button.is_pressed else 'released'}")

Custom Pin Factory

from gpiozero.pins import Factory, Pin
from gpiozero import Device

class MyCustomFactory(Factory):
    def __init__(self):
        super().__init__()
        # Initialize custom hardware interface
        
    def pin(self, spec):
        # Return custom pin implementation
        return MyCustomPin(self, spec)
        
    def _get_board_info(self):
        # Return custom board information
        return my_board_info

# Use custom factory
Device.pin_factory = MyCustomFactory()

Pin Reservation

from gpiozero import LED, Device

# Create device (pins are automatically reserved)
led = LED(17)

# Manual pin reservation
factory = Device.pin_factory
factory.reserve_pins(led, 17, 18, 19)

# Check reservations
try:
    led2 = LED(17)  # This will fail - pin already reserved
except GPIOPinInUse:
    print("Pin 17 is already in use")

# Release reservations
led.close()  # Automatically releases pin 17
factory.release_pins(led, 18, 19)  # Manual release

SPI Configuration

from gpiozero import MCP3008

# Default SPI (port=0, device=0)
adc = MCP3008(channel=0)

# Custom SPI configuration
adc2 = MCP3008(channel=0, port=0, device=1)  # Use CE1 instead of CE0

# Access underlying SPI interface
spi = Device.pin_factory.spi(port=0, device=0)
response = spi.transfer([0x01, 0x80, 0x00])  # Raw SPI transfer
spi.close()

Install with Tessl CLI

npx tessl i tessl/pypi-gpiozero

docs

composite-devices.md

index.md

input-devices.md

output-devices.md

pin-factories.md

spi-devices.md

system-monitoring.md

tone-system.md

tools.md

tile.json