mirror of
				https://github.com/KevinMidboe/python-gpiozero.git
				synced 2025-10-29 17:50:37 +00:00 
			
		
		
		
	Add pin_factory param to all devices
And some docs ...
This commit is contained in:
		| @@ -47,6 +47,10 @@ class CompositeOutputDevice(SourceMixin, CompositeDevice): | ||||
|         specific order). All keyword arguments *must* be included in the | ||||
|         collection. If omitted, an alphabetically sorted order will be selected | ||||
|         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): | ||||
| @@ -124,6 +128,10 @@ class ButtonBoard(HoldMixin, CompositeDevice): | ||||
|         executed once per hold. This parameter can only be 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: | ||||
|         Specify GPIO pins that buttons of the board are attached to, | ||||
|         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) | ||||
|         hold_time = kwargs.pop('hold_time', 1) | ||||
|         hold_repeat = kwargs.pop('hold_repeat', False) | ||||
|         pin_factory = kwargs.pop('pin_factory', None) | ||||
|         order = kwargs.pop('_order', None) | ||||
|         super(ButtonBoard, self).__init__( | ||||
|             *( | ||||
| @@ -142,6 +151,7 @@ class ButtonBoard(HoldMixin, CompositeDevice): | ||||
|                 for pin in args | ||||
|                 ), | ||||
|             _order=order, | ||||
|             pin_factory=pin_factory, | ||||
|             **{ | ||||
|                 name: Button(pin, pull_up, bounce_time, hold_time, hold_repeat) | ||||
|                 for name, pin in kwargs.items() | ||||
| @@ -209,20 +219,28 @@ class LEDCollection(CompositeOutputDevice): | ||||
|         pwm = kwargs.pop('pwm', False) | ||||
|         active_high = kwargs.pop('active_high', True) | ||||
|         initial_value = kwargs.pop('initial_value', False) | ||||
|         pin_factory = kwargs.pop('pin_factory', None) | ||||
|         order = kwargs.pop('_order', None) | ||||
|         LEDClass = PWMLED if pwm else LED | ||||
|         super(LEDCollection, self).__init__( | ||||
|             *( | ||||
|                 pin_or_collection | ||||
|                 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 | ||||
|                 ), | ||||
|             _order=order, | ||||
|             pin_factory=pin_factory, | ||||
|             **{ | ||||
|                 name: pin_or_collection | ||||
|                 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() | ||||
|                 }) | ||||
|         leds = [] | ||||
| @@ -283,6 +301,10 @@ class LEDBoard(LEDCollection): | ||||
|         the device will be switched on initially. This parameter can only be | ||||
|         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: | ||||
|         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 | ||||
| @@ -486,6 +508,10 @@ class LEDBarGraph(LEDCollection): | ||||
|         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 | ||||
|         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): | ||||
| @@ -495,9 +521,12 @@ class LEDBarGraph(LEDCollection): | ||||
|         pwm = kwargs.pop('pwm', False) | ||||
|         active_high = kwargs.pop('active_high', True) | ||||
|         initial_value = kwargs.pop('initial_value', 0.0) | ||||
|         pin_factory = kwargs.pop('pin_factory', None) | ||||
|         if kwargs: | ||||
|             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: | ||||
|             self.value = initial_value | ||||
|         except: | ||||
| @@ -572,12 +601,17 @@ class LedBorg(RGBLED): | ||||
|         each component of the LedBorg. If ``False``, construct regular | ||||
|         :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 | ||||
|     """ | ||||
|  | ||||
|     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, | ||||
|                                       pwm=pwm, initial_value=initial_value) | ||||
|                                       pwm=pwm, initial_value=initial_value, | ||||
|                                       pin_factory=pin_factory) | ||||
|  | ||||
|  | ||||
| class PiLiter(LEDBoard): | ||||
| @@ -604,12 +638,17 @@ class PiLiter(LEDBoard): | ||||
|         in when configured for output (warning: this can be on). If ``True``, | ||||
|         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/ | ||||
|     """ | ||||
|  | ||||
|     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, | ||||
|                                       pwm=pwm, initial_value=initial_value) | ||||
|                                       pwm=pwm, initial_value=initial_value, | ||||
|                                       pin_factory=pin_factory) | ||||
|  | ||||
|  | ||||
| class PiLiterBarGraph(LEDBarGraph): | ||||
| @@ -634,13 +673,18 @@ class PiLiterBarGraph(LEDBarGraph): | ||||
|         The initial :attr:`value` of the graph given as a float between -1 and | ||||
|         +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/ | ||||
|     """ | ||||
|  | ||||
|     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) | ||||
|         super(PiLiterBarGraph, self).__init__(*pins, | ||||
|                 pwm=pwm, initial_value=initial_value) | ||||
|         super(PiLiterBarGraph, self).__init__( | ||||
|             *pins, pwm=pwm, initial_value=initial_value, pin_factory=pin_factory | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class TrafficLights(LEDBoard): | ||||
| @@ -680,9 +724,14 @@ class TrafficLights(LEDBoard): | ||||
|         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`` | ||||
|         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, | ||||
|                  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: | ||||
|             raise OutputDeviceBadValue( | ||||
|                 'Only one of amber or yellow can be specified' | ||||
| @@ -700,7 +749,7 @@ class TrafficLights(LEDBoard): | ||||
|             ) | ||||
|         super(TrafficLights, self).__init__( | ||||
|             pwm=pwm, initial_value=initial_value, | ||||
|             _order=devices.keys(), | ||||
|             _order=devices.keys(), pin_factory=pin_factory, | ||||
|             **devices) | ||||
|  | ||||
|     def __getattr__(self, name): | ||||
| @@ -739,11 +788,16 @@ class PiTraffic(TrafficLights): | ||||
|         in when configured for output (warning: this can be on). If ``True``, | ||||
|         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/ | ||||
|     """ | ||||
|     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, | ||||
|                                         pwm=pwm, initial_value=initial_value) | ||||
|                                         pwm=pwm, initial_value=initial_value, | ||||
|                                         pin_factory=pin_factory) | ||||
|  | ||||
|  | ||||
| class PiStop(TrafficLights): | ||||
| @@ -774,6 +828,10 @@ class PiStop(TrafficLights): | ||||
|         in when configured for output (warning: this can be on). If ``True``, | ||||
|         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/ | ||||
|     .. _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), | ||||
|     } | ||||
|  | ||||
|     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) | ||||
|         if gpios is None: | ||||
|             raise ValueError('location must be one of: %s' % | ||||
|                              ', '.join(sorted(self.LOCATIONS.keys()))) | ||||
|         super(PiStop, self).__init__(*gpios, | ||||
|                                         pwm=pwm, initial_value=initial_value) | ||||
|         super(PiStop, self).__init__( | ||||
|             *gpios, pwm=pwm, initial_value=initial_value, | ||||
|             pin_factory=pin_factory | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class StatusZero(LEDBoard): | ||||
| @@ -817,6 +879,10 @@ class StatusZero(LEDBoard): | ||||
|         not all 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 Zero: https://thepihut.com/statuszero | ||||
|     """ | ||||
|     default_labels = ('one', 'two', 'three') | ||||
| @@ -827,6 +893,7 @@ class StatusZero(LEDBoard): | ||||
|             (22, 27), | ||||
|             (9, 10), | ||||
|         ) | ||||
|         pin_factory = kwargs.pop('pin_factory', None) | ||||
|         if len(labels) == 0: | ||||
|             labels = self.default_labels | ||||
|         elif len(labels) > len(pins): | ||||
| @@ -834,10 +901,15 @@ class StatusZero(LEDBoard): | ||||
|         dup, count = Counter(labels).most_common(1)[0] | ||||
|         if count > 1: | ||||
|             raise ValueError("Duplicate label %s" % dup) | ||||
|         super(StatusZero, self).__init__(_order=labels, **{ | ||||
|             label: LEDBoard(red=red, green=green, _order=('red', 'green'), **kwargs) | ||||
|             for (green, red), label in zip(pins, labels) | ||||
|         }) | ||||
|         super(StatusZero, self).__init__( | ||||
|             _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) | ||||
|             } | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class StatusBoard(CompositeOutputDevice): | ||||
| @@ -862,6 +934,10 @@ class StatusBoard(CompositeOutputDevice): | ||||
|         will be initialised with names 'one' to 'five'. If some, but not all | ||||
|         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 | ||||
|     """ | ||||
|     default_labels = ('one', 'two', 'three', 'four', 'five') | ||||
| @@ -874,6 +950,7 @@ class StatusBoard(CompositeOutputDevice): | ||||
|             (5, 11, 26), | ||||
|             (13, 6, 18), | ||||
|         ) | ||||
|         pin_factory = kwargs.pop('pin_factory', None) | ||||
|         if len(labels) == 0: | ||||
|             labels = self.default_labels | ||||
|         elif len(labels) > len(pins): | ||||
| @@ -881,14 +958,18 @@ class StatusBoard(CompositeOutputDevice): | ||||
|         dup, count = Counter(labels).most_common(1)[0] | ||||
|         if count > 1: | ||||
|             raise ValueError("Duplicate label %s" % dup) | ||||
|         super(StatusBoard, self).__init__(_order=labels, **{ | ||||
|             label: CompositeOutputDevice( | ||||
|                 button=Button(button), | ||||
|                 lights=LEDBoard( | ||||
|                     red=red, green=green, _order=('red', 'green'), **kwargs | ||||
|                 ), _order=('button', 'lights')) | ||||
|             for (green, red, button), label in zip(pins, labels) | ||||
|         }) | ||||
|         super(StatusBoard, self).__init__( | ||||
|             _order=labels, pin_factory=pin_factory, **{ | ||||
|                 label: CompositeOutputDevice( | ||||
|                     button=Button(button), | ||||
|                     lights=LEDBoard( | ||||
|                         red=red, green=green, _order=('red', 'green'), | ||||
|                         pin_factory=pin_factory, **kwargs | ||||
|                     ), _order=('button', 'lights'), pin_factory=pin_factory | ||||
|                 ) | ||||
|                 for (green, red, button), label in zip(pins, labels) | ||||
|             } | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class SnowPi(LEDBoard): | ||||
| @@ -917,30 +998,39 @@ class SnowPi(LEDBoard): | ||||
|         in when configured for output (warning: this can be on). If ``True``, | ||||
|         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 | ||||
|     """ | ||||
|     def __init__(self, pwm=False, initial_value=False): | ||||
|     def __init__(self, pwm=False, initial_value=False, pin_factory=None): | ||||
|         super(SnowPi, self).__init__( | ||||
|             arms=LEDBoard( | ||||
|                 left=LEDBoard( | ||||
|                     top=17, middle=18, bottom=22, | ||||
|                     pwm=pwm, initial_value=initial_value, | ||||
|                     _order=('top', 'middle', 'bottom')), | ||||
|                     _order=('top', 'middle', 'bottom'), | ||||
|                     pin_factory=pin_factory), | ||||
|                 right=LEDBoard( | ||||
|                     top=7, middle=8, bottom=9, | ||||
|                     pwm=pwm, initial_value=initial_value, | ||||
|                     _order=('top', 'middle', 'bottom')), | ||||
|                 _order=('left', 'right') | ||||
|                     _order=('top', 'middle', 'bottom'), | ||||
|                     pin_factory=pin_factory), | ||||
|                 _order=('left', 'right'), | ||||
|                 pin_factory=pin_factory | ||||
|                 ), | ||||
|             eyes=LEDBoard( | ||||
|                 left=23, right=24, | ||||
|                 pwm=pwm, initial_value=initial_value, | ||||
|                 _order=('left', 'right') | ||||
|                 _order=('left', 'right'), | ||||
|                 pin_factory=pin_factory | ||||
|                 ), | ||||
|             nose=25, | ||||
|             pwm=pwm, initial_value=initial_value, | ||||
|             _order=('eyes', 'nose', 'arms') | ||||
|             ) | ||||
|             _order=('eyes', 'nose', 'arms'), | ||||
|             pin_factory=pin_factory | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class TrafficLightsBuzzer(CompositeOutputDevice): | ||||
| @@ -957,12 +1047,18 @@ class TrafficLightsBuzzer(CompositeOutputDevice): | ||||
|  | ||||
|     :param Button button: | ||||
|         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__( | ||||
|             lights=lights, buzzer=buzzer, button=button, | ||||
|             _order=('lights', 'buzzer', 'button')) | ||||
|             _order=('lights', 'buzzer', 'button'), | ||||
|             pin_factory=pin_factory | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class FishDish(TrafficLightsBuzzer): | ||||
| @@ -985,14 +1081,19 @@ class FishDish(TrafficLightsBuzzer): | ||||
|         LED. If ``False`` (the default), construct regular :class:`LED` | ||||
|         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/ | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, pwm=False): | ||||
|     def __init__(self, pwm=False, pin_factory=None): | ||||
|         super(FishDish, self).__init__( | ||||
|             TrafficLights(9, 22, 4, pwm=pwm), | ||||
|             Buzzer(8), | ||||
|             Button(7, pull_up=False), | ||||
|             TrafficLights(9, 22, 4, pwm=pwm, pin_factory=pin_factory), | ||||
|             Buzzer(8, pin_factory=pin_factory), | ||||
|             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` | ||||
|         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 | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, pwm=False): | ||||
|     def __init__(self, pwm=False, pin_factory=None): | ||||
|         super(TrafficHat, self).__init__( | ||||
|             TrafficLights(24, 23, 22, pwm=pwm), | ||||
|             Buzzer(5), | ||||
|             Button(25), | ||||
|             TrafficLights(24, 23, 22, pwm=pwm, pin_factory=pin_factory), | ||||
|             Buzzer(5, pin_factory=pin_factory), | ||||
|             Button(25, pin_factory=pin_factory), | ||||
|             pin_factory=pin_factory | ||||
|         ) | ||||
|  | ||||
|  | ||||
| @@ -1049,13 +1155,19 @@ class Robot(SourceMixin, CompositeDevice): | ||||
|     :param tuple right: | ||||
|         A tuple of two GPIO pins representing the forward and backward inputs | ||||
|         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__( | ||||
|                 left_motor=Motor(*left), | ||||
|                 right_motor=Motor(*right), | ||||
|                 _order=('left_motor', 'right_motor')) | ||||
|             left_motor=Motor(*left, pin_factory=pin_factory), | ||||
|             right_motor=Motor(*right, pin_factory=pin_factory), | ||||
|             _order=('left_motor', 'right_motor'), | ||||
|             pin_factory=pin_factory | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def value(self): | ||||
| @@ -1148,11 +1260,17 @@ class RyanteckRobot(Robot): | ||||
|         robot = RyanteckRobot() | ||||
|         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 | ||||
|     """ | ||||
|  | ||||
|     def __init__(self): | ||||
|         super(RyanteckRobot, self).__init__((17, 18), (22, 23)) | ||||
|     def __init__(self, pin_factory=None): | ||||
|         super(RyanteckRobot, self).__init__( | ||||
|             (17, 18), (22, 23), pin_factory=pin_factory | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class CamJamKitRobot(Robot): | ||||
| @@ -1168,20 +1286,31 @@ class CamJamKitRobot(Robot): | ||||
|         robot = CamJamKitRobot() | ||||
|         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 | ||||
|     """ | ||||
|  | ||||
|     def __init__(self): | ||||
|         super(CamJamKitRobot, self).__init__((9, 10), (7, 8)) | ||||
|     def __init__(self, pin_factory=None): | ||||
|         super(CamJamKitRobot, self).__init__( | ||||
|             (9, 10), (7, 8), pin_factory=pin_factory | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class _EnergenieMaster(SharedMixin, CompositeOutputDevice): | ||||
|     def __init__(self): | ||||
|     def __init__(self, pin_factory=None): | ||||
|         self._lock = Lock() | ||||
|         super(_EnergenieMaster, self).__init__( | ||||
|                 *(OutputDevice(pin) for pin in (17, 22, 23, 27)), | ||||
|                 mode=OutputDevice(24), enable=OutputDevice(25), | ||||
|                 _order=('mode', 'enable')) | ||||
|             *( | ||||
|                 OutputDevice(pin, pin_factory=pin_factory) | ||||
|                 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): | ||||
|         if self._lock: | ||||
| @@ -1190,7 +1319,7 @@ class _EnergenieMaster(SharedMixin, CompositeOutputDevice): | ||||
|             self._lock = None | ||||
|  | ||||
|     @classmethod | ||||
|     def _shared_key(cls): | ||||
|     def _shared_key(cls, pin_factory): | ||||
|         # There's only one Energenie master | ||||
|         return None | ||||
|  | ||||
| @@ -1231,18 +1360,22 @@ class Energenie(SourceMixin, Device): | ||||
|         the socket, which will be set upon construction. This defaults to | ||||
|         ``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 | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, socket=None, initial_value=False): | ||||
|     def __init__(self, socket=None, initial_value=False, pin_factory=None): | ||||
|         if socket is None: | ||||
|             raise EnergenieSocketMissing('socket number must be provided') | ||||
|         if not (1 <= socket <= 4): | ||||
|             raise EnergenieBadSocket('socket number must be between 1 and 4') | ||||
|         self._value = None | ||||
|         super(Energenie, self).__init__() | ||||
|         super(Energenie, self).__init__(pin_factory=pin_factory) | ||||
|         self._socket = socket | ||||
|         self._master = _EnergenieMaster() | ||||
|         self._master = _EnergenieMaster(pin_factory=pin_factory) | ||||
|         if initial_value: | ||||
|             self.on() | ||||
|         else: | ||||
|   | ||||
| @@ -197,7 +197,11 @@ class Device(ValuesMixin, GPIOBase): | ||||
|  | ||||
|     def __init__(self, **kwargs): | ||||
|         # Force pin_factory to be keyword-only, even in Python 2 | ||||
|         self.pin_factory = kwargs.pop('pin_factory', Device.pin_factory) | ||||
|         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]) | ||||
| @@ -281,8 +285,7 @@ class CompositeDevice(Device): | ||||
|                     dev.close() | ||||
|             raise | ||||
|         self._all = args + tuple(kwargs[v] for v in self._order) | ||||
|         kwargs = {'pin_factory': pin_factory} if pin_factory is not None else {} | ||||
|         super(CompositeDevice, self).__init__(**kwargs) | ||||
|         super(CompositeDevice, self).__init__(pin_factory=pin_factory) | ||||
|  | ||||
|     def __getattr__(self, name): | ||||
|         # if _named doesn't exist yet, pretend it's an empty dict | ||||
|   | ||||
| @@ -32,9 +32,13 @@ class InputDevice(GPIODevice): | ||||
|     :param bool pull_up: | ||||
|         If ``True``, the pin will be pulled high with an internal resistor. If | ||||
|         ``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): | ||||
|         super(InputDevice, self).__init__(pin) | ||||
|     def __init__(self, pin=None, pull_up=False, pin_factory=None): | ||||
|         super(InputDevice, self).__init__(pin, pin_factory=pin_factory) | ||||
|         try: | ||||
|             self.pin.function = 'input' | ||||
|             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 | ||||
|         ignore changes in state after an initial change. This defaults to | ||||
|         ``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): | ||||
|         super(DigitalInputDevice, self).__init__(pin, pull_up) | ||||
|     def __init__( | ||||
|             self, pin=None, pull_up=False, bounce_time=None, pin_factory=None): | ||||
|         super(DigitalInputDevice, self).__init__( | ||||
|             pin, pull_up, pin_factory=pin_factory | ||||
|         ) | ||||
|         try: | ||||
|             self.pin.bounce = bounce_time | ||||
|             self.pin.edges = 'both' | ||||
| @@ -127,12 +138,18 @@ class SmoothedInputDevice(EventsMixin, InputDevice): | ||||
|         (from the :attr:`is_active` property) will block until the queue has | ||||
|         filled.  If ``True``, a value will be returned immediately, but be | ||||
|         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__( | ||||
|             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 | ||||
|         super(SmoothedInputDevice, self).__init__(pin, pull_up) | ||||
|         super(SmoothedInputDevice, self).__init__( | ||||
|             pin, pull_up, pin_factory=pin_factory | ||||
|         ) | ||||
|         try: | ||||
|             self._queue = GPIOQueue(self, queue_len, sample_wait, partial) | ||||
|             self.threshold = float(threshold) | ||||
| @@ -263,11 +280,17 @@ class Button(HoldMixin, DigitalInputDevice): | ||||
|         as long as the device remains active, every *hold_time* seconds. If | ||||
|         ``False`` (the default) the :attr:`when_held` handler will be only be | ||||
|         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__( | ||||
|             self, pin=None, pull_up=True, bounce_time=None, | ||||
|             hold_time=1, hold_repeat=False): | ||||
|         super(Button, self).__init__(pin, pull_up, bounce_time) | ||||
|             hold_time=1, hold_repeat=False, pin_factory=None): | ||||
|         super(Button, self).__init__( | ||||
|             pin, pull_up, bounce_time, pin_factory=pin_factory | ||||
|         ) | ||||
|         self.hold_time = hold_time | ||||
|         self.hold_repeat = hold_repeat | ||||
|  | ||||
| @@ -325,14 +348,19 @@ class LineSensor(SmoothedInputDevice): | ||||
|         filled with values.  Only set this to ``True`` if you require values | ||||
|         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 | ||||
|     """ | ||||
|     def __init__( | ||||
|             self, pin=None, queue_len=5, sample_rate=100, threshold=0.5, | ||||
|             partial=False): | ||||
|             partial=False, pin_factory=None): | ||||
|         super(LineSensor, self).__init__( | ||||
|             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: | ||||
|             self._queue.start() | ||||
| @@ -394,13 +422,18 @@ class MotionSensor(SmoothedInputDevice): | ||||
|         :attr:`~SmoothedInputDevice.is_active` until the internal queue has | ||||
|         filled with values.  Only set this to ``True`` if you require values | ||||
|         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__( | ||||
|             self, pin=None, queue_len=1, sample_rate=10, threshold=0.5, | ||||
|             partial=False): | ||||
|             partial=False, pin_factory=None): | ||||
|         super(MotionSensor, self).__init__( | ||||
|             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: | ||||
|             self._queue.start() | ||||
| @@ -460,14 +493,19 @@ class LightSensor(SmoothedInputDevice): | ||||
|         filled with values.  Only set this to ``True`` if you require values | ||||
|         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 | ||||
|     """ | ||||
|     def __init__( | ||||
|             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__( | ||||
|             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: | ||||
|             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 | ||||
|         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 | ||||
|     """ | ||||
|     def __init__( | ||||
|             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: | ||||
|             raise ValueError('invalid maximum distance (must be positive)') | ||||
|         self._trigger = None | ||||
|         super(DistanceSensor, self).__init__( | ||||
|             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: | ||||
|             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 | ||||
|         when configured for output (warning: this can be on).  If ``True``, 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). | ||||
|     """ | ||||
|     def __init__(self, pin=None, active_high=True, initial_value=False): | ||||
|         super(OutputDevice, self).__init__(pin) | ||||
|     def __init__( | ||||
|             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.active_high = active_high | ||||
|         if initial_value is None: | ||||
| @@ -126,10 +132,14 @@ class DigitalOutputDevice(OutputDevice): | ||||
|     uses an optional background thread to handle toggling the device state | ||||
|     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._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 | ||||
|     def value(self): | ||||
| @@ -230,6 +240,10 @@ class LED(DigitalOutputDevice): | ||||
|         ``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 | ||||
|         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 | ||||
|  | ||||
| @@ -265,6 +279,10 @@ class Buzzer(DigitalOutputDevice): | ||||
|         ``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 | ||||
|         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 | ||||
|  | ||||
| @@ -293,13 +311,21 @@ class PWMOutputDevice(OutputDevice): | ||||
|     :param int frequency: | ||||
|         The frequency (in Hz) of pulses emitted to drive the device. Defaults | ||||
|         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._controller = None | ||||
|         if not 0 <= initial_value <= 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: | ||||
|             # XXX need a way of setting these together | ||||
|             self.pin.frequency = frequency | ||||
| @@ -500,6 +526,10 @@ class PWMLED(PWMOutputDevice): | ||||
|     :param int frequency: | ||||
|         The frequency (in Hz) of pulses emitted to drive the LED. Defaults | ||||
|         to 100Hz. | ||||
|  | ||||
|     :param Factory pin_factory: | ||||
|         See :doc:`api_pins` for more information (this is an advanced feature | ||||
|         which most users can ignore). | ||||
|     """ | ||||
|     pass | ||||
|  | ||||
| @@ -552,17 +582,24 @@ class RGBLED(SourceMixin, Device): | ||||
|         If ``True`` (the default), construct :class:`PWMLED` instances for | ||||
|         each component of the RGBLED. If ``False``, construct regular | ||||
|         :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__( | ||||
|             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._blink_thread = None | ||||
|         if not all(p is not None for p in [red, green, blue]): | ||||
|             raise GPIOPinMissing('red, green, and blue pins must be provided') | ||||
|         LEDClass = PWMLED if pwm else LED | ||||
|         super(RGBLED, self).__init__() | ||||
|         self._leds = tuple(LEDClass(pin, active_high) for pin in (red, green, blue)) | ||||
|         super(RGBLED, self).__init__(pin_factory=pin_factory) | ||||
|         self._leds = tuple( | ||||
|             LEDClass(pin, active_high, pin_factory=pin_factory) | ||||
|             for pin in (red, green, blue) | ||||
|         ) | ||||
|         self.value = initial_value | ||||
|  | ||||
|     red = _led_property(0) | ||||
| @@ -803,17 +840,23 @@ class Motor(SourceMixin, CompositeDevice): | ||||
|         variable speed control. If ``False``, construct | ||||
|         :class:`DigitalOutputDevice` instances, allowing only direction | ||||
|         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]): | ||||
|             raise GPIOPinMissing( | ||||
|                 'forward and backward pins must be provided' | ||||
|             ) | ||||
|         PinClass = PWMOutputDevice if pwm else DigitalOutputDevice | ||||
|         super(Motor, self).__init__( | ||||
|                 forward_device=PinClass(forward), | ||||
|                 backward_device=PinClass(backward), | ||||
|                 _order=('forward_device', 'backward_device')) | ||||
|                 forward_device=PinClass(forward, pin_factory=pin_factory), | ||||
|                 backward_device=PinClass(backward, pin_factory=pin_factory), | ||||
|                 _order=('forward_device', 'backward_device'), | ||||
|                 pin_factory=pin_factory | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def value(self): | ||||
| @@ -946,11 +989,15 @@ class Servo(SourceMixin, CompositeDevice): | ||||
|     :param float frame_width: | ||||
|         The length of time between servo control pulses measured in seconds. | ||||
|         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__( | ||||
|             self, pin=None, initial_value=0.0, | ||||
|             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: | ||||
|             raise ValueError('min_pulse_width must be less than max_pulse_width') | ||||
|         if max_pulse_width >= frame_width: | ||||
| @@ -961,7 +1008,11 @@ class Servo(SourceMixin, CompositeDevice): | ||||
|         self._min_value = -1 | ||||
|         self._value_range = 2 | ||||
|         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: | ||||
|             self.value = initial_value | ||||
|         except: | ||||
| @@ -1146,17 +1197,23 @@ class AngularServo(Servo): | ||||
|     :param float frame_width: | ||||
|         The length of time between servo control pulses measured in seconds. | ||||
|         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__( | ||||
|             self, pin=None, initial_angle=0.0, | ||||
|             min_angle=-90, max_angle=90, | ||||
|             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._angular_range = max_angle - min_angle | ||||
|         initial_value = 2 * ((initial_angle - min_angle) / self._angular_range) - 1 | ||||
|         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 | ||||
|     def min_angle(self): | ||||
|   | ||||
| @@ -28,7 +28,9 @@ class SPIDevice(Device): | ||||
|     """ | ||||
|     def __init__(self, **spi_args): | ||||
|         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) | ||||
|  | ||||
|     def close(self): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user