Source code for jled.jled_sequence

# SPDX-FileCopyrightText: Copyright (c) 2022 Jan Delgado
# SPDX-License-Identifier: MIT
#
"""
jled
================================================================================

Non-blocking LED controlling library

A pure python port of JLed (https://github.com/jandelgado/jled)

* Author(s): Jan Delgado

"""

from .jled import JLed


[docs]class JLedSequence: """The ``JLedSequence`` class allows controlling a group of effects either in parallel or sequentially. An effect is either a :class:`~jled.jled.JLed` object or a ``JLedSequence``. Example:: from jled import JLed, JLedSequence led1 = JLed(board.LED).blink(500, 250).repeat(5) led2 = JLed(board.GP2).breathe(1000).repeat(5) seq = JLedSequence(JLedSequence.SEQUENTIAL, [led1, led2]) """ PARALLEL = 0 SEQUENTIAL = 1 _REPEAT_FOREVER = -1 def __init__(self, mode, leds): """Construct a JLedSequence for the given list of effects. An effect can be either a ``JLed`` object, or another ``JLedSequence``. For convenience, two additional functions are provided: :func:`parallel` and :func:`sequential` :param mode: one of ``JLedSequence.PARALLEL`` or ``JLedSequence.SEQUENTIAL`` :param leds: list of effects to control """ self._mode = mode self._leds = leds self._num_repetitions = 1 self._cur = 0 self._iteration = 0 self._is_running = True
[docs] @staticmethod def parallel(leds): """Initialize a JLedSequence to play given effects in parallel. This is a convenience method for calling ``JLedSequence(JLedSequence.PARALLEL, leds)``. :param leds: list of effects to play :return: a new JLedSequence object """ return JLedSequence(JLedSequence.PARALLEL, leds)
[docs] @staticmethod def sequential(leds): """Initialize a JLedSequence to play given effects sequentially. This is a convenience method for calling ``JLedSequence(JLedSequence.SEQUENTIAL, leds)``. :param leds: list of effects to play :return: a new JLedSequence object """ return JLedSequence(JLedSequence.SEQUENTIAL, leds)
def _reset_leds(self): for led in self._leds: led.reset() def _update_parallel(self, t): result = False for led in self._leds: # pylint: disable=protected-access result |= led._update(t) # considered "friend class" return result def _update_sequentially(self, t): n = len(self._leds) if self._cur >= n: return False # pylint: disable=protected-access if not self._leds[self._cur]._update(t): self._cur += 1 return self._cur < n return True def _update(self, t): # if self._mode == JLedSequence.PARALLEL: # return self._update_parallel(t) # return self._update_sequentially(t) running = ( self._update_parallel(t) if self._mode == JLedSequence.PARALLEL else self._update_sequentially(t) ) if running: return True self._cur = 0 self._iteration += 1 is_running = self._iteration < self._num_repetitions or self.is_forever if is_running: # reset all leds after each full iteration as long as the sequence is running self._reset_leds() self._is_running = is_running return is_running
[docs] def update(self): """ Call update periodically to play the effects/LEDs. :return: True if the effect is still running, otherwise False """ if not self._is_running: return False t = JLed._TIME_HAL.millis() # pylint: disable=protected-access return self._update(t)
[docs] def reset(self): """Reset all LEDs controlled by this ``JLedSequence`` and the JLedSequence itself. Calling update afterwards will start all all LEDs over. :return: this JLedSequence object """ self._reset_leds() self._cur = 0 self._iteration = 0 self._is_running = True return self
[docs] def stop(self): """Turns off all objects controlled by this ``JLedSequence`` and stops the sequence. Further calls to :func:`update` will have no effect. :return: this JLedSequence object """ self._is_running = False for led in self._leds: led.stop() return self
[docs] def repeat(self, num): """Use the ``repeat`` method to specify the number of repetitions. The default value is 1 repetition. :param num: number of repetitions :return: this JLedSequence object """ self._num_repetitions = num return self
[docs] def forever(self): """Set this ``JLedSequence`` to run forever. :return: this JLedSequence object """ """set effect to run forever""" return self.repeat(JLedSequence._REPEAT_FOREVER)
@property def is_forever(self): """ :return: True if this ``JLedSequence`` is set to run :func:`forever`, otherwise False """ return self._num_repetitions == JLedSequence._REPEAT_FOREVER @property def is_running(self): """ :return: True if ``JLedSequence`` is running, otherwise False. """ return self._is_running