mirror of
https://github.com/KevinMidboe/python-gpiozero.git
synced 2025-10-29 17:50:37 +00:00
@@ -18,21 +18,21 @@ individually.
|
|||||||
LEDBoard
|
LEDBoard
|
||||||
========
|
========
|
||||||
|
|
||||||
.. autoclass:: LEDBoard(\*pins, pwm=False, active_high=True, initial_value=False, \*\*named_pins)
|
.. autoclass:: LEDBoard(\*pins, pwm=False, active_high=True, initial_value=False, pin_factory=None, \*\*named_pins)
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
LEDBarGraph
|
LEDBarGraph
|
||||||
===========
|
===========
|
||||||
|
|
||||||
.. autoclass:: LEDBarGraph(\*pins, pwm=False, active_high=True, initial_value=0)
|
.. autoclass:: LEDBarGraph(\*pins, pwm=False, active_high=True, initial_value=0, pin_factory=None)
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
ButtonBoard
|
ButtonBoard
|
||||||
===========
|
===========
|
||||||
|
|
||||||
.. autoclass:: ButtonBoard(\*pins, pull_up=True, bounce_time=None, hold_time=1, hold_repeat=False, \*\*named_pins)
|
.. autoclass:: ButtonBoard(\*pins, pull_up=True, bounce_time=None, hold_time=1, hold_repeat=False, pin_factory=None, \*\*named_pins)
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
@@ -130,14 +130,14 @@ Energenie
|
|||||||
StatusZero
|
StatusZero
|
||||||
==========
|
==========
|
||||||
|
|
||||||
.. autoclass:: StatusZero
|
.. autoclass:: StatusZero(\*labels, pwm=False, active_high=True, initial_value=False, pin_factory=None)
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
StatusBoard
|
StatusBoard
|
||||||
===========
|
===========
|
||||||
|
|
||||||
.. autoclass:: StatusBoard
|
.. autoclass:: StatusBoard(\*labels, pwm=False, active_high=True, initial_value=False, pin_factory=None)
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
@@ -168,17 +168,17 @@ to construct classes for their own devices.
|
|||||||
LEDCollection
|
LEDCollection
|
||||||
=============
|
=============
|
||||||
|
|
||||||
.. autoclass:: LEDCollection
|
.. autoclass:: LEDCollection(\*pins, pwm=False, active_high=True, initial_value=False, pin_factory=None, \*\*named_pins)
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
CompositeOutputDevice
|
CompositeOutputDevice
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
.. autoclass:: CompositeOutputDevice(\*args, _order=None, \*\*kwargs)
|
.. autoclass:: CompositeOutputDevice(\*args, _order=None, pin_factory=None, \*\*kwargs)
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
CompositeDevice
|
CompositeDevice
|
||||||
===============
|
===============
|
||||||
|
|
||||||
.. autoclass:: CompositeDevice(\*args, _order=None, \*\*kwargs)
|
.. autoclass:: CompositeDevice(\*args, _order=None, pin_factory=None, \*\*kwargs)
|
||||||
:members:
|
:members:
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ are represented in purple, while abstract classes are shaded lighter):
|
|||||||
Device
|
Device
|
||||||
======
|
======
|
||||||
|
|
||||||
.. autoclass:: Device
|
.. autoclass:: Device(\*, pin_factory=None)
|
||||||
:members: close, closed, value, is_active
|
:members: close, closed, value, is_active
|
||||||
|
|
||||||
ValuesMixin
|
ValuesMixin
|
||||||
|
|||||||
@@ -16,35 +16,35 @@ everyday components. Components must be wired up correctly before use in code.
|
|||||||
Button
|
Button
|
||||||
======
|
======
|
||||||
|
|
||||||
.. autoclass:: Button(pin, pull_up=True, bounce_time=None, hold_time=1, hold_repeat=False)
|
.. autoclass:: Button(pin, \*, pull_up=True, bounce_time=None, hold_time=1, hold_repeat=False, pin_factory=None)
|
||||||
:members: wait_for_press, wait_for_release, pin, is_pressed, is_held, hold_time, held_time, hold_repeat, pull_up, when_pressed, when_released, when_held
|
:members: wait_for_press, wait_for_release, pin, is_pressed, is_held, hold_time, held_time, hold_repeat, pull_up, when_pressed, when_released, when_held
|
||||||
|
|
||||||
|
|
||||||
Line Sensor (TRCT5000)
|
Line Sensor (TRCT5000)
|
||||||
======================
|
======================
|
||||||
|
|
||||||
.. autoclass:: LineSensor(pin, queue_len=5, sample_rate=100, threshold=0.5, partial=False)
|
.. autoclass:: LineSensor(pin, \*, queue_len=5, sample_rate=100, threshold=0.5, partial=False, pin_factory=None)
|
||||||
:members: wait_for_line, wait_for_no_line, pin, line_detected, when_line, when_no_line
|
:members: wait_for_line, wait_for_no_line, pin, line_detected, when_line, when_no_line
|
||||||
|
|
||||||
|
|
||||||
Motion Sensor (D-SUN PIR)
|
Motion Sensor (D-SUN PIR)
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
.. autoclass:: MotionSensor(pin, queue_len=1, sample_rate=10, threshold=0.5, partial=False)
|
.. autoclass:: MotionSensor(pin, \*, queue_len=1, sample_rate=10, threshold=0.5, partial=False, pin_factory=None)
|
||||||
:members: wait_for_motion, wait_for_no_motion, pin, motion_detected, when_motion, when_no_motion
|
:members: wait_for_motion, wait_for_no_motion, pin, motion_detected, when_motion, when_no_motion
|
||||||
|
|
||||||
|
|
||||||
Light Sensor (LDR)
|
Light Sensor (LDR)
|
||||||
==================
|
==================
|
||||||
|
|
||||||
.. autoclass:: LightSensor(pin, queue_len=5, charge_time_limit=0.01, threshold=0.1, partial=False)
|
.. autoclass:: LightSensor(pin, \*, queue_len=5, charge_time_limit=0.01, threshold=0.1, partial=False, pin_factory=None)
|
||||||
:members: wait_for_light, wait_for_dark, pin, light_detected, when_light, when_dark
|
:members: wait_for_light, wait_for_dark, pin, light_detected, when_light, when_dark
|
||||||
|
|
||||||
|
|
||||||
Distance Sensor (HC-SR04)
|
Distance Sensor (HC-SR04)
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
.. autoclass:: DistanceSensor(echo, trigger, queue_len=30, max_distance=1, threshold_distance=0.3, partial=False)
|
.. autoclass:: DistanceSensor(echo, trigger, \*, queue_len=30, max_distance=1, threshold_distance=0.3, partial=False, pin_factory=None)
|
||||||
:members: wait_for_in_range, wait_for_out_of_range, trigger, echo, when_in_range, when_out_of_range, max_distance, distance, threshold_distance
|
:members: wait_for_in_range, wait_for_out_of_range, trigger, echo, when_in_range, when_out_of_range, max_distance, distance, threshold_distance
|
||||||
|
|
||||||
Base Classes
|
Base Classes
|
||||||
@@ -63,24 +63,24 @@ to construct classes for their own devices.
|
|||||||
DigitalInputDevice
|
DigitalInputDevice
|
||||||
==================
|
==================
|
||||||
|
|
||||||
.. autoclass:: DigitalInputDevice(pin, pull_up=False, bounce_time=None)
|
.. autoclass:: DigitalInputDevice(pin, \*, pull_up=False, bounce_time=None, pin_factory=None)
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
SmoothedInputDevice
|
SmoothedInputDevice
|
||||||
===================
|
===================
|
||||||
|
|
||||||
.. autoclass:: SmoothedInputDevice
|
.. autoclass:: SmoothedInputDevice(pin, \*, pull_up=False, threshold=0.5, queue_len=5, sample_wait=0.0, partial=False, pin_factory=None)
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
InputDevice
|
InputDevice
|
||||||
===========
|
===========
|
||||||
|
|
||||||
.. autoclass:: InputDevice(pin, pull_up=False)
|
.. autoclass:: InputDevice(pin, \*, pull_up=False, pin_factory=None)
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
GPIODevice
|
GPIODevice
|
||||||
==========
|
==========
|
||||||
|
|
||||||
.. autoclass:: GPIODevice(pin)
|
.. autoclass:: GPIODevice(pin, pin_factory=None)
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
|||||||
@@ -16,44 +16,44 @@ everyday components. Components must be wired up correctly before use in code.
|
|||||||
LED
|
LED
|
||||||
===
|
===
|
||||||
|
|
||||||
.. autoclass:: LED(pin, active_high=True, initial_value=False)
|
.. autoclass:: LED(pin, \*, active_high=True, initial_value=False, pin_factory=None)
|
||||||
:members: on, off, toggle, blink, pin, is_lit
|
:members: on, off, toggle, blink, pin, is_lit
|
||||||
|
|
||||||
PWMLED
|
PWMLED
|
||||||
======
|
======
|
||||||
|
|
||||||
.. autoclass:: PWMLED(pin, active_high=True, initial_value=0, frequency=100)
|
.. autoclass:: PWMLED(pin, \*, active_high=True, initial_value=0, frequency=100, pin_factory=None)
|
||||||
:members: on, off, toggle, blink, pulse, pin, is_lit, value
|
:members: on, off, toggle, blink, pulse, pin, is_lit, value
|
||||||
|
|
||||||
RGBLED
|
RGBLED
|
||||||
======
|
======
|
||||||
|
|
||||||
.. autoclass:: RGBLED(red, green, blue, active_high=True, initial_value=(0, 0, 0), pwm=True)
|
.. autoclass:: RGBLED(red, green, blue, \*, active_high=True, initial_value=(0, 0, 0), pwm=True, pin_factory=None)
|
||||||
:members: on, off, toggle, blink, pulse, red, green, blue, is_lit, color
|
:members: on, off, toggle, blink, pulse, red, green, blue, is_lit, color
|
||||||
|
|
||||||
Buzzer
|
Buzzer
|
||||||
======
|
======
|
||||||
|
|
||||||
.. autoclass:: Buzzer(pin, active_high=True, initial_value=False)
|
.. autoclass:: Buzzer(pin, \*, active_high=True, initial_value=False, pin_factory=None)
|
||||||
:members: on, off, toggle, beep, pin, is_active
|
:members: on, off, toggle, beep, pin, is_active
|
||||||
|
|
||||||
Motor
|
Motor
|
||||||
=====
|
=====
|
||||||
|
|
||||||
.. autoclass:: Motor(forward, backward, pwm=True)
|
.. autoclass:: Motor(forward, backward, \*, pwm=True, pin_factory=None)
|
||||||
:members: forward, backward, stop
|
:members: forward, backward, stop
|
||||||
|
|
||||||
Servo
|
Servo
|
||||||
=====
|
=====
|
||||||
|
|
||||||
.. autoclass:: Servo(pin, initial_value=0, min_pulse_width=1/1000, max_pulse_width=2/1000, frame_width=20/1000)
|
.. autoclass:: Servo(pin, \*, initial_value=0, min_pulse_width=1/1000, max_pulse_width=2/1000, frame_width=20/1000, pin_factory=None)
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
AngularServo
|
AngularServo
|
||||||
============
|
============
|
||||||
|
|
||||||
.. autoclass:: AngularServo(pin, initial_angle=0, min_angle=-90, max_angle=90, min_pulse_width=1/1000, max_pulse_width=2/1000, frame_width=20/1000)
|
.. autoclass:: AngularServo(pin, \*, initial_angle=0, min_angle=-90, max_angle=90, min_pulse_width=1/1000, max_pulse_width=2/1000, frame_width=20/1000, pin_factory=None)
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
@@ -73,25 +73,25 @@ to construct classes for their own devices.
|
|||||||
DigitalOutputDevice
|
DigitalOutputDevice
|
||||||
===================
|
===================
|
||||||
|
|
||||||
.. autoclass:: DigitalOutputDevice(pin, active_high=True, initial_value=False)
|
.. autoclass:: DigitalOutputDevice(pin, \*, active_high=True, initial_value=False, pin_factory=None)
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
PWMOutputDevice
|
PWMOutputDevice
|
||||||
===============
|
===============
|
||||||
|
|
||||||
.. autoclass:: PWMOutputDevice(pin, active_high=True, initial_value=0, frequency=100)
|
.. autoclass:: PWMOutputDevice(pin, \*, active_high=True, initial_value=0, frequency=100, pin_factory=None)
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
OutputDevice
|
OutputDevice
|
||||||
============
|
============
|
||||||
|
|
||||||
.. autoclass:: OutputDevice(pin, active_high=True, initial_value=False)
|
.. autoclass:: OutputDevice(pin, \*, active_high=True, initial_value=False, pin_factory=None)
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
GPIODevice
|
GPIODevice
|
||||||
==========
|
==========
|
||||||
|
|
||||||
.. autoclass:: GPIODevice(pin)
|
.. autoclass:: GPIODevice(pin, \*, pin_factory=None)
|
||||||
:members:
|
:members:
|
||||||
:noindex:
|
:noindex:
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,23 @@ are concerned with. However, some users may wish to take advantage of the
|
|||||||
capabilities of alternative GPIO implementations or (in future) use GPIO
|
capabilities of alternative GPIO implementations or (in future) use GPIO
|
||||||
extender chips. This is the purpose of the pins portion of the library.
|
extender chips. This is the purpose of the pins portion of the library.
|
||||||
|
|
||||||
When you construct a device, you pass in a pin specification. However, what the
|
When you construct a device, you pass in a pin specification. This is passed to
|
||||||
library actually expects is a :class:`Pin` implementation. If it finds anything
|
a pin :class:`Factory` which turns it into a :class:`Pin` implementation. The
|
||||||
else, it uses the existing ``Device.pin_factory`` to construct a :class:`Pin`
|
default factory can be queried (and changed) with ``Device.pin_factory``, i.e.
|
||||||
implementation based on the specification.
|
the ``pin_factory`` attribute of the :class:`Device` class. However, all
|
||||||
|
classes accept a ``pin_factory`` keyword argument to their constructors
|
||||||
|
permitting the factory to be overridden on a per-device basis (the reason for
|
||||||
|
allowing per-device factories is made apparent later in the :doc:`remote_gpio`
|
||||||
|
chapter).
|
||||||
|
|
||||||
|
This is illustrated in the following flow-chart:
|
||||||
|
|
||||||
|
.. image:: images/device_pin_flowchart.*
|
||||||
|
|
||||||
|
The default factory is constructed when GPIO Zero is first imported; if no
|
||||||
|
default factory can be constructed (e.g. because no GPIO implementations are
|
||||||
|
installed, or all of them fail to load for whatever reason), an
|
||||||
|
:exc:`ImportError` will be raised.
|
||||||
|
|
||||||
Changing the pin factory
|
Changing the pin factory
|
||||||
========================
|
========================
|
||||||
@@ -24,7 +37,7 @@ The default pin factory can be replaced by specifying a value for the
|
|||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
pi@raspberrypi $ GPIOZERO_PIN_FACTORY=native python
|
$ GPIOZERO_PIN_FACTORY=native python
|
||||||
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
|
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
|
||||||
[GCC 4.9.1] on linux
|
[GCC 4.9.1] on linux
|
||||||
Type "help", "copyright", "credits" or "license" for more information.
|
Type "help", "copyright", "credits" or "license" for more information.
|
||||||
@@ -37,8 +50,8 @@ export this value:
|
|||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
pi@raspberrypi $ export GPIOZERO_PIN_FACTORY=native
|
$ export GPIOZERO_PIN_FACTORY=native
|
||||||
pi@raspberrypi $ python
|
$ python
|
||||||
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
|
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
|
||||||
[GCC 4.9.1] on linux
|
[GCC 4.9.1] on linux
|
||||||
Type "help", "copyright", "credits" or "license" for more information.
|
Type "help", "copyright", "credits" or "license" for more information.
|
||||||
@@ -46,7 +59,7 @@ export this value:
|
|||||||
>>> gpiozero.Device.pin_factory
|
>>> gpiozero.Device.pin_factory
|
||||||
<gpiozero.pins.native.NativeFactory object at 0x762c26b0>
|
<gpiozero.pins.native.NativeFactory object at 0x762c26b0>
|
||||||
>>> quit()
|
>>> quit()
|
||||||
pi@raspberrypi $ python
|
$ python
|
||||||
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
|
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
|
||||||
[GCC 4.9.1] on linux
|
[GCC 4.9.1] on linux
|
||||||
Type "help", "copyright", "credits" or "license" for more information.
|
Type "help", "copyright", "credits" or "license" for more information.
|
||||||
@@ -73,17 +86,30 @@ they are tried by default.
|
|||||||
| native | :class:`gpiozero.pins.native.NativeFactory` | :class:`gpiozero.pins.native.NativePin` |
|
| native | :class:`gpiozero.pins.native.NativeFactory` | :class:`gpiozero.pins.native.NativePin` |
|
||||||
+---------+-----------------------------------------------+-------------------------------------------+
|
+---------+-----------------------------------------------+-------------------------------------------+
|
||||||
|
|
||||||
If you need to change the default pin factory from within a script, set
|
If you need to change the default pin factory from within a script, either set
|
||||||
``Device.pin_factory`` to the new factory instance to use::
|
``Device.pin_factory`` to the new factory instance to use::
|
||||||
|
|
||||||
from gpiozero.pins.native import NativeFactory
|
from gpiozero.pins.native import NativeFactory
|
||||||
from gpiozero import *
|
from gpiozero import Device, LED
|
||||||
|
|
||||||
Device.pin_factory = NativeFactory()
|
Device.pin_factory = NativeFactory()
|
||||||
|
|
||||||
|
# These will now implicitly use NativePin instead of
|
||||||
|
# RPiGPIOPin
|
||||||
|
led1 = LED(16)
|
||||||
|
led2 = LED(17)
|
||||||
|
|
||||||
|
Or use the ``pin_factory`` keyword parameter mentioned above::
|
||||||
|
|
||||||
|
from gpiozero.pins.native import NativeFactory
|
||||||
from gpiozero import LED
|
from gpiozero import LED
|
||||||
|
|
||||||
# This will now use NativePin instead of RPiGPIOPin
|
my_factory = NativeFactory()
|
||||||
led = LED(16)
|
|
||||||
|
# This will use NativePin instead of RPiGPIOPin for led1
|
||||||
|
# but led2 will continue to use RPiGPIOPin
|
||||||
|
led1 = LED(16, pin_factory=my_factory)
|
||||||
|
led2 = LED(17)
|
||||||
|
|
||||||
Certain factories may take default information from additional sources.
|
Certain factories may take default information from additional sources.
|
||||||
For example, to default to creating pins with
|
For example, to default to creating pins with
|
||||||
@@ -100,11 +126,13 @@ 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 pin
|
The astute and mischievous reader may note that it is possible to mix
|
||||||
implementations, e.g. using ``RPiGPIOPin`` for one pin, and ``NativePin``
|
strictly local pin implementations, e.g. using ``RPiGPIOPin`` for one pin,
|
||||||
for another. This is unsupported, and if it results in your script
|
and ``NativePin`` for another. This is unsupported, and if it results in
|
||||||
crashing, your components failing, or your Raspberry Pi turning into an
|
your script crashing, your components failing, or your Raspberry Pi turning
|
||||||
actual raspberry pie, you have only yourself to blame.
|
into an actual raspberry pie, you have only yourself to blame.
|
||||||
|
|
||||||
|
Sensible uses of multiple pin factories are given in :doc:`remote_gpio`.
|
||||||
|
|
||||||
|
|
||||||
RPi.GPIO
|
RPi.GPIO
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ omit any arguments from either scheme. The defaults are:
|
|||||||
* *clock_pin* defaults to 11, *mosi_pin* defaults to 10, *miso_pin* defaults
|
* *clock_pin* defaults to 11, *mosi_pin* defaults to 10, *miso_pin* defaults
|
||||||
to 9, and *select_pin* defaults to 8.
|
to 9, and *select_pin* defaults to 8.
|
||||||
|
|
||||||
|
* As with other GPIO based devices you can optionally specify a *pin_factory*
|
||||||
|
argument overriding the default pin factory (see :doc:`api_pins` for more
|
||||||
|
information).
|
||||||
|
|
||||||
Hence the following constructors are all equivalent::
|
Hence the following constructors are all equivalent::
|
||||||
|
|
||||||
from gpiozero import MCP3008
|
from gpiozero import MCP3008
|
||||||
|
|||||||
19
docs/images/device_pin_flowchart.dot
Normal file
19
docs/images/device_pin_flowchart.dot
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/* vim: set et sw=4 sts=4: */
|
||||||
|
|
||||||
|
digraph device_pins {
|
||||||
|
graph [rankdir=TB];
|
||||||
|
node [shape=rect, shape=filled, fontname=Sans, fontsize=10];
|
||||||
|
edge [fontname=Sans, fontsize=10];
|
||||||
|
|
||||||
|
constructor [label="LED(pin_spec, ...,\npin_factory=None)"];
|
||||||
|
pin_factory_kwarg [shape=diamond,label="pin_factory == None?"];
|
||||||
|
default_factory [label="self.pin_factory = Device.pin_factory"];
|
||||||
|
override_factory [label="self.pin_factory = pin_factory"];
|
||||||
|
factory_pin [label="self.pin = self.pin_factory.pin(pin_spec)"];
|
||||||
|
|
||||||
|
constructor->pin_factory_kwarg;
|
||||||
|
pin_factory_kwarg->default_factory [label="yes"];
|
||||||
|
pin_factory_kwarg->override_factory [label="no"];
|
||||||
|
default_factory->factory_pin;
|
||||||
|
override_factory->factory_pin;
|
||||||
|
}
|
||||||
BIN
docs/images/device_pin_flowchart.pdf
Normal file
BIN
docs/images/device_pin_flowchart.pdf
Normal file
Binary file not shown.
BIN
docs/images/device_pin_flowchart.png
Normal file
BIN
docs/images/device_pin_flowchart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
66
docs/images/device_pin_flowchart.svg
Normal file
66
docs/images/device_pin_flowchart.svg
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||||
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
||||||
|
-->
|
||||||
|
<!-- Title: device_pins Pages: 1 -->
|
||||||
|
<svg width="372pt" height="273pt"
|
||||||
|
viewBox="0.00 0.00 371.50 273.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 269)">
|
||||||
|
<title>device_pins</title>
|
||||||
|
<polygon fill="white" stroke="none" points="-4,4 -4,-269 367.5,-269 367.5,4 -4,4"/>
|
||||||
|
<!-- constructor -->
|
||||||
|
<g id="node1" class="node"><title>constructor</title>
|
||||||
|
<polygon fill="none" stroke="black" points="243.5,-265 136.5,-265 136.5,-229 243.5,-229 243.5,-265"/>
|
||||||
|
<text text-anchor="middle" x="190" y="-250" font-family="Sans" font-size="10.00">LED(pin_spec, ...,</text>
|
||||||
|
<text text-anchor="middle" x="190" y="-239" font-family="Sans" font-size="10.00">pin_factory=None)</text>
|
||||||
|
</g>
|
||||||
|
<!-- pin_factory_kwarg -->
|
||||||
|
<g id="node2" class="node"><title>pin_factory_kwarg</title>
|
||||||
|
<polygon fill="none" stroke="black" points="190,-192 88.3711,-174 190,-156 291.629,-174 190,-192"/>
|
||||||
|
<text text-anchor="middle" x="190" y="-171.5" font-family="Sans" font-size="10.00">pin_factory == None?</text>
|
||||||
|
</g>
|
||||||
|
<!-- constructor->pin_factory_kwarg -->
|
||||||
|
<g id="edge1" class="edge"><title>constructor->pin_factory_kwarg</title>
|
||||||
|
<path fill="none" stroke="black" d="M190,-228.813C190,-220.789 190,-211.047 190,-202.069"/>
|
||||||
|
<polygon fill="black" stroke="black" points="193.5,-202.029 190,-192.029 186.5,-202.029 193.5,-202.029"/>
|
||||||
|
</g>
|
||||||
|
<!-- default_factory -->
|
||||||
|
<g id="node3" class="node"><title>default_factory</title>
|
||||||
|
<polygon fill="none" stroke="black" points="190,-109 0,-109 0,-73 190,-73 190,-109"/>
|
||||||
|
<text text-anchor="middle" x="95" y="-88.5" font-family="Sans" font-size="10.00">self.pin_factory = Device.pin_factory</text>
|
||||||
|
</g>
|
||||||
|
<!-- pin_factory_kwarg->default_factory -->
|
||||||
|
<g id="edge2" class="edge"><title>pin_factory_kwarg->default_factory</title>
|
||||||
|
<path fill="none" stroke="black" d="M173.452,-158.891C159.473,-146.971 139.158,-129.65 122.703,-115.621"/>
|
||||||
|
<polygon fill="black" stroke="black" points="124.861,-112.861 114.98,-109.036 120.319,-118.187 124.861,-112.861"/>
|
||||||
|
<text text-anchor="middle" x="157.5" y="-130" font-family="Sans" font-size="10.00">yes</text>
|
||||||
|
</g>
|
||||||
|
<!-- override_factory -->
|
||||||
|
<g id="node4" class="node"><title>override_factory</title>
|
||||||
|
<polygon fill="none" stroke="black" points="363.5,-109 208.5,-109 208.5,-73 363.5,-73 363.5,-109"/>
|
||||||
|
<text text-anchor="middle" x="286" y="-88.5" font-family="Sans" font-size="10.00">self.pin_factory = pin_factory</text>
|
||||||
|
</g>
|
||||||
|
<!-- pin_factory_kwarg->override_factory -->
|
||||||
|
<g id="edge3" class="edge"><title>pin_factory_kwarg->override_factory</title>
|
||||||
|
<path fill="none" stroke="black" d="M206.722,-158.891C220.849,-146.971 241.377,-129.65 258.005,-115.621"/>
|
||||||
|
<polygon fill="black" stroke="black" points="260.424,-118.16 265.809,-109.036 255.909,-112.81 260.424,-118.16"/>
|
||||||
|
<text text-anchor="middle" x="250.5" y="-130" font-family="Sans" font-size="10.00">no</text>
|
||||||
|
</g>
|
||||||
|
<!-- factory_pin -->
|
||||||
|
<g id="node5" class="node"><title>factory_pin</title>
|
||||||
|
<polygon fill="none" stroke="black" points="311,-36 111,-36 111,-0 311,-0 311,-36"/>
|
||||||
|
<text text-anchor="middle" x="211" y="-15.5" font-family="Sans" font-size="10.00">self.pin = self.pin_factory.pin(pin_spec)</text>
|
||||||
|
</g>
|
||||||
|
<!-- default_factory->factory_pin -->
|
||||||
|
<g id="edge4" class="edge"><title>default_factory->factory_pin</title>
|
||||||
|
<path fill="none" stroke="black" d="M122.785,-72.9937C138.167,-63.5785 157.484,-51.7554 174.117,-41.5748"/>
|
||||||
|
<polygon fill="black" stroke="black" points="176.338,-44.3193 183.04,-36.1136 172.683,-38.3489 176.338,-44.3193"/>
|
||||||
|
</g>
|
||||||
|
<!-- override_factory->factory_pin -->
|
||||||
|
<g id="edge5" class="edge"><title>override_factory->factory_pin</title>
|
||||||
|
<path fill="none" stroke="black" d="M267.845,-72.8129C258.448,-63.9174 246.82,-52.9094 236.533,-43.1717"/>
|
||||||
|
<polygon fill="black" stroke="black" points="238.656,-40.3619 228.988,-36.0288 233.844,-45.4454 238.656,-40.3619"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 36 KiB |
@@ -9,42 +9,58 @@ operating systems, including for PCs using the :doc:`remote_gpio` feature.
|
|||||||
Raspberry Pi
|
Raspberry Pi
|
||||||
============
|
============
|
||||||
|
|
||||||
First, update your repositories list::
|
First, update your repositories list:
|
||||||
|
|
||||||
sudo apt update
|
.. code-block:: console
|
||||||
|
|
||||||
Then install the package for Python 3::
|
pi@raspberrypi:~$ sudo apt update
|
||||||
|
|
||||||
sudo apt install python3-gpiozero
|
Then install the package for Python 3:
|
||||||
|
|
||||||
or Python 2::
|
.. code-block:: console
|
||||||
|
|
||||||
sudo apt install python-gpiozero
|
pi@raspberrypi:~$ sudo apt install python3-gpiozero
|
||||||
|
|
||||||
|
or Python 2:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
pi@raspberrypi:~$ sudo apt install python-gpiozero
|
||||||
|
|
||||||
Linux
|
Linux
|
||||||
=====
|
=====
|
||||||
|
|
||||||
First, update your distribution's repositories list. For example::
|
First, update your distribution's repositories list. For example:
|
||||||
|
|
||||||
sudo apt update
|
.. code-block:: console
|
||||||
|
|
||||||
Then install pip for Python 3::
|
$ sudo apt update
|
||||||
|
|
||||||
sudo apt install python3-pip
|
Then install pip for Python 3:
|
||||||
|
|
||||||
or Python 3::
|
.. code-block:: console
|
||||||
|
|
||||||
sudo apt install python-pip
|
$ sudo apt install python3-pip
|
||||||
|
|
||||||
|
or Python 3:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ sudo apt install python-pip
|
||||||
|
|
||||||
(Alternatively, install pip with `get-pip`_.)
|
(Alternatively, install pip with `get-pip`_.)
|
||||||
|
|
||||||
Next, install gpiozero for Python 3::
|
Next, install gpiozero for Python 3:
|
||||||
|
|
||||||
sudo pip3 install gpiozero
|
.. code-block:: console
|
||||||
|
|
||||||
or Python 2::
|
$ sudo pip3 install gpiozero
|
||||||
|
|
||||||
sudo pip install gpiozero
|
or Python 2:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ sudo pip install gpiozero
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@@ -55,24 +71,32 @@ or Python 2::
|
|||||||
Mac OS
|
Mac OS
|
||||||
======
|
======
|
||||||
|
|
||||||
First, install pip::
|
First, install pip:
|
||||||
|
|
||||||
???
|
.. code-block:: console
|
||||||
|
|
||||||
Next, install gpiozero with pip::
|
$ ???
|
||||||
|
|
||||||
pip install gpiozero
|
Next, install gpiozero with pip:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ pip install gpiozero
|
||||||
|
|
||||||
Windows
|
Windows
|
||||||
=======
|
=======
|
||||||
|
|
||||||
First, install pip::
|
First, install pip:
|
||||||
|
|
||||||
???
|
.. code-block:: doscon
|
||||||
|
|
||||||
Next, install gpiozero with pip::
|
C:\Users\user1> ???
|
||||||
|
|
||||||
pip install gpiozero
|
Next, install gpiozero with pip:
|
||||||
|
|
||||||
|
.. code-block:: doscon
|
||||||
|
|
||||||
|
C:\Users\user1> pip install gpiozero
|
||||||
|
|
||||||
|
|
||||||
.. _Raspbian Jessie: https://www.raspberrypi.org/downloads/raspbian/
|
.. _Raspbian Jessie: https://www.raspberrypi.org/downloads/raspbian/
|
||||||
|
|||||||
@@ -102,4 +102,4 @@ the ``pip`` utility. This can be done with the following command in Raspbian:
|
|||||||
Alternatively, install pip with `get-pip`_.
|
Alternatively, install pip with `get-pip`_.
|
||||||
|
|
||||||
|
|
||||||
.. _get_pip: https://pip.pypa.io/en/stable/installing/
|
.. _get-pip: https://pip.pypa.io/en/stable/installing/
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ functionality without the need to wire up your own LEDs (also useful because
|
|||||||
the power and activity LEDs are "known good").
|
the power and activity LEDs are "known good").
|
||||||
|
|
||||||
Firstly you need to disable the usual triggers for the built-in LEDs. This can
|
Firstly you need to disable the usual triggers for the built-in LEDs. This can
|
||||||
be done from the terminal with the following commands::
|
be done from the terminal with the following commands:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
$ echo none | sudo tee /sys/class/leds/led0/trigger
|
$ echo none | sudo tee /sys/class/leds/led0/trigger
|
||||||
$ echo gpio | sudo tee /sys/class/leds/led1/trigger
|
$ echo gpio | sudo tee /sys/class/leds/led1/trigger
|
||||||
@@ -46,7 +48,9 @@ Now you can control the LEDs with gpiozero like so:
|
|||||||
.. literalinclude:: examples/led_builtin.py
|
.. literalinclude:: examples/led_builtin.py
|
||||||
|
|
||||||
To revert the LEDs to their usual purpose you can either reboot your Pi or
|
To revert the LEDs to their usual purpose you can either reboot your Pi or
|
||||||
run the following commands::
|
run the following commands:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
$ echo mmc0 | sudo tee /sys/class/leds/led0/trigger
|
$ echo mmc0 | sudo tee /sys/class/leds/led0/trigger
|
||||||
$ echo input | sudo tee /sys/class/leds/led1/trigger
|
$ echo input | sudo tee /sys/class/leds/led1/trigger
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Remote GPIO
|
|||||||
GPIO Zero supports a number of different pin implementations (low-level pin
|
GPIO Zero supports a number of different pin implementations (low-level pin
|
||||||
libraries which deal with the GPIO pins directly). By default, the `RPi.GPIO`_
|
libraries which deal with the GPIO pins directly). By default, the `RPi.GPIO`_
|
||||||
library is used (assuming it is installed on your system), but you can
|
library is used (assuming it is installed on your system), but you can
|
||||||
optionally specify one to use. For more information, see the :doc:`pins`
|
optionally specify one to use. For more information, see the :doc:`api_pins`
|
||||||
documentation page.
|
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
|
||||||
@@ -23,9 +23,11 @@ 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 Lite,
|
||||||
or another distribution, you'll need to install pigpio::
|
or another distribution, you'll need to install pigpio:
|
||||||
|
|
||||||
sudo apt install pigpio
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ sudo apt install pigpio
|
||||||
|
|
||||||
Then you just need to enable **Remote GPIO** in the Raspberry Pi configuration
|
Then you just need to enable **Remote GPIO** in the Raspberry Pi configuration
|
||||||
tool:
|
tool:
|
||||||
@@ -34,21 +36,25 @@ tool:
|
|||||||
|
|
||||||
(Alternatively, use ``sudo raspi-config`` on the command line)
|
(Alternatively, use ``sudo raspi-config`` on the command line)
|
||||||
|
|
||||||
Then launch the pigpio daemon::
|
Then launch the pigpio daemon:
|
||||||
|
|
||||||
sudo pigpiod
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ sudo pigpiod
|
||||||
|
|
||||||
To only allow connections from a specific IP address, use the ``-n`` flag. For
|
To only allow connections from a specific IP address, use the ``-n`` flag. For
|
||||||
example::
|
example:
|
||||||
|
|
||||||
sudo pigpiod -n localhost # allow localhost only
|
.. code-block:: console
|
||||||
sudo pigpiod -n 192.168.1.65 # allow 192.168.1.65 only
|
|
||||||
sudo pigpiod -n localhost -n 192.168.1.65 # allow localhost and 192.168.1.65 only
|
$ sudo pigpiod -n localhost # allow localhost only
|
||||||
|
$ sudo pigpiod -n 192.168.1.65 # allow 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::
|
||||||
|
|
||||||
sudo systemctl enable pigpiod
|
$ sudo systemctl enable pigpiod
|
||||||
|
|
||||||
Preparing the host computer
|
Preparing the host computer
|
||||||
===========================
|
===========================
|
||||||
@@ -61,72 +67,100 @@ Python library on the PC.
|
|||||||
Raspberry Pi
|
Raspberry Pi
|
||||||
------------
|
------------
|
||||||
|
|
||||||
First, update your repositories list::
|
First, update your repositories list:
|
||||||
|
|
||||||
sudo apt update
|
.. code-block:: console
|
||||||
|
|
||||||
Then install the pigpio library for Python 3::
|
$ sudo apt update
|
||||||
|
|
||||||
sudo apt install python3-pigpio
|
Then install the pigpio library for Python 3:
|
||||||
|
|
||||||
or Python 2::
|
.. code-block:: console
|
||||||
|
|
||||||
sudo apt install python-pigpio
|
$ sudo apt install python3-pigpio
|
||||||
|
|
||||||
Alternatively, install with pip::
|
or Python 2:
|
||||||
|
|
||||||
sudo pip3 install pigpio
|
.. code-block:: console
|
||||||
|
|
||||||
or::
|
$ sudo apt install python-pigpio
|
||||||
|
|
||||||
sudo pip install pigpio
|
Alternatively, install with pip:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ sudo pip3 install pigpio
|
||||||
|
|
||||||
|
or:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ sudo pip install pigpio
|
||||||
|
|
||||||
Linux
|
Linux
|
||||||
-----
|
-----
|
||||||
|
|
||||||
First, update your distribution's repositories list. For example::
|
First, update your distribution's repositories list. For example:
|
||||||
|
|
||||||
sudo apt update
|
.. code-block:: console
|
||||||
|
|
||||||
Then install pip for Python 3::
|
$ sudo apt update
|
||||||
|
|
||||||
sudo apt install python3-pip
|
Then install pip for Python 3:
|
||||||
|
|
||||||
or Python 2::
|
.. code-block:: console
|
||||||
|
|
||||||
sudo apt install python-pip
|
$ sudo apt install python3-pip
|
||||||
|
|
||||||
|
or Python 2:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ sudo apt install python-pip
|
||||||
|
|
||||||
(Alternatively, install pip with `get-pip`_.)
|
(Alternatively, install pip with `get-pip`_.)
|
||||||
|
|
||||||
Next, install pigpio for Python 3::
|
Next, install pigpio for Python 3:
|
||||||
|
|
||||||
sudo pip3 install pigpio
|
.. code-block:: console
|
||||||
|
|
||||||
or Python 2::
|
$ sudo pip3 install pigpio
|
||||||
|
|
||||||
sudo pip install pigpio
|
or Python 2:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ sudo pip install pigpio
|
||||||
|
|
||||||
Mac OS
|
Mac OS
|
||||||
------
|
------
|
||||||
|
|
||||||
First, install pip::
|
First, install pip:
|
||||||
|
|
||||||
???
|
.. code-block:: console
|
||||||
|
|
||||||
Next, install pigpio with pip::
|
$ ???
|
||||||
|
|
||||||
pip install pigpio
|
Next, install pigpio with pip:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ pip install pigpio
|
||||||
|
|
||||||
Windows
|
Windows
|
||||||
-------
|
-------
|
||||||
|
|
||||||
First install pip::
|
First install pip:
|
||||||
|
|
||||||
???
|
.. code-block:: doscon
|
||||||
|
|
||||||
Next, install pigpio with pip::
|
C:\Users\user1> ???
|
||||||
|
|
||||||
pip install pigpio
|
Next, install pigpio with pip:
|
||||||
|
|
||||||
|
.. code-block:: doscon
|
||||||
|
|
||||||
|
C:\Users\user1> pip install pigpio
|
||||||
|
|
||||||
Environment variables
|
Environment variables
|
||||||
=====================
|
=====================
|
||||||
@@ -135,7 +169,9 @@ The simplest way to use devices with remote pins is to set the ``PIGPIO_ADDR``
|
|||||||
environment variable to the IP address of the desired Raspberry Pi. You must
|
environment variable to the IP address of the desired Raspberry Pi. You must
|
||||||
run your Python script or launch your development environment with the
|
run your Python script or launch your development environment with the
|
||||||
environment variable set using the command line. For example, one of the
|
environment variable set using the command line. For example, one of the
|
||||||
following::
|
following:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
$ PIGPIO_ADDR=192.168.1.3 python3 hello.py
|
$ PIGPIO_ADDR=192.168.1.3 python3 hello.py
|
||||||
$ PIGPIO_ADDR=192.168.1.3 python3
|
$ PIGPIO_ADDR=192.168.1.3 python3
|
||||||
@@ -147,7 +183,9 @@ 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 ``PiGPIOPin``. 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 uninstall
|
||||||
it, or use another environment variable to set it to ``PiGPIOPin``::
|
it, or use another environment variable to set it to ``PiGPIOPin``:
|
||||||
|
|
||||||
|
.. 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
|
||||||
|
|
||||||
@@ -160,12 +198,16 @@ with no modifications needed. For example:
|
|||||||
|
|
||||||
.. literalinclude:: examples/led_1.py
|
.. literalinclude:: examples/led_1.py
|
||||||
|
|
||||||
When run with::
|
When run with:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
$ PIGPIO_ADDR=192.168.1.3 python3 led.py
|
$ PIGPIO_ADDR=192.168.1.3 python3 led.py
|
||||||
|
|
||||||
will flash the LED connected to pin 17 of the Raspberry Pi with the IP address
|
will flash the LED connected to pin 17 of the Raspberry Pi with the IP address
|
||||||
``192.168.1.3``. And::
|
``192.168.1.3``. And:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
$ PIGPIO_ADDR=192.168.1.4 python3 led.py
|
$ PIGPIO_ADDR=192.168.1.4 python3 led.py
|
||||||
|
|
||||||
@@ -236,11 +278,13 @@ computer using remote pins.
|
|||||||
First, configure the boot partition of the SD card:
|
First, configure the boot partition of the SD card:
|
||||||
|
|
||||||
1. Edit ``config.txt`` and add ``dtoverlay=dwc2`` on a new line, then save the
|
1. Edit ``config.txt`` and add ``dtoverlay=dwc2`` on a new line, then save the
|
||||||
file.
|
file.
|
||||||
|
|
||||||
2. Create an empty file called ``ssh`` (no file extension) and save it in the
|
2. Create an empty file called ``ssh`` (no file extension) and save it in the
|
||||||
boot partition.
|
boot partition.
|
||||||
|
|
||||||
3. Edit ``cmdline.txt`` and insert ``modules-load=dwc2,g_ether`` after
|
3. Edit ``cmdline.txt`` and insert ``modules-load=dwc2,g_ether`` after
|
||||||
``rootwait``.
|
``rootwait``.
|
||||||
|
|
||||||
(See `blog.gbaman.info`_ for more information)
|
(See `blog.gbaman.info`_ for more information)
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ class CompositeOutputDevice(SourceMixin, CompositeDevice):
|
|||||||
specific order). All keyword arguments *must* be included in the
|
specific order). All keyword arguments *must* be included in the
|
||||||
collection. If omitted, an alphabetically sorted order will be selected
|
collection. If omitted, an alphabetically sorted order will be selected
|
||||||
for keyword arguments.
|
for keyword arguments.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def on(self):
|
def on(self):
|
||||||
@@ -124,6 +128,10 @@ class ButtonBoard(HoldMixin, CompositeDevice):
|
|||||||
executed once per hold. This parameter can only be specified as a
|
executed once per hold. This parameter can only be specified as a
|
||||||
keyword parameter.
|
keyword parameter.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
:param \*\*named_pins:
|
:param \*\*named_pins:
|
||||||
Specify GPIO pins that buttons of the board are attached to,
|
Specify GPIO pins that buttons of the board are attached to,
|
||||||
associating each button with a property name. You can designate as
|
associating each button with a property name. You can designate as
|
||||||
@@ -135,6 +143,7 @@ class ButtonBoard(HoldMixin, CompositeDevice):
|
|||||||
bounce_time = kwargs.pop('bounce_time', None)
|
bounce_time = kwargs.pop('bounce_time', None)
|
||||||
hold_time = kwargs.pop('hold_time', 1)
|
hold_time = kwargs.pop('hold_time', 1)
|
||||||
hold_repeat = kwargs.pop('hold_repeat', False)
|
hold_repeat = kwargs.pop('hold_repeat', False)
|
||||||
|
pin_factory = kwargs.pop('pin_factory', None)
|
||||||
order = kwargs.pop('_order', None)
|
order = kwargs.pop('_order', None)
|
||||||
super(ButtonBoard, self).__init__(
|
super(ButtonBoard, self).__init__(
|
||||||
*(
|
*(
|
||||||
@@ -142,6 +151,7 @@ class ButtonBoard(HoldMixin, CompositeDevice):
|
|||||||
for pin in args
|
for pin in args
|
||||||
),
|
),
|
||||||
_order=order,
|
_order=order,
|
||||||
|
pin_factory=pin_factory,
|
||||||
**{
|
**{
|
||||||
name: Button(pin, pull_up, bounce_time, hold_time, hold_repeat)
|
name: Button(pin, pull_up, bounce_time, hold_time, hold_repeat)
|
||||||
for name, pin in kwargs.items()
|
for name, pin in kwargs.items()
|
||||||
@@ -209,20 +219,28 @@ class LEDCollection(CompositeOutputDevice):
|
|||||||
pwm = kwargs.pop('pwm', False)
|
pwm = kwargs.pop('pwm', False)
|
||||||
active_high = kwargs.pop('active_high', True)
|
active_high = kwargs.pop('active_high', True)
|
||||||
initial_value = kwargs.pop('initial_value', False)
|
initial_value = kwargs.pop('initial_value', False)
|
||||||
|
pin_factory = kwargs.pop('pin_factory', None)
|
||||||
order = kwargs.pop('_order', None)
|
order = kwargs.pop('_order', None)
|
||||||
LEDClass = PWMLED if pwm else LED
|
LEDClass = PWMLED if pwm else LED
|
||||||
super(LEDCollection, self).__init__(
|
super(LEDCollection, self).__init__(
|
||||||
*(
|
*(
|
||||||
pin_or_collection
|
pin_or_collection
|
||||||
if isinstance(pin_or_collection, LEDCollection) else
|
if isinstance(pin_or_collection, LEDCollection) else
|
||||||
LEDClass(pin_or_collection, active_high, initial_value)
|
LEDClass(
|
||||||
|
pin_or_collection, active_high, initial_value,
|
||||||
|
pin_factory=pin_factory
|
||||||
|
)
|
||||||
for pin_or_collection in args
|
for pin_or_collection in args
|
||||||
),
|
),
|
||||||
_order=order,
|
_order=order,
|
||||||
|
pin_factory=pin_factory,
|
||||||
**{
|
**{
|
||||||
name: pin_or_collection
|
name: pin_or_collection
|
||||||
if isinstance(pin_or_collection, LEDCollection) else
|
if isinstance(pin_or_collection, LEDCollection) else
|
||||||
LEDClass(pin_or_collection, active_high, initial_value)
|
LEDClass(
|
||||||
|
pin_or_collection, active_high, initial_value,
|
||||||
|
pin_factory=pin_factory
|
||||||
|
)
|
||||||
for name, pin_or_collection in kwargs.items()
|
for name, pin_or_collection in kwargs.items()
|
||||||
})
|
})
|
||||||
leds = []
|
leds = []
|
||||||
@@ -283,6 +301,10 @@ class LEDBoard(LEDCollection):
|
|||||||
the device will be switched on initially. This parameter can only be
|
the device will be switched on initially. This parameter can only be
|
||||||
specified as a keyword parameter.
|
specified as a keyword parameter.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
:param \*\*named_pins:
|
:param \*\*named_pins:
|
||||||
Specify GPIO pins that LEDs of the board are attached to, associating
|
Specify GPIO pins that LEDs of the board are attached to, associating
|
||||||
each LED with a property name. You can designate as many pins as
|
each LED with a property name. You can designate as many pins as
|
||||||
@@ -486,6 +508,10 @@ class LEDBarGraph(LEDCollection):
|
|||||||
The initial :attr:`value` of the graph given as a float between -1 and
|
The initial :attr:`value` of the graph given as a float between -1 and
|
||||||
+1. Defaults to ``0.0``. This parameter can only be specified as a
|
+1. Defaults to ``0.0``. This parameter can only be specified as a
|
||||||
keyword parameter.
|
keyword parameter.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *pins, **kwargs):
|
def __init__(self, *pins, **kwargs):
|
||||||
@@ -495,9 +521,12 @@ class LEDBarGraph(LEDCollection):
|
|||||||
pwm = kwargs.pop('pwm', False)
|
pwm = kwargs.pop('pwm', False)
|
||||||
active_high = kwargs.pop('active_high', True)
|
active_high = kwargs.pop('active_high', True)
|
||||||
initial_value = kwargs.pop('initial_value', 0.0)
|
initial_value = kwargs.pop('initial_value', 0.0)
|
||||||
|
pin_factory = kwargs.pop('pin_factory', None)
|
||||||
if kwargs:
|
if kwargs:
|
||||||
raise TypeError('unexpected keyword argument: %s' % kwargs.popitem()[0])
|
raise TypeError('unexpected keyword argument: %s' % kwargs.popitem()[0])
|
||||||
super(LEDBarGraph, self).__init__(*pins, pwm=pwm, active_high=active_high)
|
super(LEDBarGraph, self).__init__(
|
||||||
|
*pins, pwm=pwm, active_high=active_high, pin_factory=pin_factory
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
self.value = initial_value
|
self.value = initial_value
|
||||||
except:
|
except:
|
||||||
@@ -572,12 +601,17 @@ class LedBorg(RGBLED):
|
|||||||
each component of the LedBorg. If ``False``, construct regular
|
each component of the LedBorg. If ``False``, construct regular
|
||||||
:class:`LED` instances, which prevents smooth color graduations.
|
:class:`LED` instances, which prevents smooth color graduations.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _PiBorg LedBorg: https://www.piborg.org/ledborg
|
.. _PiBorg LedBorg: https://www.piborg.org/ledborg
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, initial_value=(0, 0, 0), pwm=True):
|
def __init__(self, initial_value=(0, 0, 0), pwm=True, pin_factory=None):
|
||||||
super(LedBorg, self).__init__(red=17, green=27, blue=22,
|
super(LedBorg, self).__init__(red=17, green=27, blue=22,
|
||||||
pwm=pwm, initial_value=initial_value)
|
pwm=pwm, initial_value=initial_value,
|
||||||
|
pin_factory=pin_factory)
|
||||||
|
|
||||||
|
|
||||||
class PiLiter(LEDBoard):
|
class PiLiter(LEDBoard):
|
||||||
@@ -604,12 +638,17 @@ class PiLiter(LEDBoard):
|
|||||||
in when configured for output (warning: this can be on). If ``True``,
|
in when configured for output (warning: this can be on). If ``True``,
|
||||||
the device will be switched on initially.
|
the device will be switched on initially.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _Ciseco Pi-LITEr: http://shop.ciseco.co.uk/pi-liter-8-led-strip-for-the-raspberry-pi/
|
.. _Ciseco Pi-LITEr: http://shop.ciseco.co.uk/pi-liter-8-led-strip-for-the-raspberry-pi/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, pwm=False, initial_value=False):
|
def __init__(self, pwm=False, initial_value=False, pin_factory=None):
|
||||||
super(PiLiter, self).__init__(4, 17, 27, 18, 22, 23, 24, 25,
|
super(PiLiter, self).__init__(4, 17, 27, 18, 22, 23, 24, 25,
|
||||||
pwm=pwm, initial_value=initial_value)
|
pwm=pwm, initial_value=initial_value,
|
||||||
|
pin_factory=pin_factory)
|
||||||
|
|
||||||
|
|
||||||
class PiLiterBarGraph(LEDBarGraph):
|
class PiLiterBarGraph(LEDBarGraph):
|
||||||
@@ -634,13 +673,18 @@ class PiLiterBarGraph(LEDBarGraph):
|
|||||||
The initial :attr:`value` of the graph given as a float between -1 and
|
The initial :attr:`value` of the graph given as a float between -1 and
|
||||||
+1. Defaults to ``0.0``.
|
+1. Defaults to ``0.0``.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _Ciseco Pi-LITEr: http://shop.ciseco.co.uk/pi-liter-8-led-strip-for-the-raspberry-pi/
|
.. _Ciseco Pi-LITEr: http://shop.ciseco.co.uk/pi-liter-8-led-strip-for-the-raspberry-pi/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, pwm=False, initial_value=0.0):
|
def __init__(self, pwm=False, initial_value=0.0, pin_factory=None):
|
||||||
pins = (4, 17, 27, 18, 22, 23, 24, 25)
|
pins = (4, 17, 27, 18, 22, 23, 24, 25)
|
||||||
super(PiLiterBarGraph, self).__init__(*pins,
|
super(PiLiterBarGraph, self).__init__(
|
||||||
pwm=pwm, initial_value=initial_value)
|
*pins, pwm=pwm, initial_value=initial_value, pin_factory=pin_factory
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TrafficLights(LEDBoard):
|
class TrafficLights(LEDBoard):
|
||||||
@@ -680,9 +724,14 @@ class TrafficLights(LEDBoard):
|
|||||||
The GPIO pin that the yellow LED is attached to. This is merely an
|
The GPIO pin that the yellow LED is attached to. This is merely an
|
||||||
alias for the ``amber`` parameter - you can't specify both ``amber``
|
alias for the ``amber`` parameter - you can't specify both ``amber``
|
||||||
and ``yellow``.
|
and ``yellow``.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(self, red=None, amber=None, green=None,
|
def __init__(self, red=None, amber=None, green=None,
|
||||||
pwm=False, initial_value=False, yellow=None):
|
pwm=False, initial_value=False, yellow=None,
|
||||||
|
pin_factory=None):
|
||||||
if amber is not None and yellow is not None:
|
if amber is not None and yellow is not None:
|
||||||
raise OutputDeviceBadValue(
|
raise OutputDeviceBadValue(
|
||||||
'Only one of amber or yellow can be specified'
|
'Only one of amber or yellow can be specified'
|
||||||
@@ -700,7 +749,7 @@ class TrafficLights(LEDBoard):
|
|||||||
)
|
)
|
||||||
super(TrafficLights, self).__init__(
|
super(TrafficLights, self).__init__(
|
||||||
pwm=pwm, initial_value=initial_value,
|
pwm=pwm, initial_value=initial_value,
|
||||||
_order=devices.keys(),
|
_order=devices.keys(), pin_factory=pin_factory,
|
||||||
**devices)
|
**devices)
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
@@ -739,11 +788,16 @@ class PiTraffic(TrafficLights):
|
|||||||
in when configured for output (warning: this can be on). If ``True``,
|
in when configured for output (warning: this can be on). If ``True``,
|
||||||
the device will be switched on initially.
|
the device will be switched on initially.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _Low Voltage Labs PI-TRAFFIC: http://lowvoltagelabs.com/products/pi-traffic/
|
.. _Low Voltage Labs PI-TRAFFIC: http://lowvoltagelabs.com/products/pi-traffic/
|
||||||
"""
|
"""
|
||||||
def __init__(self, pwm=False, initial_value=False):
|
def __init__(self, pwm=False, initial_value=False, pin_factory=None):
|
||||||
super(PiTraffic, self).__init__(9, 10, 11,
|
super(PiTraffic, self).__init__(9, 10, 11,
|
||||||
pwm=pwm, initial_value=initial_value)
|
pwm=pwm, initial_value=initial_value,
|
||||||
|
pin_factory=pin_factory)
|
||||||
|
|
||||||
|
|
||||||
class PiStop(TrafficLights):
|
class PiStop(TrafficLights):
|
||||||
@@ -774,6 +828,10 @@ class PiStop(TrafficLights):
|
|||||||
in when configured for output (warning: this can be on). If ``True``,
|
in when configured for output (warning: this can be on). If ``True``,
|
||||||
the device will be switched on initially.
|
the device will be switched on initially.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _PiHardware Pi-Stop: https://pihw.wordpress.com/meltwaters-pi-hardware-kits/pi-stop/
|
.. _PiHardware Pi-Stop: https://pihw.wordpress.com/meltwaters-pi-hardware-kits/pi-stop/
|
||||||
.. _location: https://github.com/PiHw/Pi-Stop/blob/master/markdown_source/markdown/Discover-PiStop.md
|
.. _location: https://github.com/PiHw/Pi-Stop/blob/master/markdown_source/markdown/Discover-PiStop.md
|
||||||
"""
|
"""
|
||||||
@@ -786,13 +844,17 @@ class PiStop(TrafficLights):
|
|||||||
'D': (2, 3, 4),
|
'D': (2, 3, 4),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, location=None, pwm=False, initial_value=False):
|
def __init__(
|
||||||
|
self, location=None, pwm=False, initial_value=False,
|
||||||
|
pin_factory=None):
|
||||||
gpios = self.LOCATIONS.get(location, None)
|
gpios = self.LOCATIONS.get(location, None)
|
||||||
if gpios is None:
|
if gpios is None:
|
||||||
raise ValueError('location must be one of: %s' %
|
raise ValueError('location must be one of: %s' %
|
||||||
', '.join(sorted(self.LOCATIONS.keys())))
|
', '.join(sorted(self.LOCATIONS.keys())))
|
||||||
super(PiStop, self).__init__(*gpios,
|
super(PiStop, self).__init__(
|
||||||
pwm=pwm, initial_value=initial_value)
|
*gpios, pwm=pwm, initial_value=initial_value,
|
||||||
|
pin_factory=pin_factory
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class StatusZero(LEDBoard):
|
class StatusZero(LEDBoard):
|
||||||
@@ -817,6 +879,10 @@ class StatusZero(LEDBoard):
|
|||||||
not all strips are given labels, any remaining strips will not be
|
not all strips are given labels, any remaining strips will not be
|
||||||
initialised.
|
initialised.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _STATUS Zero: https://thepihut.com/statuszero
|
.. _STATUS Zero: https://thepihut.com/statuszero
|
||||||
"""
|
"""
|
||||||
default_labels = ('one', 'two', 'three')
|
default_labels = ('one', 'two', 'three')
|
||||||
@@ -827,6 +893,7 @@ class StatusZero(LEDBoard):
|
|||||||
(22, 27),
|
(22, 27),
|
||||||
(9, 10),
|
(9, 10),
|
||||||
)
|
)
|
||||||
|
pin_factory = kwargs.pop('pin_factory', None)
|
||||||
if len(labels) == 0:
|
if len(labels) == 0:
|
||||||
labels = self.default_labels
|
labels = self.default_labels
|
||||||
elif len(labels) > len(pins):
|
elif len(labels) > len(pins):
|
||||||
@@ -834,10 +901,15 @@ class StatusZero(LEDBoard):
|
|||||||
dup, count = Counter(labels).most_common(1)[0]
|
dup, count = Counter(labels).most_common(1)[0]
|
||||||
if count > 1:
|
if count > 1:
|
||||||
raise ValueError("Duplicate label %s" % dup)
|
raise ValueError("Duplicate label %s" % dup)
|
||||||
super(StatusZero, self).__init__(_order=labels, **{
|
super(StatusZero, self).__init__(
|
||||||
label: LEDBoard(red=red, green=green, _order=('red', 'green'), **kwargs)
|
_order=labels, pin_factory=pin_factory, **{
|
||||||
|
label: LEDBoard(
|
||||||
|
red=red, green=green, _order=('red', 'green'),
|
||||||
|
pin_factory=pin_factory, **kwargs
|
||||||
|
)
|
||||||
for (green, red), label in zip(pins, labels)
|
for (green, red), label in zip(pins, labels)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class StatusBoard(CompositeOutputDevice):
|
class StatusBoard(CompositeOutputDevice):
|
||||||
@@ -862,6 +934,10 @@ class StatusBoard(CompositeOutputDevice):
|
|||||||
will be initialised with names 'one' to 'five'. If some, but not all
|
will be initialised with names 'one' to 'five'. If some, but not all
|
||||||
strips are given labels, any remaining strips will not be initialised.
|
strips are given labels, any remaining strips will not be initialised.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _STATUS: https://thepihut.com/status
|
.. _STATUS: https://thepihut.com/status
|
||||||
"""
|
"""
|
||||||
default_labels = ('one', 'two', 'three', 'four', 'five')
|
default_labels = ('one', 'two', 'three', 'four', 'five')
|
||||||
@@ -874,6 +950,7 @@ class StatusBoard(CompositeOutputDevice):
|
|||||||
(5, 11, 26),
|
(5, 11, 26),
|
||||||
(13, 6, 18),
|
(13, 6, 18),
|
||||||
)
|
)
|
||||||
|
pin_factory = kwargs.pop('pin_factory', None)
|
||||||
if len(labels) == 0:
|
if len(labels) == 0:
|
||||||
labels = self.default_labels
|
labels = self.default_labels
|
||||||
elif len(labels) > len(pins):
|
elif len(labels) > len(pins):
|
||||||
@@ -881,14 +958,18 @@ class StatusBoard(CompositeOutputDevice):
|
|||||||
dup, count = Counter(labels).most_common(1)[0]
|
dup, count = Counter(labels).most_common(1)[0]
|
||||||
if count > 1:
|
if count > 1:
|
||||||
raise ValueError("Duplicate label %s" % dup)
|
raise ValueError("Duplicate label %s" % dup)
|
||||||
super(StatusBoard, self).__init__(_order=labels, **{
|
super(StatusBoard, self).__init__(
|
||||||
|
_order=labels, pin_factory=pin_factory, **{
|
||||||
label: CompositeOutputDevice(
|
label: CompositeOutputDevice(
|
||||||
button=Button(button),
|
button=Button(button, pin_factory=pin_factory),
|
||||||
lights=LEDBoard(
|
lights=LEDBoard(
|
||||||
red=red, green=green, _order=('red', 'green'), **kwargs
|
red=red, green=green, _order=('red', 'green'),
|
||||||
), _order=('button', 'lights'))
|
pin_factory=pin_factory, **kwargs
|
||||||
|
), _order=('button', 'lights'), pin_factory=pin_factory
|
||||||
|
)
|
||||||
for (green, red, button), label in zip(pins, labels)
|
for (green, red, button), label in zip(pins, labels)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SnowPi(LEDBoard):
|
class SnowPi(LEDBoard):
|
||||||
@@ -917,29 +998,38 @@ class SnowPi(LEDBoard):
|
|||||||
in when configured for output (warning: this can be on). If ``True``,
|
in when configured for output (warning: this can be on). If ``True``,
|
||||||
the device will be switched on initially.
|
the device will be switched on initially.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _Ryanteck SnowPi: https://ryanteck.uk/raspberry-pi/114-snowpi-the-gpio-snowman-for-raspberry-pi-0635648608303.html
|
.. _Ryanteck SnowPi: https://ryanteck.uk/raspberry-pi/114-snowpi-the-gpio-snowman-for-raspberry-pi-0635648608303.html
|
||||||
"""
|
"""
|
||||||
def __init__(self, pwm=False, initial_value=False):
|
def __init__(self, pwm=False, initial_value=False, pin_factory=None):
|
||||||
super(SnowPi, self).__init__(
|
super(SnowPi, self).__init__(
|
||||||
arms=LEDBoard(
|
arms=LEDBoard(
|
||||||
left=LEDBoard(
|
left=LEDBoard(
|
||||||
top=17, middle=18, bottom=22,
|
top=17, middle=18, bottom=22,
|
||||||
pwm=pwm, initial_value=initial_value,
|
pwm=pwm, initial_value=initial_value,
|
||||||
_order=('top', 'middle', 'bottom')),
|
_order=('top', 'middle', 'bottom'),
|
||||||
|
pin_factory=pin_factory),
|
||||||
right=LEDBoard(
|
right=LEDBoard(
|
||||||
top=7, middle=8, bottom=9,
|
top=7, middle=8, bottom=9,
|
||||||
pwm=pwm, initial_value=initial_value,
|
pwm=pwm, initial_value=initial_value,
|
||||||
_order=('top', 'middle', 'bottom')),
|
_order=('top', 'middle', 'bottom'),
|
||||||
_order=('left', 'right')
|
pin_factory=pin_factory),
|
||||||
|
_order=('left', 'right'),
|
||||||
|
pin_factory=pin_factory
|
||||||
),
|
),
|
||||||
eyes=LEDBoard(
|
eyes=LEDBoard(
|
||||||
left=23, right=24,
|
left=23, right=24,
|
||||||
pwm=pwm, initial_value=initial_value,
|
pwm=pwm, initial_value=initial_value,
|
||||||
_order=('left', 'right')
|
_order=('left', 'right'),
|
||||||
|
pin_factory=pin_factory
|
||||||
),
|
),
|
||||||
nose=25,
|
nose=25,
|
||||||
pwm=pwm, initial_value=initial_value,
|
pwm=pwm, initial_value=initial_value,
|
||||||
_order=('eyes', 'nose', 'arms')
|
_order=('eyes', 'nose', 'arms'),
|
||||||
|
pin_factory=pin_factory
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -957,12 +1047,18 @@ class TrafficLightsBuzzer(CompositeOutputDevice):
|
|||||||
|
|
||||||
:param Button button:
|
:param Button button:
|
||||||
An instance of :class:`Button` representing the button on the HAT.
|
An instance of :class:`Button` representing the button on the HAT.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, lights, buzzer, button):
|
def __init__(self, lights, buzzer, button, pin_factory=None):
|
||||||
super(TrafficLightsBuzzer, self).__init__(
|
super(TrafficLightsBuzzer, self).__init__(
|
||||||
lights=lights, buzzer=buzzer, button=button,
|
lights=lights, buzzer=buzzer, button=button,
|
||||||
_order=('lights', 'buzzer', 'button'))
|
_order=('lights', 'buzzer', 'button'),
|
||||||
|
pin_factory=pin_factory
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FishDish(TrafficLightsBuzzer):
|
class FishDish(TrafficLightsBuzzer):
|
||||||
@@ -985,14 +1081,19 @@ class FishDish(TrafficLightsBuzzer):
|
|||||||
LED. If ``False`` (the default), construct regular :class:`LED`
|
LED. If ``False`` (the default), construct regular :class:`LED`
|
||||||
instances.
|
instances.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _Pi Supply FishDish: https://www.pi-supply.com/product/fish-dish-raspberry-pi-led-buzzer-board/
|
.. _Pi Supply FishDish: https://www.pi-supply.com/product/fish-dish-raspberry-pi-led-buzzer-board/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, pwm=False):
|
def __init__(self, pwm=False, pin_factory=None):
|
||||||
super(FishDish, self).__init__(
|
super(FishDish, self).__init__(
|
||||||
TrafficLights(9, 22, 4, pwm=pwm),
|
TrafficLights(9, 22, 4, pwm=pwm, pin_factory=pin_factory),
|
||||||
Buzzer(8),
|
Buzzer(8, pin_factory=pin_factory),
|
||||||
Button(7, pull_up=False),
|
Button(7, pull_up=False, pin_factory=pin_factory),
|
||||||
|
pin_factory=pin_factory
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -1016,14 +1117,19 @@ class TrafficHat(TrafficLightsBuzzer):
|
|||||||
LED. If ``False`` (the default), construct regular :class:`LED`
|
LED. If ``False`` (the default), construct regular :class:`LED`
|
||||||
instances.
|
instances.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _Ryanteck Traffic HAT: https://ryanteck.uk/hats/1-traffichat-0635648607122.html
|
.. _Ryanteck Traffic HAT: https://ryanteck.uk/hats/1-traffichat-0635648607122.html
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, pwm=False):
|
def __init__(self, pwm=False, pin_factory=None):
|
||||||
super(TrafficHat, self).__init__(
|
super(TrafficHat, self).__init__(
|
||||||
TrafficLights(24, 23, 22, pwm=pwm),
|
TrafficLights(24, 23, 22, pwm=pwm, pin_factory=pin_factory),
|
||||||
Buzzer(5),
|
Buzzer(5, pin_factory=pin_factory),
|
||||||
Button(25),
|
Button(25, pin_factory=pin_factory),
|
||||||
|
pin_factory=pin_factory
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -1049,13 +1155,19 @@ class Robot(SourceMixin, CompositeDevice):
|
|||||||
:param tuple right:
|
:param tuple right:
|
||||||
A tuple of two GPIO pins representing the forward and backward inputs
|
A tuple of two GPIO pins representing the forward and backward inputs
|
||||||
of the right motor's controller.
|
of the right motor's controller.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, left=None, right=None):
|
def __init__(self, left=None, right=None, pin_factory=None):
|
||||||
super(Robot, self).__init__(
|
super(Robot, self).__init__(
|
||||||
left_motor=Motor(*left),
|
left_motor=Motor(*left, pin_factory=pin_factory),
|
||||||
right_motor=Motor(*right),
|
right_motor=Motor(*right, pin_factory=pin_factory),
|
||||||
_order=('left_motor', 'right_motor'))
|
_order=('left_motor', 'right_motor'),
|
||||||
|
pin_factory=pin_factory
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
@@ -1148,11 +1260,17 @@ class RyanteckRobot(Robot):
|
|||||||
robot = RyanteckRobot()
|
robot = RyanteckRobot()
|
||||||
robot.forward()
|
robot.forward()
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _Ryanteck MCB: https://ryanteck.uk/add-ons/6-ryanteck-rpi-motor-controller-board-0635648607160.html
|
.. _Ryanteck MCB: https://ryanteck.uk/add-ons/6-ryanteck-rpi-motor-controller-board-0635648607160.html
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, pin_factory=None):
|
||||||
super(RyanteckRobot, self).__init__((17, 18), (22, 23))
|
super(RyanteckRobot, self).__init__(
|
||||||
|
(17, 18), (22, 23), pin_factory=pin_factory
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CamJamKitRobot(Robot):
|
class CamJamKitRobot(Robot):
|
||||||
@@ -1168,20 +1286,31 @@ class CamJamKitRobot(Robot):
|
|||||||
robot = CamJamKitRobot()
|
robot = CamJamKitRobot()
|
||||||
robot.forward()
|
robot.forward()
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _CamJam #3 EduKit: http://camjam.me/?page_id=1035
|
.. _CamJam #3 EduKit: http://camjam.me/?page_id=1035
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, pin_factory=None):
|
||||||
super(CamJamKitRobot, self).__init__((9, 10), (7, 8))
|
super(CamJamKitRobot, self).__init__(
|
||||||
|
(9, 10), (7, 8), pin_factory=pin_factory
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class _EnergenieMaster(SharedMixin, CompositeOutputDevice):
|
class _EnergenieMaster(SharedMixin, CompositeOutputDevice):
|
||||||
def __init__(self):
|
def __init__(self, pin_factory=None):
|
||||||
self._lock = Lock()
|
self._lock = Lock()
|
||||||
super(_EnergenieMaster, self).__init__(
|
super(_EnergenieMaster, self).__init__(
|
||||||
*(OutputDevice(pin) for pin in (17, 22, 23, 27)),
|
*(
|
||||||
mode=OutputDevice(24), enable=OutputDevice(25),
|
OutputDevice(pin, pin_factory=pin_factory)
|
||||||
_order=('mode', 'enable'))
|
for pin in (17, 22, 23, 27)
|
||||||
|
),
|
||||||
|
mode=OutputDevice(24, pin_factory=pin_factory),
|
||||||
|
enable=OutputDevice(25, pin_factory=pin_factory),
|
||||||
|
_order=('mode', 'enable'), pin_factory=pin_factory
|
||||||
|
)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if self._lock:
|
if self._lock:
|
||||||
@@ -1190,7 +1319,7 @@ class _EnergenieMaster(SharedMixin, CompositeOutputDevice):
|
|||||||
self._lock = None
|
self._lock = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _shared_key(cls):
|
def _shared_key(cls, pin_factory):
|
||||||
# There's only one Energenie master
|
# There's only one Energenie master
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -1231,18 +1360,22 @@ class Energenie(SourceMixin, Device):
|
|||||||
the socket, which will be set upon construction. This defaults to
|
the socket, which will be set upon construction. This defaults to
|
||||||
``False`` which will switch the socket off.
|
``False`` which will switch the socket off.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _Energenie socket: https://energenie4u.co.uk/index.php/catalogue/product/ENER002-2PI
|
.. _Energenie socket: https://energenie4u.co.uk/index.php/catalogue/product/ENER002-2PI
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, socket=None, initial_value=False):
|
def __init__(self, socket=None, initial_value=False, pin_factory=None):
|
||||||
if socket is None:
|
if socket is None:
|
||||||
raise EnergenieSocketMissing('socket number must be provided')
|
raise EnergenieSocketMissing('socket number must be provided')
|
||||||
if not (1 <= socket <= 4):
|
if not (1 <= socket <= 4):
|
||||||
raise EnergenieBadSocket('socket number must be between 1 and 4')
|
raise EnergenieBadSocket('socket number must be between 1 and 4')
|
||||||
self._value = None
|
self._value = None
|
||||||
super(Energenie, self).__init__()
|
super(Energenie, self).__init__(pin_factory=pin_factory)
|
||||||
self._socket = socket
|
self._socket = socket
|
||||||
self._master = _EnergenieMaster()
|
self._master = _EnergenieMaster(pin_factory=pin_factory)
|
||||||
if initial_value:
|
if initial_value:
|
||||||
self.on()
|
self.on()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import os
|
|||||||
import atexit
|
import atexit
|
||||||
import weakref
|
import weakref
|
||||||
import warnings
|
import warnings
|
||||||
from collections import namedtuple, defaultdict
|
from collections import namedtuple
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from types import FunctionType
|
from types import FunctionType
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
@@ -194,77 +194,25 @@ class Device(ValuesMixin, GPIOBase):
|
|||||||
property, the :attr:`value` property, and the :meth:`close` method).
|
property, the :attr:`value` property, and the :meth:`close` method).
|
||||||
"""
|
"""
|
||||||
pin_factory = None # instance of a Factory sub-class
|
pin_factory = None # instance of a Factory sub-class
|
||||||
_reservations = defaultdict(list) # maps pin addresses to lists of devices
|
|
||||||
_res_lock = Lock()
|
def __init__(self, **kwargs):
|
||||||
|
# Force pin_factory to be keyword-only, even in Python 2
|
||||||
|
pin_factory = kwargs.pop('pin_factory', None)
|
||||||
|
if pin_factory is None:
|
||||||
|
self.pin_factory = Device.pin_factory
|
||||||
|
else:
|
||||||
|
self.pin_factory = pin_factory
|
||||||
|
if kwargs:
|
||||||
|
raise TypeError("Device.__init__() got unexpected keyword "
|
||||||
|
"argument '%s'" % kwargs.popitem()[0])
|
||||||
|
super(Device, self).__init__()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<gpiozero.%s object>" % (self.__class__.__name__)
|
return "<gpiozero.%s object>" % (self.__class__.__name__)
|
||||||
|
|
||||||
def _reserve_pins(self, *pins_or_addresses):
|
|
||||||
"""
|
|
||||||
Called to indicate that the device reserves the right to use the
|
|
||||||
specified *pins_or_addresses*. This should be done during device
|
|
||||||
construction. If pins are reserved, you must ensure that the
|
|
||||||
reservation is released by eventually called :meth:`_release_pins`.
|
|
||||||
|
|
||||||
The *pins_or_addresses* can be actual :class:`Pin` instances or the
|
|
||||||
addresses of pin instances (each address is a tuple of strings). The
|
|
||||||
latter form is permitted to ensure that devices do not have to
|
|
||||||
construct :class:`Pin` objects to reserve pins. This is important as
|
|
||||||
constructing a pin often configures it (e.g. as an input) which
|
|
||||||
conflicts with alternate pin functions like SPI.
|
|
||||||
"""
|
|
||||||
addresses = (
|
|
||||||
p.address if isinstance(p, Pin) else p
|
|
||||||
for p in pins_or_addresses
|
|
||||||
)
|
|
||||||
with Device._res_lock:
|
|
||||||
for address in addresses:
|
|
||||||
for device_ref in Device._reservations[address]:
|
|
||||||
device = device_ref()
|
|
||||||
if device is not None and self._conflicts_with(device):
|
|
||||||
raise GPIOPinInUse(
|
|
||||||
'pin %s is already in use by %r' % (
|
|
||||||
'/'.join(address), device)
|
|
||||||
)
|
|
||||||
Device._reservations[address].append(weakref.ref(self))
|
|
||||||
|
|
||||||
def _release_pins(self, *pins_or_addresses):
|
|
||||||
"""
|
|
||||||
Releases the reservation of this device against *pins_or_addresses*.
|
|
||||||
This is typically called during :meth:`close` to clean up reservations
|
|
||||||
taken during construction. Releasing a reservation that is not
|
|
||||||
currently held will be silently ignored (to permit clean-up after
|
|
||||||
failed / partial construction).
|
|
||||||
"""
|
|
||||||
addresses = (
|
|
||||||
p.address if isinstance(p, Pin) else p
|
|
||||||
for p in pins_or_addresses
|
|
||||||
)
|
|
||||||
with Device._res_lock:
|
|
||||||
for address in addresses:
|
|
||||||
Device._reservations[address] = [
|
|
||||||
ref for ref in Device._reservations[address]
|
|
||||||
if ref() not in (self, None) # may as well clean up dead refs
|
|
||||||
]
|
|
||||||
|
|
||||||
def _release_all(self):
|
|
||||||
"""
|
|
||||||
Releases all pin reservations taken out by this device. See
|
|
||||||
:meth:`_release_pins` for further information).
|
|
||||||
"""
|
|
||||||
with Device._res_lock:
|
|
||||||
Device._reservations = defaultdict(list, {
|
|
||||||
address: [
|
|
||||||
ref for ref in conflictors
|
|
||||||
if ref() not in (self, None)
|
|
||||||
]
|
|
||||||
for address, conflictors in Device._reservations.items()
|
|
||||||
})
|
|
||||||
|
|
||||||
def _conflicts_with(self, other):
|
def _conflicts_with(self, other):
|
||||||
"""
|
"""
|
||||||
Called by :meth:`_reserve_pin` to test whether the *other*
|
Called by :meth:`Factory.reserve_pins` to test whether the *other*
|
||||||
:class:`Device` using a common pin conflicts with this device's intent
|
:class:`Device` using a common pin conflicts with this device's intent
|
||||||
to use it. The default is ``True`` indicating that all devices conflict
|
to use it. The default is ``True`` indicating that all devices conflict
|
||||||
with common pins. Sub-classes may override this to permit more nuanced
|
with common pins. Sub-classes may override this to permit more nuanced
|
||||||
@@ -315,6 +263,7 @@ class CompositeDevice(Device):
|
|||||||
self._named = frozendict({})
|
self._named = frozendict({})
|
||||||
self._namedtuple = None
|
self._namedtuple = None
|
||||||
self._order = kwargs.pop('_order', None)
|
self._order = kwargs.pop('_order', None)
|
||||||
|
pin_factory = kwargs.pop('pin_factory', None)
|
||||||
try:
|
try:
|
||||||
if self._order is None:
|
if self._order is None:
|
||||||
self._order = sorted(kwargs.keys())
|
self._order = sorted(kwargs.keys())
|
||||||
@@ -336,7 +285,7 @@ class CompositeDevice(Device):
|
|||||||
dev.close()
|
dev.close()
|
||||||
raise
|
raise
|
||||||
self._all = args + tuple(kwargs[v] for v in self._order)
|
self._all = args + tuple(kwargs[v] for v in self._order)
|
||||||
super(CompositeDevice, self).__init__()
|
super(CompositeDevice, self).__init__(pin_factory=pin_factory)
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
# if _named doesn't exist yet, pretend it's an empty dict
|
# if _named doesn't exist yet, pretend it's an empty dict
|
||||||
@@ -412,20 +361,17 @@ class GPIODevice(Device):
|
|||||||
this is ``None``, :exc:`GPIOPinMissing` will be raised. If the pin is
|
this is ``None``, :exc:`GPIOPinMissing` will be raised. If the pin is
|
||||||
already in use by another device, :exc:`GPIOPinInUse` will be raised.
|
already in use by another device, :exc:`GPIOPinInUse` will be raised.
|
||||||
"""
|
"""
|
||||||
def __init__(self, pin=None):
|
def __init__(self, pin=None, **kwargs):
|
||||||
super(GPIODevice, self).__init__()
|
super(GPIODevice, self).__init__(**kwargs)
|
||||||
# self._pin must be set before any possible exceptions can be raised
|
# self._pin must be set before any possible exceptions can be raised
|
||||||
# because it's accessed in __del__. However, it mustn't be given the
|
# because it's accessed in __del__. However, it mustn't be given the
|
||||||
# value of pin until we've verified that it isn't already allocated
|
# value of pin until we've verified that it isn't already allocated
|
||||||
self._pin = None
|
self._pin = None
|
||||||
if pin is None:
|
if pin is None:
|
||||||
raise GPIOPinMissing('No pin given')
|
raise GPIOPinMissing('No pin given')
|
||||||
if isinstance(pin, Pin):
|
|
||||||
self._reserve_pins(pin)
|
|
||||||
else:
|
|
||||||
# Check you can reserve *before* constructing the pin
|
# Check you can reserve *before* constructing the pin
|
||||||
self._reserve_pins(Device.pin_factory.pin_address(pin))
|
self.pin_factory.reserve_pins(self, pin)
|
||||||
pin = Device.pin_factory.pin(pin)
|
pin = self.pin_factory.pin(pin)
|
||||||
self._pin = pin
|
self._pin = pin
|
||||||
self._active_state = True
|
self._active_state = True
|
||||||
self._inactive_state = False
|
self._inactive_state = False
|
||||||
@@ -443,7 +389,7 @@ class GPIODevice(Device):
|
|||||||
def close(self):
|
def close(self):
|
||||||
super(GPIODevice, self).close()
|
super(GPIODevice, self).close()
|
||||||
if self._pin is not None:
|
if self._pin is not None:
|
||||||
self._release_pins(self._pin)
|
self.pin_factory.release_pins(self, self._pin.number)
|
||||||
self._pin.close()
|
self._pin.close()
|
||||||
self._pin = None
|
self._pin = None
|
||||||
|
|
||||||
@@ -512,10 +458,10 @@ def _default_pin_factory(name=os.getenv('GPIOZERO_PIN_FACTORY', None)):
|
|||||||
|
|
||||||
def _devices_shutdown():
|
def _devices_shutdown():
|
||||||
if Device.pin_factory:
|
if Device.pin_factory:
|
||||||
with Device._res_lock:
|
with Device.pin_factory._res_lock:
|
||||||
reserved_devices = {
|
reserved_devices = {
|
||||||
dev
|
dev
|
||||||
for ref_list in Device._reservations.values()
|
for ref_list in Device.pin_factory._reservations.values()
|
||||||
for ref in ref_list
|
for ref in ref_list
|
||||||
for dev in (ref(),)
|
for dev in (ref(),)
|
||||||
if dev is not None
|
if dev is not None
|
||||||
|
|||||||
@@ -32,9 +32,13 @@ class InputDevice(GPIODevice):
|
|||||||
:param bool pull_up:
|
:param bool pull_up:
|
||||||
If ``True``, the pin will be pulled high with an internal resistor. If
|
If ``True``, the pin will be pulled high with an internal resistor. If
|
||||||
``False`` (the default), the pin will be pulled low.
|
``False`` (the default), the pin will be pulled low.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(self, pin=None, pull_up=False):
|
def __init__(self, pin=None, pull_up=False, pin_factory=None):
|
||||||
super(InputDevice, self).__init__(pin)
|
super(InputDevice, self).__init__(pin, pin_factory=pin_factory)
|
||||||
try:
|
try:
|
||||||
self.pin.function = 'input'
|
self.pin.function = 'input'
|
||||||
pull = 'up' if pull_up else 'down'
|
pull = 'up' if pull_up else 'down'
|
||||||
@@ -75,9 +79,16 @@ class DigitalInputDevice(EventsMixin, InputDevice):
|
|||||||
Specifies the length of time (in seconds) that the component will
|
Specifies the length of time (in seconds) that the component will
|
||||||
ignore changes in state after an initial change. This defaults to
|
ignore changes in state after an initial change. This defaults to
|
||||||
``None`` which indicates that no bounce compensation will be performed.
|
``None`` which indicates that no bounce compensation will be performed.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(self, pin=None, pull_up=False, bounce_time=None):
|
def __init__(
|
||||||
super(DigitalInputDevice, self).__init__(pin, pull_up)
|
self, pin=None, pull_up=False, bounce_time=None, pin_factory=None):
|
||||||
|
super(DigitalInputDevice, self).__init__(
|
||||||
|
pin, pull_up, pin_factory=pin_factory
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
self.pin.bounce = bounce_time
|
self.pin.bounce = bounce_time
|
||||||
self.pin.edges = 'both'
|
self.pin.edges = 'both'
|
||||||
@@ -127,12 +138,18 @@ class SmoothedInputDevice(EventsMixin, InputDevice):
|
|||||||
(from the :attr:`is_active` property) will block until the queue has
|
(from the :attr:`is_active` property) will block until the queue has
|
||||||
filled. If ``True``, a value will be returned immediately, but be
|
filled. If ``True``, a value will be returned immediately, but be
|
||||||
aware that this value is likely to fluctuate excessively.
|
aware that this value is likely to fluctuate excessively.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, pin=None, pull_up=False, threshold=0.5,
|
self, pin=None, pull_up=False, threshold=0.5,
|
||||||
queue_len=5, sample_wait=0.0, partial=False):
|
queue_len=5, sample_wait=0.0, partial=False, pin_factory=None):
|
||||||
self._queue = None
|
self._queue = None
|
||||||
super(SmoothedInputDevice, self).__init__(pin, pull_up)
|
super(SmoothedInputDevice, self).__init__(
|
||||||
|
pin, pull_up, pin_factory=pin_factory
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
self._queue = GPIOQueue(self, queue_len, sample_wait, partial)
|
self._queue = GPIOQueue(self, queue_len, sample_wait, partial)
|
||||||
self.threshold = float(threshold)
|
self.threshold = float(threshold)
|
||||||
@@ -263,11 +280,17 @@ class Button(HoldMixin, DigitalInputDevice):
|
|||||||
as long as the device remains active, every *hold_time* seconds. If
|
as long as the device remains active, every *hold_time* seconds. If
|
||||||
``False`` (the default) the :attr:`when_held` handler will be only be
|
``False`` (the default) the :attr:`when_held` handler will be only be
|
||||||
executed once per hold.
|
executed once per hold.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, pin=None, pull_up=True, bounce_time=None,
|
self, pin=None, pull_up=True, bounce_time=None,
|
||||||
hold_time=1, hold_repeat=False):
|
hold_time=1, hold_repeat=False, pin_factory=None):
|
||||||
super(Button, self).__init__(pin, pull_up, bounce_time)
|
super(Button, self).__init__(
|
||||||
|
pin, pull_up, bounce_time, pin_factory=pin_factory
|
||||||
|
)
|
||||||
self.hold_time = hold_time
|
self.hold_time = hold_time
|
||||||
self.hold_repeat = hold_repeat
|
self.hold_repeat = hold_repeat
|
||||||
|
|
||||||
@@ -325,14 +348,19 @@ class LineSensor(SmoothedInputDevice):
|
|||||||
filled with values. Only set this to ``True`` if you require values
|
filled with values. Only set this to ``True`` if you require values
|
||||||
immediately after object construction.
|
immediately after object construction.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _CamJam #3 EduKit: http://camjam.me/?page_id=1035
|
.. _CamJam #3 EduKit: http://camjam.me/?page_id=1035
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, pin=None, queue_len=5, sample_rate=100, threshold=0.5,
|
self, pin=None, queue_len=5, sample_rate=100, threshold=0.5,
|
||||||
partial=False):
|
partial=False, pin_factory=None):
|
||||||
super(LineSensor, self).__init__(
|
super(LineSensor, self).__init__(
|
||||||
pin, pull_up=False, threshold=threshold,
|
pin, pull_up=False, threshold=threshold,
|
||||||
queue_len=queue_len, sample_wait=1 / sample_rate, partial=partial
|
queue_len=queue_len, sample_wait=1 / sample_rate, partial=partial,
|
||||||
|
pin_factory=pin_factory
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
self._queue.start()
|
self._queue.start()
|
||||||
@@ -394,13 +422,18 @@ class MotionSensor(SmoothedInputDevice):
|
|||||||
:attr:`~SmoothedInputDevice.is_active` until the internal queue has
|
:attr:`~SmoothedInputDevice.is_active` until the internal queue has
|
||||||
filled with values. Only set this to ``True`` if you require values
|
filled with values. Only set this to ``True`` if you require values
|
||||||
immediately after object construction.
|
immediately after object construction.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, pin=None, queue_len=1, sample_rate=10, threshold=0.5,
|
self, pin=None, queue_len=1, sample_rate=10, threshold=0.5,
|
||||||
partial=False):
|
partial=False, pin_factory=None):
|
||||||
super(MotionSensor, self).__init__(
|
super(MotionSensor, self).__init__(
|
||||||
pin, pull_up=False, threshold=threshold,
|
pin, pull_up=False, threshold=threshold,
|
||||||
queue_len=queue_len, sample_wait=1 / sample_rate, partial=partial
|
queue_len=queue_len, sample_wait=1 / sample_rate, partial=partial,
|
||||||
|
pin_factory=pin_factory
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
self._queue.start()
|
self._queue.start()
|
||||||
@@ -460,14 +493,19 @@ class LightSensor(SmoothedInputDevice):
|
|||||||
filled with values. Only set this to ``True`` if you require values
|
filled with values. Only set this to ``True`` if you require values
|
||||||
immediately after object construction.
|
immediately after object construction.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _CamJam #2 EduKit: http://camjam.me/?page_id=623
|
.. _CamJam #2 EduKit: http://camjam.me/?page_id=623
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, pin=None, queue_len=5, charge_time_limit=0.01,
|
self, pin=None, queue_len=5, charge_time_limit=0.01,
|
||||||
threshold=0.1, partial=False):
|
threshold=0.1, partial=False, pin_factory=None):
|
||||||
super(LightSensor, self).__init__(
|
super(LightSensor, self).__init__(
|
||||||
pin, pull_up=False, threshold=threshold,
|
pin, pull_up=False, threshold=threshold,
|
||||||
queue_len=queue_len, sample_wait=0.0, partial=partial
|
queue_len=queue_len, sample_wait=0.0, partial=partial,
|
||||||
|
pin_factory=pin_factory
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
self._charge_time_limit = charge_time_limit
|
self._charge_time_limit = charge_time_limit
|
||||||
@@ -568,17 +606,22 @@ class DistanceSensor(SmoothedInputDevice):
|
|||||||
filled with values. Only set this to ``True`` if you require values
|
filled with values. Only set this to ``True`` if you require values
|
||||||
immediately after object construction.
|
immediately after object construction.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
|
|
||||||
.. _CamJam #3 EduKit: http://camjam.me/?page_id=1035
|
.. _CamJam #3 EduKit: http://camjam.me/?page_id=1035
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, echo=None, trigger=None, queue_len=30, max_distance=1,
|
self, echo=None, trigger=None, queue_len=30, max_distance=1,
|
||||||
threshold_distance=0.3, partial=False):
|
threshold_distance=0.3, partial=False, pin_factory=None):
|
||||||
if max_distance <= 0:
|
if max_distance <= 0:
|
||||||
raise ValueError('invalid maximum distance (must be positive)')
|
raise ValueError('invalid maximum distance (must be positive)')
|
||||||
self._trigger = None
|
self._trigger = None
|
||||||
super(DistanceSensor, self).__init__(
|
super(DistanceSensor, self).__init__(
|
||||||
echo, pull_up=False, threshold=threshold_distance / max_distance,
|
echo, pull_up=False, threshold=threshold_distance / max_distance,
|
||||||
queue_len=queue_len, sample_wait=0.0, partial=partial
|
queue_len=queue_len, sample_wait=0.0, partial=partial,
|
||||||
|
pin_factory=pin_factory
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
self.speed_of_sound = 343.26 # m/s
|
self.speed_of_sound = 343.26 # m/s
|
||||||
|
|||||||
@@ -36,9 +36,15 @@ class OutputDevice(SourceMixin, GPIODevice):
|
|||||||
``None``, the device will be left in whatever state the pin is found in
|
``None``, the device will be left in whatever state the pin is found in
|
||||||
when configured for output (warning: this can be on). If ``True``, the
|
when configured for output (warning: this can be on). If ``True``, the
|
||||||
device will be switched on initially.
|
device will be switched on initially.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(self, pin=None, active_high=True, initial_value=False):
|
def __init__(
|
||||||
super(OutputDevice, self).__init__(pin)
|
self, pin=None, active_high=True, initial_value=False,
|
||||||
|
pin_factory=None):
|
||||||
|
super(OutputDevice, self).__init__(pin, pin_factory=pin_factory)
|
||||||
self._lock = Lock()
|
self._lock = Lock()
|
||||||
self.active_high = active_high
|
self.active_high = active_high
|
||||||
if initial_value is None:
|
if initial_value is None:
|
||||||
@@ -126,10 +132,14 @@ class DigitalOutputDevice(OutputDevice):
|
|||||||
uses an optional background thread to handle toggling the device state
|
uses an optional background thread to handle toggling the device state
|
||||||
without further interaction.
|
without further interaction.
|
||||||
"""
|
"""
|
||||||
def __init__(self, pin=None, active_high=True, initial_value=False):
|
def __init__(
|
||||||
|
self, pin=None, active_high=True, initial_value=False,
|
||||||
|
pin_factory=None):
|
||||||
self._blink_thread = None
|
self._blink_thread = None
|
||||||
self._controller = None
|
self._controller = None
|
||||||
super(DigitalOutputDevice, self).__init__(pin, active_high, initial_value)
|
super(DigitalOutputDevice, self).__init__(
|
||||||
|
pin, active_high, initial_value, pin_factory=pin_factory
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
@@ -230,6 +240,10 @@ class LED(DigitalOutputDevice):
|
|||||||
``None``, the LED will be left in whatever state the pin is found in
|
``None``, the LED will be left in whatever state the pin is found in
|
||||||
when configured for output (warning: this can be on). If ``True``, the
|
when configured for output (warning: this can be on). If ``True``, the
|
||||||
LED will be switched on initially.
|
LED will be switched on initially.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -265,6 +279,10 @@ class Buzzer(DigitalOutputDevice):
|
|||||||
``None``, the buzzer will be left in whatever state the pin is found in
|
``None``, the buzzer will be left in whatever state the pin is found in
|
||||||
when configured for output (warning: this can be on). If ``True``, the
|
when configured for output (warning: this can be on). If ``True``, the
|
||||||
buzzer will be switched on initially.
|
buzzer will be switched on initially.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -293,13 +311,21 @@ class PWMOutputDevice(OutputDevice):
|
|||||||
:param int frequency:
|
:param int frequency:
|
||||||
The frequency (in Hz) of pulses emitted to drive the device. Defaults
|
The frequency (in Hz) of pulses emitted to drive the device. Defaults
|
||||||
to 100Hz.
|
to 100Hz.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(self, pin=None, active_high=True, initial_value=0, frequency=100):
|
def __init__(
|
||||||
|
self, pin=None, active_high=True, initial_value=0, frequency=100,
|
||||||
|
pin_factory=None):
|
||||||
self._blink_thread = None
|
self._blink_thread = None
|
||||||
self._controller = None
|
self._controller = None
|
||||||
if not 0 <= initial_value <= 1:
|
if not 0 <= initial_value <= 1:
|
||||||
raise OutputDeviceBadValue("initial_value must be between 0 and 1")
|
raise OutputDeviceBadValue("initial_value must be between 0 and 1")
|
||||||
super(PWMOutputDevice, self).__init__(pin, active_high, initial_value=None)
|
super(PWMOutputDevice, self).__init__(
|
||||||
|
pin, active_high, initial_value=None, pin_factory=pin_factory
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
# XXX need a way of setting these together
|
# XXX need a way of setting these together
|
||||||
self.pin.frequency = frequency
|
self.pin.frequency = frequency
|
||||||
@@ -500,6 +526,10 @@ class PWMLED(PWMOutputDevice):
|
|||||||
:param int frequency:
|
:param int frequency:
|
||||||
The frequency (in Hz) of pulses emitted to drive the LED. Defaults
|
The frequency (in Hz) of pulses emitted to drive the LED. Defaults
|
||||||
to 100Hz.
|
to 100Hz.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -552,17 +582,24 @@ class RGBLED(SourceMixin, Device):
|
|||||||
If ``True`` (the default), construct :class:`PWMLED` instances for
|
If ``True`` (the default), construct :class:`PWMLED` instances for
|
||||||
each component of the RGBLED. If ``False``, construct regular
|
each component of the RGBLED. If ``False``, construct regular
|
||||||
:class:`LED` instances, which prevents smooth color graduations.
|
:class:`LED` instances, which prevents smooth color graduations.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, red=None, green=None, blue=None, active_high=True,
|
self, red=None, green=None, blue=None, active_high=True,
|
||||||
initial_value=(0, 0, 0), pwm=True):
|
initial_value=(0, 0, 0), pwm=True, pin_factory=None):
|
||||||
self._leds = ()
|
self._leds = ()
|
||||||
self._blink_thread = None
|
self._blink_thread = None
|
||||||
if not all(p is not None for p in [red, green, blue]):
|
if not all(p is not None for p in [red, green, blue]):
|
||||||
raise GPIOPinMissing('red, green, and blue pins must be provided')
|
raise GPIOPinMissing('red, green, and blue pins must be provided')
|
||||||
LEDClass = PWMLED if pwm else LED
|
LEDClass = PWMLED if pwm else LED
|
||||||
super(RGBLED, self).__init__()
|
super(RGBLED, self).__init__(pin_factory=pin_factory)
|
||||||
self._leds = tuple(LEDClass(pin, active_high) for pin in (red, green, blue))
|
self._leds = tuple(
|
||||||
|
LEDClass(pin, active_high, pin_factory=pin_factory)
|
||||||
|
for pin in (red, green, blue)
|
||||||
|
)
|
||||||
self.value = initial_value
|
self.value = initial_value
|
||||||
|
|
||||||
red = _led_property(0)
|
red = _led_property(0)
|
||||||
@@ -803,17 +840,23 @@ class Motor(SourceMixin, CompositeDevice):
|
|||||||
variable speed control. If ``False``, construct
|
variable speed control. If ``False``, construct
|
||||||
:class:`DigitalOutputDevice` instances, allowing only direction
|
:class:`DigitalOutputDevice` instances, allowing only direction
|
||||||
control.
|
control.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(self, forward=None, backward=None, pwm=True):
|
def __init__(self, forward=None, backward=None, pwm=True, pin_factory=None):
|
||||||
if not all(p is not None for p in [forward, backward]):
|
if not all(p is not None for p in [forward, backward]):
|
||||||
raise GPIOPinMissing(
|
raise GPIOPinMissing(
|
||||||
'forward and backward pins must be provided'
|
'forward and backward pins must be provided'
|
||||||
)
|
)
|
||||||
PinClass = PWMOutputDevice if pwm else DigitalOutputDevice
|
PinClass = PWMOutputDevice if pwm else DigitalOutputDevice
|
||||||
super(Motor, self).__init__(
|
super(Motor, self).__init__(
|
||||||
forward_device=PinClass(forward),
|
forward_device=PinClass(forward, pin_factory=pin_factory),
|
||||||
backward_device=PinClass(backward),
|
backward_device=PinClass(backward, pin_factory=pin_factory),
|
||||||
_order=('forward_device', 'backward_device'))
|
_order=('forward_device', 'backward_device'),
|
||||||
|
pin_factory=pin_factory
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
@@ -946,11 +989,15 @@ class Servo(SourceMixin, CompositeDevice):
|
|||||||
:param float frame_width:
|
:param float frame_width:
|
||||||
The length of time between servo control pulses measured in seconds.
|
The length of time between servo control pulses measured in seconds.
|
||||||
This defaults to 20ms which is a common value for servos.
|
This defaults to 20ms which is a common value for servos.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, pin=None, initial_value=0.0,
|
self, pin=None, initial_value=0.0,
|
||||||
min_pulse_width=1/1000, max_pulse_width=2/1000,
|
min_pulse_width=1/1000, max_pulse_width=2/1000,
|
||||||
frame_width=20/1000):
|
frame_width=20/1000, pin_factory=None):
|
||||||
if min_pulse_width >= max_pulse_width:
|
if min_pulse_width >= max_pulse_width:
|
||||||
raise ValueError('min_pulse_width must be less than max_pulse_width')
|
raise ValueError('min_pulse_width must be less than max_pulse_width')
|
||||||
if max_pulse_width >= frame_width:
|
if max_pulse_width >= frame_width:
|
||||||
@@ -961,7 +1008,11 @@ class Servo(SourceMixin, CompositeDevice):
|
|||||||
self._min_value = -1
|
self._min_value = -1
|
||||||
self._value_range = 2
|
self._value_range = 2
|
||||||
super(Servo, self).__init__(
|
super(Servo, self).__init__(
|
||||||
pwm_device=PWMOutputDevice(pin, frequency=int(1 / frame_width)))
|
pwm_device=PWMOutputDevice(
|
||||||
|
pin, frequency=int(1 / frame_width), pin_factory=pin_factory
|
||||||
|
),
|
||||||
|
pin_factory=pin_factory
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
self.value = initial_value
|
self.value = initial_value
|
||||||
except:
|
except:
|
||||||
@@ -1146,17 +1197,23 @@ class AngularServo(Servo):
|
|||||||
:param float frame_width:
|
:param float frame_width:
|
||||||
The length of time between servo control pulses measured in seconds.
|
The length of time between servo control pulses measured in seconds.
|
||||||
This defaults to 20ms which is a common value for servos.
|
This defaults to 20ms which is a common value for servos.
|
||||||
|
|
||||||
|
:param Factory pin_factory:
|
||||||
|
See :doc:`api_pins` for more information (this is an advanced feature
|
||||||
|
which most users can ignore).
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, pin=None, initial_angle=0.0,
|
self, pin=None, initial_angle=0.0,
|
||||||
min_angle=-90, max_angle=90,
|
min_angle=-90, max_angle=90,
|
||||||
min_pulse_width=1/1000, max_pulse_width=2/1000,
|
min_pulse_width=1/1000, max_pulse_width=2/1000,
|
||||||
frame_width=20/1000):
|
frame_width=20/1000, pin_factory=None):
|
||||||
self._min_angle = min_angle
|
self._min_angle = min_angle
|
||||||
self._angular_range = max_angle - min_angle
|
self._angular_range = max_angle - min_angle
|
||||||
initial_value = 2 * ((initial_angle - min_angle) / self._angular_range) - 1
|
initial_value = 2 * ((initial_angle - min_angle) / self._angular_range) - 1
|
||||||
super(AngularServo, self).__init__(
|
super(AngularServo, self).__init__(
|
||||||
pin, initial_value, min_pulse_width, max_pulse_width, frame_width)
|
pin, initial_value, min_pulse_width, max_pulse_width, frame_width,
|
||||||
|
pin_factory=pin_factory
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def min_angle(self):
|
def min_angle(self):
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ from __future__ import (
|
|||||||
)
|
)
|
||||||
str = type('')
|
str = type('')
|
||||||
|
|
||||||
|
from weakref import ref
|
||||||
|
from collections import defaultdict
|
||||||
|
from threading import Lock
|
||||||
|
|
||||||
from ..exc import (
|
from ..exc import (
|
||||||
PinInvalidFunction,
|
PinInvalidFunction,
|
||||||
PinSetInput,
|
PinSetInput,
|
||||||
@@ -20,6 +24,7 @@ from ..exc import (
|
|||||||
SPIFixedBitOrder,
|
SPIFixedBitOrder,
|
||||||
SPIFixedSelect,
|
SPIFixedSelect,
|
||||||
SPIFixedWordSize,
|
SPIFixedWordSize,
|
||||||
|
GPIOPinInUse,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -36,10 +41,61 @@ class Factory(object):
|
|||||||
applicable:
|
applicable:
|
||||||
|
|
||||||
* :meth:`close`
|
* :meth:`close`
|
||||||
|
* :meth:`reserve_pins`
|
||||||
|
* :meth:`release_pins`
|
||||||
|
* :meth:`release_all`
|
||||||
* :meth:`pin`
|
* :meth:`pin`
|
||||||
* :meth:`spi`
|
* :meth:`spi`
|
||||||
* :meth:`_get_pi_info`
|
* :meth:`_get_pi_info`
|
||||||
"""
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self._reservations = defaultdict(list)
|
||||||
|
self._res_lock = Lock()
|
||||||
|
|
||||||
|
def reserve_pins(self, requester, *pins):
|
||||||
|
"""
|
||||||
|
Called to indicate that the device reserves the right to use the
|
||||||
|
specified *pins*. This should be done during device construction. If
|
||||||
|
pins are reserved, you must ensure that the reservation is released by
|
||||||
|
eventually called :meth:`release_pins`.
|
||||||
|
"""
|
||||||
|
with self._res_lock:
|
||||||
|
for pin in pins:
|
||||||
|
for reserver_ref in self._reservations[pin]:
|
||||||
|
reserver = reserver_ref()
|
||||||
|
if reserver is not None and requester._conflicts_with(reserver):
|
||||||
|
raise GPIOPinInUse('pin %s is already in use by %r' %
|
||||||
|
(pin, reserver))
|
||||||
|
self._reservations[pin].append(ref(requester))
|
||||||
|
|
||||||
|
def release_pins(self, reserver, *pins):
|
||||||
|
"""
|
||||||
|
Releases the reservation of *reserver* against *pins*. This is
|
||||||
|
typically called during :meth:`Device.close` to clean up reservations
|
||||||
|
taken during construction. Releasing a reservation that is not currently
|
||||||
|
held will be silently ignored (to permit clean-up after failed / partial
|
||||||
|
construction).
|
||||||
|
"""
|
||||||
|
with self._res_lock:
|
||||||
|
for pin in pins:
|
||||||
|
self._reservations[pin] = [
|
||||||
|
ref for ref in self._reservations[pin]
|
||||||
|
if ref() not in (reserver, None) # may as well clean up dead refs
|
||||||
|
]
|
||||||
|
|
||||||
|
def release_all(self, reserver):
|
||||||
|
"""
|
||||||
|
Releases all pin reservations taken out by *reserver*. See
|
||||||
|
:meth:`release_pins` for further information).
|
||||||
|
"""
|
||||||
|
with self._res_lock:
|
||||||
|
self._reservations = defaultdict(list, {
|
||||||
|
pin: [
|
||||||
|
ref for ref in conflictors
|
||||||
|
if ref() not in (reserver, None)
|
||||||
|
]
|
||||||
|
for pin, conflictors in self._reservations.items()
|
||||||
|
})
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""
|
"""
|
||||||
@@ -63,19 +119,6 @@ class Factory(object):
|
|||||||
"""
|
"""
|
||||||
raise PinUnsupported("Individual pins are not supported by this pin factory")
|
raise PinUnsupported("Individual pins are not supported by this pin factory")
|
||||||
|
|
||||||
def pin_address(self, spec):
|
|
||||||
"""
|
|
||||||
Returns the address that a pin *would* have if constructed from the
|
|
||||||
given *spec*.
|
|
||||||
|
|
||||||
This unusual method is used by the pin reservation system to check
|
|
||||||
for conflicts *prior* to pin construction; with most implementations,
|
|
||||||
pin construction implicitly alters the state of the pin (e.g. setting
|
|
||||||
it to an input). This allows pin reservation to take place without
|
|
||||||
affecting the state of other components.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def spi(self, **spi_args):
|
def spi(self, **spi_args):
|
||||||
"""
|
"""
|
||||||
Returns an instance of an :class:`SPI` interface, for the specified SPI
|
Returns an instance of an :class:`SPI` interface, for the specified SPI
|
||||||
@@ -89,21 +132,6 @@ class Factory(object):
|
|||||||
def _get_address(self):
|
def _get_address(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
address = property(
|
|
||||||
lambda self: self._get_address(),
|
|
||||||
doc="""\
|
|
||||||
Returns a tuple of strings representing the address of the factory.
|
|
||||||
For the Pi itself this is a tuple of one string representing the Pi's
|
|
||||||
address (e.g. "localhost"). Expander chips can return a tuple appending
|
|
||||||
whatever string they require to uniquely identify the expander chip
|
|
||||||
amongst all factories in the system.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
This property *must* return an immutable object capable of being
|
|
||||||
used as a dictionary key.
|
|
||||||
""")
|
|
||||||
|
|
||||||
def _get_pi_info(self):
|
def _get_pi_info(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -128,7 +156,6 @@ class Pin(object):
|
|||||||
represent the capabilities of pins. Descendents *must* override the
|
represent the capabilities of pins. Descendents *must* override the
|
||||||
following methods:
|
following methods:
|
||||||
|
|
||||||
* :meth:`_get_address`
|
|
||||||
* :meth:`_get_function`
|
* :meth:`_get_function`
|
||||||
* :meth:`_set_function`
|
* :meth:`_set_function`
|
||||||
* :meth:`_get_state`
|
* :meth:`_get_state`
|
||||||
@@ -153,7 +180,7 @@ class Pin(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.address[-1]
|
return "<Pin>"
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""
|
"""
|
||||||
@@ -195,18 +222,6 @@ class Pin(object):
|
|||||||
self.function = 'input'
|
self.function = 'input'
|
||||||
self.pull = pull
|
self.pull = pull
|
||||||
|
|
||||||
def _get_address(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
address = property(
|
|
||||||
lambda self: self._get_address(),
|
|
||||||
doc="""\
|
|
||||||
The address of the pin. This property is a tuple of strings constructed
|
|
||||||
from the owning factory's address with the unique address of the pin
|
|
||||||
appended to it. The tuple as a whole uniquely identifies the pin
|
|
||||||
amongst all pins attached to the system.
|
|
||||||
""")
|
|
||||||
|
|
||||||
def _get_function(self):
|
def _get_function(self):
|
||||||
return "input"
|
return "input"
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ str = type('')
|
|||||||
|
|
||||||
import io
|
import io
|
||||||
import warnings
|
import warnings
|
||||||
|
from collections import defaultdict
|
||||||
|
from threading import Lock
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from spidev import SpiDev
|
from spidev import SpiDev
|
||||||
@@ -31,6 +33,8 @@ class LocalPiFactory(PiFactory):
|
|||||||
:class:`~gpiozero.pins.native.NativePin`).
|
:class:`~gpiozero.pins.native.NativePin`).
|
||||||
"""
|
"""
|
||||||
pins = {}
|
pins = {}
|
||||||
|
_reservations = defaultdict(list)
|
||||||
|
_res_lock = Lock()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(LocalPiFactory, self).__init__()
|
super(LocalPiFactory, self).__init__()
|
||||||
@@ -40,14 +44,13 @@ class LocalPiFactory(PiFactory):
|
|||||||
('software', 'exclusive'): LocalPiSoftwareSPI,
|
('software', 'exclusive'): LocalPiSoftwareSPI,
|
||||||
('software', 'shared'): LocalPiSoftwareSPIShared,
|
('software', 'shared'): LocalPiSoftwareSPIShared,
|
||||||
}
|
}
|
||||||
# Override the pins dict to be this class' pins dict. This is a bit of
|
# Override the reservations and pins dict to be this class' attributes.
|
||||||
# a dirty hack, but ensures that anyone evil enough to mix pin
|
# This is a bit of a dirty hack, but ensures that anyone evil enough to
|
||||||
# implementations doesn't try and control the same pin with different
|
# mix pin implementations doesn't try and control the same pin with
|
||||||
# backends
|
# different backends
|
||||||
self.pins = LocalPiFactory.pins
|
self.pins = LocalPiFactory.pins
|
||||||
|
self._reservations = LocalPiFactory._reservations
|
||||||
def _get_address(self):
|
self._res_lock = LocalPiFactory._res_lock
|
||||||
return ('localhost',)
|
|
||||||
|
|
||||||
def _get_revision(self):
|
def _get_revision(self):
|
||||||
# Cache the result as we can reasonably assume it won't change during
|
# Cache the result as we can reasonably assume it won't change during
|
||||||
@@ -74,19 +77,19 @@ class LocalPiPin(PiPin):
|
|||||||
|
|
||||||
class LocalPiHardwareSPI(SPI, Device):
|
class LocalPiHardwareSPI(SPI, Device):
|
||||||
def __init__(self, factory, port, device):
|
def __init__(self, factory, port, device):
|
||||||
if SpiDev is None:
|
|
||||||
raise ImportError('failed to import spidev')
|
|
||||||
self._port = port
|
self._port = port
|
||||||
self._device = device
|
self._device = device
|
||||||
self._interface = None
|
self._interface = None
|
||||||
self._address = factory.address + ('SPI(port=%d, device=%d)' % (port, device),)
|
if SpiDev is None:
|
||||||
|
raise ImportError('failed to import spidev')
|
||||||
super(LocalPiHardwareSPI, self).__init__()
|
super(LocalPiHardwareSPI, self).__init__()
|
||||||
pins = SPI_HARDWARE_PINS[port]
|
pins = SPI_HARDWARE_PINS[port]
|
||||||
self._reserve_pins(
|
self.pin_factory.reserve_pins(
|
||||||
factory.pin_address(pins['clock']),
|
self,
|
||||||
factory.pin_address(pins['mosi']),
|
pins['clock'],
|
||||||
factory.pin_address(pins['miso']),
|
pins['mosi'],
|
||||||
factory.pin_address(pins['select'][device])
|
pins['miso'],
|
||||||
|
pins['select'][device]
|
||||||
)
|
)
|
||||||
self._interface = SpiDev()
|
self._interface = SpiDev()
|
||||||
self._interface.open(port, device)
|
self._interface.open(port, device)
|
||||||
@@ -98,7 +101,7 @@ class LocalPiHardwareSPI(SPI, Device):
|
|||||||
self._interface.close()
|
self._interface.close()
|
||||||
finally:
|
finally:
|
||||||
self._interface = None
|
self._interface = None
|
||||||
self._release_all()
|
self.pin_factory.release_all(self)
|
||||||
super(LocalPiHardwareSPI, self).close()
|
super(LocalPiHardwareSPI, self).close()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -148,10 +151,6 @@ class LocalPiHardwareSPI(SPI, Device):
|
|||||||
class LocalPiSoftwareSPI(SPI, OutputDevice):
|
class LocalPiSoftwareSPI(SPI, OutputDevice):
|
||||||
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._bus = None
|
self._bus = None
|
||||||
self._address = factory.address + (
|
|
||||||
'SPI(clock_pin=%d, mosi_pin=%d, miso_pin=%d, select_pin=%d)' % (
|
|
||||||
clock_pin, mosi_pin, miso_pin, select_pin),
|
|
||||||
)
|
|
||||||
super(LocalPiSoftwareSPI, self).__init__(select_pin, active_high=False)
|
super(LocalPiSoftwareSPI, self).__init__(select_pin, active_high=False)
|
||||||
try:
|
try:
|
||||||
self._clock_phase = False
|
self._clock_phase = False
|
||||||
@@ -163,6 +162,7 @@ class LocalPiSoftwareSPI(SPI, OutputDevice):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
def _conflicts_with(self, other):
|
def _conflicts_with(self, other):
|
||||||
|
# XXX Need to refine this
|
||||||
return not (
|
return not (
|
||||||
isinstance(other, LocalPiSoftwareSPI) and
|
isinstance(other, LocalPiSoftwareSPI) and
|
||||||
(self.pin.number != other.pin.number)
|
(self.pin.number != other.pin.number)
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class MockPin(PiPin):
|
|||||||
def __init__(self, factory, number):
|
def __init__(self, factory, number):
|
||||||
super(MockPin, self).__init__(factory, number)
|
super(MockPin, self).__init__(factory, number)
|
||||||
self._function = 'input'
|
self._function = 'input'
|
||||||
self._pull = 'up' if 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._state = self._pull == 'up'
|
self._state = self._pull == 'up'
|
||||||
self._bounce = None
|
self._bounce = None
|
||||||
self._edges = 'both'
|
self._edges = 'both'
|
||||||
@@ -94,7 +94,7 @@ class MockPin(PiPin):
|
|||||||
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)
|
||||||
if value not in ('floating', 'up', 'down'):
|
if value not in ('floating', 'up', 'down'):
|
||||||
raise PinInvalidPull('pull must be floating, up, or down')
|
raise PinInvalidPull('pull must be floating, up, or down')
|
||||||
@@ -423,14 +423,12 @@ class MockFactory(LocalPiFactory):
|
|||||||
pin_class = pkg_resources.load_entry_point(dist, group, pin_class.lower())
|
pin_class = pkg_resources.load_entry_point(dist, group, pin_class.lower())
|
||||||
self.pin_class = pin_class
|
self.pin_class = pin_class
|
||||||
|
|
||||||
def _get_address(self):
|
|
||||||
return ('mock',)
|
|
||||||
|
|
||||||
def _get_revision(self):
|
def _get_revision(self):
|
||||||
return self._revision
|
return self._revision
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.pins.clear()
|
self.pins.clear()
|
||||||
|
self._reservations.clear()
|
||||||
|
|
||||||
def pin(self, spec, pin_class=None, **kwargs):
|
def pin(self, spec, pin_class=None, **kwargs):
|
||||||
if pin_class is None:
|
if pin_class is None:
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ class NativePin(LocalPiPin):
|
|||||||
self._change_thread = None
|
self._change_thread = None
|
||||||
self._change_event = Event()
|
self._change_event = Event()
|
||||||
self.function = 'input'
|
self.function = 'input'
|
||||||
self.pull = 'up' if 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.bounce = None
|
self.bounce = None
|
||||||
self.edges = 'both'
|
self.edges = 'both'
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ class NativePin(LocalPiPin):
|
|||||||
self.frequency = None
|
self.frequency = None
|
||||||
self.when_changed = None
|
self.when_changed = None
|
||||||
self.function = 'input'
|
self.function = 'input'
|
||||||
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'
|
||||||
|
|
||||||
def _get_function(self):
|
def _get_function(self):
|
||||||
return self.GPIO_FUNCTION_NAMES[(self.factory.mem[self._func_offset] >> self._func_shift) & 7]
|
return self.GPIO_FUNCTION_NAMES[(self.factory.mem[self._func_offset] >> self._func_shift) & 7]
|
||||||
@@ -269,7 +269,7 @@ class NativePin(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:
|
||||||
value = self.GPIO_PULL_UPS[value]
|
value = self.GPIO_PULL_UPS[value]
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ from __future__ import (
|
|||||||
str = type('')
|
str = type('')
|
||||||
|
|
||||||
import io
|
import io
|
||||||
from threading import RLock
|
from threading import RLock, Lock
|
||||||
from types import MethodType
|
from types import MethodType
|
||||||
|
from collections import defaultdict
|
||||||
try:
|
try:
|
||||||
from weakref import ref, WeakMethod
|
from weakref import ref, WeakMethod
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -48,6 +49,7 @@ class PiFactory(Factory):
|
|||||||
forms the base of :class:`~gpiozero.pins.local.LocalPiFactory`.
|
forms the base of :class:`~gpiozero.pins.local.LocalPiFactory`.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
super(PiFactory, self).__init__()
|
||||||
self._info = None
|
self._info = None
|
||||||
self.pins = {}
|
self.pins = {}
|
||||||
self.pin_class = None
|
self.pin_class = None
|
||||||
@@ -72,10 +74,6 @@ class PiFactory(Factory):
|
|||||||
self.pins[n] = pin
|
self.pins[n] = pin
|
||||||
return pin
|
return pin
|
||||||
|
|
||||||
def pin_address(self, spec):
|
|
||||||
n = self._to_gpio(spec)
|
|
||||||
return self.address + ('GPIO%d' % n,)
|
|
||||||
|
|
||||||
def _to_gpio(self, spec):
|
def _to_gpio(self, spec):
|
||||||
"""
|
"""
|
||||||
Converts the pin *spec* to a GPIO port number.
|
Converts the pin *spec* to a GPIO port number.
|
||||||
@@ -240,23 +238,23 @@ class PiPin(Pin):
|
|||||||
self._when_changed = None
|
self._when_changed = None
|
||||||
self._number = number
|
self._number = number
|
||||||
try:
|
try:
|
||||||
factory.pi_info.physical_pin(self.address[-1])
|
factory.pi_info.physical_pin('GPIO%d' % self.number)
|
||||||
except PinNoPins:
|
except PinNoPins:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
PinNonPhysical(
|
PinNonPhysical(
|
||||||
'no physical pins exist for %s' % self.address[-1]))
|
'no physical pins exist for GPIO%d' % self.number))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def number(self):
|
def number(self):
|
||||||
return self._number
|
return self._number
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return 'GPIO%d' % self._number
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def factory(self):
|
def factory(self):
|
||||||
return self._factory
|
return self._factory
|
||||||
|
|
||||||
def _get_address(self):
|
|
||||||
return self.factory.address + ('GPIO%d' % self.number,)
|
|
||||||
|
|
||||||
def _call_when_changed(self):
|
def _call_when_changed(self):
|
||||||
"""
|
"""
|
||||||
Called to fire the :attr:`when_changed` event handler; override this
|
Called to fire the :attr:`when_changed` event handler; override this
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from __future__ import (
|
|||||||
str = type('')
|
str = type('')
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from weakref import proxy
|
|
||||||
|
|
||||||
import pigpio
|
import pigpio
|
||||||
|
|
||||||
@@ -126,9 +125,6 @@ class PiGPIOFactory(PiFactory):
|
|||||||
def _get_revision(self):
|
def _get_revision(self):
|
||||||
return self.connection.get_hardware_revision()
|
return self.connection.get_hardware_revision()
|
||||||
|
|
||||||
def _get_address(self):
|
|
||||||
return ("%s:%d" % (self.host, self.port),)
|
|
||||||
|
|
||||||
def spi(self, **spi_args):
|
def spi(self, **spi_args):
|
||||||
intf = super(PiGPIOFactory, self).spi(**spi_args)
|
intf = super(PiGPIOFactory, self).spi(**spi_args)
|
||||||
self._spis.append(intf)
|
self._spis.append(intf)
|
||||||
@@ -166,7 +162,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(self.address[-1]) else 'floating'
|
self._pull = 'up' if 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
|
||||||
@@ -183,7 +179,7 @@ class PiGPIOPin(PiPin):
|
|||||||
self.frequency = None
|
self.frequency = None
|
||||||
self.when_changed = None
|
self.when_changed = None
|
||||||
self.function = 'input'
|
self.function = 'input'
|
||||||
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'
|
||||||
|
|
||||||
def _get_function(self):
|
def _get_function(self):
|
||||||
return self.GPIO_FUNCTION_NAMES[self.factory.connection.get_mode(self.number)]
|
return self.GPIO_FUNCTION_NAMES[self.factory.connection.get_mode(self.number)]
|
||||||
@@ -225,7 +221,7 @@ class PiGPIOPin(PiPin):
|
|||||||
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:
|
||||||
self.factory.connection.set_pull_up_down(self.number, self.GPIO_PULL_UPS[value])
|
self.factory.connection.set_pull_up_down(self.number, self.GPIO_PULL_UPS[value])
|
||||||
@@ -296,19 +292,17 @@ class PiGPIOHardwareSPI(SPI, Device):
|
|||||||
def __init__(self, factory, port, device):
|
def __init__(self, factory, port, device):
|
||||||
self._port = port
|
self._port = port
|
||||||
self._device = device
|
self._device = device
|
||||||
self._factory = proxy(factory)
|
self._factory = factory
|
||||||
self._handle = None
|
self._handle = None
|
||||||
super(PiGPIOHardwareSPI, self).__init__()
|
super(PiGPIOHardwareSPI, self).__init__()
|
||||||
pins = SPI_HARDWARE_PINS[port]
|
pins = SPI_HARDWARE_PINS[port]
|
||||||
self._reserve_pins(*(
|
self._factory.reserve_pins(
|
||||||
factory.address + ('GPIO%d' % pin,)
|
self,
|
||||||
for pin in (
|
|
||||||
pins['clock'],
|
pins['clock'],
|
||||||
pins['mosi'],
|
pins['mosi'],
|
||||||
pins['miso'],
|
pins['miso'],
|
||||||
pins['select'][device]
|
pins['select'][device]
|
||||||
)
|
)
|
||||||
))
|
|
||||||
self._spi_flags = 8 << 16
|
self._spi_flags = 8 << 16
|
||||||
self._baud = 500000
|
self._baud = 500000
|
||||||
self._handle = self._factory.connection.spi_open(
|
self._handle = self._factory.connection.spi_open(
|
||||||
@@ -330,7 +324,7 @@ class PiGPIOHardwareSPI(SPI, Device):
|
|||||||
if not self.closed:
|
if not self.closed:
|
||||||
self._factory.connection.spi_close(self._handle)
|
self._factory.connection.spi_close(self._handle)
|
||||||
self._handle = None
|
self._handle = None
|
||||||
self._release_all()
|
self._factory.release_all(self)
|
||||||
super(PiGPIOHardwareSPI, self).close()
|
super(PiGPIOHardwareSPI, self).close()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -397,13 +391,14 @@ class PiGPIOSoftwareSPI(SPI, Device):
|
|||||||
self._clock_pin = clock_pin
|
self._clock_pin = clock_pin
|
||||||
self._mosi_pin = mosi_pin
|
self._mosi_pin = mosi_pin
|
||||||
self._miso_pin = miso_pin
|
self._miso_pin = miso_pin
|
||||||
self._factory = proxy(factory)
|
self._factory = factory
|
||||||
super(PiGPIOSoftwareSPI, self).__init__()
|
super(PiGPIOSoftwareSPI, self).__init__()
|
||||||
self._reserve_pins(
|
self._factory.reserve_pins(
|
||||||
factory.pin_address(clock_pin),
|
self,
|
||||||
factory.pin_address(mosi_pin),
|
clock_pin,
|
||||||
factory.pin_address(miso_pin),
|
mosi_pin,
|
||||||
factory.pin_address(select_pin),
|
miso_pin,
|
||||||
|
select_pin,
|
||||||
)
|
)
|
||||||
self._spi_flags = 0
|
self._spi_flags = 0
|
||||||
self._baud = 100000
|
self._baud = 100000
|
||||||
@@ -434,7 +429,7 @@ class PiGPIOSoftwareSPI(SPI, Device):
|
|||||||
if not self.closed:
|
if not self.closed:
|
||||||
self._closed = True
|
self._closed = True
|
||||||
self._factory.connection.bb_spi_close(self._select_pin)
|
self._factory.connection.bb_spi_close(self._select_pin)
|
||||||
self._release_all()
|
self.factory.release_all(self)
|
||||||
super(PiGPIOSoftwareSPI, self).close()
|
super(PiGPIOSoftwareSPI, self).close()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -85,7 +85,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 factory.pi_info.pulled_up(self.address[-1]) else 'floating'
|
self._pull = 'up' if self.factory.pi_info.pulled_up(self.address[-1]) else 'floating'
|
||||||
self._pwm = None
|
self._pwm = None
|
||||||
self._frequency = None
|
self._frequency = None
|
||||||
self._duty_cycle = None
|
self._duty_cycle = None
|
||||||
|
|||||||
@@ -80,7 +80,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 factory.pi_info.pulled_up(self.address[-1]) else 'floating'
|
self._pull = 'up' if self.factory.pi_info.pulled_up(self.address[-1]) else 'floating'
|
||||||
self._pwm = False
|
self._pwm = False
|
||||||
self._duty_cycle = None
|
self._duty_cycle = None
|
||||||
self._bounce = None
|
self._bounce = None
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ class SPIDevice(Device):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, **spi_args):
|
def __init__(self, **spi_args):
|
||||||
self._spi = None
|
self._spi = None
|
||||||
super(SPIDevice, self).__init__()
|
super(SPIDevice, self).__init__(
|
||||||
|
pin_factory=spi_args.pop('pin_factory', None)
|
||||||
|
)
|
||||||
self._spi = self.pin_factory.spi(**spi_args)
|
self._spi = self.pin_factory.spi(**spi_args)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ def setup_function(function):
|
|||||||
|
|
||||||
def teardown_function(function):
|
def teardown_function(function):
|
||||||
Device.pin_factory.reset()
|
Device.pin_factory.reset()
|
||||||
Device._reservations.clear()
|
|
||||||
|
|
||||||
def teardown_module(module):
|
def teardown_module(module):
|
||||||
# make sure we reset the default
|
# make sure we reset the default
|
||||||
@@ -47,7 +46,7 @@ def test_composite_output_on_off():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with CompositeOutputDevice(OutputDevice(pin1), OutputDevice(pin2), foo=OutputDevice(pin3)) as device:
|
with CompositeOutputDevice(OutputDevice(2), OutputDevice(3), foo=OutputDevice(4)) as device:
|
||||||
device.on()
|
device.on()
|
||||||
assert all((pin1.state, pin2.state, pin3.state))
|
assert all((pin1.state, pin2.state, pin3.state))
|
||||||
device.off()
|
device.off()
|
||||||
@@ -57,7 +56,7 @@ def test_composite_output_toggle():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with CompositeOutputDevice(OutputDevice(pin1), OutputDevice(pin2), foo=OutputDevice(pin3)) as device:
|
with CompositeOutputDevice(OutputDevice(2), OutputDevice(3), foo=OutputDevice(4)) as device:
|
||||||
device.toggle()
|
device.toggle()
|
||||||
assert all((pin1.state, pin2.state, pin3.state))
|
assert all((pin1.state, pin2.state, pin3.state))
|
||||||
device[0].off()
|
device[0].off()
|
||||||
@@ -70,7 +69,7 @@ def test_composite_output_value():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with CompositeOutputDevice(OutputDevice(pin1), OutputDevice(pin2), foo=OutputDevice(pin3)) as device:
|
with CompositeOutputDevice(OutputDevice(2), OutputDevice(3), foo=OutputDevice(4)) as device:
|
||||||
assert device.value == (0, 0, 0)
|
assert device.value == (0, 0, 0)
|
||||||
device.toggle()
|
device.toggle()
|
||||||
assert device.value == (1, 1, 1)
|
assert device.value == (1, 1, 1)
|
||||||
@@ -83,7 +82,7 @@ def test_led_board_on_off():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBoard(pin1, pin2, foo=pin3) as board:
|
with LEDBoard(2, 3, foo=4) as board:
|
||||||
assert isinstance(board[0], LED)
|
assert isinstance(board[0], LED)
|
||||||
assert isinstance(board[1], LED)
|
assert isinstance(board[1], LED)
|
||||||
assert isinstance(board[2], LED)
|
assert isinstance(board[2], LED)
|
||||||
@@ -140,7 +139,7 @@ def test_led_board_active_low():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBoard(pin1, pin2, foo=pin3, active_high=False) as board:
|
with LEDBoard(2, 3, foo=4, active_high=False) as board:
|
||||||
assert not board.active_high
|
assert not board.active_high
|
||||||
assert not board[0].active_high
|
assert not board[0].active_high
|
||||||
assert not board[1].active_high
|
assert not board[1].active_high
|
||||||
@@ -164,7 +163,7 @@ def test_led_board_value():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBoard(pin1, pin2, foo=pin3) as board:
|
with LEDBoard(2, 3, foo=4) as board:
|
||||||
assert board.value == (0, 0, 0)
|
assert board.value == (0, 0, 0)
|
||||||
board.value = (0, 1, 0)
|
board.value = (0, 1, 0)
|
||||||
assert board.value == (0, 1, 0)
|
assert board.value == (0, 1, 0)
|
||||||
@@ -175,7 +174,7 @@ def test_led_board_pwm_value():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBoard(pin1, pin2, foo=pin3, pwm=True) as board:
|
with LEDBoard(2, 3, foo=4, pwm=True) as board:
|
||||||
assert board.value == (0, 0, 0)
|
assert board.value == (0, 0, 0)
|
||||||
board.value = (0, 1, 0)
|
board.value = (0, 1, 0)
|
||||||
assert board.value == (0, 1, 0)
|
assert board.value == (0, 1, 0)
|
||||||
@@ -186,7 +185,7 @@ def test_led_board_pwm_bad_value():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBoard(pin1, pin2, foo=pin3, pwm=True) as board:
|
with LEDBoard(2, 3, foo=4, pwm=True) as board:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
board.value = (-1, 0, 0)
|
board.value = (-1, 0, 0)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
@@ -196,20 +195,20 @@ def test_led_board_initial_value():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBoard(pin1, pin2, foo=pin3, initial_value=0) as board:
|
with LEDBoard(2, 3, foo=4, initial_value=0) as board:
|
||||||
assert board.value == (0, 0, 0)
|
assert board.value == (0, 0, 0)
|
||||||
with LEDBoard(pin1, pin2, foo=pin3, initial_value=1) as board:
|
with LEDBoard(2, 3, foo=4, initial_value=1) as board:
|
||||||
assert board.value == (1, 1, 1)
|
assert board.value == (1, 1, 1)
|
||||||
|
|
||||||
def test_led_board_pwm_initial_value():
|
def test_led_board_pwm_initial_value():
|
||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBoard(pin1, pin2, foo=pin3, pwm=True, initial_value=0) as board:
|
with LEDBoard(2, 3, foo=4, pwm=True, initial_value=0) as board:
|
||||||
assert board.value == (0, 0, 0)
|
assert board.value == (0, 0, 0)
|
||||||
with LEDBoard(pin1, pin2, foo=pin3, pwm=True, initial_value=1) as board:
|
with LEDBoard(2, 3, foo=4, pwm=True, initial_value=1) as board:
|
||||||
assert board.value == (1, 1, 1)
|
assert board.value == (1, 1, 1)
|
||||||
with LEDBoard(pin1, pin2, foo=pin3, pwm=True, initial_value=0.5) as board:
|
with LEDBoard(2, 3, foo=4, pwm=True, initial_value=0.5) as board:
|
||||||
assert board.value == (0.5, 0.5, 0.5)
|
assert board.value == (0.5, 0.5, 0.5)
|
||||||
|
|
||||||
def test_led_board_pwm_bad_initial_value():
|
def test_led_board_pwm_bad_initial_value():
|
||||||
@@ -217,15 +216,15 @@ def test_led_board_pwm_bad_initial_value():
|
|||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
LEDBoard(pin1, pin2, foo=pin3, pwm=True, initial_value=-1)
|
LEDBoard(2, 3, foo=4, pwm=True, initial_value=-1)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
LEDBoard(pin1, pin2, foo=pin3, pwm=True, initial_value=2)
|
LEDBoard(2, 3, foo=4, pwm=True, initial_value=2)
|
||||||
|
|
||||||
def test_led_board_nested():
|
def test_led_board_nested():
|
||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
with LEDBoard(2, LEDBoard(3, 4)) as board:
|
||||||
assert list(led.pin for led in board.leds) == [pin1, pin2, pin3]
|
assert list(led.pin for led in board.leds) == [pin1, pin2, pin3]
|
||||||
assert board.value == (0, (0, 0))
|
assert board.value == (0, (0, 0))
|
||||||
board.value = (1, (0, 1))
|
board.value = (1, (0, 1))
|
||||||
@@ -237,7 +236,7 @@ def test_led_board_bad_blink():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
with LEDBoard(2, LEDBoard(3, 4)) as board:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
board.blink(fade_in_time=1, fade_out_time=1)
|
board.blink(fade_in_time=1, fade_out_time=1)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
@@ -251,7 +250,7 @@ def test_led_board_blink_background():
|
|||||||
pin1 = Device.pin_factory.pin(4)
|
pin1 = Device.pin_factory.pin(4)
|
||||||
pin2 = Device.pin_factory.pin(5)
|
pin2 = Device.pin_factory.pin(5)
|
||||||
pin3 = Device.pin_factory.pin(6)
|
pin3 = Device.pin_factory.pin(6)
|
||||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
with LEDBoard(4, LEDBoard(5, 6)) as board:
|
||||||
# Instantiation takes a long enough time that it throws off our timing
|
# Instantiation takes a long enough time that it throws off our timing
|
||||||
# here!
|
# here!
|
||||||
pin1.clear_states()
|
pin1.clear_states()
|
||||||
@@ -276,7 +275,7 @@ def test_led_board_blink_foreground():
|
|||||||
pin1 = Device.pin_factory.pin(4)
|
pin1 = Device.pin_factory.pin(4)
|
||||||
pin2 = Device.pin_factory.pin(5)
|
pin2 = Device.pin_factory.pin(5)
|
||||||
pin3 = Device.pin_factory.pin(6)
|
pin3 = Device.pin_factory.pin(6)
|
||||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
with LEDBoard(4, LEDBoard(5, 6)) as board:
|
||||||
pin1.clear_states()
|
pin1.clear_states()
|
||||||
pin2.clear_states()
|
pin2.clear_states()
|
||||||
pin3.clear_states()
|
pin3.clear_states()
|
||||||
@@ -298,7 +297,7 @@ def test_led_board_blink_control():
|
|||||||
pin1 = Device.pin_factory.pin(4)
|
pin1 = Device.pin_factory.pin(4)
|
||||||
pin2 = Device.pin_factory.pin(5)
|
pin2 = Device.pin_factory.pin(5)
|
||||||
pin3 = Device.pin_factory.pin(6)
|
pin3 = Device.pin_factory.pin(6)
|
||||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
with LEDBoard(4, LEDBoard(5, 6)) as board:
|
||||||
pin1.clear_states()
|
pin1.clear_states()
|
||||||
pin2.clear_states()
|
pin2.clear_states()
|
||||||
pin3.clear_states()
|
pin3.clear_states()
|
||||||
@@ -326,7 +325,7 @@ def test_led_board_blink_take_over():
|
|||||||
pin1 = Device.pin_factory.pin(4)
|
pin1 = Device.pin_factory.pin(4)
|
||||||
pin2 = Device.pin_factory.pin(5)
|
pin2 = Device.pin_factory.pin(5)
|
||||||
pin3 = Device.pin_factory.pin(6)
|
pin3 = Device.pin_factory.pin(6)
|
||||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
with LEDBoard(4, LEDBoard(5, 6)) as board:
|
||||||
pin1.clear_states()
|
pin1.clear_states()
|
||||||
pin2.clear_states()
|
pin2.clear_states()
|
||||||
pin3.clear_states()
|
pin3.clear_states()
|
||||||
@@ -351,7 +350,7 @@ def test_led_board_blink_control_all():
|
|||||||
pin1 = Device.pin_factory.pin(4)
|
pin1 = Device.pin_factory.pin(4)
|
||||||
pin2 = Device.pin_factory.pin(5)
|
pin2 = Device.pin_factory.pin(5)
|
||||||
pin3 = Device.pin_factory.pin(6)
|
pin3 = Device.pin_factory.pin(6)
|
||||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
with LEDBoard(4, LEDBoard(5, 6)) as board:
|
||||||
pin1.clear_states()
|
pin1.clear_states()
|
||||||
pin2.clear_states()
|
pin2.clear_states()
|
||||||
pin3.clear_states()
|
pin3.clear_states()
|
||||||
@@ -376,7 +375,7 @@ def test_led_board_blink_interrupt_on():
|
|||||||
pin1 = Device.pin_factory.pin(4)
|
pin1 = Device.pin_factory.pin(4)
|
||||||
pin2 = Device.pin_factory.pin(5)
|
pin2 = Device.pin_factory.pin(5)
|
||||||
pin3 = Device.pin_factory.pin(6)
|
pin3 = Device.pin_factory.pin(6)
|
||||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
with LEDBoard(4, LEDBoard(5, 6)) as board:
|
||||||
board.blink(1, 0.1)
|
board.blink(1, 0.1)
|
||||||
sleep(0.2)
|
sleep(0.2)
|
||||||
board.off() # should interrupt while on
|
board.off() # should interrupt while on
|
||||||
@@ -388,7 +387,7 @@ def test_led_board_blink_interrupt_off():
|
|||||||
pin1 = Device.pin_factory.pin(4)
|
pin1 = Device.pin_factory.pin(4)
|
||||||
pin2 = Device.pin_factory.pin(5)
|
pin2 = Device.pin_factory.pin(5)
|
||||||
pin3 = Device.pin_factory.pin(6)
|
pin3 = Device.pin_factory.pin(6)
|
||||||
with LEDBoard(pin1, LEDBoard(pin2, pin3)) as board:
|
with LEDBoard(4, LEDBoard(5, 6)) as board:
|
||||||
pin1.clear_states()
|
pin1.clear_states()
|
||||||
pin2.clear_states()
|
pin2.clear_states()
|
||||||
pin3.clear_states()
|
pin3.clear_states()
|
||||||
@@ -405,7 +404,7 @@ def test_led_board_fade_background():
|
|||||||
pin1 = Device.pin_factory.pin(4)
|
pin1 = Device.pin_factory.pin(4)
|
||||||
pin2 = Device.pin_factory.pin(5)
|
pin2 = Device.pin_factory.pin(5)
|
||||||
pin3 = Device.pin_factory.pin(6)
|
pin3 = Device.pin_factory.pin(6)
|
||||||
with LEDBoard(pin1, LEDBoard(pin2, pin3, pwm=True), pwm=True) as board:
|
with LEDBoard(4, LEDBoard(5, 6, pwm=True), pwm=True) as board:
|
||||||
pin1.clear_states()
|
pin1.clear_states()
|
||||||
pin2.clear_states()
|
pin2.clear_states()
|
||||||
pin3.clear_states()
|
pin3.clear_states()
|
||||||
@@ -442,7 +441,7 @@ def test_led_bar_graph_value():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBarGraph(pin1, pin2, pin3) as graph:
|
with LEDBarGraph(2, 3, 4) as graph:
|
||||||
assert isinstance(graph[0], LED)
|
assert isinstance(graph[0], LED)
|
||||||
assert isinstance(graph[1], LED)
|
assert isinstance(graph[1], LED)
|
||||||
assert isinstance(graph[2], LED)
|
assert isinstance(graph[2], LED)
|
||||||
@@ -475,7 +474,7 @@ def test_led_bar_graph_active_low():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBarGraph(pin1, pin2, pin3, active_high=False) as graph:
|
with LEDBarGraph(2, 3, 4, active_high=False) as graph:
|
||||||
assert not graph.active_high
|
assert not graph.active_high
|
||||||
assert not graph[0].active_high
|
assert not graph[0].active_high
|
||||||
assert not graph[1].active_high
|
assert not graph[1].active_high
|
||||||
@@ -497,7 +496,7 @@ def test_led_bar_graph_pwm_value():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBarGraph(pin1, pin2, pin3, pwm=True) as graph:
|
with LEDBarGraph(2, 3, 4, pwm=True) as graph:
|
||||||
assert isinstance(graph[0], PWMLED)
|
assert isinstance(graph[0], PWMLED)
|
||||||
assert isinstance(graph[1], PWMLED)
|
assert isinstance(graph[1], PWMLED)
|
||||||
assert isinstance(graph[2], PWMLED)
|
assert isinstance(graph[2], PWMLED)
|
||||||
@@ -524,7 +523,7 @@ def test_led_bar_graph_bad_value():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBarGraph(pin1, pin2, pin3) as graph:
|
with LEDBarGraph(2, 3, 4) as graph:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
graph.value = -2
|
graph.value = -2
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
@@ -535,20 +534,20 @@ def test_led_bar_graph_bad_init():
|
|||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
LEDBarGraph(pin1, pin2, foo=pin3)
|
LEDBarGraph(2, 3, foo=4)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
LEDBarGraph(pin1, pin2, pin3, initial_value=-2)
|
LEDBarGraph(2, 3, 4, initial_value=-2)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
LEDBarGraph(pin1, pin2, pin3, initial_value=2)
|
LEDBarGraph(2, 3, 4, initial_value=2)
|
||||||
|
|
||||||
def test_led_bar_graph_initial_value():
|
def test_led_bar_graph_initial_value():
|
||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBarGraph(pin1, pin2, pin3, initial_value=1/3) as graph:
|
with LEDBarGraph(2, 3, 4, initial_value=1/3) as graph:
|
||||||
assert graph.value == 1/3
|
assert graph.value == 1/3
|
||||||
assert pin1.state and not (pin2.state or pin3.state)
|
assert pin1.state and not (pin2.state or pin3.state)
|
||||||
with LEDBarGraph(pin1, pin2, pin3, initial_value=-1/3) as graph:
|
with LEDBarGraph(2, 3, 4, initial_value=-1/3) as graph:
|
||||||
assert graph.value == -1/3
|
assert graph.value == -1/3
|
||||||
assert pin3.state and not (pin1.state or pin2.state)
|
assert pin3.state and not (pin1.state or pin2.state)
|
||||||
|
|
||||||
@@ -556,10 +555,10 @@ def test_led_bar_graph_pwm_initial_value():
|
|||||||
pin1 = Device.pin_factory.pin(2)
|
pin1 = Device.pin_factory.pin(2)
|
||||||
pin2 = Device.pin_factory.pin(3)
|
pin2 = Device.pin_factory.pin(3)
|
||||||
pin3 = Device.pin_factory.pin(4)
|
pin3 = Device.pin_factory.pin(4)
|
||||||
with LEDBarGraph(pin1, pin2, pin3, pwm=True, initial_value=0.5) as graph:
|
with LEDBarGraph(2, 3, 4, pwm=True, initial_value=0.5) as graph:
|
||||||
assert graph.value == 0.5
|
assert graph.value == 0.5
|
||||||
assert (pin1.state, pin2.state, pin3.state) == (1, 0.5, 0)
|
assert (pin1.state, pin2.state, pin3.state) == (1, 0.5, 0)
|
||||||
with LEDBarGraph(pin1, pin2, pin3, pwm=True, initial_value=-0.5) as graph:
|
with LEDBarGraph(2, 3, 4, pwm=True, initial_value=-0.5) as graph:
|
||||||
assert graph.value == -0.5
|
assert graph.value == -0.5
|
||||||
assert (pin1.state, pin2.state, pin3.state) == (0, 0.5, 1)
|
assert (pin1.state, pin2.state, pin3.state) == (0, 0.5, 1)
|
||||||
|
|
||||||
@@ -585,7 +584,7 @@ def test_traffic_lights():
|
|||||||
red_pin = Device.pin_factory.pin(2)
|
red_pin = Device.pin_factory.pin(2)
|
||||||
amber_pin = Device.pin_factory.pin(3)
|
amber_pin = Device.pin_factory.pin(3)
|
||||||
green_pin = Device.pin_factory.pin(4)
|
green_pin = Device.pin_factory.pin(4)
|
||||||
with TrafficLights(red_pin, amber_pin, green_pin) as board:
|
with TrafficLights(2, 3, 4) as board:
|
||||||
board.red.on()
|
board.red.on()
|
||||||
assert board.red.value
|
assert board.red.value
|
||||||
assert not board.amber.value
|
assert not board.amber.value
|
||||||
@@ -598,7 +597,7 @@ def test_traffic_lights():
|
|||||||
assert amber_pin.state
|
assert amber_pin.state
|
||||||
board.yellow.off()
|
board.yellow.off()
|
||||||
assert not amber_pin.state
|
assert not amber_pin.state
|
||||||
with TrafficLights(red=red_pin, yellow=amber_pin, green=green_pin) as board:
|
with TrafficLights(red=2, yellow=3, green=4) as board:
|
||||||
board.yellow.on()
|
board.yellow.on()
|
||||||
assert not board.red.value
|
assert not board.red.value
|
||||||
assert board.amber.value
|
assert board.amber.value
|
||||||
@@ -618,7 +617,7 @@ def test_traffic_lights_bad_init():
|
|||||||
green_pin = Device.pin_factory.pin(4)
|
green_pin = Device.pin_factory.pin(4)
|
||||||
yellow_pin = Device.pin_factory.pin(5)
|
yellow_pin = Device.pin_factory.pin(5)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
TrafficLights(red=red_pin, amber=amber_pin, yellow=yellow_pin, green=green_pin)
|
TrafficLights(red=2, amber=3, yellow=5, green=4)
|
||||||
|
|
||||||
def test_pi_traffic():
|
def test_pi_traffic():
|
||||||
pins = [Device.pin_factory.pin(n) for n in (9, 10, 11)]
|
pins = [Device.pin_factory.pin(n) for n in (9, 10, 11)]
|
||||||
@@ -677,9 +676,9 @@ def test_traffic_lights_buzzer():
|
|||||||
buzzer_pin = Device.pin_factory.pin(5)
|
buzzer_pin = Device.pin_factory.pin(5)
|
||||||
button_pin = Device.pin_factory.pin(6)
|
button_pin = Device.pin_factory.pin(6)
|
||||||
with TrafficLightsBuzzer(
|
with TrafficLightsBuzzer(
|
||||||
TrafficLights(red_pin, amber_pin, green_pin),
|
TrafficLights(2, 3, 4),
|
||||||
Buzzer(buzzer_pin),
|
Buzzer(5),
|
||||||
Button(button_pin)) as board:
|
Button(6)) as board:
|
||||||
board.lights.red.on()
|
board.lights.red.on()
|
||||||
board.buzzer.on()
|
board.buzzer.on()
|
||||||
assert red_pin.state
|
assert red_pin.state
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ def test_device_non_physical():
|
|||||||
|
|
||||||
def test_device_init():
|
def test_device_init():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with GPIODevice(pin) as device:
|
with GPIODevice(2) as device:
|
||||||
assert not device.closed
|
assert not device.closed
|
||||||
assert device.pin == pin
|
assert device.pin == pin
|
||||||
|
|
||||||
@@ -56,9 +56,9 @@ def test_device_close():
|
|||||||
|
|
||||||
def test_device_reopen_same_pin():
|
def test_device_reopen_same_pin():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with GPIODevice(pin) as device:
|
with GPIODevice(2) as device:
|
||||||
pass
|
pass
|
||||||
with GPIODevice(pin) as device2:
|
with GPIODevice(2) as device2:
|
||||||
assert not device2.closed
|
assert not device2.closed
|
||||||
assert device2.pin is pin
|
assert device2.pin is pin
|
||||||
assert device.closed
|
assert device.closed
|
||||||
|
|||||||
@@ -18,22 +18,21 @@ from gpiozero import *
|
|||||||
|
|
||||||
def teardown_function(function):
|
def teardown_function(function):
|
||||||
Device.pin_factory.reset()
|
Device.pin_factory.reset()
|
||||||
Device._reservations.clear()
|
|
||||||
|
|
||||||
|
|
||||||
def test_input_initial_values():
|
def test_input_initial_values():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with InputDevice(pin, pull_up=True) as device:
|
with InputDevice(4, pull_up=True) as device:
|
||||||
assert pin.function == 'input'
|
assert pin.function == 'input'
|
||||||
assert pin.pull == 'up'
|
assert pin.pull == 'up'
|
||||||
assert device.pull_up
|
assert device.pull_up
|
||||||
with InputDevice(pin, pull_up=False) as device:
|
with InputDevice(4, pull_up=False) as device:
|
||||||
assert pin.pull == 'down'
|
assert pin.pull == 'down'
|
||||||
assert not device.pull_up
|
assert not device.pull_up
|
||||||
|
|
||||||
def test_input_is_active_low():
|
def test_input_is_active_low():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with InputDevice(pin, pull_up=True) as device:
|
with InputDevice(2, pull_up=True) as device:
|
||||||
pin.drive_high()
|
pin.drive_high()
|
||||||
assert not device.is_active
|
assert not device.is_active
|
||||||
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO2, pull_up=True, is_active=False>'
|
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO2, pull_up=True, is_active=False>'
|
||||||
@@ -43,7 +42,7 @@ def test_input_is_active_low():
|
|||||||
|
|
||||||
def test_input_is_active_high():
|
def test_input_is_active_high():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with InputDevice(pin, pull_up=False) as device:
|
with InputDevice(4, pull_up=False) as device:
|
||||||
pin.drive_high()
|
pin.drive_high()
|
||||||
assert device.is_active
|
assert device.is_active
|
||||||
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO4, pull_up=False, is_active=True>'
|
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO4, pull_up=False, is_active=True>'
|
||||||
@@ -54,12 +53,12 @@ def test_input_is_active_high():
|
|||||||
def test_input_pulled_up():
|
def test_input_pulled_up():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with pytest.raises(PinFixedPull):
|
with pytest.raises(PinFixedPull):
|
||||||
InputDevice(pin, pull_up=False)
|
InputDevice(2, pull_up=False)
|
||||||
|
|
||||||
def test_input_event_activated():
|
def test_input_event_activated():
|
||||||
event = Event()
|
event = Event()
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with DigitalInputDevice(pin) as device:
|
with DigitalInputDevice(4) as device:
|
||||||
device.when_activated = lambda: event.set()
|
device.when_activated = lambda: event.set()
|
||||||
assert not event.is_set()
|
assert not event.is_set()
|
||||||
pin.drive_high()
|
pin.drive_high()
|
||||||
@@ -68,7 +67,7 @@ def test_input_event_activated():
|
|||||||
def test_input_event_deactivated():
|
def test_input_event_deactivated():
|
||||||
event = Event()
|
event = Event()
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with DigitalInputDevice(pin) as device:
|
with DigitalInputDevice(4) as device:
|
||||||
device.when_deactivated = lambda: event.set()
|
device.when_deactivated = lambda: event.set()
|
||||||
assert not event.is_set()
|
assert not event.is_set()
|
||||||
pin.drive_high()
|
pin.drive_high()
|
||||||
@@ -84,7 +83,7 @@ def test_input_partial_callback():
|
|||||||
return a + b
|
return a + b
|
||||||
bar = partial(foo, 1)
|
bar = partial(foo, 1)
|
||||||
baz = partial(bar, 2)
|
baz = partial(bar, 2)
|
||||||
with DigitalInputDevice(pin) as device:
|
with DigitalInputDevice(4) as device:
|
||||||
device.when_activated = baz
|
device.when_activated = baz
|
||||||
assert not event.is_set()
|
assert not event.is_set()
|
||||||
pin.drive_high()
|
pin.drive_high()
|
||||||
@@ -92,20 +91,20 @@ def test_input_partial_callback():
|
|||||||
|
|
||||||
def test_input_wait_active():
|
def test_input_wait_active():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with DigitalInputDevice(pin) as device:
|
with DigitalInputDevice(4) as device:
|
||||||
pin.drive_high()
|
pin.drive_high()
|
||||||
assert device.wait_for_active(1)
|
assert device.wait_for_active(1)
|
||||||
assert not device.wait_for_inactive(0)
|
assert not device.wait_for_inactive(0)
|
||||||
|
|
||||||
def test_input_wait_inactive():
|
def test_input_wait_inactive():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with DigitalInputDevice(pin) as device:
|
with DigitalInputDevice(4) as device:
|
||||||
assert device.wait_for_inactive(1)
|
assert device.wait_for_inactive(1)
|
||||||
assert not device.wait_for_active(0)
|
assert not device.wait_for_active(0)
|
||||||
|
|
||||||
def test_input_smoothed_attrib():
|
def test_input_smoothed_attrib():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with SmoothedInputDevice(pin, threshold=0.5, queue_len=5, partial=False) as device:
|
with SmoothedInputDevice(4, threshold=0.5, queue_len=5, partial=False) as device:
|
||||||
assert repr(device) == '<gpiozero.SmoothedInputDevice object on pin GPIO4, pull_up=False>'
|
assert repr(device) == '<gpiozero.SmoothedInputDevice object on pin GPIO4, pull_up=False>'
|
||||||
assert device.threshold == 0.5
|
assert device.threshold == 0.5
|
||||||
assert device.queue_len == 5
|
assert device.queue_len == 5
|
||||||
@@ -117,7 +116,7 @@ def test_input_smoothed_attrib():
|
|||||||
|
|
||||||
def test_input_smoothed_values():
|
def test_input_smoothed_values():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with SmoothedInputDevice(pin) as device:
|
with SmoothedInputDevice(4) as device:
|
||||||
device._queue.start()
|
device._queue.start()
|
||||||
assert not device.is_active
|
assert not device.is_active
|
||||||
pin.drive_high()
|
pin.drive_high()
|
||||||
@@ -127,7 +126,7 @@ def test_input_smoothed_values():
|
|||||||
|
|
||||||
def test_input_button():
|
def test_input_button():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with Button(pin) as button:
|
with Button(2) as button:
|
||||||
assert pin.pull == 'up'
|
assert pin.pull == 'up'
|
||||||
assert not button.is_pressed
|
assert not button.is_pressed
|
||||||
pin.drive_low()
|
pin.drive_low()
|
||||||
@@ -139,7 +138,7 @@ def test_input_button():
|
|||||||
|
|
||||||
def test_input_line_sensor():
|
def test_input_line_sensor():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with LineSensor(pin) as sensor:
|
with LineSensor(4) as sensor:
|
||||||
pin.drive_low() # logic is inverted for line sensor
|
pin.drive_low() # logic is inverted for line sensor
|
||||||
assert sensor.wait_for_line(1)
|
assert sensor.wait_for_line(1)
|
||||||
assert sensor.line_detected
|
assert sensor.line_detected
|
||||||
@@ -149,7 +148,7 @@ def test_input_line_sensor():
|
|||||||
|
|
||||||
def test_input_motion_sensor():
|
def test_input_motion_sensor():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with MotionSensor(pin) as sensor:
|
with MotionSensor(4) as sensor:
|
||||||
pin.drive_high()
|
pin.drive_high()
|
||||||
assert sensor.wait_for_motion(1)
|
assert sensor.wait_for_motion(1)
|
||||||
assert sensor.motion_detected
|
assert sensor.motion_detected
|
||||||
@@ -161,7 +160,7 @@ def test_input_motion_sensor():
|
|||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_input_light_sensor():
|
def test_input_light_sensor():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockChargingPin)
|
pin = Device.pin_factory.pin(4, pin_class=MockChargingPin)
|
||||||
with LightSensor(pin) as sensor:
|
with LightSensor(4) as sensor:
|
||||||
pin.charge_time = 0.1
|
pin.charge_time = 0.1
|
||||||
assert sensor.wait_for_dark(1)
|
assert sensor.wait_for_dark(1)
|
||||||
pin.charge_time = 0.0
|
pin.charge_time = 0.0
|
||||||
@@ -173,10 +172,10 @@ def test_input_distance_sensor():
|
|||||||
echo_pin = Device.pin_factory.pin(4)
|
echo_pin = Device.pin_factory.pin(4)
|
||||||
trig_pin = Device.pin_factory.pin(5, pin_class=MockTriggerPin, echo_pin=echo_pin, echo_time=0.02)
|
trig_pin = Device.pin_factory.pin(5, pin_class=MockTriggerPin, echo_pin=echo_pin, echo_time=0.02)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
DistanceSensor(echo_pin, trig_pin, max_distance=-1)
|
DistanceSensor(4, 5, max_distance=-1)
|
||||||
# normal queue len is large (because the sensor is *really* jittery) but
|
# normal queue len is large (because the sensor is *really* jittery) but
|
||||||
# we want quick tests and we've got precisely controlled pins :)
|
# we want quick tests and we've got precisely controlled pins :)
|
||||||
with DistanceSensor(echo_pin, trig_pin, queue_len=5, max_distance=1) as sensor:
|
with DistanceSensor(4, 5, queue_len=5, max_distance=1) as sensor:
|
||||||
assert sensor.max_distance == 1
|
assert sensor.max_distance == 1
|
||||||
assert sensor.trigger is trig_pin
|
assert sensor.trigger is trig_pin
|
||||||
assert sensor.echo is echo_pin
|
assert sensor.echo is echo_pin
|
||||||
|
|||||||
@@ -16,29 +16,73 @@ except ImportError:
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from gpiozero.pins.mock import MockPWMPin
|
from gpiozero.pins.mock import MockPin, MockPWMPin
|
||||||
from gpiozero import *
|
from gpiozero import *
|
||||||
|
|
||||||
|
|
||||||
|
def setup_function(function):
|
||||||
|
# dirty, but it does the job
|
||||||
|
Device.pin_factory.pin_class = MockPWMPin if function.__name__ in (
|
||||||
|
'test_output_pwm_states',
|
||||||
|
'test_output_pwm_read',
|
||||||
|
'test_output_pwm_write',
|
||||||
|
'test_output_pwm_toggle',
|
||||||
|
'test_output_pwm_active_high_read',
|
||||||
|
'test_output_pwm_bad_value',
|
||||||
|
'test_output_pwm_write_closed',
|
||||||
|
'test_output_pwm_write_silly',
|
||||||
|
'test_output_pwm_blink_background',
|
||||||
|
'test_output_pwm_blink_foreground',
|
||||||
|
'test_output_pwm_fade_background',
|
||||||
|
'test_output_pwm_fade_foreground',
|
||||||
|
'test_output_pwm_pulse_background',
|
||||||
|
'test_output_pwm_pulse_foreground',
|
||||||
|
'test_output_pwm_blink_interrupt',
|
||||||
|
'test_rgbled_initial_value',
|
||||||
|
'test_rgbled_initial_bad_value',
|
||||||
|
'test_rgbled_value',
|
||||||
|
'test_rgbled_bad_value',
|
||||||
|
'test_rgbled_toggle',
|
||||||
|
'test_rgbled_blink_background',
|
||||||
|
'test_rgbled_blink_foreground',
|
||||||
|
'test_rgbled_fade_background',
|
||||||
|
'test_rgbled_fade_foreground',
|
||||||
|
'test_rgbled_pulse_background',
|
||||||
|
'test_rgbled_pulse_foreground',
|
||||||
|
'test_rgbled_blink_interrupt',
|
||||||
|
'test_rgbled_close',
|
||||||
|
'test_motor_pins',
|
||||||
|
'test_motor_close',
|
||||||
|
'test_motor_value',
|
||||||
|
'test_motor_bad_value',
|
||||||
|
'test_motor_reverse',
|
||||||
|
'test_servo_pins',
|
||||||
|
'test_servo_bad_value',
|
||||||
|
'test_servo_close',
|
||||||
|
'test_servo_pulse_width',
|
||||||
|
'test_servo_values',
|
||||||
|
'test_angular_servo_range',
|
||||||
|
'test_angular_servo_angles',
|
||||||
|
) else MockPin
|
||||||
|
|
||||||
def teardown_function(function):
|
def teardown_function(function):
|
||||||
Device.pin_factory.reset()
|
Device.pin_factory.reset()
|
||||||
Device._reservations.clear()
|
|
||||||
|
|
||||||
|
|
||||||
def test_output_initial_values():
|
def test_output_initial_values():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with OutputDevice(pin, initial_value=False) as device:
|
with OutputDevice(2, initial_value=False) as device:
|
||||||
assert pin.function == 'output'
|
assert pin.function == 'output'
|
||||||
assert not pin.state
|
assert not pin.state
|
||||||
with OutputDevice(pin, initial_value=True) as device:
|
with OutputDevice(2, initial_value=True) as device:
|
||||||
assert pin.state
|
assert pin.state
|
||||||
state = pin.state
|
state = pin.state
|
||||||
with OutputDevice(pin, initial_value=None) as device:
|
with OutputDevice(2, initial_value=None) as device:
|
||||||
assert state == pin.state
|
assert state == pin.state
|
||||||
|
|
||||||
def test_output_write_active_high():
|
def test_output_write_active_high():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with OutputDevice(pin) as device:
|
with OutputDevice(2) as device:
|
||||||
device.on()
|
device.on()
|
||||||
assert pin.state
|
assert pin.state
|
||||||
device.off()
|
device.off()
|
||||||
@@ -46,14 +90,14 @@ def test_output_write_active_high():
|
|||||||
|
|
||||||
def test_output_write_active_low():
|
def test_output_write_active_low():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with OutputDevice(pin, active_high=False) as device:
|
with OutputDevice(2, active_high=False) as device:
|
||||||
device.on()
|
device.on()
|
||||||
assert not pin.state
|
assert not pin.state
|
||||||
device.off()
|
device.off()
|
||||||
assert pin.state
|
assert pin.state
|
||||||
|
|
||||||
def test_output_write_closed():
|
def test_output_write_closed():
|
||||||
with OutputDevice(Device.pin_factory.pin(2)) as device:
|
with OutputDevice(2) as device:
|
||||||
device.close()
|
device.close()
|
||||||
assert device.closed
|
assert device.closed
|
||||||
device.close()
|
device.close()
|
||||||
@@ -63,14 +107,14 @@ def test_output_write_closed():
|
|||||||
|
|
||||||
def test_output_write_silly():
|
def test_output_write_silly():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with OutputDevice(pin) as device:
|
with OutputDevice(2) as device:
|
||||||
pin.function = 'input'
|
pin.function = 'input'
|
||||||
with pytest.raises(AttributeError):
|
with pytest.raises(AttributeError):
|
||||||
device.on()
|
device.on()
|
||||||
|
|
||||||
def test_output_value():
|
def test_output_value():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with OutputDevice(pin) as device:
|
with OutputDevice(2) as device:
|
||||||
assert not device.value
|
assert not device.value
|
||||||
assert not pin.state
|
assert not pin.state
|
||||||
device.on()
|
device.on()
|
||||||
@@ -82,7 +126,7 @@ def test_output_value():
|
|||||||
|
|
||||||
def test_output_digital_toggle():
|
def test_output_digital_toggle():
|
||||||
pin = Device.pin_factory.pin(2)
|
pin = Device.pin_factory.pin(2)
|
||||||
with DigitalOutputDevice(pin) as device:
|
with DigitalOutputDevice(2) as device:
|
||||||
assert not device.value
|
assert not device.value
|
||||||
assert not pin.state
|
assert not pin.state
|
||||||
device.toggle()
|
device.toggle()
|
||||||
@@ -96,7 +140,7 @@ def test_output_digital_toggle():
|
|||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_output_blink_background():
|
def test_output_blink_background():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with DigitalOutputDevice(pin) as device:
|
with DigitalOutputDevice(4) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2)
|
device.blink(0.1, 0.1, n=2)
|
||||||
assert isclose(time() - start, 0, abs_tol=0.05)
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
@@ -114,7 +158,7 @@ def test_output_blink_background():
|
|||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_output_blink_foreground():
|
def test_output_blink_foreground():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with DigitalOutputDevice(pin) as device:
|
with DigitalOutputDevice(4) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2, background=False)
|
device.blink(0.1, 0.1, n=2, background=False)
|
||||||
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||||
@@ -128,7 +172,7 @@ def test_output_blink_foreground():
|
|||||||
|
|
||||||
def test_output_blink_interrupt_on():
|
def test_output_blink_interrupt_on():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with DigitalOutputDevice(pin) as device:
|
with DigitalOutputDevice(4) as device:
|
||||||
device.blink(1, 0.1)
|
device.blink(1, 0.1)
|
||||||
sleep(0.2)
|
sleep(0.2)
|
||||||
device.off() # should interrupt while on
|
device.off() # should interrupt while on
|
||||||
@@ -136,7 +180,7 @@ def test_output_blink_interrupt_on():
|
|||||||
|
|
||||||
def test_output_blink_interrupt_off():
|
def test_output_blink_interrupt_off():
|
||||||
pin = Device.pin_factory.pin(4)
|
pin = Device.pin_factory.pin(4)
|
||||||
with DigitalOutputDevice(pin) as device:
|
with DigitalOutputDevice(4) as device:
|
||||||
device.blink(0.1, 1)
|
device.blink(0.1, 1)
|
||||||
sleep(0.2)
|
sleep(0.2)
|
||||||
device.off() # should interrupt while off
|
device.off() # should interrupt while off
|
||||||
@@ -144,23 +188,23 @@ def test_output_blink_interrupt_off():
|
|||||||
|
|
||||||
def test_output_pwm_bad_initial_value():
|
def test_output_pwm_bad_initial_value():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
PWMOutputDevice(Device.pin_factory.pin(2), initial_value=2)
|
PWMOutputDevice(2, initial_value=2)
|
||||||
|
|
||||||
def test_output_pwm_not_supported():
|
def test_output_pwm_not_supported():
|
||||||
with pytest.raises(AttributeError):
|
with pytest.raises(AttributeError):
|
||||||
PWMOutputDevice(Device.pin_factory.pin(2))
|
PWMOutputDevice(2)
|
||||||
|
|
||||||
def test_output_pwm_states():
|
def test_output_pwm_states():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(4)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(4) as device:
|
||||||
device.value = 0.1
|
device.value = 0.1
|
||||||
device.value = 0.2
|
device.value = 0.2
|
||||||
device.value = 0.0
|
device.value = 0.0
|
||||||
pin.assert_states([0.0, 0.1, 0.2, 0.0])
|
pin.assert_states([0.0, 0.1, 0.2, 0.0])
|
||||||
|
|
||||||
def test_output_pwm_read():
|
def test_output_pwm_read():
|
||||||
pin = Device.pin_factory.pin(2, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(2)
|
||||||
with PWMOutputDevice(pin, frequency=100) as device:
|
with PWMOutputDevice(2, frequency=100) as device:
|
||||||
assert device.frequency == 100
|
assert device.frequency == 100
|
||||||
device.value = 0.1
|
device.value = 0.1
|
||||||
assert isclose(device.value, 0.1)
|
assert isclose(device.value, 0.1)
|
||||||
@@ -172,15 +216,15 @@ def test_output_pwm_read():
|
|||||||
assert device.frequency is None
|
assert device.frequency is None
|
||||||
|
|
||||||
def test_output_pwm_write():
|
def test_output_pwm_write():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(4)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(4) as device:
|
||||||
device.on()
|
device.on()
|
||||||
device.off()
|
device.off()
|
||||||
pin.assert_states([False, True, False])
|
pin.assert_states([False, True, False])
|
||||||
|
|
||||||
def test_output_pwm_toggle():
|
def test_output_pwm_toggle():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(4)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(4) as device:
|
||||||
device.toggle()
|
device.toggle()
|
||||||
device.value = 0.5
|
device.value = 0.5
|
||||||
device.value = 0.1
|
device.value = 0.1
|
||||||
@@ -189,8 +233,8 @@ def test_output_pwm_toggle():
|
|||||||
pin.assert_states([False, True, 0.5, 0.1, 0.9, False])
|
pin.assert_states([False, True, 0.5, 0.1, 0.9, False])
|
||||||
|
|
||||||
def test_output_pwm_active_high_read():
|
def test_output_pwm_active_high_read():
|
||||||
pin = Device.pin_factory.pin(2, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(2)
|
||||||
with PWMOutputDevice(pin, active_high=False) as device:
|
with PWMOutputDevice(2, active_high=False) as device:
|
||||||
device.value = 0.1
|
device.value = 0.1
|
||||||
assert isclose(device.value, 0.1)
|
assert isclose(device.value, 0.1)
|
||||||
assert isclose(pin.state, 0.9)
|
assert isclose(pin.state, 0.9)
|
||||||
@@ -198,19 +242,21 @@ def test_output_pwm_active_high_read():
|
|||||||
assert device.value
|
assert device.value
|
||||||
|
|
||||||
def test_output_pwm_bad_value():
|
def test_output_pwm_bad_value():
|
||||||
with PWMOutputDevice(Device.pin_factory.pin(2, pin_class=MockPWMPin)) as device:
|
pin = Device.pin_factory.pin(2)
|
||||||
|
with PWMOutputDevice(2) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.value = 2
|
device.value = 2
|
||||||
|
|
||||||
def test_output_pwm_write_closed():
|
def test_output_pwm_write_closed():
|
||||||
with PWMOutputDevice(Device.pin_factory.pin(2, pin_class=MockPWMPin)) as device:
|
pin = Device.pin_factory.pin(2)
|
||||||
|
with PWMOutputDevice(2) as device:
|
||||||
device.close()
|
device.close()
|
||||||
with pytest.raises(GPIODeviceClosed):
|
with pytest.raises(GPIODeviceClosed):
|
||||||
device.on()
|
device.on()
|
||||||
|
|
||||||
def test_output_pwm_write_silly():
|
def test_output_pwm_write_silly():
|
||||||
pin = Device.pin_factory.pin(2, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(2)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(2) as device:
|
||||||
pin.function = 'input'
|
pin.function = 'input'
|
||||||
with pytest.raises(AttributeError):
|
with pytest.raises(AttributeError):
|
||||||
device.off()
|
device.off()
|
||||||
@@ -218,8 +264,8 @@ def test_output_pwm_write_silly():
|
|||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_output_pwm_blink_background():
|
def test_output_pwm_blink_background():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(4)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(4) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2)
|
device.blink(0.1, 0.1, n=2)
|
||||||
assert isclose(time() - start, 0, abs_tol=0.05)
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
@@ -236,8 +282,8 @@ def test_output_pwm_blink_background():
|
|||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_output_pwm_blink_foreground():
|
def test_output_pwm_blink_foreground():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(4)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(4) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2, background=False)
|
device.blink(0.1, 0.1, n=2, background=False)
|
||||||
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||||
@@ -252,8 +298,8 @@ def test_output_pwm_blink_foreground():
|
|||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_output_pwm_fade_background():
|
def test_output_pwm_fade_background():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(4)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(4) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0, 0, 0.2, 0.2, n=2)
|
device.blink(0, 0, 0.2, 0.2, n=2)
|
||||||
assert isclose(time() - start, 0, abs_tol=0.05)
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
@@ -286,8 +332,8 @@ def test_output_pwm_fade_background():
|
|||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_output_pwm_fade_foreground():
|
def test_output_pwm_fade_foreground():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(4)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(4) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
||||||
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
@@ -318,8 +364,8 @@ def test_output_pwm_fade_foreground():
|
|||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_output_pwm_pulse_background():
|
def test_output_pwm_pulse_background():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(4)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(4) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.pulse(0.2, 0.2, n=2)
|
device.pulse(0.2, 0.2, n=2)
|
||||||
assert isclose(time() - start, 0, abs_tol=0.05)
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
@@ -352,8 +398,8 @@ def test_output_pwm_pulse_background():
|
|||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_output_pwm_pulse_foreground():
|
def test_output_pwm_pulse_foreground():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(4)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(4) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.pulse(0.2, 0.2, n=2, background=False)
|
device.pulse(0.2, 0.2, n=2, background=False)
|
||||||
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
@@ -382,8 +428,8 @@ def test_output_pwm_pulse_foreground():
|
|||||||
])
|
])
|
||||||
|
|
||||||
def test_output_pwm_blink_interrupt():
|
def test_output_pwm_blink_interrupt():
|
||||||
pin = Device.pin_factory.pin(4, pin_class=MockPWMPin)
|
pin = Device.pin_factory.pin(4)
|
||||||
with PWMOutputDevice(pin) as device:
|
with PWMOutputDevice(4) as device:
|
||||||
device.blink(1, 0.1)
|
device.blink(1, 0.1)
|
||||||
sleep(0.2)
|
sleep(0.2)
|
||||||
device.off() # should interrupt while on
|
device.off() # should interrupt while on
|
||||||
@@ -394,8 +440,8 @@ def test_rgbled_missing_pins():
|
|||||||
RGBLED()
|
RGBLED()
|
||||||
|
|
||||||
def test_rgbled_initial_value():
|
def test_rgbled_initial_value():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, initial_value=(0.1, 0.2, 0)) as device:
|
with RGBLED(1, 2, 3, initial_value=(0.1, 0.2, 0)) as device:
|
||||||
assert r.frequency
|
assert r.frequency
|
||||||
assert g.frequency
|
assert g.frequency
|
||||||
assert b.frequency
|
assert b.frequency
|
||||||
@@ -405,24 +451,24 @@ def test_rgbled_initial_value():
|
|||||||
|
|
||||||
def test_rgbled_initial_value_nonpwm():
|
def test_rgbled_initial_value_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, pwm=False, initial_value=(0, 1, 1)) as device:
|
with RGBLED(1, 2, 3, pwm=False, initial_value=(0, 1, 1)) as device:
|
||||||
assert r.state == 0
|
assert r.state == 0
|
||||||
assert g.state == 1
|
assert g.state == 1
|
||||||
assert b.state == 1
|
assert b.state == 1
|
||||||
|
|
||||||
def test_rgbled_initial_bad_value():
|
def test_rgbled_initial_bad_value():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
RGBLED(r, g, b, initial_value=(0.1, 0.2, 1.2))
|
RGBLED(1, 2, 3, initial_value=(0.1, 0.2, 1.2))
|
||||||
|
|
||||||
def test_rgbled_initial_bad_value_nonpwm():
|
def test_rgbled_initial_bad_value_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
RGBLED(r, g, b, pwm=False, initial_value=(0.1, 0.2, 0))
|
RGBLED(1, 2, 3, pwm=False, initial_value=(0.1, 0.2, 0))
|
||||||
|
|
||||||
def test_rgbled_value():
|
def test_rgbled_value():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
assert isinstance(device._leds[0], PWMLED)
|
assert isinstance(device._leds[0], PWMLED)
|
||||||
assert isinstance(device._leds[1], PWMLED)
|
assert isinstance(device._leds[1], PWMLED)
|
||||||
assert isinstance(device._leds[2], PWMLED)
|
assert isinstance(device._leds[2], PWMLED)
|
||||||
@@ -440,7 +486,7 @@ def test_rgbled_value():
|
|||||||
|
|
||||||
def test_rgbled_value_nonpwm():
|
def test_rgbled_value_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
assert isinstance(device._leds[0], LED)
|
assert isinstance(device._leds[0], LED)
|
||||||
assert isinstance(device._leds[1], LED)
|
assert isinstance(device._leds[1], LED)
|
||||||
assert isinstance(device._leds[2], LED)
|
assert isinstance(device._leds[2], LED)
|
||||||
@@ -454,35 +500,35 @@ def test_rgbled_value_nonpwm():
|
|||||||
assert device.value == (0, 0, 0)
|
assert device.value == (0, 0, 0)
|
||||||
|
|
||||||
def test_rgbled_bad_value():
|
def test_rgbled_bad_value():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.value = (2, 0, 0)
|
device.value = (2, 0, 0)
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.value = (0, -1, 0)
|
device.value = (0, -1, 0)
|
||||||
|
|
||||||
def test_rgbled_bad_value_nonpwm():
|
def test_rgbled_bad_value_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.value = (2, 0, 0)
|
device.value = (2, 0, 0)
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.value = (0, -1, 0)
|
device.value = (0, -1, 0)
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.value = (0.5, 0, 0)
|
device.value = (0.5, 0, 0)
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.value = (0, 0.5, 0)
|
device.value = (0, 0.5, 0)
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.value = (0, 0, 0.5)
|
device.value = (0, 0, 0.5)
|
||||||
|
|
||||||
def test_rgbled_toggle():
|
def test_rgbled_toggle():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
assert not device.is_active
|
assert not device.is_active
|
||||||
assert device.value == (0, 0, 0)
|
assert device.value == (0, 0, 0)
|
||||||
device.toggle()
|
device.toggle()
|
||||||
@@ -494,7 +540,7 @@ def test_rgbled_toggle():
|
|||||||
|
|
||||||
def test_rgbled_toggle_nonpwm():
|
def test_rgbled_toggle_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
assert not device.is_active
|
assert not device.is_active
|
||||||
assert device.value == (0, 0, 0)
|
assert device.value == (0, 0, 0)
|
||||||
device.toggle()
|
device.toggle()
|
||||||
@@ -506,7 +552,7 @@ def test_rgbled_toggle_nonpwm():
|
|||||||
|
|
||||||
def test_rgbled_blink_nonpwm():
|
def test_rgbled_blink_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.blink(fade_in_time=1)
|
device.blink(fade_in_time=1)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
@@ -515,8 +561,8 @@ def test_rgbled_blink_nonpwm():
|
|||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_rgbled_blink_background():
|
def test_rgbled_blink_background():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2)
|
device.blink(0.1, 0.1, n=2)
|
||||||
assert isclose(time() - start, 0, abs_tol=0.05)
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
@@ -537,7 +583,7 @@ def test_rgbled_blink_background():
|
|||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_rgbled_blink_background_nonpwm():
|
def test_rgbled_blink_background_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2)
|
device.blink(0.1, 0.1, n=2)
|
||||||
assert isclose(time() - start, 0, abs_tol=0.05)
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
@@ -557,8 +603,8 @@ def test_rgbled_blink_background_nonpwm():
|
|||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_rgbled_blink_foreground():
|
def test_rgbled_blink_foreground():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2, background=False)
|
device.blink(0.1, 0.1, n=2, background=False)
|
||||||
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||||
@@ -577,7 +623,7 @@ def test_rgbled_blink_foreground():
|
|||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_rgbled_blink_foreground_nonpwm():
|
def test_rgbled_blink_foreground_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0.1, 0.1, n=2, background=False)
|
device.blink(0.1, 0.1, n=2, background=False)
|
||||||
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||||
@@ -595,8 +641,8 @@ def test_rgbled_blink_foreground_nonpwm():
|
|||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_rgbled_fade_background():
|
def test_rgbled_fade_background():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0, 0, 0.2, 0.2, n=2)
|
device.blink(0, 0, 0.2, 0.2, n=2)
|
||||||
assert isclose(time() - start, 0, abs_tol=0.05)
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
@@ -631,15 +677,15 @@ def test_rgbled_fade_background():
|
|||||||
|
|
||||||
def test_rgbled_fade_background_nonpwm():
|
def test_rgbled_fade_background_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.blink(0, 0, 0.2, 0.2, n=2)
|
device.blink(0, 0, 0.2, 0.2, n=2)
|
||||||
|
|
||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_rgbled_fade_foreground():
|
def test_rgbled_fade_foreground():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
||||||
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
@@ -672,15 +718,15 @@ def test_rgbled_fade_foreground():
|
|||||||
|
|
||||||
def test_rgbled_fade_foreground_nonpwm():
|
def test_rgbled_fade_foreground_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
||||||
|
|
||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_rgbled_pulse_background():
|
def test_rgbled_pulse_background():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.pulse(0.2, 0.2, n=2)
|
device.pulse(0.2, 0.2, n=2)
|
||||||
assert isclose(time() - start, 0, abs_tol=0.05)
|
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||||
@@ -715,15 +761,15 @@ def test_rgbled_pulse_background():
|
|||||||
|
|
||||||
def test_rgbled_pulse_background_nonpwm():
|
def test_rgbled_pulse_background_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.pulse(0.2, 0.2, n=2)
|
device.pulse(0.2, 0.2, n=2)
|
||||||
|
|
||||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||||
reason='timing is too random on pypy')
|
reason='timing is too random on pypy')
|
||||||
def test_rgbled_pulse_foreground():
|
def test_rgbled_pulse_foreground():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
start = time()
|
start = time()
|
||||||
device.pulse(0.2, 0.2, n=2, background=False)
|
device.pulse(0.2, 0.2, n=2, background=False)
|
||||||
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
assert isclose(time() - start, 0.8, abs_tol=0.05)
|
||||||
@@ -756,13 +802,13 @@ def test_rgbled_pulse_foreground():
|
|||||||
|
|
||||||
def test_rgbled_pulse_foreground_nonpwm():
|
def test_rgbled_pulse_foreground_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.pulse(0.2, 0.2, n=2, background=False)
|
device.pulse(0.2, 0.2, n=2, background=False)
|
||||||
|
|
||||||
def test_rgbled_blink_interrupt():
|
def test_rgbled_blink_interrupt():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (4, 5, 6))
|
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
device.blink(1, 0.1)
|
device.blink(1, 0.1)
|
||||||
sleep(0.2)
|
sleep(0.2)
|
||||||
device.off() # should interrupt while on
|
device.off() # should interrupt while on
|
||||||
@@ -772,7 +818,7 @@ def test_rgbled_blink_interrupt():
|
|||||||
|
|
||||||
def test_rgbled_blink_interrupt_nonpwm():
|
def test_rgbled_blink_interrupt_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
r, g, b = (Device.pin_factory.pin(i) for i in (4, 5, 6))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
device.blink(1, 0.1)
|
device.blink(1, 0.1)
|
||||||
sleep(0.2)
|
sleep(0.2)
|
||||||
device.off() # should interrupt while on
|
device.off() # should interrupt while on
|
||||||
@@ -781,8 +827,8 @@ def test_rgbled_blink_interrupt_nonpwm():
|
|||||||
b.assert_states([0, 1, 0])
|
b.assert_states([0, 1, 0])
|
||||||
|
|
||||||
def test_rgbled_close():
|
def test_rgbled_close():
|
||||||
r, g, b = (Device.pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b) as device:
|
with RGBLED(1, 2, 3) as device:
|
||||||
assert not device.closed
|
assert not device.closed
|
||||||
device.close()
|
device.close()
|
||||||
assert device.closed
|
assert device.closed
|
||||||
@@ -791,7 +837,7 @@ def test_rgbled_close():
|
|||||||
|
|
||||||
def test_rgbled_close_nonpwm():
|
def test_rgbled_close_nonpwm():
|
||||||
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
r, g, b = (Device.pin_factory.pin(i) for i in (1, 2, 3))
|
||||||
with RGBLED(r, g, b, pwm=False) as device:
|
with RGBLED(1, 2, 3, pwm=False) as device:
|
||||||
assert not device.closed
|
assert not device.closed
|
||||||
device.close()
|
device.close()
|
||||||
assert device.closed
|
assert device.closed
|
||||||
@@ -803,9 +849,9 @@ def test_motor_missing_pins():
|
|||||||
Motor()
|
Motor()
|
||||||
|
|
||||||
def test_motor_pins():
|
def test_motor_pins():
|
||||||
f = Device.pin_factory.pin(1, pin_class=MockPWMPin)
|
f = Device.pin_factory.pin(1)
|
||||||
b = Device.pin_factory.pin(2, pin_class=MockPWMPin)
|
b = Device.pin_factory.pin(2)
|
||||||
with Motor(f, b) as device:
|
with Motor(1, 2) as device:
|
||||||
assert device.forward_device.pin is f
|
assert device.forward_device.pin is f
|
||||||
assert isinstance(device.forward_device, PWMOutputDevice)
|
assert isinstance(device.forward_device, PWMOutputDevice)
|
||||||
assert device.backward_device.pin is b
|
assert device.backward_device.pin is b
|
||||||
@@ -814,16 +860,16 @@ def test_motor_pins():
|
|||||||
def test_motor_pins_nonpwm():
|
def test_motor_pins_nonpwm():
|
||||||
f = Device.pin_factory.pin(1)
|
f = Device.pin_factory.pin(1)
|
||||||
b = Device.pin_factory.pin(2)
|
b = Device.pin_factory.pin(2)
|
||||||
with Motor(f, b, pwm=False) as device:
|
with Motor(1, 2, pwm=False) as device:
|
||||||
assert device.forward_device.pin is f
|
assert device.forward_device.pin is f
|
||||||
assert isinstance(device.forward_device, DigitalOutputDevice)
|
assert isinstance(device.forward_device, DigitalOutputDevice)
|
||||||
assert device.backward_device.pin is b
|
assert device.backward_device.pin is b
|
||||||
assert isinstance(device.backward_device, DigitalOutputDevice)
|
assert isinstance(device.backward_device, DigitalOutputDevice)
|
||||||
|
|
||||||
def test_motor_close():
|
def test_motor_close():
|
||||||
f = Device.pin_factory.pin(1, pin_class=MockPWMPin)
|
f = Device.pin_factory.pin(1)
|
||||||
b = Device.pin_factory.pin(2, pin_class=MockPWMPin)
|
b = Device.pin_factory.pin(2)
|
||||||
with Motor(f, b) as device:
|
with Motor(1, 2) as device:
|
||||||
device.close()
|
device.close()
|
||||||
assert device.closed
|
assert device.closed
|
||||||
assert device.forward_device.pin is None
|
assert device.forward_device.pin is None
|
||||||
@@ -834,16 +880,16 @@ def test_motor_close():
|
|||||||
def test_motor_close_nonpwm():
|
def test_motor_close_nonpwm():
|
||||||
f = Device.pin_factory.pin(1)
|
f = Device.pin_factory.pin(1)
|
||||||
b = Device.pin_factory.pin(2)
|
b = Device.pin_factory.pin(2)
|
||||||
with Motor(f, b, pwm=False) as device:
|
with Motor(1, 2, pwm=False) as device:
|
||||||
device.close()
|
device.close()
|
||||||
assert device.closed
|
assert device.closed
|
||||||
assert device.forward_device.pin is None
|
assert device.forward_device.pin is None
|
||||||
assert device.backward_device.pin is None
|
assert device.backward_device.pin is None
|
||||||
|
|
||||||
def test_motor_value():
|
def test_motor_value():
|
||||||
f = Device.pin_factory.pin(1, pin_class=MockPWMPin)
|
f = Device.pin_factory.pin(1)
|
||||||
b = Device.pin_factory.pin(2, pin_class=MockPWMPin)
|
b = Device.pin_factory.pin(2)
|
||||||
with Motor(f, b) as device:
|
with Motor(1, 2) as device:
|
||||||
device.value = -1
|
device.value = -1
|
||||||
assert device.is_active
|
assert device.is_active
|
||||||
assert device.value == -1
|
assert device.value == -1
|
||||||
@@ -868,7 +914,7 @@ def test_motor_value():
|
|||||||
def test_motor_value_nonpwm():
|
def test_motor_value_nonpwm():
|
||||||
f = Device.pin_factory.pin(1)
|
f = Device.pin_factory.pin(1)
|
||||||
b = Device.pin_factory.pin(2)
|
b = Device.pin_factory.pin(2)
|
||||||
with Motor(f, b, pwm=False) as device:
|
with Motor(1, 2, pwm=False) as device:
|
||||||
device.value = -1
|
device.value = -1
|
||||||
assert device.is_active
|
assert device.is_active
|
||||||
assert device.value == -1
|
assert device.value == -1
|
||||||
@@ -883,9 +929,9 @@ def test_motor_value_nonpwm():
|
|||||||
assert b.state == 0 and f.state == 0
|
assert b.state == 0 and f.state == 0
|
||||||
|
|
||||||
def test_motor_bad_value():
|
def test_motor_bad_value():
|
||||||
f = Device.pin_factory.pin(1, pin_class=MockPWMPin)
|
f = Device.pin_factory.pin(1)
|
||||||
b = Device.pin_factory.pin(2, pin_class=MockPWMPin)
|
b = Device.pin_factory.pin(2)
|
||||||
with Motor(f, b) as device:
|
with Motor(1, 2) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.value = -2
|
device.value = -2
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
@@ -898,7 +944,7 @@ def test_motor_bad_value():
|
|||||||
def test_motor_bad_value_nonpwm():
|
def test_motor_bad_value_nonpwm():
|
||||||
f = Device.pin_factory.pin(1)
|
f = Device.pin_factory.pin(1)
|
||||||
b = Device.pin_factory.pin(2)
|
b = Device.pin_factory.pin(2)
|
||||||
with Motor(f, b, pwm=False) as device:
|
with Motor(1, 2, pwm=False) as device:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
device.value = -2
|
device.value = -2
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
@@ -909,9 +955,9 @@ def test_motor_bad_value_nonpwm():
|
|||||||
device.value = -0.5
|
device.value = -0.5
|
||||||
|
|
||||||
def test_motor_reverse():
|
def test_motor_reverse():
|
||||||
f = Device.pin_factory.pin(1, pin_class=MockPWMPin)
|
f = Device.pin_factory.pin(1)
|
||||||
b = Device.pin_factory.pin(2, pin_class=MockPWMPin)
|
b = Device.pin_factory.pin(2)
|
||||||
with Motor(f, b) as device:
|
with Motor(1, 2) as device:
|
||||||
device.forward()
|
device.forward()
|
||||||
assert device.value == 1
|
assert device.value == 1
|
||||||
assert b.state == 0 and f.state == 1
|
assert b.state == 0 and f.state == 1
|
||||||
@@ -928,7 +974,7 @@ def test_motor_reverse():
|
|||||||
def test_motor_reverse_nonpwm():
|
def test_motor_reverse_nonpwm():
|
||||||
f = Device.pin_factory.pin(1)
|
f = Device.pin_factory.pin(1)
|
||||||
b = Device.pin_factory.pin(2)
|
b = Device.pin_factory.pin(2)
|
||||||
with Motor(f, b, pwm=False) as device:
|
with Motor(1, 2, pwm=False) as device:
|
||||||
device.forward()
|
device.forward()
|
||||||
assert device.value == 1
|
assert device.value == 1
|
||||||
assert b.state == 0 and f.state == 1
|
assert b.state == 0 and f.state == 1
|
||||||
@@ -937,28 +983,28 @@ def test_motor_reverse_nonpwm():
|
|||||||
assert b.state == 1 and f.state == 0
|
assert b.state == 1 and f.state == 0
|
||||||
|
|
||||||
def test_servo_pins():
|
def test_servo_pins():
|
||||||
p = Device.pin_factory.pin(1, pin_class=MockPWMPin)
|
p = Device.pin_factory.pin(1)
|
||||||
with Servo(p) as device:
|
with Servo(1) as device:
|
||||||
assert device.pwm_device.pin is p
|
assert device.pwm_device.pin is p
|
||||||
assert isinstance(device.pwm_device, PWMOutputDevice)
|
assert isinstance(device.pwm_device, PWMOutputDevice)
|
||||||
|
|
||||||
def test_servo_bad_value():
|
def test_servo_bad_value():
|
||||||
p = Device.pin_factory.pin(1, pin_class=MockPWMPin)
|
p = Device.pin_factory.pin(1)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Servo(p, initial_value=2)
|
Servo(1, initial_value=2)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Servo(p, min_pulse_width=30/1000)
|
Servo(1, min_pulse_width=30/1000)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Servo(p, max_pulse_width=30/1000)
|
Servo(1, max_pulse_width=30/1000)
|
||||||
|
|
||||||
def test_servo_pins_nonpwm():
|
def test_servo_pins_nonpwm():
|
||||||
p = Device.pin_factory.pin(2)
|
p = Device.pin_factory.pin(2)
|
||||||
with pytest.raises(PinPWMUnsupported):
|
with pytest.raises(PinPWMUnsupported):
|
||||||
Servo(p)
|
Servo(1)
|
||||||
|
|
||||||
def test_servo_close():
|
def test_servo_close():
|
||||||
p = Device.pin_factory.pin(2, pin_class=MockPWMPin)
|
p = Device.pin_factory.pin(2)
|
||||||
with Servo(p) as device:
|
with Servo(1) as device:
|
||||||
device.close()
|
device.close()
|
||||||
assert device.closed
|
assert device.closed
|
||||||
assert device.pwm_device.pin is None
|
assert device.pwm_device.pin is None
|
||||||
@@ -966,8 +1012,8 @@ def test_servo_close():
|
|||||||
assert device.closed
|
assert device.closed
|
||||||
|
|
||||||
def test_servo_pulse_width():
|
def test_servo_pulse_width():
|
||||||
p = Device.pin_factory.pin(2, pin_class=MockPWMPin)
|
p = Device.pin_factory.pin(2)
|
||||||
with Servo(p, min_pulse_width=5/10000, max_pulse_width=25/10000) as device:
|
with Servo(1, min_pulse_width=5/10000, max_pulse_width=25/10000) as device:
|
||||||
assert isclose(device.min_pulse_width, 5/10000)
|
assert isclose(device.min_pulse_width, 5/10000)
|
||||||
assert isclose(device.max_pulse_width, 25/10000)
|
assert isclose(device.max_pulse_width, 25/10000)
|
||||||
assert isclose(device.frame_width, 20/1000)
|
assert isclose(device.frame_width, 20/1000)
|
||||||
@@ -980,8 +1026,8 @@ def test_servo_pulse_width():
|
|||||||
assert device.pulse_width is None
|
assert device.pulse_width is None
|
||||||
|
|
||||||
def test_servo_values():
|
def test_servo_values():
|
||||||
p = Device.pin_factory.pin(1, pin_class=MockPWMPin)
|
p = Device.pin_factory.pin(1)
|
||||||
with Servo(p) as device:
|
with Servo(1) as device:
|
||||||
device.min()
|
device.min()
|
||||||
assert device.is_active
|
assert device.is_active
|
||||||
assert device.value == -1
|
assert device.value == -1
|
||||||
@@ -1007,14 +1053,14 @@ def test_servo_values():
|
|||||||
assert device.value is None
|
assert device.value is None
|
||||||
|
|
||||||
def test_angular_servo_range():
|
def test_angular_servo_range():
|
||||||
p = Device.pin_factory.pin(1, pin_class=MockPWMPin)
|
p = Device.pin_factory.pin(1)
|
||||||
with AngularServo(p, initial_angle=15, min_angle=0, max_angle=90) as device:
|
with AngularServo(1, initial_angle=15, min_angle=0, max_angle=90) as device:
|
||||||
assert device.min_angle == 0
|
assert device.min_angle == 0
|
||||||
assert device.max_angle == 90
|
assert device.max_angle == 90
|
||||||
|
|
||||||
def test_angular_servo_angles():
|
def test_angular_servo_angles():
|
||||||
p = Device.pin_factory.pin(1, pin_class=MockPWMPin)
|
p = Device.pin_factory.pin(1)
|
||||||
with AngularServo(p) as device:
|
with AngularServo(1) as device:
|
||||||
device.angle = 0
|
device.angle = 0
|
||||||
assert device.angle == 0
|
assert device.angle == 0
|
||||||
assert isclose(device.value, 0)
|
assert isclose(device.value, 0)
|
||||||
@@ -1026,7 +1072,7 @@ def test_angular_servo_angles():
|
|||||||
assert isclose(device.value, -1)
|
assert isclose(device.value, -1)
|
||||||
device.detach()
|
device.detach()
|
||||||
assert device.angle is None
|
assert device.angle is None
|
||||||
with AngularServo(p, initial_angle=15, min_angle=0, max_angle=90) as device:
|
with AngularServo(1, initial_angle=15, min_angle=0, max_angle=90) as device:
|
||||||
assert device.angle == 15
|
assert device.angle == 15
|
||||||
assert isclose(device.value, -2/3)
|
assert isclose(device.value, -2/3)
|
||||||
device.angle = 0
|
device.angle = 0
|
||||||
@@ -1037,7 +1083,7 @@ def test_angular_servo_angles():
|
|||||||
assert isclose(device.value, 1)
|
assert isclose(device.value, 1)
|
||||||
device.angle = None
|
device.angle = None
|
||||||
assert device.angle is None
|
assert device.angle is None
|
||||||
with AngularServo(p, min_angle=45, max_angle=-45) as device:
|
with AngularServo(1, min_angle=45, max_angle=-45) as device:
|
||||||
assert device.angle == 0
|
assert device.angle == 0
|
||||||
assert isclose(device.value, 0)
|
assert isclose(device.value, 0)
|
||||||
device.angle = -45
|
device.angle = -45
|
||||||
|
|||||||
@@ -33,50 +33,50 @@ def test_spi_hardware_params():
|
|||||||
with patch('os.open'), patch('mmap.mmap') as mmap_mmap, patch('io.open') as io_open:
|
with patch('os.open'), patch('mmap.mmap') as mmap_mmap, patch('io.open') as io_open:
|
||||||
mmap_mmap.return_value = array(nstr('B'), (0,) * 4096)
|
mmap_mmap.return_value = array(nstr('B'), (0,) * 4096)
|
||||||
io_open.return_value.__enter__.return_value = ['Revision: a21042']
|
io_open.return_value.__enter__.return_value = ['Revision: a21042']
|
||||||
with patch('gpiozero.devices.Device.pin_factory', NativeFactory()), \
|
factory = NativeFactory()
|
||||||
patch('gpiozero.pins.local.SpiDev'):
|
with patch('gpiozero.pins.local.SpiDev'):
|
||||||
with Device.pin_factory.spi() as device:
|
with factory.spi() as device:
|
||||||
assert isinstance(device, LocalPiHardwareSPI)
|
assert isinstance(device, LocalPiHardwareSPI)
|
||||||
with Device.pin_factory.spi(port=0, device=0) as device:
|
with factory.spi(port=0, device=0) as device:
|
||||||
assert isinstance(device, LocalPiHardwareSPI)
|
assert isinstance(device, LocalPiHardwareSPI)
|
||||||
with Device.pin_factory.spi(port=0, device=1) as device:
|
with factory.spi(port=0, device=1) as device:
|
||||||
assert isinstance(device, LocalPiHardwareSPI)
|
assert isinstance(device, LocalPiHardwareSPI)
|
||||||
with Device.pin_factory.spi(clock_pin=11) as device:
|
with factory.spi(clock_pin=11) as device:
|
||||||
assert isinstance(device, LocalPiHardwareSPI)
|
assert isinstance(device, LocalPiHardwareSPI)
|
||||||
with Device.pin_factory.spi(clock_pin=11, mosi_pin=10, select_pin=8) as device:
|
with factory.spi(clock_pin=11, mosi_pin=10, select_pin=8) as device:
|
||||||
assert isinstance(device, LocalPiHardwareSPI)
|
assert isinstance(device, LocalPiHardwareSPI)
|
||||||
with Device.pin_factory.spi(clock_pin=11, mosi_pin=10, select_pin=7) as device:
|
with factory.spi(clock_pin=11, mosi_pin=10, select_pin=7) as device:
|
||||||
assert isinstance(device, LocalPiHardwareSPI)
|
assert isinstance(device, LocalPiHardwareSPI)
|
||||||
with Device.pin_factory.spi(shared=True) as device:
|
with factory.spi(shared=True) as device:
|
||||||
assert isinstance(device, LocalPiHardwareSPIShared)
|
assert isinstance(device, LocalPiHardwareSPIShared)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Device.pin_factory.spi(port=1)
|
factory.spi(port=1)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Device.pin_factory.spi(device=2)
|
factory.spi(device=2)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Device.pin_factory.spi(port=0, clock_pin=12)
|
factory.spi(port=0, clock_pin=12)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Device.pin_factory.spi(foo='bar')
|
factory.spi(foo='bar')
|
||||||
|
|
||||||
def test_spi_software_params():
|
def test_spi_software_params():
|
||||||
with patch('os.open'), patch('mmap.mmap') as mmap_mmap, patch('io.open') as io_open:
|
with patch('os.open'), patch('mmap.mmap') as mmap_mmap, patch('io.open') as io_open:
|
||||||
mmap_mmap.return_value = array(nstr('B'), (0,) * 4096)
|
mmap_mmap.return_value = array(nstr('B'), (0,) * 4096)
|
||||||
io_open.return_value.__enter__.return_value = ['Revision: a21042']
|
io_open.return_value.__enter__.return_value = ['Revision: a21042']
|
||||||
with patch('gpiozero.devices.Device.pin_factory', NativeFactory()), \
|
factory = NativeFactory()
|
||||||
patch('gpiozero.pins.local.SpiDev'):
|
with patch('gpiozero.pins.local.SpiDev'):
|
||||||
with Device.pin_factory.spi(select_pin=6) as device:
|
with factory.spi(select_pin=6) as device:
|
||||||
assert isinstance(device, LocalPiSoftwareSPI)
|
assert isinstance(device, LocalPiSoftwareSPI)
|
||||||
with Device.pin_factory.spi(clock_pin=11, mosi_pin=9, miso_pin=10) as device:
|
with factory.spi(clock_pin=11, mosi_pin=9, miso_pin=10) as device:
|
||||||
assert isinstance(device, LocalPiSoftwareSPI)
|
assert isinstance(device, LocalPiSoftwareSPI)
|
||||||
with Device.pin_factory.spi(select_pin=6, shared=True) as device:
|
with factory.spi(select_pin=6, shared=True) as device:
|
||||||
assert isinstance(device, LocalPiSoftwareSPIShared)
|
assert isinstance(device, LocalPiSoftwareSPIShared)
|
||||||
with patch('gpiozero.devices.Device.pin_factory', NativeFactory()), \
|
with patch('gpiozero.pins.local.SpiDev', None):
|
||||||
patch('gpiozero.pins.local.SpiDev', None):
|
# Clear out the old factory's caches (this is only necessary because
|
||||||
# Clear out the old factory's pins cache (this is only necessary
|
# we're being naughty switching out patches)
|
||||||
# because we're being very naughty switching out pin factories)
|
factory.pins.clear()
|
||||||
Device.pin_factory.pins.clear()
|
factory._reservations.clear()
|
||||||
# Ensure software fallback works when SpiDev isn't present
|
# Ensure software fallback works when SpiDev isn't present
|
||||||
with Device.pin_factory.spi() as device:
|
with factory.spi() as device:
|
||||||
assert isinstance(device, LocalPiSoftwareSPI)
|
assert isinstance(device, LocalPiSoftwareSPI)
|
||||||
|
|
||||||
def test_spi_hardware_conflict():
|
def test_spi_hardware_conflict():
|
||||||
|
|||||||
Reference in New Issue
Block a user