Exemple #1
0
class Canvas():
    def __init__(self):
        # strip = None
        # self.DotCount = LED_COUNT
        # Create NeoPixel object with appropriate configuration.
        self.strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA,
                                LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
        # Intialize the library (must be called once before other functions).
        self.strip.begin()
        self.DotCount = self.strip.numPixels()

    def FillSolid(self, color):
        for i in range(self.strip.numPixels()):
            self.strip.setPixelColor(i, color)

    # def DrawPixels(self, position, size, color):
    #     dot = int(position)
    #     if dot < 0:return
    #     if dot >= self.DotCount:return
    #     # print("{dot:.2f}, {position:.2f}, {size:.2f}".format(dot=dot, position=position, size=size))
    #     self.strip.setPixelColor(dot, color)
    def DrawPixels(self, position, size, color):
        left_dot = int(position - size / 2)
        right_dot = int(position + size / 2)
        if right_dot < 0: return
        if left_dot < 0:
            left_dot = 0
        if left_dot >= self.DotCount: return
        if right_dot >= self.DotCount:
            right_dot = self.DotCount
        # print("{dot:.2f}, {position:.2f}, {size:.2f}".format(dot=dot, position=position, size=size))
        for dot in range(left_dot, right_dot + 1):
            self.strip.setPixelColor(dot, color)
def dither_fade(
    strip: ws.PixelStrip,
    new_color: Union[ws.Color, np.array],
    leds_to_switch: Optional[Iterable[int]] = None,
    dither_time: float = 1,
):
    """
    Dither in to a new set of colours by switching small batches of pixels.

    Parameters
    ---------
    strip
        the LED strip to animate
    new_color
        Either a single ws.Color or an array of them. Providing one colour acts as an array of that one colour.
    leds_to_switch
        Only dither these LEDs to leave specific elements static.
    dither_time
        the time over which to dither. Do not make this too short
    """

    try:
        iter(new_color)
    except TypeError:
        # this is not iterable, therefore it is one colour.
        # Make an array of that colour.
        new_color = np.array([new_color for _ in range(strip.numPixels())])

    start_time = time.time()
    if leds_to_switch is None:
        leds_to_switch = [i for i in range(strip.numPixels())]
    random.shuffle(leds_to_switch)

    num_leds = len(leds_to_switch)
    # As a rough rule of thumb, it takes 0.005 seconds to switch an LED and render an
    # update. Calculate the group size dynamically to fit into our time budget.

    min_update_time = 0.005
    switches_in_time = int(round(dither_time / min_update_time))
    batch_size = int(round((strip.numPixels() / switches_in_time) + 0.5))
    if batch_size != 1:
        num_batches = int(round((strip.numPixels() / batch_size)))
        batch_size = int(round((strip.numPixels() / num_batches)))

    while leds_to_switch:
        these_leds = [leds_to_switch.pop() for _ in range(batch_size) if leds_to_switch]
        for this_led in these_leds:
            strip.setPixelColor(this_led, new_color[this_led])
        time.sleep(dither_time / (batch_size * num_leds))
        strip.show()

    # Sometimes we go too fast with the switching, as
    # the batching approximation is horrible. If we
    # do, just chill here before moving on
    end_time = time.time()
    time_diff = end_time - start_time
    if time_diff < dither_time:
        time.sleep(dither_time - time_diff)
Exemple #3
0
class Steps(list):
    def __init__(self):
        # Create NeoPixel object with appropriate configuration.
        self.strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
        # Intialize the library (must be called once before other functions).
        self.strip.begin()

        for i, led_counter in enumerate(NUMBER_OF_LEDS):
            # get last led
            start = 0 if i == 0 else (self[-1][-1] + 1)
            # define step 
            step = Step(self.strip, start, start + led_counter)
            self.append(step)
    
    def __len__(self):
        return sum(NUMBER_OF_LEDS)

    def off(self, step_ms=0, led_ms=0):
        for step in self:
            step.off(led_ms)
        wait(step_ms)

    def color_test(self):
        for i, step in enumerate(self):
            color = Color(255, 0, 0) if i % 2 == 0 else Color(0, 255, 0)
            for led in step:
                self.strip.setPixelColor(led, color)
                self.strip.show()

    def pong(self, ms=10):
        for step in self:
            step.pong_init()

        while True:
            for step in self:
                step.pong_loop(ms=0)
            wait(ms)
    
    def rainbow(self, wait_ms=20, iterations=1):
        """Draw rainbow that fades across all pixels at once."""
        for i in range(self.strip.numPixels()):
            self.strip.setPixelColor(i, wheel(i & 255))
            self.strip.show()
            wait(wait_ms)

    def rainbowCycle(self, wait_ms=20, iterations=5):
        """Draw rainbow that uniformly distributes itself across all pixels."""
        for j in range(256*iterations):
            for i in range(self.strip.numPixels()):
                self.strip.setPixelColor(i, wheel((int(i * 256 / self.strip.numPixels()) + j) & 255))
            self.strip.show()
            wait(wait_ms)
def rainbow_cycle(strip: PixelStrip, wait_ms: int = 20, iterations: int = 5):
    """Draw rainbow that uniformly distributes itself across all pixels.

    :param strip:
    :param wait_ms:
    :param iterations:
    :return:
    """
    for j in range(256 * iterations):
        for i in range(strip.numPixels()):
            strip.setPixelColor(
                i, wheel((int(i * 256 / strip.numPixels()) + j) & 255))
        strip.show()
        time.sleep(wait_ms / 1000.0)
def theater_chase_rainbow(strip: PixelStrip, wait_ms: int = 50):
    """Rainbow movie theater light style chaser animation.

    :param strip:
    :param wait_ms:
    :return:
    """
    for j in range(256):
        for q in range(3):
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i + q, wheel((i + j) % 255))
            strip.show()
            time.sleep(wait_ms / 1000.0)
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i + q, 0)
Exemple #6
0
class PlasmaWS281X(Plasma):
    def __init__(self,
                 light_count,
                 gpio_pin=13,
                 strip_type='WS2812',
                 channel=1,
                 brightness=255,
                 freq_hz=800000,
                 dma=10,
                 invert=False):
        from rpi_ws281x import PixelStrip, ws

        strip_types = {}
        for t in ws.__dict__:
            if '_STRIP' in t:
                k = t.replace('_STRIP', '')
                v = getattr(ws, t)
                strip_types[k] = v

        strip_type = strip_types[strip_type]
        self._strip = PixelStrip(light_count, gpio_pin, freq_hz, dma, invert,
                                 brightness, channel, strip_type)
        self._strip.begin()

        Plasma.__init__(self, light_count)

    def show(self):
        """Output the buffer."""
        for i in range(self._strip.numPixels()):
            r, g, b, brightness = self._pixels[i]
            self._strip.setPixelColorRGB(i, r, g, b)

        self._strip.show()
Exemple #7
0
class PlasmaWS281X(Plasma):
    """Class for Plasma light devices in the WS281X/SK6812 family."""

    name = "WS281X"

    options = {
        'pixel_count': int,
        "gpio_pin": int,
        "strip_type": str,
        "channel": int,
        "brightness": int,
        "freq_hz": int,
        "dma": int,
        "invert": bool
    }

    option_order = ("gpio_pin", "strip_type", "channel", "brightness", "freq_hz", "dma", "invert")

    def __init__(self, pixel_count=1, gpio_pin=13, strip_type='WS2812', channel=None, brightness=255, freq_hz=800000, dma=10, invert=False):
        """Initialise WS281X device.

        :param pixel_count: Number of individual RGB LEDs
        :param gpio_pin: BCM GPIO pin for output signal
        :param strip_type: Strip type: one of WS2812 or SK6812
        :param channel: LED channel (0 or 1, or None for automatic)
        :param brightness: Global WS281X LED brightness scale
        :param freq_hz: WS281X output signal frequency (usually 800khz)
        :param dma: DMA channel
        :param invert: Invert signals for NPN-transistor based level shifters

        """
        from rpi_ws281x import PixelStrip, ws

        strip_types = {}
        for t in ws.__dict__:
            if '_STRIP' in t:
                k = t.replace('_STRIP', '')
                v = getattr(ws, t)
                strip_types[k] = v

        strip_type = strip_types[strip_type]

        if channel is None:
            if gpio_pin in [13]:
                channel = 1
            elif gpio_pin in [12, 18]:
                channel = 0

        self._strip = PixelStrip(pixel_count, gpio_pin, freq_hz, dma, invert, brightness, channel, strip_type)
        self._strip.begin()

        Plasma.__init__(self, pixel_count)

    def show(self):
        """Output the buffer."""
        for i in range(self._strip.numPixels()):
            r, g, b, brightness = self._pixels[i]
            self._strip.setPixelColorRGB(i, r, g, b)

        self._strip.show()
def turn_lights_off(strip: ws.PixelStrip, runtime: float = RUNTIME):
    print(f"Turning the lights off over {runtime}s")
    weather = get_weather()
    WEATHER_ANIMATIONS[weather](strip, runtime, reverse=True)
    for i in range(strip.numPixels()):
        strip.setPixelColor(i, ws.Color(0, 0, 0))
    strip.show()
def clear_strip(strip: PixelStrip):
    """Turn all lights off instantly.

    :return:
    """
    for i in range(strip.numPixels()):
        strip.setPixelColor(i, color(0, 0, 0))
    strip.show()
Exemple #10
0
def getPixels(strip: PixelStrip):
    num_pixels = strip.numPixels()
    all_pixels = []
    for i in range(num_pixels):
        c = strip.getPixelColorRGB(i)
        # all_pixels.append((c.r, c.g, c.b))
        all_pixels.append(c)

    return all_pixels
Exemple #11
0
class RpiWs281xLedstrip(AbstractLight):

    def __init__(self) -> None:
        super().__init__(led_count=LED_COUNT)
        
        self.pixel_strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
        self.pixel_strip.begin()

    def write(self):
        assert self.pixel_strip.numPixels() == len(self.leds)

        # Update the value for each of the pixels in the strip
        for i in range(startLED, self.pixel_strip.numPixels()):
            [red, green, blue, brightness] = self.leds[i]
            colors = (int(c * brightness * 255) for c in (red, green, blue))
            self.pixel_strip.setPixelColorRGB(i, *colors, 255)

        # Flush the new values to the strip
        self.pixel_strip.show()
def theater_chase(
    strip: ws.PixelStrip, color: ws.Color, wait_ms: float = 50.0, iterations: int = 10
):
    """
    Movie theater light style chaser animation.

    :param strip: the strip to animate
    :param color: the color to set each pixel to
    :param wait_ms: the time between animating each pixel, in milliseconds
    :param iterations: the number of times this animation will play
    """
    for j in range(iterations):
        for q in range(3):
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i + q, color)
            strip.show()
            time.sleep(wait_ms / 1000.0)
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i + q, 0)
def theater_chase(strip: PixelStrip,
                  color: color,
                  wait_ms: int = 50,
                  iterations: int = 10):
    """Movie theater light style chaser animation.

    :param strip:
    :param color:
    :param wait_ms:
    :param iterations:
    :return:
    """
    for j in range(iterations):
        for q in range(3):
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i + q, color)
            strip.show()
            time.sleep(wait_ms / 1000.0)
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i + q, 0)
def color_wipe(strip: PixelStrip, color: color, wait_ms: int = 50):
    """Wipe color across display a pixel at a time.

    :param strip: PixelStrip object to apply the effect to
    :param color: Color to wipe
    :param wait_ms: blocking time to wait (in ms) before returning
    :return:
    """
    for i in range(strip.numPixels()):
        strip.setPixelColor(i, color)
        strip.show()
        time.sleep(wait_ms / 1000.0)
def alternate_colors(strip: ws.PixelStrip, colors: Optional[Iterable[ws.Color]] = None):
    """
    Show a set of colours along the strip.

    :param strip: the strip to show the colors on
    :param colors: a list of colors to show
    """
    if colors is None:
        colors = [ws.Color(255, 0, 0), ws.Color(0, 255, 0), ws.Color(0, 0, 255)]
    for i in range(strip.numPixels()):
        strip.setPixelColor(i, colors[i % len(colors)])
    strip.show()
def color_wipe(strip: ws.PixelStrip, color: ws.Color, wait_ms: float = 50.0):
    """
    Wipe color across display a pixel at a time.

    :param strip: the strip to animate
    :param color: the color to set each pixel to
    :param wait_ms: the time between animating each pixel, in milliseconds
    """
    for i in range(strip.numPixels()):
        strip.setPixelColor(i, color)
        strip.show()
        time.sleep(wait_ms / 1000.0)
def rainbow(strip: PixelStrip, wait_ms: int = 20, iterations: int = 1):
    """Draw rainbow that fades across all pixels at once.

    :param strip:
    :param wait_ms:
    :param iterations:
    :return:
    """
    for j in range(256 * iterations):
        for i in range(strip.numPixels()):
            strip.setPixelColor(i, wheel((i + j) & 255))
        strip.show()
        time.sleep(wait_ms / 1000.0)
def rainbow(strip: ws.PixelStrip, wait_ms: float = 20.0, iterations: int = 1):
    """
    Draw rainbow that fades across all pixels at once.

    :param strip: the strip to animate
    :param wait_ms: the time between each fading step
    :param iterations: the number of times to play this animation
    """
    for j in range(256 * iterations):
        for i in range(strip.numPixels()):
            strip.setPixelColor(i, get_rainbow_color((i + j) & 255))
        strip.show()
        time.sleep(wait_ms / 1000.0)
Exemple #19
0
    def set_color(self, color):
        rgb = int(color, 16)
        r = int(rgb / 256 / 256)
        rgb = rgb - r * 256 * 256
        g = int(rgb / 256)
        b = rgb - g * 256
        # Create NeoPixel object with appropriate configuration.
        strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA,
                           LED_INVERT, LED_BRIGHTNESS)
        # Intialize the library (must be called once before other functions).
        strip.begin()

        for i in range(0, strip.numPixels(), 1):
            strip.setPixelColor(i, Color(g, r, b))
            strip.show()
Exemple #20
0
def run():
    prev_animation = None
    prev_brightness = None
    strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT,
                       LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP)
    strip.begin()

    threading.Thread(target=app.run).start()
    print('Press Ctrl-C to quit.')
    len_animations = None
    try:
        while True:
            if len(curr_animations) != len_animations:
                len_animations = len(curr_animations)
                clear(strip)

                generators = []
                for animation in curr_animations:
                    generators.append(animation(VStrip(strip)))

            if curr_brightness != prev_brightness:
                strip.setBrightness(curr_brightness)
                prev_brightness = curr_brightness

            vstrips = []
            for gen in generators:
                vstrips.append(next(gen))
                # vstrip.reverse()

            for pos in range(strip.numPixels()):
                col = np.array([0., 0., 0.])
                transparency = 1
                for v in vstrips:
                    cur_col = np.array(v.getPixelColor(pos))
                    col += cur_col[:3] * transparency
                    transparency *= cur_col[3]

                col = np.maximum(
                    np.minimum(np.array(np.floor(col), dtype=np.int), 255), 0)
                strip.setPixelColor(pos, Color(*col.tolist()))

            strip.show()

    except KeyboardInterrupt:
        clear(strip)
Exemple #21
0
class LedManager(object):
    # TODO: - Log and document this class

    # LED strip configuration:
    __LED_COUNT = 3         # Number of LED pixels.
    __LED_PIN = 18          # GPIO pin connected to the pixels (must support PWM!).
    __LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
    __LED_DMA = 10          # DMA channel to use for generating signal (try 10)
    __LED_BRIGHTNESS = 255  # Set to 0 for darkest and 255 for brightest
    __LED_INVERT = False    # True to invert the signal (when using NPN transistor level shift)
    __LED_CHANNEL = 0
    __LED_STRIP = ws.WS2812_STRIP

    __instance = None

    def __init__(self):
        if LedManager.__instance is None:
            LedManager.__instance = self
            self.strip = PixelStrip(self.__LED_COUNT, self.__LED_PIN, self.__LED_FREQ_HZ, self.__LED_DMA,
                                    self.__LED_INVERT, self.__LED_BRIGHTNESS, self.__LED_CHANNEL, self.__LED_STRIP)
            self.strip.begin()
        else:
            raise Exception("This class is a Singleton")

    @staticmethod
    def get_instance():
        """
        :rtype: LedManager
        """
        if LedManager.__instance is None:
            LedManager()
        return LedManager.__instance

    # Define function that colors all LEDs of the given color.
    def color_wipe(self, led_color, wait_ms=50):
        for i in range(0, self.strip.numPixels()):
            self.strip.setPixelColor(i, led_color.value)
            self.strip.show()
            time.sleep(wait_ms / 1000.0)
Exemple #22
0
class LedStrip(object):
    def __init__(self):
        self.status = 'off'
        self.strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
        self.strip.begin()
        self.set_color(BLACK)

    def toggle_light(self):
        if self.status == STATUS_ON:
            self.set_color(BLACK)
            self.status = STATUS_OFF
        else:
            self.set_color(SOFT_WHITE)
            self.status = STATUS_ON

    def set_color(self, color, wait_ms=200):
        for i in range(self.strip.numPixels()):
            self.strip.setPixelColor(i, color)
        self.strip.show()
        time.sleep(wait_ms / 1000)

    def get_status(self):
        return self.status
Exemple #23
0
class LEDStrip(object):
    """
    An object wrapper for the LED strip.
    """

    def __init__(self, n_led, led_pin):
        """
        Initialize the object.

        Args
        ----
        n_led: int
            Number of LEDs on the strip.
        led_pin: int
            GPIO bin the data line is connected to.
        """

        # Create the led strip object.
        if led_pin in [12, 18]:
            channel = 0
        elif led_pin in [13, 19]:
            channel = 1
        else:
            raise ValueError(('GPIO pin {} can not be used for the LED '
                'strip.').format(led_pin))
        self._strip = PixelStrip(n_led, led_pin, channel=channel)
        self._strip.begin()

    @property
    def n_led(self):
        """
        Return the number of LEDs on the strip.
        """
        return self._strip.numPixels()

    def flush(self, colors):
        """
        Display the colors contained in data on the strip.

        Args
        ----
        colors: Color, [Color]
            If a single color is given, the whole strip is colored with that
            color. If a list is given, colors in the list are set.
        """

        if isinstance(colors, int):
            for i_led in range(self.n_led):
                self._strip.setPixelColor(i_led, colors)
        else:
            for i_led, color in enumerate(colors):
                self._strip.setPixelColor(i_led, color)
        self._strip.show()

    def clear(self):
        """
        Deactivate all LEDs on the strip.
        """

        self.flush(Color(0, 0, 0))
        self._strip.show()
class RGBLight():
    "Simple wrapper for a RGB light device "

    def __init__(self, pin: int, nb_led: int = 5):
        self.pixels = PixelStrip(nb_led, pin)
        self.pixels.begin()
        self._state: bool = False
        self.delay: float = 0.01
        self._mode: int = MODE_RGB

        self.off()

    @property
    def state(self) -> bool:
        return self._state

    @state.setter
    def state(self, state: bool) -> None:
        self._state = state

    @property
    def mode(self) -> int:
        return self._mode

    @mode.setter
    def mode(self, mode) -> None:
        self._mode = mode

    def on(self) -> None:
        self.state = True
        for i in range(self.pixels.numPixels()):
            print(i)
            self.pixels.setPixelColorRGB(i, 50, 50, 50)
            self.pixels.show()
            sleep(0.01)

    def off(self) -> None:
        self.state = False
        for i in range(self.pixels.numPixels()):
            self.pixels.setPixelColorRGB(i, 0, 0, 0)
            self.pixels.show()
            sleep(self.delay)

    def toggle(self) -> None:
        if self.state is True:
            self.off()
        else:
            self.on()

    @property
    def color(self) -> Tuple[int, int, int]:
        if self.mode != MODE_RGB:
            raise Exception("Light is not in RGB mode")
        color_raw = self.pixels.getPixelColorRGB(0)
        color = (color_raw.r, color_raw.g, color_raw.b)
        return color

    @color.setter
    def color(self, color: Tuple[int, int, int]) -> None:
        self.state = True
        self.mode = MODE_RGB
        for i in range(self.pixels.numPixels()):
            self.pixels.setPixelColorRGB(i, *color)
            self.pixels.show()
            sleep(self.delay)

    @property
    def brightness(self) -> int:
        bri = self.pixels.getBrightness()
        return bri

    @brightness.setter
    def brightness(self, value: int) -> None:
        self.pixels.setBrightness(value)

    @property
    def temperature(self) -> int:
        if self.mode != MODE_TEMPERATURE:
            raise Exception("Light is not in temperature mode")
        color_raw = self.pixels.getPixelColorRGB(0)
        rgb = (color_raw.r, color_raw.g, color_raw.b)
        print(rgb)
        for temp in kelvin_table.keys():
            if kelvin_table[temp] == rgb:
                return temp

        return 0

    @temperature.setter
    def temperature(self, temp: int) -> None:
        self.mode = MODE_TEMPERATURE
        safe_temp = temp - (temp % 100)
        rgb: Tuple[int, int, int] = kelvin_table[safe_temp]
        for i in range(self.pixels.numPixels()):
            self.pixels.setPixelColorRGB(i, *rgb)
            self.pixels.show()
            sleep(self.delay)
class LEDController:
    def __init__(self, LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT,
                 LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP):
        self._strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA,
                                 LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL,
                                 LED_STRIP)
        self._strip.begin()
        self._step = 0.5
        self._start = 0

    def color_wipe(self, color, wait_ms=50):
        for i in range(self._strip.numPixels()):
            self._strip.setPixelColor(i, color)
            time.sleep(wait_ms / 1000.0)
        self._strip.show()
        #time.sleep(wait_ms / 1000.0)

    def idle_lighting(self):
        self.color_wipe(Color(50, 50, 50), 0)

    def listening_lighting(self):
        #proximity = ProximityController.get_proximity_data()
        self.color_wipe(Color(150, 150, 150), 0)

    def map_range(self, x, inLow, inHigh, outLow, outHigh):
        inRange = inHigh - inLow
        outRange = outHigh - outLow
        inScale = (x - inLow) / inRange
        return outLow + (inScale * outRange)

    def breathing_effect(self):
        while responding:
            duty = self.map_range(math.sin(self._start), -1, 1, 0, 150)
            self._start += self._step
            #self.color_wipe(Color(0,0,0,int(duty)),0)
            self.color_wipe(Color(int(duty), int(duty), int(duty)), 0)
            time.sleep(0.05)

    def alternate_lighting(self, color, wait_ms=50):
        for i in range(0, self._strip.numPixels(), 2):
            self._strip.setPixelColor(i, color)
            time.sleep(wait_ms / 1000.0)
        self._strip.show()
        time.sleep(1)

    def greeting_effetct(self):
        brightness = self.map_range(-distance, -4000, 0, 0, 150)
        self.color_wipe(
            Color(int(brightness), int(brightness), int(brightness), 0), 0)

    def wave_effect(self, color=Color(50, 50, 50), wait_ms=5):
        for i in range(0, self._strip.numPixels(), 5):
            self.switch_off()
            for j in range(0, 5):
                self._strip.setPixelColor(i + j, color)
                time.sleep(wait_ms / 1000.0)
            self._strip.show()

        for i in range(self._strip.numPixels(), -1, -5):
            self.switch_off()
            for j in range(0, min(5, i)):
                self._strip.setPixelColor(i - j, color)
                time.sleep(wait_ms / 1000.0)
            self._strip.show()

    def switch_off(self):
        self.color_wipe(Color(0, 0, 0), 0)
Exemple #26
0
class Light:
    """
  Class that represents a LED light strip connected to a Raspberry PI through a single I/O port.
  Data going through that I/O port and power supplied externally (because it's too much for the PI
  to power them if there are too many).
  """
    def __init__(self, name: str):
        """ Constructor, initializing members with default values. """
        print("  ..creating light object: " + name)
        self._name = name  # Human name of the LED strip;
        self._ledCount = 100  # Number of individually addressable LEDs on the strip;
        self._redRGB = 1  # RGB Red color value;
        self._greenRGB = 1  # RGB Green color value;
        self._blueRGB = 1  # RGB Blue color value;
        self._ledBrightness = 255  # Set to 0 for darkest and 255 for brightest;
        self._ledFrequency = 800000  # LED signal frequency in hertz (usually 800khz);
        self._ledDmaChannel = 10  # DMA channel to use for generating signal (try 10);
        self._ledInvert = False  # True to invert the signal (when using NPN transistor level shift);
        self._ledChannel = 0
        self._stripGpioPin = 18  # RaspberryPI GPIO pin that is used to drive the LED strip;
        self._stripType = ws.SK6812_STRIP_RGBW  # The type of the LED strip (just RGB or does it also include a White LED);
        self._strip = None  # Instance of the rpi_ws281x LED strip;
        self._lightState = False  # Is the light "off" (false) or "on" (true);
        self._switches = [
        ]  # Optional list of Switch objects that are linked to this light object;
        self._debug = False  # Debug level logging;

    def __del__(self):
        """ Destructor will turn off this light. """
        print("destroying light object: " + self._name)
        self.Off()

    @property
    def name(self):
        """ Return the name of this light. """
        return self._name

    @name.setter
    def name(self, value: str):
        """ Set the name for this light. """
        self._name = value

    @property
    def ledCount(self) -> int:
        """ Return the number of individual LEDs on the light strip. """
        return self._ledCount

    @ledCount.setter
    def ledCount(self, value: int):
        """ Set the number of LEDs to use on this light strip.  You can activate fewer than available. """
        if not (value > 0):
            raise Exception("You need to have at least 1 LED on the strip!")
        self._ledCount = value

    @property
    def redRGB(self) -> int:
        """ Return the current Red RGB color value for the light strip. """
        return self._redRGB

    @redRGB.setter
    def redRGB(self, value: int):
        """ Set the red RGB color value of LEDs to use on this light strip. """
        if not ((value >= 0) and (value <= 255)):
            raise Exception("The red RGB value needs to be between 0 and 255!")
        self._redRGB = value

    @property
    def greenRGB(self) -> int:
        """ Return the current Green RGB color value for the light strip. """
        return self._greenRGB

    @greenRGB.setter
    def greenRGB(self, value: int):
        """ Set the green RGB color value of LEDs to use on this light strip. """
        if not ((value >= 0) and (value <= 255)):
            raise Exception(
                "The green RGB value needs to be between 0 and 255!")
        self._greenRGB = value

    @property
    def blueRGB(self) -> int:
        """ Return the current Blue RGB color value for the light strip. """
        return self._blueRGB

    @blueRGB.setter
    def blueRGB(self, value: int):
        """ Set the blue RGB color value of LEDs to use on this light strip. """
        if not ((value >= 0) and (value <= 255)):
            raise Exception(
                "The blue RGB value needs to be between 0 and 255!")
        self._blueRGB = value

#  @property
#  def ledColor(self) -> str:
#    """ Return the RGB color value of the LEDs. """
#    return self._ledColor
#
#  @ledColor.setter
#  def ledColor(self, value: str):
#    """ Set the RGB color value of the LEDs. """
#    self._ledColor=value

    @property
    def ledBrightness(self) -> int:
        """ Return the brightness that the LED have been configured with (0 to 255). """
        return self._ledBrightness

    @ledBrightness.setter
    def ledBrightness(self, value: int):
        """ Set the brightness of the LEDs (0 to 255). """
        if not ((value > 0) and (value <= 255)):
            raise Exception("Brightness needs to be between 1 and 255!")
        self._ledBrightness = value

    @property
    def stripGpioPin(self) -> int:
        """ Return the Raspberry PI GPIO pin the LED strip is connected to (data). """
        return self._stripGpioPin

    @stripGpioPin.setter
    def stripGpioPin(self, value: int):
        """ Set the Raspberry PI GPIO pin the LED strip is connected to (data). """
        # The number of valid GPIO ports is limited and specific.
        # A good validator should check the port based on RPi model and throw an exception if the
        # selected port does not work to drive a LED strip like these.
        # I've decided to have a very rough validator here that enforces a port between 2 and 26.
        # I know this is not a great validator and I should probably make it more specific at some point.
        if not ((value >= 2) and (value <= 26)):
            raise Exception("The RPi GPIO port needs to be between 2 and 26!")
        self._stripGpioPin = value

    @property
    def state(self) -> bool:
        """ Show if the light is currently on or off.  "True" means "On" and "False" means "Off". """
        return self._lightState

    @property
    def debug(self) -> bool:
        """ Return the debug-flag that is set for this light. """
        return self._debug

    @debug.setter
    def debug(self, flag: bool):
        """ Set the debug level. """
        self._debug = flag

    @property
    def switches(self) -> list:
        """ Return a list of 0 or more Switch objects that have been mapped to this light. """
        return self._switches

    def addSwitch(self, switch):
        """ Add a new Switch object that can control this light. """
        self._switches.append(switch)

    def delSwitch(self, switch):
        """ Remove a switch from this light. """
        self._switches.remove(switch)
        del switch

    def Start(self):
        """ Initialize the LED strip at the hardware level so that we can start control the individual LEDs. """
        self._strip=PixelStrip(self._ledCount, \
                    self._stripGpioPin, \
                    self._ledFrequency, \
                    self._ledDmaChannel, \
                    self._ledInvert, \
                    self._ledBrightness, \
                    self._ledChannel, \
                    self._stripType)
        # Initialize the library (must be called once before other functions):
        self._strip.begin()

    def On(self):
        """ Turn the leds on. """
        # Set the led color, full brightness:
        color = Color(self._greenRGB, self._redRGB, self._blueRGB,
                      self._ledBrightness)
        for i in range(self._strip.numPixels()):
            self._strip.setPixelColor(i, color)
        self._strip.show()
        self._lightState = True

    def Off(self):
        """ Turn the leds off. """
        color = Color(0, 0, 0, 0)
        for i in range(self._strip.numPixels()):
            self._strip.setPixelColor(i, color)
        self._strip.show()
        self._lightState = False

    def Toggle(self):
        """ Toggle the light on or off. """
        if self._lightState:
            self.Off()
        else:
            self.On()

    def Update(self):
        """ Apply the Updated LED settings if they are on. """
        if self._lightState:
            self.Off()
            self.On()
class LEDController:

    """ Takes care of lighting effects for Voxx

    @params: LED_COUNT: Number of LEDs to light up
             LED_PIN  : Which pin LED is connected to
             LED_FREQ_HZ: Signal frequency in Hz
             LED_DMA: DMA channel for generating the signal - defaults to 10
             LED_INVERT: Option to invert signal. Default False
             LED_BRIGHTNESS: Max brightness of LEDs - set to 10. Max 255
             LED_CHANNEL: Defaults to 0
             LED_STRIP: LED strip type. 'ws.WS2811_STRIP_RGB' to be used for Voxx
    """
    def __init__(self,LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA,LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL,LED_STRIP):
        self._strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA,LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL,LED_STRIP)
        self._strip.begin()
        self._step = 0.5
        self._start = 0

    """Sets all pixels to 'color - Color(R,G,B)' color given by RGB values from 0-255"""
    def color_wipe(self,color,wait_ms=50):
        for i in range(0,self._strip.numPixels()):
            self._strip.setPixelColor(i, color)
            time.sleep(wait_ms / 1000.0)
        self._strip.show()
            #time.sleep(wait_ms / 1000.0)

    """ Minimum brightness idle state lighting"""
    def idle_lighting(self):
        self.color_wipe(Color(50,50,50),0)

    """ Maximum brightness listening state lighting"""
    def listening_lighting(self):
        #proximity = ProximityController.get_proximity_data()
        self.color_wipe(Color(255,255,255),0)

    """ Maps 'x' in input range to output range """
    def map_range(self,x, inLow, inHigh, outLow, outHigh):
        inRange = inHigh - inLow
        outRange = outHigh - outLow
        inScale = float(x - inLow)/float(inRange)
        return outLow + (inScale * outRange)
    """
    # Alternate breathing effect if signalling does not work
    def breathing_effect(self):
        self._start = 0
        has_responded = 0
        while True:
            if tts.responding:
                duty = self.map_range(math.sin(self._start),-1,1,0,255)
                self._start += self._step
                #self.color_wipe(Color(0,0,0,int(duty)),0)
                self.color_wipe(Color(int(duty),int(duty),int(duty)),0)
                time.sleep(0.05)
                has_responded = 1

            elif has_responded:
                break
            time.sleep(0.1)
    """

    """ Breathing effect for response state lighting"""
    def breathing_effect(self):
        self._start = 0
        tts.response_available.wait()
        print("response lighting")
        while tts.responding:
        #while True:
            duty = self.map_range(math.sin(self._start),-1,1,0,200)
            self._start += self._step
            #self.color_wipe(Color(0,0,0,int(duty)),0)
            self.color_wipe(Color(int(duty),int(duty),int(duty)),0)
            time.sleep(0.2)

    """ Lights up alternate LEDs """
    def alternate_lighting(self,color,wait_ms=50):
        for i in range(0,self._strip.numPixels(),2):
            self._strip.setPixelColor(i, color)
            time.sleep(wait_ms / 1000.0)
        self._strip.show()
        time.sleep(1)

    """ Maps user distance to light intensity """
    def greeting_effect(self,distance):
        if(distance > 2500):
            brightness = 50
        else:
            brightness = self.map_range(-distance,-2500,0,50,200)
        print(str(brightness))
        #time.sleep(0.1)
        self.color_wipe(Color(int(brightness),int(brightness),int(brightness)),0)

    """ Indicates unavailability of internet """
    def blink(self):
        while(True):
            self.color_wipe(Color(50,50,50),0)
            time.sleep(1)
            self.color_wipe(Color(0,0,0),0)
            time.sleep(1)

    """ Wave effect to convey that Voxx is 'thinking' """
    def wave_effect(self,color=Color(255,255,255),wait_ms=5):
        while tts.thinking:
            for i in range(0,self._strip.numPixels(),5):
                if(tts.thinking == 0):
                    break
                self.switch_off()
                for j in range(0,10):
                    self._strip.setPixelColor(i+j, color)
                    time.sleep(wait_ms / 1000.0)
                self._strip.show()

            for i in range(self._strip.numPixels(),-1,-5):
                if(tts.thinking == 0):
                    break
                self.switch_off()
                for j in range(0,min(10,i)):
                    self._strip.setPixelColor(i-j, color)
                    time.sleep(wait_ms / 1000.0)
                self._strip.show()
            time.sleep(0.1)

    def switch_off(self):
        self.color_wipe(Color(0,0,0),0)
Exemple #28
0
class RGBMatrix:

    def __init__(self):
        # LED strip configuration:
        LED_COUNT = 64        # Number of LED pixels.
        LED_PIN = 12          # GPIO pin connected to the pixels (18 uses $
        LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800$
        LED_DMA = 10          # DMA channel to use for generating signal ($
        LED_BRIGHTNESS = 10   # Set to 0 for darkest and 255 for brightest
        LED_INVERT = False    # True to invert the signal (when using NPN $
        LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53

        # TODO: root
        self.strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
        # Intialize the library (must be called once before other functions).
        self.strip.begin()

        #  0  1  2  3  4  5  6  7
        #  8  9 10 11 12 13 14 15
        # 16 17 18 19 20 21 22 23
        # 24 25 26 27 28 29 30 31
        # 32 33 34 35 36 37 38 39
        # 40 41 42 43 44 45 46 47
        # 48 49 50 51 52 53 54 55
        # 56 57 58 59 60 61 62 63
        self.numbers = [
            [0, 1, 2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 55, 63, 62, 61, 60, 59, 58, 57, 56, 48, 40, 32, 24, 16, 8], # 0
            [3, 11, 19, 27, 35, 43, 51, 59], # 1
            [9, 2, 3, 4, 13, 21, 28, 28, 34, 41, 49, 57, 58, 59, 60, 61],     # 2
            [2, 3, 4, 13, 21, 28, 27, 26, 25, 37, 45, 53, 60, 59, 58, 57],    # 3
            [1, 9, 17, 25, 33, 41, 42, 43, 44, 45, 46, 47, 28, 36, 52, 60],   # 4
            [1, 9, 17, 25, 26, 27, 28, 29, 38, 46, 54, 61, 60, 59, 58, 57, 2, 3, 4, 5], # 5
            [6, 5, 4, 3, 2, 1, 9, 17, 25, 33, 41, 49, 57, 58, 59, 60, 61, 62, 54, 46, 38, 37, 36, 35, 34], # 6
            [1, 2, 3, 4, 5, 6, 7, 15, 22, 29, 36, 44, 52, 60],                # 7
            [4, 3, 2, 9, 18, 27, 36, 45, 53, 60, 59, 58, 49, 41, 34, 20, 13], # 8
            [7, 6, 5, 4, 3, 2, 1, 9, 17, 25, 33, 34, 35, 36, 37, 38, 39, 31, 23, 15, 47, 55, 63, 62, 61, 60, 59, 58, 57], # 9
            [16, 17, 18, 19, 20, 21, 22, 23, 40, 41, 42, 43, 44, 45, 46, 47, 2, 10, 26, 34, 50, 58, 5, 13, 29, 37, 53, 61], # 10 #
            [17, 18, 19, 20, 21, 22, 49, 50, 51, 52, 53, 54], # 11 =
            [28], # 12 -
            [26, 27, 28, 19, 35], # 13 +
            [7, 56, 14, 49, 21, 42, 28, 35], # 14 /
            [63, 54, 45, 36, 27, 35, 42, 49, 56, 0, 9, 18, 28, 21, 14, 7], # 15 X
        ]
        # or # color code
        #[0,  0,  0,  0,  0,  0,  0, 0,
        # 0,200,  0,  0, 70,  0,  0, 0,
        # 0,  0,  0,  0, 60,  0,  0, 0,
        # 0,  0,  0,  0, 50,  0,  0, 0,
        # 0, 10, 20, 30, 40, 30, 20, 0,
        # 0,  0,  0, 80,  0,  0,  0, 0,
        # 0,  0,  0, 90,  0,  0,  0, 0,
        # 0,  0,  0,100,  0,  0,  0, 0]

    def colorWipe(self, color, wait_ms=50):
        """Wipe color across display a pixel at a time."""
        for i in range(self.strip.numPixels()):
            self.strip.setPixelColor(i, color)
            self.strip.show()
            time.sleep(wait_ms / 1000.0)

    def clear(self, r=0, g=0, b=0):
        self.colorWipe(Color(r, g, b), 5)

    def fill(self, col):
        self.colorWipe(col, 10)

    def rand(self):
        l = list(range(self.strip.numPixels()))
        random.shuffle(l)
        for i in l:
            self.strip.setPixelColor(i, Color(random.randint(10, 250), random.randint(10, 250), random.randint(10, 250)))
            self.strip.show()
            time.sleep(0.01)

    def dot(self, num, col):
        self.strip.setPixelColor(int(num), col)
        self.strip.show()

    def show_template(self, num, col):
        self.clear()
        for cell in self.numbers[int(num)]:
            self.strip.setPixelColor(cell, col)
        self.strip.show()
Exemple #29
0
class neoled:

    # LED strip configuration:
    LED_COUNT = 16  # Number of LED pixels.
    LED_PIN = 10  # GPIO pin connected to the pixels (must support PWM!).
    LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
    LED_DMA = 10  # DMA channel to use for generating signal (try 10)
    LED_BRIGHTNESS = 255  # Set to 0 for darkest and 255 for brightest
    LED_INVERT = False  # True to invert the signal (when using NPN transistor level shift)
    LED_CHANNEL = 0
    LED_STRIP = ws.SK6812_STRIP_GRBW

    def __init__(self):
        # Create NeoPixel object with appropriate configuration.
        self.strip = PixelStrip(self.LED_COUNT, self.LED_PIN, self.LED_FREQ_HZ,
                                self.LED_DMA, self.LED_INVERT,
                                self.LED_BRIGHTNESS, self.LED_CHANNEL,
                                self.LED_STRIP)
        # Intialize the library (must be called once before other functions).
        self.strip.begin()
        self.colorFill(Color(0, 0, 0, 0))

    # Define functions which animate LEDs in various ways.
    def colorFill(self, color):
        """Fill strip with color at once."""
        for i in range(self.strip.numPixels()):
            self.strip.setPixelColor(i, color)
        self.strip.show()

    def colorWipe(self, color, wait_ms=10):
        """Wipe color across display a pixel at a time."""
        for i in range(self.strip.numPixels()):
            self.strip.setPixelColor(i, color)
            self.strip.show()
            time.sleep(wait_ms / 1000.0)

    def colorBlink(self, color, blink_ms=20, nblinks=1):
        for i in range(nblinks):
            self.colorFill(color)
            time.sleep(blink_ms / 1000.0)
            self.colorFill(Color(0, 0, 0, 0))
            if i < (nblinks - 1):
                time.sleep(blink_ms / 1000.0)

    def colorBlinkPos(self, color, blink_ms=30, nblinks=1, pos=0):
        for i in range(nblinks):
            for i in range(self.strip.numPixels()):
                if ((i + pos) % 7 == 0):
                    self.strip.setPixelColor(i, color)
                else:
                    self.strip.setPixelColor(i, Color(0, 0, 0, 0))
            self.strip.show()
            time.sleep(blink_ms / 1000.0)
            self.colorFill(Color(0, 0, 0, 0))
            if i < (nblinks - 1):
                time.sleep(blink_ms / 1000.0)

    def multColor(self, color, multiplier):
        white = (color >> 24) & 0xFF
        red = (color >> 16) & 0xFF
        green = (color >> 8) & 0xFF
        blue = color & 0xFF
        return Color(int(red * multiplier), int(green * multiplier),
                     int(blue * multiplier), int(white * multiplier))

    def dualbulb(self, color, pos):
        dualbulb_pattern = {
            0: 0.1,
            1: 0.2,
            2: 0.5,
            3: 1,
            4: 0.5,
            5: 0.2,
            6: 0.5,
            7: 1,
            8: 0.5,
            9: 0.2,
            10: 0.1,
            11: 0.2,
            12: 0.5,
            13: 1,
            14: 0.5,
            15: 0.2,
        }
        return self.multColor(color, dualbulb_pattern[pos % 16])

    def nightlight(self, color):
        wait_ms = 25
        # Ramp UP 0-0.5
        s = 0
        for j in range(10):
            s += 0.05
            for i in range(self.strip.numPixels()):
                self.strip.setPixelColor(
                    i, self.multColor(self.dualbulb(color, i), s))
            self.strip.show()
            time.sleep(wait_ms / 1000.0)
        for c in range(5):
            # Ramp UP 0.5-1
            s = 0.5
            for j in range(10):
                s += 0.05
                for i in range(self.strip.numPixels()):
                    self.strip.setPixelColor(
                        i, self.multColor(self.dualbulb(color, i + c), s))
                self.strip.show()
                time.sleep(wait_ms / 1000.0)
            # Ramp DOWN 1-05
            for j in range(10):
                s -= 0.05
                for i in range(self.strip.numPixels()):
                    self.strip.setPixelColor(
                        i, self.multColor(self.dualbulb(color, i + c), s))
                self.strip.show()
                time.sleep(wait_ms / 1000.0)
        # Ramp DOWN 0.5-0
        for j in range(10):
            s -= 0.05
            for i in range(self.strip.numPixels()):
                self.strip.setPixelColor(
                    i, self.multColor(self.dualbulb(color, i), s))
            self.strip.show()
            time.sleep(wait_ms / 1000.0)
        self.colorFill(Color(0, 0, 0))

    def wheel(self, pos):
        """Generate rainbow colors across 0-255 positions."""
        if pos < 85:
            return Color(pos * 3, 255 - pos * 3, 0)
        elif pos < 170:
            pos -= 85
            return Color(255 - pos * 3, 0, pos * 3)
        else:
            pos -= 170
            return Color(0, pos * 3, 255 - pos * 3)

    def rainbow(self, wait_ms=20, iterations=1):
        """Draw rainbow that fades across all pixels at once."""
        for j in range(256 * iterations):
            for i in range(self.strip.numPixels()):
                self.strip.setPixelColor(i, wheel((i + j) & 255))
            self.strip.show()
            time.sleep(wait_ms / 1000.0)

    def rainbowCycle(self, wait_ms=20, iterations=5):
        """Draw rainbow that uniformly distributes itself across all pixels."""
        for j in range(256 * iterations):
            for i in range(self.strip.numPixels()):
                self.strip.setPixelColor(
                    i, wheel(((i * 256 // self.strip.numPixels()) + j) & 255))
            self.strip.show()
            time.sleep(wait_ms / 1000.0)
Exemple #30
0
class Led(Thread):

    # LED strip configuration:
    LED_COUNT = 95  # Number of LED pixels.
    LED_PIN = 18  # GPIO pin connected to the pixels (18 uses PWM!).
    # LED_PIN = 10        # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
    LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
    LED_DMA = 10  # DMA channel to use for generating signal (try 10)
    LED_BRIGHTNESS = 170  # Set to 0 for darkest and 255 for brightest
    LED_INVERT = False  # True to invert the signal (when using NPN transistor level shift)
    LED_CHANNEL = 0  # set to '1' for GPIOs 13, 19, 41, 45 or 53
    FRAMERATE = 50

    def __init__(self):
        # Create NeoPixel object with appropriate configuration.
        self.strip = PixelStrip(self.LED_COUNT, \
                                self.LED_PIN, \
                                self.LED_FREQ_HZ, \
                                self.LED_DMA, \
                                self.LED_INVERT, \
                                self.LED_BRIGHTNESS//2, \
                                self.LED_CHANNEL)
        # Intialize the library (must be called once before other functions).
        self.strip.begin()

        # Variables that store what the LEDs will do

        self.loop = False  # whether the current sequence of frames should be
        # repeated after completion

        self.colorSeqs = {}  # a dictionary storing color sequences
        # KEY: the key is arbitrary, to distinguish different color sequences
        #      - It is up to the implementation to determine the key
        # VAL: a list of colors, stored as integers, that form the sequence
        #      - All values in colorSeqs must have the same length

        self.seqLen = 0  # the length of color sequences in colorSeqs

        self.mapping = []  # a list containing integers
        # these integers correspond to indices in colorSeqs
        # length of mapping = number of LEDs in the LightBox

        self.currInd = 0  # an integer marking where in the color sequences the LEDs are

        self.targetBrightness = self.strip.getBrightness(
        )  # value storing brightness to be attained
        # during gradual fade towards it

        # Initialize these variables for the first time (LEDs off)
        self.loop = False
        self.colorSeqs[0] = [0x000000]
        self.seqLen = 1
        self.mapping = [0] * self.strip.numPixels()
        self.currInd = 0
        # These settings will cause the LED's to switch to #000000 (off) once

        # Start thread that will handle LED changes in the background
        Thread.__init__(self)
        self.daemon = True

        print("Led Strip Initialized")

    # Continuous loop that handles LED changes registered in mapping and colorSeqs
    def run(self):
        while True:
            refreshStrip = True
            time.sleep(1.0 / self.FRAMERATE)

            if self.currInd == self.seqLen:  #reached end of sequence
                if self.loop:
                    self.currInd = 0  #loop to beginning of sequence
                else:
                    refreshStrip = False

            if refreshStrip:
                try:
                    for i in range(self.strip.numPixels()):
                        self.strip.setPixelColor(
                            i, self.colorSeqs[self.mapping[i]][self.currInd])
                except KeyError:
                    print("Error: invalid key %d" % self.mapping[i])
                    continue
                self.currInd += 1

            if self.strip.getBrightness() != self.targetBrightness:
                self.strip.setBrightness( max( min(
                        self.strip.getBrightness() + (self.FRAMERATE//25) * \
                        (1 if self.targetBrightness > self.strip.getBrightness() else -1) \
                    , 255), 0) \
                )
                if (abs(self.targetBrightness -
                        self.strip.getBrightness())) < (self.FRAMERATE // 25):
                    self.strip.setBrightness(self.targetBrightness)
                refreshStrip = True

            if refreshStrip:
                self.strip.show()

    # Color Manipulation functions...

    def solidColor(self, color):
        ''' Changes LightBox to a solid color, defined by color '''

        colorSeqs = {}
        mapping = [0] * self.strip.numPixels()

        # Iterate through each led in the strip
        for currLed in range(self.strip.numPixels()):
            # Add entry to mapping for the color sequence
            mapping[currLed] = self.strip.getPixelColor(currLed)

            # Add sequence to colorSeqs if it doesn't exist already
            if mapping[currLed] not in colorSeqs:
                colorSeqs[mapping[currLed]] = \
                    colorUtil.linear_gradient(mapping[currLed], \
                                              color, \
                                              self.FRAMERATE//4)

        self.loop = False
        self.seqLen = self.FRAMERATE // 4
        self.currInd = 0
        self.mapping = mapping
        self.colorSeqs = colorSeqs

    def clear(self):
        '''clears all leds'''
        self.solidColor(0)

    def changeBrightness(self, newBrightnessValue):
        '''sets brightness of LEDs (0-100)'''
        self.targetBrightness = int(self.LED_BRIGHTNESS *
                                    newBrightnessValue**1.5 /
                                    1000)  #1000=100^1.5

    def rainbow(self):
        '''creates a rainbow sequence that loops'''

        #generates list of colors that cycle in hue
        numFrames = self.FRAMERATE * 10  # the number is how many seconds per rainbow cycle
        rainbowColors = [
            colorUtil.HSV_to_hex(k / numFrames * 360, 1, 1)
            for k in range(0, numFrames, 1)
        ]

        colorSeqs = {}
        seqLen = len(rainbowColors)
        mapping = [0] * self.strip.numPixels()

        for led in range(self.strip.numPixels()):
            mapping[led] = led  #unique mapping for each led
            colorSeqs[led] = [0] * seqLen

        for colorPos in range(seqLen):
            for led in range(self.strip.numPixels()):
                colorSeqs[led][colorPos] = rainbowColors[(colorPos + led) %
                                                         seqLen]

        self.loop = True
        self.seqLen = seqLen
        self.currInd = 0
        self.colorSeqs = colorSeqs
        self.mapping = mapping

    def sparkle(self, seqLenSeconds=30):
        '''creates a sparkle sequence that loops'''

        numFrames = self.FRAMERATE * 1  # the number is how many seconds for average flash
        deviation = self.FRAMERATE // 2  # random deviation of the flash lengths
        satChoice = ([0.0]) + ([0.5] * 5) + (
            [1] * 50)  # weighted probability for saturation
        # prevents too many 'white' LEDs
        valChoice = ([0.2]) + ([0.5] * 5) + (
            [1] * 10)  # weighted probability for value
        # prevents too many dim LED's

        colorSeqs = {}
        seqLen = numFrames * seqLenSeconds
        mapping = [0] * self.strip.numPixels()

        for led in range(self.strip.numPixels()):
            mapping[led] = led  # unique mapping for each led
            colorSeqs[led] = [0] * seqLen

        for colorPos in range(seqLen):

            for i in range(random.randrange(
                    0, 4)):  # repeat a random number of times
                # to create variety

                led = random.randrange(0, self.strip.numPixels())
                if colorSeqs[led][colorPos] != 0:  # already a flash at that led
                    continue  # don't overwrite it
                duration = random.randint(numFrames - deviation,
                                          numFrames + deviation)
                hue = random.uniform(0, 360)
                sat = random.choice(satChoice)
                val = random.choice(valChoice)

                for k in range(duration):
                    # fill in colorSeqs for the flash, given by the piecewise function
                    # at https://www.desmos.com/calculator/lmsoc2uoif
                    colorSeqs[led][(colorPos+k)%seqLen] = colorUtil.HSV_to_hex(hue, sat, \
                        val * ( (3/duration)*k if k < duration/3 \
                        else (-3/(2*duration))*(k-duration) ) \
                    )

        self.loop = True
        self.seqLen = seqLen
        self.currInd = 0
        self.colorSeqs = colorSeqs
        self.mapping = mapping