Add mock pins docs and tidy up some other bits of the pins docs
This commit is contained in:
Dave Jones
2017-07-14 15:11:59 +01:00
parent 4009bf39df
commit a0d784082d
10 changed files with 171 additions and 52 deletions

View File

@@ -135,36 +135,22 @@ Like the ``GPIOZERO_PIN_FACTORY`` value, these can be exported from your
Sensible uses of multiple pin factories are given in :doc:`remote_gpio`. Sensible uses of multiple pin factories are given in :doc:`remote_gpio`.
RPi.GPIO Mock pins
======== =========
.. autoclass:: gpiozero.pins.rpigpio.RPiGPIOFactory There's also a :class:`gpiozero.pins.mock.MockFactory` which generates entirely
fake pins. This was originally intended for GPIO Zero developers who wish to
write tests for devices without having to have the physical device wired in to
their Pi. However, they have also proven relatively useful in developing GPIO
Zero scripts without having a Pi to hand. This pin factory will never be loaded
by default; it must be explicitly specified. For example:
.. autoclass:: gpiozero.pins.rpigpio.RPiGPIOPin .. literalinclude:: examples/mock_demo.py
Several sub-classes of mock pins exist for emulating various other things
RPIO (pins that do/don't support PWM, pins that are connected together, pins that
==== drive high after a delay, etc). Interested users are invited to read the GPIO
Zero test suite for further examples of usage.
.. autoclass:: gpiozero.pins.rpio.RPIOFactory
.. autoclass:: gpiozero.pins.rpio.RPIOPin
PiGPIO
======
.. autoclass:: gpiozero.pins.pigpio.PiGPIOFactory
.. autoclass:: gpiozero.pins.pigpio.PiGPIOPin
Native
======
.. autoclass:: gpiozero.pins.native.NativeFactory
.. autoclass:: gpiozero.pins.native.NativePin
Base classes Base classes
@@ -196,22 +182,62 @@ Base classes
:members: :members:
Utilities RPi.GPIO
========= ========
The pins module also contains a database of information about the various .. currentmodule:: gpiozero.pins.rpigpio
revisions of Raspberry Pi. This is used internally to raise warnings when
non-physical pins are used, or to raise exceptions when pull-downs are
requested on pins with physical pull-up resistors attached. The following
functions and classes can be used to query this database:
.. currentmodule:: gpiozero .. autoclass:: gpiozero.pins.rpigpio.RPiGPIOFactory
.. autofunction:: pi_info .. autoclass:: gpiozero.pins.rpigpio.RPiGPIOPin
.. autoclass:: PiBoardInfo
.. autoclass:: HeaderInfo RPIO
====
.. autoclass:: PinInfo .. currentmodule:: gpiozero.pins.rpio
.. autoclass:: gpiozero.pins.rpio.RPIOFactory
.. autoclass:: gpiozero.pins.rpio.RPIOPin
PiGPIO
======
.. currentmodule:: gpiozero.pins.pigpio
.. autoclass:: gpiozero.pins.pigpio.PiGPIOFactory
.. autoclass:: gpiozero.pins.pigpio.PiGPIOPin
Native
======
.. currentmodule:: gpiozero.pins.native
.. autoclass:: gpiozero.pins.native.NativeFactory
.. autoclass:: gpiozero.pins.native.NativePin
Mock
====
.. currentmodule:: gpiozero.pins.mock
.. autoclass:: gpiozero.pins.mock.MockFactory
:members:
.. autoclass:: gpiozero.pins.mock.MockPin
:members:
.. autoclass:: gpiozero.pins.mock.MockPWMPin
.. autoclass:: gpiozero.pins.mock.MockConnectedPin
.. autoclass:: gpiozero.pins.mock.MockChargingPin
.. autoclass:: gpiozero.pins.mock.MockTriggerPin

20
docs/api_utils.rst Normal file
View File

@@ -0,0 +1,20 @@
=========
Utilities
=========
.. currentmodule:: gpiozero
The GPIO Zero library also contains a database of information about the various
revisions of Raspberry Pi. This is used internally to raise warnings when
non-physical pins are used, or to raise exceptions when pull-downs are
requested on pins with physical pull-up resistors attached. The following
functions and classes can be used to query this database:
.. autofunction:: pi_info
.. autoclass:: PiBoardInfo
.. autoclass:: HeaderInfo
.. autoclass:: PinInfo

View File

@@ -0,0 +1,28 @@
from gpiozero.pins.mock import MockFactory
from gpiozero import Device, Button, LED
from time import sleep
# Set the default pin factory to a mock factory
Device.pin_factory = MockFactory()
# Construct a couple of devices attached to mock pins 16 and 17, and link the
# devices
led = LED(17)
btn = Button(16)
led.source = btn.values
# Here the button isn't "pushed" so the LED's value should be False
print(led.value)
# Get a reference to mock pin 16 (used by the button)
btn_pin = Device.pin_factory.pin(16)
# Drive the pin low (this is what would happen eletrically when the button is
# pushed)
btn_pin.drive_low()
sleep(0.1) # give source some time to re-read the button state
print(led.value)
btn_pin.drive_high()
sleep(0.1)
print(led.value)

View File

@@ -17,6 +17,7 @@ Table of Contents
api_generic api_generic
api_tools api_tools
api_pins api_pins
api_utils
api_exc api_exc
cli_tools cli_tools
source_values source_values

View File

@@ -30,15 +30,9 @@ from ..exc import (
class Factory(object): class Factory(object):
""" """
Generates pins, SPI, and I2C interfaces for devices. This is an abstract Generates pins and SPI interfaces for devices. This is an abstract
base class for pin factories. Descendents *must* override the following base class for pin factories. Descendents *may* override the following
methods: methods, if applicable:
* :meth:`_get_address`
* :meth:`pin_address`
Descendents *may* additionally override the following methods, if
applicable:
* :meth:`close` * :meth:`close`
* :meth:`reserve_pins` * :meth:`reserve_pins`
@@ -129,9 +123,6 @@ class Factory(object):
""" """
raise PinSPIUnsupported('SPI not supported by this pin factory') raise PinSPIUnsupported('SPI not supported by this pin factory')
def _get_address(self):
raise NotImplementedError
def _get_pi_info(self): def _get_pi_info(self):
return None return None

View File

@@ -216,7 +216,7 @@ class MockChargingPin(MockPin):
class MockTriggerPin(MockPin): class MockTriggerPin(MockPin):
""" """
This derivative of :class:`MockPin` is intended to be used with another This derivative of :class:`MockPin` is intended to be used with another
:class:`MockPin` to emulate a distance sensor. Set :attr:`echo_pin` to the :class:`MockPin` to emulate a distance sensor. Set *echo_pin* to the
corresponding pin instance. When this pin is driven high it will trigger corresponding pin instance. When this pin is driven high it will trigger
the echo pin to drive high for the echo time. the echo pin to drive high for the echo time.
""" """
@@ -410,6 +410,14 @@ class MockSPIDevice(object):
class MockFactory(LocalPiFactory): class MockFactory(LocalPiFactory):
"""
Factory for generating mock pins. The *revision* parameter specifies what
revision of Pi the mock factory pretends to be (this affects the result of
the :attr:`pi_info` attribute as well as where pull-ups are assumed to be).
The *pin_class* attribute specifies which mock pin class will be generated
by the :meth:`pin` method by default. This can be changed after
construction by modifying the :attr:`pin_class` attribute.
"""
def __init__( def __init__(
self, revision=os.getenv('GPIOZERO_MOCK_REVISION', 'a02082'), self, revision=os.getenv('GPIOZERO_MOCK_REVISION', 'a02082'),
pin_class=os.getenv('GPIOZERO_MOCK_PIN_CLASS', MockPin)): pin_class=os.getenv('GPIOZERO_MOCK_PIN_CLASS', MockPin)):
@@ -427,10 +435,22 @@ class MockFactory(LocalPiFactory):
return self._revision return self._revision
def reset(self): def reset(self):
"""
Clears the pins and reservations sets. This is primarily useful in
test suites to ensure the pin factory is back in a "clean" state before
the next set of tests are run.
"""
self.pins.clear() self.pins.clear()
self._reservations.clear() self._reservations.clear()
def pin(self, spec, pin_class=None, **kwargs): def pin(self, spec, pin_class=None, **kwargs):
"""
The pin method for :class:`MockFactory` additionally takes a *pin_class*
attribute which can be used to override the class' :attr:`pin_class`
attribute. Any additional keyword arguments will be passed along to the
pin constructor (useful with things like :class:`MockConnectedPin` which
expect to be constructed with another pin).
"""
if pin_class is None: if pin_class is None:
pin_class = self.pin_class pin_class = self.pin_class
n = self._to_gpio(spec) n = self._to_gpio(spec)

View File

@@ -178,6 +178,9 @@ class NativeFactory(LocalPiFactory):
class NativePin(LocalPiPin): class NativePin(LocalPiPin):
"""
Native pin implementation. See :class:`NativeFactory` for more information.
"""
GPIO_FUNCTIONS = { GPIO_FUNCTIONS = {
'input': 0b000, 'input': 0b000,
'output': 0b001, 'output': 0b001,

View File

@@ -133,6 +133,12 @@ class PiGPIOFactory(PiFactory):
class PiGPIOPin(PiPin): class PiGPIOPin(PiPin):
"""
Pin implementation for the `pigpio`_ library. See :class:`PiGPIOFactory`
for more information.
.. _pigpio: http://abyz.co.uk/rpi/pigpio/
"""
_CONNECTIONS = {} # maps (host, port) to (connection, pi_info) _CONNECTIONS = {} # maps (host, port) to (connection, pi_info)
GPIO_FUNCTIONS = { GPIO_FUNCTIONS = {
'input': pigpio.INPUT, 'input': pigpio.INPUT,
@@ -290,6 +296,12 @@ class PiGPIOPin(PiPin):
class PiGPIOHardwareSPI(SPI, Device): class PiGPIOHardwareSPI(SPI, Device):
"""
Hardware SPI implementation for the `pigpio`_ library. Uses the ``spi_*``
functions from the pigpio API.
.. _pigpio: http://abyz.co.uk/rpi/pigpio/
"""
def __init__(self, factory, port, device): def __init__(self, factory, port, device):
self._port = port self._port = port
self._device = device self._device = device
@@ -386,6 +398,12 @@ class PiGPIOHardwareSPI(SPI, Device):
class PiGPIOSoftwareSPI(SPI, Device): class PiGPIOSoftwareSPI(SPI, Device):
"""
Software SPI implementation for the `pigpio`_ library. Uses the ``bb_spi_*``
functions from the pigpio API.
.. _pigpio: http://abyz.co.uk/rpi/pigpio/
"""
def __init__(self, factory, clock_pin, mosi_pin, miso_pin, select_pin): def __init__(self, factory, clock_pin, mosi_pin, miso_pin, select_pin):
self._closed = True self._closed = True
self._select_pin = select_pin self._select_pin = select_pin

View File

@@ -58,6 +58,12 @@ class RPiGPIOFactory(LocalPiFactory):
class RPiGPIOPin(LocalPiPin): class RPiGPIOPin(LocalPiPin):
"""
Pin implementation for the `RPi.GPIO`_ library. See :class:`RPiGPIOFactory`
for more information.
.. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO
"""
GPIO_FUNCTIONS = { GPIO_FUNCTIONS = {
'input': GPIO.IN, 'input': GPIO.IN,
'output': GPIO.OUT, 'output': GPIO.OUT,

View File

@@ -64,6 +64,12 @@ class RPIOFactory(LocalPiFactory):
class RPIOPin(LocalPiPin): class RPIOPin(LocalPiPin):
"""
Pin implementation for the `RPIO`_ library. See :class:`RPIOFactory` for
more information.
.. _RPIO: https://pythonhosted.org/RPIO/
"""
GPIO_FUNCTIONS = { GPIO_FUNCTIONS = {
'input': RPIO.IN, 'input': RPIO.IN,
'output': RPIO.OUT, 'output': RPIO.OUT,