mirror of
https://github.com/KevinMidboe/python-gpiozero.git
synced 2025-10-29 17:50:37 +00:00
Merge pull request #569 from waveform80/pin-factory-docs
Fix #568, fix #572, fix #565
This commit is contained in:
@@ -127,44 +127,30 @@ Like the ``GPIOZERO_PIN_FACTORY`` value, these can be exported from your
|
|||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
The astute and mischievous reader may note that it is possible to mix
|
The astute and mischievous reader may note that it is possible to mix
|
||||||
strictly local pin implementations, e.g. using ``RPiGPIOPin`` for one pin,
|
factories, e.g. using ``RPiGPIOFactory`` for one pin, and ``NativeFactory``
|
||||||
and ``NativePin`` for another. This is unsupported, and if it results in
|
for another. This is unsupported, and if it results in your script
|
||||||
your script crashing, your components failing, or your Raspberry Pi turning
|
crashing, your components failing, or your Raspberry Pi turning into an
|
||||||
into an actual raspberry pie, you have only yourself to blame.
|
actual raspberry pie, you have only yourself to blame.
|
||||||
|
|
||||||
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
20
docs/api_utils.rst
Normal 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
|
||||||
|
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from signal import pause
|
from signal import pause
|
||||||
|
|
||||||
|
factory = PiGPIOFactory(host='192.168.1.3')
|
||||||
|
|
||||||
button = Button(2)
|
button = Button(2)
|
||||||
led = LED(PiGPIOPin(17, host='192.168.1.3'))
|
led = LED(17, pin_factory=factory)
|
||||||
|
|
||||||
led.source = button.values
|
led.source = button.values
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from gpiozero.tools import all_values
|
from gpiozero.tools import all_values
|
||||||
from signal import pause
|
from signal import pause
|
||||||
|
|
||||||
|
factory3 = PiGPIOFactory(host='192.168.1.3')
|
||||||
|
factory4 = PiGPIOFactory(host='192.168.1.4')
|
||||||
|
|
||||||
led = LED(17)
|
led = LED(17)
|
||||||
button_1 = Button(PiGPIOPin(17, host='192.168.1.3'))
|
button_1 = Button(17, pin_factory=factory3)
|
||||||
button_2 = Button(PiGPIOPin(17, host='192.168.1.4'))
|
button_2 = Button(17, pin_factory=factory4)
|
||||||
|
|
||||||
led.source = all_values(button_1.values, button_2.values)
|
led.source = all_values(button_1.values, button_2.values)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
led = LED(PiGPIOPin(17, host='192.168.1.3'))
|
factory = PiGPIOFactory(host='192.168.1.3')
|
||||||
|
led = LED(17, pin_factory=factory)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
led.on()
|
led.on()
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
led_1 = LED(PiGPIOPin(17, host='192.168.1.3'))
|
factory3 = PiGPIOFactory(host='192.168.1.3')
|
||||||
led_2 = LED(PiGPIOPin(17, host='192.168.1.4'))
|
factory4 = PiGPIOFactory(host='192.168.1.4')
|
||||||
|
led_1 = LED(17, pin_factory=factory3)
|
||||||
|
led_2 = LED(17, pin_factory=factory4)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
led_1.on()
|
led_1.on()
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
remote_factory = PiGPIOFactory(host='192.168.1.3')
|
||||||
led_1 = LED(17) # local pin
|
led_1 = LED(17) # local pin
|
||||||
led_2 = LED(PiGPIOPin(17, host='192.168.1.3')) # remote pin
|
led_2 = LED(17, pin_factory=remote_factory) # remote pin
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
led_1.on()
|
led_1.on()
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
from gpiozero.pins.rpigpio import RPiGPIOPin
|
from gpiozero.pins.rpigpio import RPiGPIOFactory
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
led_1 = LED(RPiGPIOPin(17)) # local pin
|
local_factory = RPiGPIOFactory()
|
||||||
|
led_1 = LED(17, pin_factory=local_factory) # local pin
|
||||||
led_2 = LED(17) # remote pin
|
led_2 = LED(17) # remote pin
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
factory3 = PiGPIOFactory(host='192.168.1.3')
|
||||||
|
factory4 = PiGPIOFactory(host='192.168.1.4')
|
||||||
|
|
||||||
led_1 = LED(17) # local pin
|
led_1 = LED(17) # local pin
|
||||||
led_2 = LED(PiGPIOPin(17, host='192.168.1.3')) # remote pin on one pi
|
led_2 = LED(17, pin_factory=factory3) # remote pin on one pi
|
||||||
led_3 = LED(PiGPIOPin(17, host='192.168.1.4')) # remote pin on another pi
|
led_3 = LED(17, pin_factory=factory4) # remote pin on another pi
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
led_1.on()
|
led_1.on()
|
||||||
|
|||||||
28
docs/examples/mock_demo.py
Normal file
28
docs/examples/mock_demo.py
Normal 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)
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from signal import pause
|
from signal import pause
|
||||||
|
|
||||||
led = LED(PiGPIOPin(17, host='raspberrypi.local'))
|
factory = PiGPIOFactory(host='raspberrypi.local')
|
||||||
|
led = LED(17, pin_factory=factory)
|
||||||
|
|
||||||
led.blink()
|
led.blink()
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
from gpiozero import MotionSensor
|
from gpiozero import MotionSensor
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from sense_hat import SenseHat
|
from sense_hat import SenseHat
|
||||||
|
|
||||||
pir = MotionSensor(PiGPIOPin(4, host='192.168.1.4')) # remote motion sensor
|
remote_factory = PiGPIOFactory(host='192.198.1.4')
|
||||||
|
pir = MotionSensor(4, pin_factory=remote_factory) # remote motion sensor
|
||||||
sense = SenseHat() # local sense hat
|
sense = SenseHat() # local sense hat
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
from gpiozero import LightSensor
|
from gpiozero import LightSensor
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from sense_hat import SenseHat
|
from sense_hat import SenseHat
|
||||||
|
|
||||||
light = LightSensor(PiGPIOPin(4, host='192.168.1.4')) # remote motion sensor
|
remote_factory = PiGPIOFactory(host='192.168.1.4')
|
||||||
|
light = LightSensor(4, pin_factory=remote_factory) # remote motion sensor
|
||||||
sense = SenseHat() # local sense hat
|
sense = SenseHat() # local sense hat
|
||||||
|
|
||||||
blue = (0, 0, 255)
|
blue = (0, 0, 255)
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ from gpiozero import TrafficHat
|
|||||||
from gpiozero.pins.pigpio import PiGPIOFactory
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
gpiozero.Device._set_pin_factory(PiGPIOFactory(host='192.168.1.3'))
|
gpiozero.Device.pin_factory = PiGPIOFactory(host='192.168.1.3')
|
||||||
th = TrafficHat() # traffic hat on 192.168.1.3 using remote pins
|
th = TrafficHat() # traffic hat on 192.168.1.3 using remote pins
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from gpiozero import TrafficHat
|
|||||||
from gpiozero.pins.pigpio import PiGPIOFactory
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
remote_factory = PiGPIOFactory(host='192.168.1.3')
|
||||||
|
|
||||||
th_1 = TrafficHat() # traffic hat using local pins
|
th_1 = TrafficHat() # traffic hat using local pins
|
||||||
gpiozero.Device._set_pin_factory(PiGPIOFactory(host='192.168.1.3'))
|
th_2 = TrafficHat(pin_factory=remote_factory) # traffic hat on 192.168.1.3 using remote pins
|
||||||
th_2 = TrafficHat() # traffic hat on 192.168.1.3 using remote pins
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ documentation page.
|
|||||||
|
|
||||||
One of the pin libraries supported, `pigpio`_, provides the ability to control
|
One of the pin libraries supported, `pigpio`_, provides the ability to control
|
||||||
GPIO pins remotely over the network, which means you can use GPIO Zero to
|
GPIO pins remotely over the network, which means you can use GPIO Zero to
|
||||||
control devices connected to a Raspberry Pi on the network. You can do this from
|
control devices connected to a Raspberry Pi on the network. You can do this
|
||||||
another Raspberry Pi, or even from a PC.
|
from another Raspberry Pi, or even from a PC.
|
||||||
|
|
||||||
See the :doc:`recipes_remote_gpio` page for examples on how remote pins can be
|
See the :doc:`recipes_remote_gpio` page for examples on how remote pins can be
|
||||||
used.
|
used.
|
||||||
@@ -22,8 +22,8 @@ Preparing the Raspberry Pi
|
|||||||
==========================
|
==========================
|
||||||
|
|
||||||
If you're using Raspbian Jessie (desktop - not Jessie Lite) then you have
|
If you're using Raspbian Jessie (desktop - not Jessie Lite) then you have
|
||||||
everything you need to use the remote GPIO feature. If you're using Jessie Lite,
|
everything you need to use the remote GPIO feature. If you're using Jessie
|
||||||
or another distribution, you'll need to install pigpio:
|
Lite, or another distribution, you'll need to install pigpio:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
@@ -52,7 +52,9 @@ example:
|
|||||||
$ sudo pigpiod -n localhost -n 192.168.1.65 # allow localhost and 192.168.1.65 only
|
$ sudo pigpiod -n localhost -n 192.168.1.65 # allow localhost and 192.168.1.65 only
|
||||||
|
|
||||||
You will need to launch the pigpio daemon every time you wish to use this
|
You will need to launch the pigpio daemon every time you wish to use this
|
||||||
feature. To automate running the daemon at boot time::
|
feature. To automate running the daemon at boot time:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
$ sudo systemctl enable pigpiod
|
$ sudo systemctl enable pigpiod
|
||||||
|
|
||||||
@@ -181,17 +183,18 @@ following:
|
|||||||
If you are running this from a PC (not a Raspberry Pi) with gpiozero and the
|
If you are running this from a PC (not a Raspberry Pi) with gpiozero and the
|
||||||
pigpio Python library installed, this will work with no further configuration.
|
pigpio Python library installed, this will work with no further configuration.
|
||||||
However, if you are running this from a Raspberry Pi, you will also need to
|
However, if you are running this from a Raspberry Pi, you will also need to
|
||||||
ensure the default pin factory is set to ``PiGPIOPin``. If ``RPi.GPIO`` is
|
ensure the default pin factory is set to ``PiGPIOFactory``. If ``RPi.GPIO`` is
|
||||||
installed, this will be selected as the default pin factory, so either uninstall
|
installed, this will be selected as the default pin factory, so either
|
||||||
it, or use another environment variable to set it to ``PiGPIOPin``:
|
uninstall it, or use another environment variable to set it to
|
||||||
|
``PiGPIOFactory``:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ GPIOZERO_PIN_FACTORY=pigpio PIGPIO_ADDR=192.168.1.3 python3 hello.py
|
$ GPIOZERO_PIN_FACTORY=pigpio PIGPIO_ADDR=192.168.1.3 python3 hello.py
|
||||||
|
|
||||||
This usage will set the pin factory to :class:`PiGPIOPin` with a default host of
|
This usage will set the pin factory to :class:`PiGPIOFactory` with a default
|
||||||
``192.168.1.3``. The pin factory can be changed inline in the code, as seen in
|
host of ``192.168.1.3``. The pin factory can be changed inline in the code, as
|
||||||
the following sections.
|
seen in the following sections.
|
||||||
|
|
||||||
With this usage, you can write gpiozero code like you would on a Raspberry Pi,
|
With this usage, you can write gpiozero code like you would on a Raspberry Pi,
|
||||||
with no modifications needed. For example:
|
with no modifications needed. For example:
|
||||||
@@ -218,9 +221,9 @@ Pin objects
|
|||||||
===========
|
===========
|
||||||
|
|
||||||
An alternative (or additional) method of configuring gpiozero objects to use
|
An alternative (or additional) method of configuring gpiozero objects to use
|
||||||
remote pins is to create instances of :class:PiGPIOPin objects, and
|
remote pins is to create instances of :class:`PiGPIOFactory` objects, and use
|
||||||
instantiating device objects with those pin objects, rather than just numbers.
|
them when instantiating device objects. For example, with no environment
|
||||||
For example, with no environment variables set:
|
variables set:
|
||||||
|
|
||||||
.. literalinclude:: examples/led_remote_1.py
|
.. literalinclude:: examples/led_remote_1.py
|
||||||
|
|
||||||
@@ -230,8 +233,8 @@ This allows devices on multiple Raspberry Pis to be used in the same script:
|
|||||||
|
|
||||||
You can, of course, continue to create gpiozero device objects as normal, and
|
You can, of course, continue to create gpiozero device objects as normal, and
|
||||||
create others using remote pins. For example, if run on a Raspberry Pi, the
|
create others using remote pins. For example, if run on a Raspberry Pi, the
|
||||||
following script will flash an LED on the host Pi, and also on another Pi on the
|
following script will flash an LED on the host Pi, and also on another Pi on
|
||||||
network:
|
the network:
|
||||||
|
|
||||||
.. literalinclude:: examples/led_remote_3.py
|
.. literalinclude:: examples/led_remote_3.py
|
||||||
|
|
||||||
@@ -249,7 +252,8 @@ Note that these examples use the :class:`LED` class, which takes a ``pin``
|
|||||||
argument to initialise. Some classes, particularly those representing HATs and
|
argument to initialise. Some classes, particularly those representing HATs and
|
||||||
other add-on boards, do not require their pin numbers to be specified. However,
|
other add-on boards, do not require their pin numbers to be specified. However,
|
||||||
it is still possible to use remote pins with these devices, either using
|
it is still possible to use remote pins with these devices, either using
|
||||||
environment variables, or by using :meth:`~Device._set_pin_factory`:
|
environment variables, :attr:`Device.pin_factory`, or the ``pin_factory``
|
||||||
|
keyword argument:
|
||||||
|
|
||||||
.. literalinclude:: examples/traffichat_remote_1.py
|
.. literalinclude:: examples/traffichat_remote_1.py
|
||||||
|
|
||||||
@@ -299,10 +303,10 @@ from the computer, referencing the host by its hostname, like so:
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
When running code directly on a Raspberry Pi, any pin type can be used
|
When running code directly on a Raspberry Pi, any pin factory can be used
|
||||||
(assuming the relevant library is installed), but when a device is used
|
(assuming the relevant library is installed), but when a device is used
|
||||||
remotely, only :class:`PiGPIOPin` can be used, as pigpio is the only pin
|
remotely, only :class:`PiGPIOFactory` can be used, as pigpio is the only
|
||||||
library which supports remote GPIO.
|
pin library which supports remote GPIO.
|
||||||
|
|
||||||
|
|
||||||
.. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO
|
.. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ def _default_pin_factory(name=os.getenv('GPIOZERO_PIN_FACTORY', None)):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
PinFactoryFallback(
|
PinFactoryFallback(
|
||||||
'Failed to load factory %s: %s' % (name, str(e))))
|
'Falling back from %s: %s' % (name, str(e))))
|
||||||
raise BadPinFactory('Unable to load any default pin factory!')
|
raise BadPinFactory('Unable to load any default pin factory!')
|
||||||
else:
|
else:
|
||||||
for factory in pkg_resources.iter_entry_points(group, name.lower()):
|
for factory in pkg_resources.iter_entry_points(group, name.lower()):
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -161,10 +161,11 @@ class NativeFactory(LocalPiFactory):
|
|||||||
|
|
||||||
You can construct native pin instances manually like so::
|
You can construct native pin instances manually like so::
|
||||||
|
|
||||||
from gpiozero.pins.native import NativePin
|
from gpiozero.pins.native import NativeFactory
|
||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
|
|
||||||
led = LED(NativePin(12))
|
factory = NativeFactory()
|
||||||
|
led = LED(12, pin_factory=factory)
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(NativeFactory, self).__init__()
|
super(NativeFactory, self).__init__()
|
||||||
@@ -177,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,
|
||||||
|
|||||||
@@ -238,11 +238,11 @@ class PiPin(Pin):
|
|||||||
self._when_changed = None
|
self._when_changed = None
|
||||||
self._number = number
|
self._number = number
|
||||||
try:
|
try:
|
||||||
factory.pi_info.physical_pin('GPIO%d' % self.number)
|
factory.pi_info.physical_pin(repr(self))
|
||||||
except PinNoPins:
|
except PinNoPins:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
PinNonPhysical(
|
PinNonPhysical(
|
||||||
'no physical pins exist for GPIO%d' % self.number))
|
'no physical pins exist for %s' % repr(self)))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def number(self):
|
def number(self):
|
||||||
|
|||||||
@@ -46,20 +46,21 @@ class PiGPIOFactory(PiFactory):
|
|||||||
|
|
||||||
You can construct pigpio pins manually like so::
|
You can construct pigpio pins manually like so::
|
||||||
|
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
|
|
||||||
led = LED(PiGPIOPin(12))
|
factory = PiGPIOFactory()
|
||||||
|
led = LED(12, pin_factory=factory)
|
||||||
|
|
||||||
This is particularly useful for controlling pins on a remote machine. To
|
This is particularly useful for controlling pins on a remote machine. To
|
||||||
accomplish this simply specify the host (and optionally port) when
|
accomplish this simply specify the host (and optionally port) when
|
||||||
constructing the pin::
|
constructing the pin::
|
||||||
|
|
||||||
from gpiozero.pins.pigpio import PiGPIOPin
|
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
from signal import pause
|
|
||||||
|
|
||||||
led = LED(PiGPIOPin(12, host='192.168.0.2'))
|
factory = PiGPIOFactory(host='192.168.0.2')
|
||||||
|
led = LED(12, pin_factory=factory)
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@@ -132,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,
|
||||||
@@ -162,7 +169,7 @@ class PiGPIOPin(PiPin):
|
|||||||
|
|
||||||
def __init__(self, factory, number):
|
def __init__(self, factory, number):
|
||||||
super(PiGPIOPin, self).__init__(factory, number)
|
super(PiGPIOPin, self).__init__(factory, number)
|
||||||
self._pull = 'up' if factory.pi_info.pulled_up(repr(self)) else 'floating'
|
self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating'
|
||||||
self._pwm = False
|
self._pwm = False
|
||||||
self._bounce = None
|
self._bounce = None
|
||||||
self._callback = None
|
self._callback = None
|
||||||
@@ -289,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
|
||||||
@@ -385,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
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ class RPiGPIOFactory(LocalPiFactory):
|
|||||||
from gpiozero.pins.rpigpio import RPiGPIOFactory
|
from gpiozero.pins.rpigpio import RPiGPIOFactory
|
||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
|
|
||||||
led = LED(RPiGPIOPin(12))
|
factory = RPiGPIOFactory()
|
||||||
|
led = LED(12, pin_factory=factory)
|
||||||
|
|
||||||
.. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO
|
.. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO
|
||||||
"""
|
"""
|
||||||
@@ -57,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,
|
||||||
@@ -85,7 +92,7 @@ class RPiGPIOPin(LocalPiPin):
|
|||||||
|
|
||||||
def __init__(self, factory, number):
|
def __init__(self, factory, number):
|
||||||
super(RPiGPIOPin, self).__init__(factory, number)
|
super(RPiGPIOPin, self).__init__(factory, number)
|
||||||
self._pull = 'up' if self.factory.pi_info.pulled_up(self.address[-1]) else 'floating'
|
self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating'
|
||||||
self._pwm = None
|
self._pwm = None
|
||||||
self._frequency = None
|
self._frequency = None
|
||||||
self._duty_cycle = None
|
self._duty_cycle = None
|
||||||
@@ -103,7 +110,7 @@ class RPiGPIOPin(LocalPiPin):
|
|||||||
GPIO.setup(self.number, GPIO.OUT, initial=state)
|
GPIO.setup(self.number, GPIO.OUT, initial=state)
|
||||||
|
|
||||||
def input_with_pull(self, pull):
|
def input_with_pull(self, pull):
|
||||||
if pull != 'up' and self.factory.pi_info.pulled_up(self.address[-1]):
|
if pull != 'up' and self.factory.pi_info.pulled_up(repr(self)):
|
||||||
raise PinFixedPull('%r has a physical pull-up resistor' % self)
|
raise PinFixedPull('%r has a physical pull-up resistor' % self)
|
||||||
try:
|
try:
|
||||||
GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[pull])
|
GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[pull])
|
||||||
@@ -149,7 +156,7 @@ class RPiGPIOPin(LocalPiPin):
|
|||||||
def _set_pull(self, value):
|
def _set_pull(self, value):
|
||||||
if self.function != 'input':
|
if self.function != 'input':
|
||||||
raise PinFixedPull('cannot set pull on non-input pin %r' % self)
|
raise PinFixedPull('cannot set pull on non-input pin %r' % self)
|
||||||
if value != 'up' and self.factory.pi_info.pulled_up(self.address[-1]):
|
if value != 'up' and self.factory.pi_info.pulled_up(repr(self)):
|
||||||
raise PinFixedPull('%r has a physical pull-up resistor' % self)
|
raise PinFixedPull('%r has a physical pull-up resistor' % self)
|
||||||
try:
|
try:
|
||||||
GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[value])
|
GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[value])
|
||||||
|
|||||||
@@ -40,10 +40,11 @@ class RPIOFactory(LocalPiFactory):
|
|||||||
|
|
||||||
You can construct RPIO pins manually like so::
|
You can construct RPIO pins manually like so::
|
||||||
|
|
||||||
from gpiozero.pins.rpio import RPIOPin
|
from gpiozero.pins.rpio import RPIOFactory
|
||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
|
|
||||||
led = LED(RPIOPin(12))
|
factory = RPIOFactory()
|
||||||
|
led = LED(12, pin_factory=factory)
|
||||||
|
|
||||||
.. _RPIO: https://pythonhosted.org/RPIO/
|
.. _RPIO: https://pythonhosted.org/RPIO/
|
||||||
"""
|
"""
|
||||||
@@ -63,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,
|
||||||
@@ -80,7 +87,7 @@ class RPIOPin(LocalPiPin):
|
|||||||
|
|
||||||
def __init__(self, factory, number):
|
def __init__(self, factory, number):
|
||||||
super(RPIOPin, self).__init__(factory, number)
|
super(RPIOPin, self).__init__(factory, number)
|
||||||
self._pull = 'up' if self.factory.pi_info.pulled_up(self.address[-1]) else 'floating'
|
self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating'
|
||||||
self._pwm = False
|
self._pwm = False
|
||||||
self._duty_cycle = None
|
self._duty_cycle = None
|
||||||
self._bounce = None
|
self._bounce = None
|
||||||
@@ -138,7 +145,7 @@ class RPIOPin(LocalPiPin):
|
|||||||
def _set_pull(self, value):
|
def _set_pull(self, value):
|
||||||
if self.function != 'input':
|
if self.function != 'input':
|
||||||
raise PinFixedPull('cannot set pull on non-input pin %r' % self)
|
raise PinFixedPull('cannot set pull on non-input pin %r' % self)
|
||||||
if value != 'up' and self.factory.pi_info.pulled_up(self.address[-1]):
|
if value != 'up' and self.factory.pi_info.pulled_up(repr(self)):
|
||||||
raise PinFixedPull('%r has a physical pull-up resistor' % self)
|
raise PinFixedPull('%r has a physical pull-up resistor' % self)
|
||||||
try:
|
try:
|
||||||
RPIO.setup(self.number, RPIO.IN, self.GPIO_PULL_UPS[value])
|
RPIO.setup(self.number, RPIO.IN, self.GPIO_PULL_UPS[value])
|
||||||
|
|||||||
Reference in New Issue
Block a user