mirror of
				https://github.com/KevinMidboe/python-gpiozero.git
				synced 2025-10-29 17:50:37 +00:00 
			
		
		
		
	Merge-clean update of PR #126
This is an updated cherry-pick of Martin O'Hanlon's LEDBarGraph class.
This commit is contained in:
		@@ -22,6 +22,13 @@ LED Board
 | 
				
			|||||||
    :inherited-members:
 | 
					    :inherited-members:
 | 
				
			||||||
    :members:
 | 
					    :members:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LED Bar Graph
 | 
				
			||||||
 | 
					=============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. autoclass:: LEDBarGraph(\*pins, initial_value=0)
 | 
				
			||||||
 | 
					    :inherited-members:
 | 
				
			||||||
 | 
					    :members:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Traffic Lights
 | 
					Traffic Lights
 | 
				
			||||||
==============
 | 
					==============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -36,6 +43,13 @@ PiLITEr
 | 
				
			|||||||
    :inherited-members:
 | 
					    :inherited-members:
 | 
				
			||||||
    :members:
 | 
					    :members:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PiLITEr Bar Graph
 | 
				
			||||||
 | 
					=================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. autoclass:: PiLiterBarGraph
 | 
				
			||||||
 | 
					    :inherited-members:
 | 
				
			||||||
 | 
					    :members:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PI-TRAFFIC
 | 
					PI-TRAFFIC
 | 
				
			||||||
==========
 | 
					==========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,9 @@ from .output_devices import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
from .boards import (
 | 
					from .boards import (
 | 
				
			||||||
    LEDBoard,
 | 
					    LEDBoard,
 | 
				
			||||||
 | 
					    LEDBarGraph,
 | 
				
			||||||
    PiLiter,
 | 
					    PiLiter,
 | 
				
			||||||
 | 
					    PiLiterBarGraph,
 | 
				
			||||||
    TrafficLights,
 | 
					    TrafficLights,
 | 
				
			||||||
    PiTraffic,
 | 
					    PiTraffic,
 | 
				
			||||||
    TrafficLightsBuzzer,
 | 
					    TrafficLightsBuzzer,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,59 @@ from .output_devices import LED, PWMLED, Buzzer, Motor
 | 
				
			|||||||
from .devices import GPIOThread, CompositeDevice, SourceMixin
 | 
					from .devices import GPIOThread, CompositeDevice, SourceMixin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LEDBoard(SourceMixin, CompositeDevice):
 | 
					class LEDCollection(SourceMixin, CompositeDevice):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Abstract base class for :class:`LEDBoard` and :class:`LEDBarGraph`.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, *pins, **kwargs):
 | 
				
			||||||
 | 
					        self._blink_thread = None
 | 
				
			||||||
 | 
					        super(LEDCollection, self).__init__()
 | 
				
			||||||
 | 
					        pwm = kwargs.get('pwm', False)
 | 
				
			||||||
 | 
					        LEDClass = PWMLED if pwm else LED
 | 
				
			||||||
 | 
					        self._leds = tuple(LEDClass(pin) for pin in pins)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def close(self):
 | 
				
			||||||
 | 
					        for led in self.leds:
 | 
				
			||||||
 | 
					            led.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def closed(self):
 | 
				
			||||||
 | 
					        return all(led.closed for led in self.leds)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def leds(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        A tuple of all the :class:`LED` or :class:`PWMLED` objects contained by
 | 
				
			||||||
 | 
					        the instance.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return self._leds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def on(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Turn all the LEDs on.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        for led in self.leds:
 | 
				
			||||||
 | 
					            led.on()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def off(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Turn all the LEDs off.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        for led in self.leds:
 | 
				
			||||||
 | 
					            led.off()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def toggle(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Toggle all the LEDs. For each LED, if it's on, turn it off; if it's
 | 
				
			||||||
 | 
					        off, turn it on.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        for led in self.leds:
 | 
				
			||||||
 | 
					            led.toggle()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LEDBoard(LEDCollection):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Extends :class:`CompositeDevice` and represents a generic LED board or
 | 
					    Extends :class:`CompositeDevice` and represents a generic LED board or
 | 
				
			||||||
    collection of LEDs.
 | 
					    collection of LEDs.
 | 
				
			||||||
@@ -41,29 +93,10 @@ class LEDBoard(SourceMixin, CompositeDevice):
 | 
				
			|||||||
        ``False`` (the default), construct regular :class:`LED` instances. This
 | 
					        ``False`` (the default), construct regular :class:`LED` instances. This
 | 
				
			||||||
        parameter can only be specified as a keyword parameter.
 | 
					        parameter can only be specified as a keyword parameter.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    def __init__(self, *pins, **kwargs):
 | 
					 | 
				
			||||||
        self._blink_thread = None
 | 
					 | 
				
			||||||
        super(LEDBoard, self).__init__()
 | 
					 | 
				
			||||||
        pwm = kwargs.get('pwm', False)
 | 
					 | 
				
			||||||
        LEDClass = PWMLED if pwm else LED
 | 
					 | 
				
			||||||
        self._leds = tuple(LEDClass(pin) for pin in pins)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def close(self):
 | 
					    def close(self):
 | 
				
			||||||
        self._stop_blink()
 | 
					        self._stop_blink()
 | 
				
			||||||
        for led in self.leds:
 | 
					        super(LEDBoard, self).close()
 | 
				
			||||||
            led.close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def closed(self):
 | 
					 | 
				
			||||||
        return all(led.closed for led in self.leds)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def leds(self):
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        A tuple of all the :class:`LED` or :class:`PWMLED` objects contained by
 | 
					 | 
				
			||||||
        the instance.
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self._leds
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
@@ -75,32 +108,21 @@ class LEDBoard(SourceMixin, CompositeDevice):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @value.setter
 | 
					    @value.setter
 | 
				
			||||||
    def value(self, value):
 | 
					    def value(self, value):
 | 
				
			||||||
 | 
					        self._stop_blink()
 | 
				
			||||||
        for l, v in zip(self.leds, value):
 | 
					        for l, v in zip(self.leds, value):
 | 
				
			||||||
            l.value = v
 | 
					            l.value = v
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def on(self):
 | 
					    def on(self):
 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        Turn all the LEDs on.
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self._stop_blink()
 | 
					        self._stop_blink()
 | 
				
			||||||
        for led in self.leds:
 | 
					        super(LEDBoard, self).on()
 | 
				
			||||||
            led.on()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def off(self):
 | 
					    def off(self):
 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        Turn all the LEDs off.
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self._stop_blink()
 | 
					        self._stop_blink()
 | 
				
			||||||
        for led in self.leds:
 | 
					        super(LEDBoard, self).off()
 | 
				
			||||||
            led.off()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def toggle(self):
 | 
					    def toggle(self):
 | 
				
			||||||
        """
 | 
					        self._stop_blink()
 | 
				
			||||||
        Toggle all the LEDs. For each LED, if it's on, turn it off; if it's
 | 
					        super(LEDBoard, self).toggle()
 | 
				
			||||||
        off, turn it on.
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        for led in self.leds:
 | 
					 | 
				
			||||||
            led.toggle()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def blink(
 | 
					    def blink(
 | 
				
			||||||
            self, on_time=1, off_time=1, fade_in_time=0, fade_out_time=0,
 | 
					            self, on_time=1, off_time=1, fade_in_time=0, fade_out_time=0,
 | 
				
			||||||
@@ -178,9 +200,96 @@ class LEDBoard(SourceMixin, CompositeDevice):
 | 
				
			|||||||
                break
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LEDBarGraph(LEDCollection):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Extends :class:`CompositeDevice` to control a line of LEDs representing a
 | 
				
			||||||
 | 
					    bar graph. Positive values (0 to 1) light the LEDs from first to last.
 | 
				
			||||||
 | 
					    Negative values (-1 to 0) light the LEDs from last to first.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The following example turns on all the LEDs on a board containing 5 LEDs
 | 
				
			||||||
 | 
					    attached to GPIO pins 2 through 6::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        from gpiozero import LEDBarGraph
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        graph = LEDBarGraph(2, 3, 4, 5, 6)
 | 
				
			||||||
 | 
					        graph.value = 2/5  # Light the first two LEDs only
 | 
				
			||||||
 | 
					        graph.value = -2/5 # Light the last two LEDs only
 | 
				
			||||||
 | 
					        graph.off()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    As with other output devices, :attr:`source` and :attr:`values` are
 | 
				
			||||||
 | 
					    supported::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        from gpiozero import LEDBarGraph, MCP3008
 | 
				
			||||||
 | 
					        from signal import pause
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        graph = LEDBarGraph(2, 3, 4, 5, 6)
 | 
				
			||||||
 | 
					        pot = MCP3008(channel=0)
 | 
				
			||||||
 | 
					        graph.source = pot.values
 | 
				
			||||||
 | 
					        pause()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param int \*pins:
 | 
				
			||||||
 | 
					        Specify the GPIO pins that the LEDs of the bar graph are attached to.
 | 
				
			||||||
 | 
					        You can designate as many pins as necessary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param float initial_value:
 | 
				
			||||||
 | 
					        The initial :attr:`value` of the graph given as a float between -1 and
 | 
				
			||||||
 | 
					        +1.  Defaults to 0.0.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, *pins, **kwargs):
 | 
				
			||||||
 | 
					        super(LEDBarGraph, self).__init__(*pins, pwm=False)
 | 
				
			||||||
 | 
					        initial_value = kwargs.get('initial_value', 0)
 | 
				
			||||||
 | 
					        self.value = initial_value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def value(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        The value of the LED bar graph. When no LEDs are lit, the value is 0.
 | 
				
			||||||
 | 
					        When all LEDs are lit, the value is 1. Values between 0 and 1
 | 
				
			||||||
 | 
					        light LEDs linearly from first to last. Values between 0 and -1
 | 
				
			||||||
 | 
					        light LEDs linearly from last to first.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        To light a particular number of LEDs, simply divide that number by
 | 
				
			||||||
 | 
					        the number of LEDs. For example, if your graph contains 3 LEDs, the
 | 
				
			||||||
 | 
					        following will light the first::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            from gpiozero import LEDBarGraph
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            graph = LEDBarGraph(12, 16, 19)
 | 
				
			||||||
 | 
					            graph.value = 1/3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .. note::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Setting value to -1 will light all LEDs. However, querying it
 | 
				
			||||||
 | 
					            subsequently will return 1 as both representations are the same in
 | 
				
			||||||
 | 
					            hardware.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        for index, led in enumerate(self.leds):
 | 
				
			||||||
 | 
					            if not led.is_lit:
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            index = len(self.leds)
 | 
				
			||||||
 | 
					        if not index:
 | 
				
			||||||
 | 
					            for index, led in enumerate(reversed(self.leds)):
 | 
				
			||||||
 | 
					                if not led.is_lit:
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					            index = -index
 | 
				
			||||||
 | 
					        return index / len(self.leds)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @value.setter
 | 
				
			||||||
 | 
					    def value(self, value):
 | 
				
			||||||
 | 
					        count = len(self.leds)
 | 
				
			||||||
 | 
					        if value >= 0:
 | 
				
			||||||
 | 
					            for index, led in enumerate(self.leds, start=1):
 | 
				
			||||||
 | 
					                led.value = value >= (index / count)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            for index, led in enumerate(reversed(self.leds), start=1):
 | 
				
			||||||
 | 
					                led.value = value <= -(index / count)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PiLiter(LEDBoard):
 | 
					class PiLiter(LEDBoard):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Extends :class:`LEDBoard` for the Ciseco Pi-LITEr: a strip of 8 very bright
 | 
					    Extends :class:`LEDBoard` for the `Ciseco Pi-LITEr`_: a strip of 8 very bright
 | 
				
			||||||
    LEDs.
 | 
					    LEDs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    The Pi-LITEr pins are fixed and therefore there's no need to specify them
 | 
					    The Pi-LITEr pins are fixed and therefore there's no need to specify them
 | 
				
			||||||
@@ -196,11 +305,38 @@ class PiLiter(LEDBoard):
 | 
				
			|||||||
        If ``True``, construct :class:`PWMLED` instances for each pin. If
 | 
					        If ``True``, construct :class:`PWMLED` instances for each pin. If
 | 
				
			||||||
        ``False`` (the default), construct regular :class:`LED` instances. This
 | 
					        ``False`` (the default), construct regular :class:`LED` instances. This
 | 
				
			||||||
        parameter can only be specified as a keyword parameter.
 | 
					        parameter can only be specified as a keyword parameter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. _Ciseco Pi-LITEr: http://shop.ciseco.co.uk/pi-liter-8-led-strip-for-the-raspberry-pi/
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    def __init__(self, pwm=False):
 | 
					    def __init__(self, pwm=False):
 | 
				
			||||||
        super(PiLiter, self).__init__(4, 17, 27, 18, 22, 23, 24, 25, pwm=pwm)
 | 
					        super(PiLiter, self).__init__(4, 17, 27, 18, 22, 23, 24, 25, pwm=pwm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PiLiterBarGraph(LEDBarGraph):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Extends :class:`LEDBarGraph` to treat the `Ciseco Pi-LITEr`_ as an
 | 
				
			||||||
 | 
					    8-segment bar graph.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The Pi-LITEr pins are fixed and therefore there's no need to specify them
 | 
				
			||||||
 | 
					    when constructing this class. The following example sets the graph value
 | 
				
			||||||
 | 
					    to 0.5::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        from gpiozero import PiLiterBarGraph
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        graph = PiLiterBarGraph()
 | 
				
			||||||
 | 
					        graph.value = 0.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param bool initial_value:
 | 
				
			||||||
 | 
					        The initial value of the graph given as a float between -1 and +1.
 | 
				
			||||||
 | 
					        Defaults to 0.0.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. _Ciseco Pi-LITEr: http://shop.ciseco.co.uk/pi-liter-8-led-strip-for-the-raspberry-pi/
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    def __init__(self, initial_value=0):
 | 
				
			||||||
 | 
					        super(PiLiterBarGraph, self).__init__(
 | 
				
			||||||
 | 
					                4, 17, 27, 18, 22, 23, 24, 25, initial_value=initial_value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TrafficLightTuple = namedtuple('TrafficLightTuple', ('red', 'amber', 'green'))
 | 
					TrafficLightTuple = namedtuple('TrafficLightTuple', ('red', 'amber', 'green'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user