mirror of
				https://github.com/KevinMidboe/python-gpiozero.git
				synced 2025-10-29 17:50:37 +00:00 
			
		
		
		
	Merge pull request #569 from waveform80/pin-factory-docs
Fix #568, fix #572, fix #565
This commit is contained in:
		| @@ -127,44 +127,30 @@ Like the ``GPIOZERO_PIN_FACTORY`` value, these can be exported from your | ||||
| .. warning:: | ||||
|  | ||||
|     The astute and mischievous reader may note that it is possible to mix | ||||
|     strictly local pin implementations, e.g. using ``RPiGPIOPin`` for one pin, | ||||
|     and ``NativePin`` for another. This is unsupported, and if it results in | ||||
|     your script crashing, your components failing, or your Raspberry Pi turning | ||||
|     into an actual raspberry pie, you have only yourself to blame. | ||||
|     factories, e.g. using ``RPiGPIOFactory`` for one pin, and ``NativeFactory`` | ||||
|     for another. This is unsupported, and if it results in your script | ||||
|     crashing, your components failing, or your Raspberry Pi turning 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 | ||||
| ======== | ||||
| Mock pins | ||||
| ========= | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.rpigpio.RPiGPIOFactory | ||||
| There's also a :class:`gpiozero.pins.mock.MockFactory` which generates entirely | ||||
| fake pins. This was originally intended for GPIO Zero developers who wish to | ||||
| write tests for devices without having to have the physical device wired in to | ||||
| their Pi. However, they have also proven relatively useful in developing GPIO | ||||
| Zero scripts without having a Pi to hand. This pin factory will never be loaded | ||||
| by default; it must be explicitly specified. For example: | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.rpigpio.RPiGPIOPin | ||||
| .. literalinclude:: examples/mock_demo.py | ||||
|  | ||||
|  | ||||
| RPIO | ||||
| ==== | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.rpio.RPIOFactory | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.rpio.RPIOPin | ||||
|  | ||||
|  | ||||
| PiGPIO | ||||
| ====== | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.pigpio.PiGPIOFactory | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.pigpio.PiGPIOPin | ||||
|  | ||||
|  | ||||
| Native | ||||
| ====== | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.native.NativeFactory | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.native.NativePin | ||||
| Several sub-classes of mock pins exist for emulating various other things | ||||
| (pins that do/don't support PWM, pins that are connected together, pins that | ||||
| drive high after a delay, etc). Interested users are invited to read the GPIO | ||||
| Zero test suite for further examples of usage. | ||||
|  | ||||
|  | ||||
| Base classes | ||||
| @@ -196,22 +182,62 @@ Base classes | ||||
|     :members: | ||||
|  | ||||
|  | ||||
| Utilities | ||||
| ========= | ||||
| RPi.GPIO | ||||
| ======== | ||||
|  | ||||
| The pins module also contains a database of information about the various | ||||
| revisions of Raspberry Pi. This is used internally to raise warnings when | ||||
| non-physical pins are used, or to raise exceptions when pull-downs are | ||||
| requested on pins with physical pull-up resistors attached. The following | ||||
| functions and classes can be used to query this database: | ||||
| .. currentmodule:: gpiozero.pins.rpigpio | ||||
|  | ||||
| .. currentmodule:: gpiozero | ||||
| .. autoclass:: gpiozero.pins.rpigpio.RPiGPIOFactory | ||||
|  | ||||
| .. autofunction:: pi_info | ||||
| .. autoclass:: gpiozero.pins.rpigpio.RPiGPIOPin | ||||
|  | ||||
| .. autoclass:: PiBoardInfo | ||||
|  | ||||
| .. autoclass:: HeaderInfo | ||||
| RPIO | ||||
| ==== | ||||
|  | ||||
| .. autoclass:: PinInfo | ||||
| .. currentmodule:: gpiozero.pins.rpio | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.rpio.RPIOFactory | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.rpio.RPIOPin | ||||
|  | ||||
|  | ||||
| PiGPIO | ||||
| ====== | ||||
|  | ||||
| .. currentmodule:: gpiozero.pins.pigpio | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.pigpio.PiGPIOFactory | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.pigpio.PiGPIOPin | ||||
|  | ||||
|  | ||||
| Native | ||||
| ====== | ||||
|  | ||||
| .. currentmodule:: gpiozero.pins.native | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.native.NativeFactory | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.native.NativePin | ||||
|  | ||||
|  | ||||
| Mock | ||||
| ==== | ||||
|  | ||||
| .. currentmodule:: gpiozero.pins.mock | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.mock.MockFactory | ||||
|     :members: | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.mock.MockPin | ||||
|     :members: | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.mock.MockPWMPin | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.mock.MockConnectedPin | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.mock.MockChargingPin | ||||
|  | ||||
| .. autoclass:: gpiozero.pins.mock.MockTriggerPin | ||||
|  | ||||
|   | ||||
							
								
								
									
										20
									
								
								docs/api_utils.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								docs/api_utils.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| ========= | ||||
| Utilities | ||||
| ========= | ||||
|  | ||||
| .. currentmodule:: gpiozero | ||||
|  | ||||
| The GPIO Zero library also contains a database of information about the various | ||||
| revisions of Raspberry Pi. This is used internally to raise warnings when | ||||
| non-physical pins are used, or to raise exceptions when pull-downs are | ||||
| requested on pins with physical pull-up resistors attached. The following | ||||
| functions and classes can be used to query this database: | ||||
|  | ||||
| .. autofunction:: pi_info | ||||
|  | ||||
| .. autoclass:: PiBoardInfo | ||||
|  | ||||
| .. autoclass:: HeaderInfo | ||||
|  | ||||
| .. autoclass:: PinInfo | ||||
|  | ||||
| @@ -1,9 +1,11 @@ | ||||
| from gpiozero import LED | ||||
| from gpiozero.pins.pigpio import PiGPIOPin | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from signal import pause | ||||
|  | ||||
| factory = PiGPIOFactory(host='192.168.1.3') | ||||
|  | ||||
| button = Button(2) | ||||
| led = LED(PiGPIOPin(17, host='192.168.1.3')) | ||||
| led = LED(17, pin_factory=factory) | ||||
|  | ||||
| led.source = button.values | ||||
|  | ||||
|   | ||||
| @@ -1,11 +1,14 @@ | ||||
| from gpiozero import LED | ||||
| from gpiozero.pins.pigpio import PiGPIOPin | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from gpiozero.tools import all_values | ||||
| from signal import pause | ||||
|  | ||||
| factory3 = PiGPIOFactory(host='192.168.1.3') | ||||
| factory4 = PiGPIOFactory(host='192.168.1.4') | ||||
|  | ||||
| led = LED(17) | ||||
| button_1 = Button(PiGPIOPin(17, host='192.168.1.3')) | ||||
| button_2 = Button(PiGPIOPin(17, host='192.168.1.4')) | ||||
| button_1 = Button(17, pin_factory=factory3) | ||||
| button_2 = Button(17, pin_factory=factory4) | ||||
|  | ||||
| led.source = all_values(button_1.values, button_2.values) | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| from gpiozero import LED | ||||
| from gpiozero.pins.pigpio import PiGPIOPin | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from time import sleep | ||||
|  | ||||
| led = LED(PiGPIOPin(17, host='192.168.1.3')) | ||||
| factory = PiGPIOFactory(host='192.168.1.3') | ||||
| led = LED(17, pin_factory=factory) | ||||
|  | ||||
| while True: | ||||
|     led.on() | ||||
|   | ||||
| @@ -1,9 +1,11 @@ | ||||
| from gpiozero import LED | ||||
| from gpiozero.pins.pigpio import PiGPIOPin | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from time import sleep | ||||
|  | ||||
| led_1 = LED(PiGPIOPin(17, host='192.168.1.3')) | ||||
| led_2 = LED(PiGPIOPin(17, host='192.168.1.4')) | ||||
| factory3 = PiGPIOFactory(host='192.168.1.3') | ||||
| factory4 = PiGPIOFactory(host='192.168.1.4') | ||||
| led_1 = LED(17, pin_factory=factory3) | ||||
| led_2 = LED(17, pin_factory=factory4) | ||||
|  | ||||
| while True: | ||||
|     led_1.on() | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| from gpiozero import LED | ||||
| from gpiozero.pins.pigpio import PiGPIOPin | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from time import sleep | ||||
|  | ||||
| remote_factory = PiGPIOFactory(host='192.168.1.3') | ||||
| led_1 = LED(17)  # local pin | ||||
| led_2 = LED(PiGPIOPin(17, host='192.168.1.3'))  # remote pin | ||||
| led_2 = LED(17, pin_factory=remote_factory)  # remote pin | ||||
|  | ||||
| while True: | ||||
|     led_1.on() | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| from gpiozero import LED | ||||
| from gpiozero.pins.rpigpio import RPiGPIOPin | ||||
| from gpiozero.pins.rpigpio import RPiGPIOFactory | ||||
| from time import sleep | ||||
|  | ||||
| led_1 = LED(RPiGPIOPin(17))  # local pin | ||||
| local_factory = RPiGPIOFactory() | ||||
| led_1 = LED(17, pin_factory=local_factory)  # local pin | ||||
| led_2 = LED(17)  # remote pin | ||||
|  | ||||
| while True: | ||||
|   | ||||
| @@ -1,10 +1,13 @@ | ||||
| from gpiozero import LED | ||||
| from gpiozero.pins.pigpio import PiGPIOPin | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from time import sleep | ||||
|  | ||||
| factory3 = PiGPIOFactory(host='192.168.1.3') | ||||
| factory4 = PiGPIOFactory(host='192.168.1.4') | ||||
|  | ||||
| led_1 = LED(17)  # local pin | ||||
| led_2 = LED(PiGPIOPin(17, host='192.168.1.3'))  # remote pin on one pi | ||||
| led_3 = LED(PiGPIOPin(17, host='192.168.1.4'))  # remote pin on another pi | ||||
| led_2 = LED(17, pin_factory=factory3)  # remote pin on one pi | ||||
| led_3 = LED(17, pin_factory=factory4)  # remote pin on another pi | ||||
|  | ||||
| while True: | ||||
|     led_1.on() | ||||
|   | ||||
							
								
								
									
										28
									
								
								docs/examples/mock_demo.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								docs/examples/mock_demo.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| from gpiozero.pins.mock import MockFactory | ||||
| from gpiozero import Device, Button, LED | ||||
| from time import sleep | ||||
|  | ||||
| # Set the default pin factory to a mock factory | ||||
| Device.pin_factory = MockFactory() | ||||
|  | ||||
| # Construct a couple of devices attached to mock pins 16 and 17, and link the | ||||
| # devices | ||||
| led = LED(17) | ||||
| btn = Button(16) | ||||
| led.source = btn.values | ||||
|  | ||||
| # Here the button isn't "pushed" so the LED's value should be False | ||||
| print(led.value) | ||||
|  | ||||
| # Get a reference to mock pin 16 (used by the button) | ||||
| btn_pin = Device.pin_factory.pin(16) | ||||
|  | ||||
| # Drive the pin low (this is what would happen eletrically when the button is | ||||
| # pushed) | ||||
| btn_pin.drive_low() | ||||
| sleep(0.1) # give source some time to re-read the button state | ||||
| print(led.value) | ||||
|  | ||||
| btn_pin.drive_high() | ||||
| sleep(0.1) | ||||
| print(led.value) | ||||
| @@ -1,8 +1,9 @@ | ||||
| from gpiozero import LED | ||||
| from gpiozero.pins.pigpio import PiGPIOPin | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from signal import pause | ||||
|  | ||||
| led = LED(PiGPIOPin(17, host='raspberrypi.local')) | ||||
| factory = PiGPIOFactory(host='raspberrypi.local') | ||||
| led = LED(17, pin_factory=factory) | ||||
|  | ||||
| led.blink() | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| from gpiozero import MotionSensor | ||||
| from gpiozero.pins.pigpio import PiGPIOPin | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from sense_hat import SenseHat | ||||
|  | ||||
| pir = MotionSensor(PiGPIOPin(4, host='192.168.1.4'))  # remote motion sensor | ||||
| remote_factory = PiGPIOFactory(host='192.198.1.4') | ||||
| pir = MotionSensor(4, pin_factory=remote_factory)  # remote motion sensor | ||||
| sense = SenseHat()  # local sense hat | ||||
|  | ||||
| while True: | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| from gpiozero import LightSensor | ||||
| from gpiozero.pins.pigpio import PiGPIOPin | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from sense_hat import SenseHat | ||||
|  | ||||
| light = LightSensor(PiGPIOPin(4, host='192.168.1.4'))  # remote motion sensor | ||||
| remote_factory = PiGPIOFactory(host='192.168.1.4') | ||||
| light = LightSensor(4, pin_factory=remote_factory)  # remote motion sensor | ||||
| sense = SenseHat()  # local sense hat | ||||
|  | ||||
| blue = (0, 0, 255) | ||||
|   | ||||
| @@ -3,5 +3,5 @@ from gpiozero import TrafficHat | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from time import sleep | ||||
|  | ||||
| gpiozero.Device._set_pin_factory(PiGPIOFactory(host='192.168.1.3')) | ||||
| gpiozero.Device.pin_factory = PiGPIOFactory(host='192.168.1.3') | ||||
| th = TrafficHat()  # traffic hat on 192.168.1.3 using remote pins | ||||
|   | ||||
| @@ -3,6 +3,7 @@ from gpiozero import TrafficHat | ||||
| from gpiozero.pins.pigpio import PiGPIOFactory | ||||
| from time import sleep | ||||
|  | ||||
| remote_factory = PiGPIOFactory(host='192.168.1.3') | ||||
|  | ||||
| th_1 = TrafficHat()  # traffic hat using local pins | ||||
| gpiozero.Device._set_pin_factory(PiGPIOFactory(host='192.168.1.3')) | ||||
| th_2 = TrafficHat()  # traffic hat on 192.168.1.3 using remote pins | ||||
| th_2 = TrafficHat(pin_factory=remote_factory)  # traffic hat on 192.168.1.3 using remote pins | ||||
|   | ||||
| @@ -17,6 +17,7 @@ Table of Contents | ||||
|     api_generic | ||||
|     api_tools | ||||
|     api_pins | ||||
|     api_utils | ||||
|     api_exc | ||||
|     cli_tools | ||||
|     source_values | ||||
|   | ||||
| @@ -12,8 +12,8 @@ documentation page. | ||||
|  | ||||
| One of the pin libraries supported, `pigpio`_, provides the ability to control | ||||
| GPIO pins remotely over the network, which means you can use GPIO Zero to | ||||
| control devices connected to a Raspberry Pi on the network. You can do this from | ||||
| another Raspberry Pi, or even from a PC. | ||||
| control devices connected to a Raspberry Pi on the network. You can do this | ||||
| from another Raspberry Pi, or even from a PC. | ||||
|  | ||||
| See the :doc:`recipes_remote_gpio` page for examples on how remote pins can be | ||||
| used. | ||||
| @@ -22,8 +22,8 @@ Preparing the Raspberry Pi | ||||
| ========================== | ||||
|  | ||||
| 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, | ||||
| or another distribution, you'll need to install pigpio: | ||||
| everything you need to use the remote GPIO feature. If you're using Jessie | ||||
| Lite, or another distribution, you'll need to install pigpio: | ||||
|  | ||||
| .. code-block:: console | ||||
|  | ||||
| @@ -52,7 +52,9 @@ example: | ||||
|     $ sudo pigpiod -n localhost -n 192.168.1.65 # allow localhost and 192.168.1.65 only | ||||
|  | ||||
| You will need to launch the pigpio daemon every time you wish to use this | ||||
| feature. To automate running the daemon at boot time:: | ||||
| feature. To automate running the daemon at boot time: | ||||
|  | ||||
| .. code-block:: console | ||||
|  | ||||
|     $ sudo systemctl enable pigpiod | ||||
|  | ||||
| @@ -181,17 +183,18 @@ following: | ||||
| If you are running this from a PC (not a Raspberry Pi) with gpiozero and the | ||||
| pigpio Python library installed, this will work with no further configuration. | ||||
| 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 | ||||
| installed, this will be selected as the default pin factory, so either uninstall | ||||
| it, or use another environment variable to set it to ``PiGPIOPin``: | ||||
| ensure the default pin factory is set to ``PiGPIOFactory``. If ``RPi.GPIO`` is | ||||
| installed, this will be selected as the default pin factory, so either | ||||
| uninstall it, or use another environment variable to set it to | ||||
| ``PiGPIOFactory``: | ||||
|  | ||||
| .. code-block:: console | ||||
|  | ||||
|     $ GPIOZERO_PIN_FACTORY=pigpio PIGPIO_ADDR=192.168.1.3 python3 hello.py | ||||
|  | ||||
| This usage will set the pin factory to :class:`PiGPIOPin` with a default host of | ||||
| ``192.168.1.3``. The pin factory can be changed inline in the code, as seen in | ||||
| the following sections. | ||||
| This usage will set the pin factory to :class:`PiGPIOFactory` with a default | ||||
| host of ``192.168.1.3``. The pin factory can be changed inline in the code, as | ||||
| seen in the following sections. | ||||
|  | ||||
| With this usage, you can write gpiozero code like you would on a Raspberry Pi, | ||||
| with no modifications needed. For example: | ||||
| @@ -218,9 +221,9 @@ Pin objects | ||||
| =========== | ||||
|  | ||||
| An alternative (or additional) method of configuring gpiozero objects to use | ||||
| remote pins is to create instances of :class:PiGPIOPin objects, and | ||||
| instantiating device objects with those pin objects, rather than just numbers. | ||||
| For example, with no environment variables set: | ||||
| remote pins is to create instances of :class:`PiGPIOFactory` objects, and use | ||||
| them when instantiating device objects. For example, with no environment | ||||
| variables set: | ||||
|  | ||||
| .. literalinclude:: examples/led_remote_1.py | ||||
|  | ||||
| @@ -230,8 +233,8 @@ This allows devices on multiple Raspberry Pis to be used in the same script: | ||||
|  | ||||
| You can, of course, continue to create gpiozero device objects as normal, and | ||||
| create others using remote pins. For example, if run on a Raspberry Pi, the | ||||
| following script will flash an LED on the host Pi, and also on another Pi on the | ||||
| network: | ||||
| following script will flash an LED on the host Pi, and also on another Pi on | ||||
| the network: | ||||
|  | ||||
| .. literalinclude:: examples/led_remote_3.py | ||||
|  | ||||
| @@ -249,7 +252,8 @@ Note that these examples use the :class:`LED` class, which takes a ``pin`` | ||||
| argument to initialise. Some classes, particularly those representing HATs and | ||||
| other add-on boards, do not require their pin numbers to be specified. However, | ||||
| it is still possible to use remote pins with these devices, either using | ||||
| environment variables, or by using :meth:`~Device._set_pin_factory`: | ||||
| environment variables, :attr:`Device.pin_factory`, or the ``pin_factory`` | ||||
| keyword argument: | ||||
|  | ||||
| .. literalinclude:: examples/traffichat_remote_1.py | ||||
|  | ||||
| @@ -299,10 +303,10 @@ from the computer, referencing the host by its hostname, like so: | ||||
|  | ||||
| .. note:: | ||||
|  | ||||
|     When running code directly on a Raspberry Pi, any pin type can be used | ||||
|     When running code directly on a Raspberry Pi, any pin factory can be used | ||||
|     (assuming the relevant library is installed), but when a device is used | ||||
|     remotely, only :class:`PiGPIOPin` can be used, as pigpio is the only pin | ||||
|     library which supports remote GPIO. | ||||
|     remotely, only :class:`PiGPIOFactory` can be used, as pigpio is the only | ||||
|     pin library which supports remote GPIO. | ||||
|  | ||||
|  | ||||
| .. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO | ||||
|   | ||||
| @@ -448,7 +448,7 @@ def _default_pin_factory(name=os.getenv('GPIOZERO_PIN_FACTORY', None)): | ||||
|             except Exception as e: | ||||
|                 warnings.warn( | ||||
|                     PinFactoryFallback( | ||||
|                         'Failed to load factory %s: %s' % (name, str(e)))) | ||||
|                         'Falling back from %s: %s' % (name, str(e)))) | ||||
|         raise BadPinFactory('Unable to load any default pin factory!') | ||||
|     else: | ||||
|         for factory in pkg_resources.iter_entry_points(group, name.lower()): | ||||
|   | ||||
| @@ -30,15 +30,9 @@ from ..exc import ( | ||||
|  | ||||
| class Factory(object): | ||||
|     """ | ||||
|     Generates pins, SPI, and I2C interfaces for devices. This is an abstract | ||||
|     base class for pin factories. Descendents *must* override the following | ||||
|     methods: | ||||
|  | ||||
|     * :meth:`_get_address` | ||||
|     * :meth:`pin_address` | ||||
|  | ||||
|     Descendents *may* additionally override the following methods, if | ||||
|     applicable: | ||||
|     Generates pins and SPI interfaces for devices. This is an abstract | ||||
|     base class for pin factories. Descendents *may* override the following | ||||
|     methods, if applicable: | ||||
|  | ||||
|     * :meth:`close` | ||||
|     * :meth:`reserve_pins` | ||||
| @@ -129,9 +123,6 @@ class Factory(object): | ||||
|         """ | ||||
|         raise PinSPIUnsupported('SPI not supported by this pin factory') | ||||
|  | ||||
|     def _get_address(self): | ||||
|         raise NotImplementedError | ||||
|  | ||||
|     def _get_pi_info(self): | ||||
|         return None | ||||
|  | ||||
|   | ||||
| @@ -216,7 +216,7 @@ class MockChargingPin(MockPin): | ||||
| class MockTriggerPin(MockPin): | ||||
|     """ | ||||
|     This derivative of :class:`MockPin` is intended to be used with another | ||||
|     :class:`MockPin` to emulate a distance sensor. Set :attr:`echo_pin` to the | ||||
|     :class:`MockPin` to emulate a distance sensor. Set *echo_pin* to the | ||||
|     corresponding pin instance. When this pin is driven high it will trigger | ||||
|     the echo pin to drive high for the echo time. | ||||
|     """ | ||||
| @@ -410,6 +410,14 @@ class MockSPIDevice(object): | ||||
|  | ||||
|  | ||||
| class MockFactory(LocalPiFactory): | ||||
|     """ | ||||
|     Factory for generating mock pins. The *revision* parameter specifies what | ||||
|     revision of Pi the mock factory pretends to be (this affects the result of | ||||
|     the :attr:`pi_info` attribute as well as where pull-ups are assumed to be). | ||||
|     The *pin_class* attribute specifies which mock pin class will be generated | ||||
|     by the :meth:`pin` method by default. This can be changed after | ||||
|     construction by modifying the :attr:`pin_class` attribute. | ||||
|     """ | ||||
|     def __init__( | ||||
|             self, revision=os.getenv('GPIOZERO_MOCK_REVISION', 'a02082'), | ||||
|             pin_class=os.getenv('GPIOZERO_MOCK_PIN_CLASS', MockPin)): | ||||
| @@ -427,10 +435,22 @@ class MockFactory(LocalPiFactory): | ||||
|         return self._revision | ||||
|  | ||||
|     def reset(self): | ||||
|         """ | ||||
|         Clears the pins and reservations sets. This is primarily useful in | ||||
|         test suites to ensure the pin factory is back in a "clean" state before | ||||
|         the next set of tests are run. | ||||
|         """ | ||||
|         self.pins.clear() | ||||
|         self._reservations.clear() | ||||
|  | ||||
|     def pin(self, spec, pin_class=None, **kwargs): | ||||
|         """ | ||||
|         The pin method for :class:`MockFactory` additionally takes a *pin_class* | ||||
|         attribute which can be used to override the class' :attr:`pin_class` | ||||
|         attribute. Any additional keyword arguments will be passed along to the | ||||
|         pin constructor (useful with things like :class:`MockConnectedPin` which | ||||
|         expect to be constructed with another pin). | ||||
|         """ | ||||
|         if pin_class is None: | ||||
|             pin_class = self.pin_class | ||||
|         n = self._to_gpio(spec) | ||||
|   | ||||
| @@ -161,10 +161,11 @@ class NativeFactory(LocalPiFactory): | ||||
|  | ||||
|     You can construct native pin instances manually like so:: | ||||
|  | ||||
|         from gpiozero.pins.native import NativePin | ||||
|         from gpiozero.pins.native import NativeFactory | ||||
|         from gpiozero import LED | ||||
|  | ||||
|         led = LED(NativePin(12)) | ||||
|         factory = NativeFactory() | ||||
|         led = LED(12, pin_factory=factory) | ||||
|     """ | ||||
|     def __init__(self): | ||||
|         super(NativeFactory, self).__init__() | ||||
| @@ -177,6 +178,9 @@ class NativeFactory(LocalPiFactory): | ||||
|  | ||||
|  | ||||
| class NativePin(LocalPiPin): | ||||
|     """ | ||||
|     Native pin implementation. See :class:`NativeFactory` for more information. | ||||
|     """ | ||||
|     GPIO_FUNCTIONS = { | ||||
|         'input':   0b000, | ||||
|         'output':  0b001, | ||||
|   | ||||
| @@ -238,11 +238,11 @@ class PiPin(Pin): | ||||
|         self._when_changed = None | ||||
|         self._number = number | ||||
|         try: | ||||
|             factory.pi_info.physical_pin('GPIO%d' % self.number) | ||||
|             factory.pi_info.physical_pin(repr(self)) | ||||
|         except PinNoPins: | ||||
|             warnings.warn( | ||||
|                 PinNonPhysical( | ||||
|                     'no physical pins exist for GPIO%d' % self.number)) | ||||
|                     'no physical pins exist for %s' % repr(self))) | ||||
|  | ||||
|     @property | ||||
|     def number(self): | ||||
|   | ||||
| @@ -46,20 +46,21 @@ class PiGPIOFactory(PiFactory): | ||||
|  | ||||
|     You can construct pigpio pins manually like so:: | ||||
|  | ||||
|         from gpiozero.pins.pigpio import PiGPIOPin | ||||
|         from gpiozero.pins.pigpio import PiGPIOFactory | ||||
|         from gpiozero import LED | ||||
|  | ||||
|         led = LED(PiGPIOPin(12)) | ||||
|         factory = PiGPIOFactory() | ||||
|         led = LED(12, pin_factory=factory) | ||||
|  | ||||
|     This is particularly useful for controlling pins on a remote machine. To | ||||
|     accomplish this simply specify the host (and optionally port) when | ||||
|     constructing the pin:: | ||||
|  | ||||
|         from gpiozero.pins.pigpio import PiGPIOPin | ||||
|         from gpiozero.pins.pigpio import PiGPIOFactory | ||||
|         from gpiozero import LED | ||||
|         from signal import pause | ||||
|  | ||||
|         led = LED(PiGPIOPin(12, host='192.168.0.2')) | ||||
|         factory = PiGPIOFactory(host='192.168.0.2') | ||||
|         led = LED(12, pin_factory=factory) | ||||
|  | ||||
|     .. note:: | ||||
|  | ||||
| @@ -132,6 +133,12 @@ class PiGPIOFactory(PiFactory): | ||||
|  | ||||
|  | ||||
| class PiGPIOPin(PiPin): | ||||
|     """ | ||||
|     Pin implementation for the `pigpio`_ library. See :class:`PiGPIOFactory` | ||||
|     for more information. | ||||
|  | ||||
|     .. _pigpio: http://abyz.co.uk/rpi/pigpio/ | ||||
|     """ | ||||
|     _CONNECTIONS = {} # maps (host, port) to (connection, pi_info) | ||||
|     GPIO_FUNCTIONS = { | ||||
|         'input':   pigpio.INPUT, | ||||
| @@ -162,7 +169,7 @@ class PiGPIOPin(PiPin): | ||||
|  | ||||
|     def __init__(self, factory, number): | ||||
|         super(PiGPIOPin, self).__init__(factory, number) | ||||
|         self._pull = 'up' if factory.pi_info.pulled_up(repr(self)) else 'floating' | ||||
|         self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating' | ||||
|         self._pwm = False | ||||
|         self._bounce = None | ||||
|         self._callback = None | ||||
| @@ -289,6 +296,12 @@ class PiGPIOPin(PiPin): | ||||
|  | ||||
|  | ||||
| class PiGPIOHardwareSPI(SPI, Device): | ||||
|     """ | ||||
|     Hardware SPI implementation for the `pigpio`_ library. Uses the ``spi_*`` | ||||
|     functions from the pigpio API. | ||||
|  | ||||
|     .. _pigpio: http://abyz.co.uk/rpi/pigpio/ | ||||
|     """ | ||||
|     def __init__(self, factory, port, device): | ||||
|         self._port = port | ||||
|         self._device = device | ||||
| @@ -385,6 +398,12 @@ class PiGPIOHardwareSPI(SPI, Device): | ||||
|  | ||||
|  | ||||
| class PiGPIOSoftwareSPI(SPI, Device): | ||||
|     """ | ||||
|     Software SPI implementation for the `pigpio`_ library. Uses the ``bb_spi_*`` | ||||
|     functions from the pigpio API. | ||||
|  | ||||
|     .. _pigpio: http://abyz.co.uk/rpi/pigpio/ | ||||
|     """ | ||||
|     def __init__(self, factory, clock_pin, mosi_pin, miso_pin, select_pin): | ||||
|         self._closed = True | ||||
|         self._select_pin = select_pin | ||||
|   | ||||
| @@ -40,7 +40,8 @@ class RPiGPIOFactory(LocalPiFactory): | ||||
|         from gpiozero.pins.rpigpio import RPiGPIOFactory | ||||
|         from gpiozero import LED | ||||
|  | ||||
|         led = LED(RPiGPIOPin(12)) | ||||
|         factory = RPiGPIOFactory() | ||||
|         led = LED(12, pin_factory=factory) | ||||
|  | ||||
|     .. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO | ||||
|     """ | ||||
| @@ -57,6 +58,12 @@ class RPiGPIOFactory(LocalPiFactory): | ||||
|  | ||||
|  | ||||
| class RPiGPIOPin(LocalPiPin): | ||||
|     """ | ||||
|     Pin implementation for the `RPi.GPIO`_ library. See :class:`RPiGPIOFactory` | ||||
|     for more information. | ||||
|  | ||||
|     .. _RPi.GPIO: https://pypi.python.org/pypi/RPi.GPIO | ||||
|     """ | ||||
|     GPIO_FUNCTIONS = { | ||||
|         'input':   GPIO.IN, | ||||
|         'output':  GPIO.OUT, | ||||
| @@ -85,7 +92,7 @@ class RPiGPIOPin(LocalPiPin): | ||||
|  | ||||
|     def __init__(self, factory, number): | ||||
|         super(RPiGPIOPin, self).__init__(factory, number) | ||||
|         self._pull = 'up' if self.factory.pi_info.pulled_up(self.address[-1]) else 'floating' | ||||
|         self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating' | ||||
|         self._pwm = None | ||||
|         self._frequency = None | ||||
|         self._duty_cycle = None | ||||
| @@ -103,7 +110,7 @@ class RPiGPIOPin(LocalPiPin): | ||||
|         GPIO.setup(self.number, GPIO.OUT, initial=state) | ||||
|  | ||||
|     def input_with_pull(self, pull): | ||||
|         if pull != 'up' and self.factory.pi_info.pulled_up(self.address[-1]): | ||||
|         if pull != 'up' and self.factory.pi_info.pulled_up(repr(self)): | ||||
|             raise PinFixedPull('%r has a physical pull-up resistor' % self) | ||||
|         try: | ||||
|             GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[pull]) | ||||
| @@ -149,7 +156,7 @@ class RPiGPIOPin(LocalPiPin): | ||||
|     def _set_pull(self, value): | ||||
|         if self.function != 'input': | ||||
|             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) | ||||
|         try: | ||||
|             GPIO.setup(self.number, GPIO.IN, self.GPIO_PULL_UPS[value]) | ||||
|   | ||||
| @@ -40,10 +40,11 @@ class RPIOFactory(LocalPiFactory): | ||||
|  | ||||
|     You can construct RPIO pins manually like so:: | ||||
|  | ||||
|         from gpiozero.pins.rpio import RPIOPin | ||||
|         from gpiozero.pins.rpio import RPIOFactory | ||||
|         from gpiozero import LED | ||||
|  | ||||
|         led = LED(RPIOPin(12)) | ||||
|         factory = RPIOFactory() | ||||
|         led = LED(12, pin_factory=factory) | ||||
|  | ||||
|     .. _RPIO: https://pythonhosted.org/RPIO/ | ||||
|     """ | ||||
| @@ -63,6 +64,12 @@ class RPIOFactory(LocalPiFactory): | ||||
|  | ||||
|  | ||||
| class RPIOPin(LocalPiPin): | ||||
|     """ | ||||
|     Pin implementation for the `RPIO`_ library. See :class:`RPIOFactory` for | ||||
|     more information. | ||||
|  | ||||
|     .. _RPIO: https://pythonhosted.org/RPIO/ | ||||
|     """ | ||||
|     GPIO_FUNCTIONS = { | ||||
|         'input':   RPIO.IN, | ||||
|         'output':  RPIO.OUT, | ||||
| @@ -80,7 +87,7 @@ class RPIOPin(LocalPiPin): | ||||
|  | ||||
|     def __init__(self, factory, number): | ||||
|         super(RPIOPin, self).__init__(factory, number) | ||||
|         self._pull = 'up' if self.factory.pi_info.pulled_up(self.address[-1]) else 'floating' | ||||
|         self._pull = 'up' if self.factory.pi_info.pulled_up(repr(self)) else 'floating' | ||||
|         self._pwm = False | ||||
|         self._duty_cycle = None | ||||
|         self._bounce = None | ||||
| @@ -138,7 +145,7 @@ class RPIOPin(LocalPiPin): | ||||
|     def _set_pull(self, value): | ||||
|         if self.function != 'input': | ||||
|             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) | ||||
|         try: | ||||
|             RPIO.setup(self.number, RPIO.IN, self.GPIO_PULL_UPS[value]) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user