Пример #1
0
class LEDController(Component):
    def __init__(self, config: dict):
        super().__init__("leds")
        self.controller = None
        self.leds = {}
        led_config = config['leds']
        if led_config['type'] == "pixelstrip":
            self._process_pixelstrip(led_config)

    def _process_pixelstrip(self, config):
        self.controller = PixelStrip(config['count'], config['pin'], config['frequency'], config['dma'],
                                     config['invert'], config['brightness'], config['channel'])
        self.controller.begin()
        for index, name in config['names'].items():
            self.leds[name] = PixelStripLED(self.controller, index)

    def process_control(self, message):
        updated = False
        for name, led in self.leds.items():
            if name in message:
                state = message[name]
                led.set_color(state.get('red', 0), state.get('green', 0), state.get('blue', 0))
                updated = True

        if "brightness" in message:
            self.controller.setBrightness(message["brightness"])
            updated = True

        if updated:
            self.controller.show()
            self.update_state()

    @property
    def state(self):
        return { "brightness": self.controller.getBrightness(),
                 "leds": {name: led.state for name, led in self.leds.items()}}
Пример #2
0
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)
Пример #3
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
Пример #4
0
class Moodlights():
    def __init__(self, led_count, led_pin, led_freq_hz, led_dma, led_invert,
                 led_brightness, led_channel):
        self.strip = PixelStrip(led_count, led_pin, led_freq_hz, led_dma,
                                led_invert, led_brightness, led_channel)
        self.strip.begin()

        self.led_count = led_count
        self.pixels = [Pixel(self.strip, x) for x in range(led_count)]

        signal.signal(signal.SIGINT, self.signal_handler)

    def in_range(self, led_num):
        return led_num >= 0 and led_num < self.led_count

    def shutdown(self):
        self.all_pixels_off()
        sys.exit()

    def signal_handler(self, sig, frame):
        print("You pressed Ctrl-C! Exiting...")
        self.shutdown()

    def all_pixels_off(self):
        for pixel in self.pixels:
            pixel.switch_off()
        self.strip.show()

    def color_wipe(self, colors, iterations=0, wait_ms=0):
        """
        params:

        colors: sequence of colors to display
        wait_ms: wait time between each pixel (0 for instant)
        """
        is_infinite = iterations == 0

        i = 0
        while is_infinite or i < iterations:
            self.all_pixels_off()
            for j in range(self.led_count):
                pixel = self.pixels[j]
                pixel.set_color(colors[j % len(colors)])
                self.strip.show()
                time.sleep(wait_ms / 1000.0)
            i += 1

    def pulse(self, iterations=0, wait_ms=2):
        """
        params:

        iteration: number of pulses (0 means infinite)
        wait_ms: wait time before changing brightness by 1/255 of max brightness
        """
        is_increasing = self.strip.getBrightness() < 255
        is_infinite = iterations == 0

        i = 0
        while is_infinite or i < iterations * 256 * 2:
            if is_increasing:
                next_brightness = self.strip.getBrightness() + 1
                is_increasing = next_brightness != 255
            else:
                next_brightness = self.strip.getBrightness() - 1
                is_increasing = next_brightness == 0

            self.strip.setBrightness(next_brightness)
            time.sleep(wait_ms / 1000.0)
            self.strip.show()
            i += 1

    def wave(self,
             colors,
             iterations,
             intensity,
             wait_ms=50,
             spread=0,
             is_reverse=False):
        """
        params:

        colors: sequence of colors to display
        intensity: brightness of the crest (from 0 to 255)
        wait_ms: wait time before the crest of the wave shifts
        spread: how many pixels away from the crest will be lighted up
        """
        intensity_interval = float(intensity / (spread + 1))
        led_iteration = list(
            range(-1 - spread,
                  self.strip.numPixels() + spread + 1))
        if is_reverse:
            led_iteration.reverse()

        is_infinite = iterations == 0
        k = 0
        while is_infinite or k < iterations:
            for i in led_iteration:
                if self.in_range(i):
                    self.pixels[i].set_color(colors[i % len(colors)])
                    self.pixels[i].set_brightness(intensity)

                for j in range(1, spread + 1):
                    brightness = int(abs(intensity - intensity_interval * j))

                    if self.in_range(i - j):
                        self.pixels[i - j].set_color(colors[(i - j) %
                                                            len(colors)])
                        self.pixels[i - j].set_brightness(brightness)
                    if self.in_range(i + j):
                        self.pixels[i + j].set_color(colors[(i + j) %
                                                            len(colors)])
                        self.pixels[i + j].set_brightness(brightness)

                if self.in_range(i - spread - 1):
                    self.pixels[i - spread - 1].switch_off()
                if self.in_range(i + spread + 1):
                    self.pixels[i + spread + 1].switch_off()
                self.strip.show()

                time.sleep(wait_ms / 1000.0)
            k += 1

    def wheel(self, pos):
        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_cycle(self, iterations=0, wait_ms=160):
        is_infinite = iterations == 0

        j = 0
        while is_infinite or j < iterations * 256:
            for i in range(self.strip.numPixels()):
                self.strip.setPixelColor(i, self.wheel((i + j) & 255))
            self.strip.show()
            j += 1
            time.sleep(wait_ms / 1000.0)

    def rainbow_chase(self, iterations=0, wait_ms=100):
        is_infinite = iterations == 0

        j = 0
        while is_infinite or j < iterations * 256:
            for q in range(3):
                for i in range(0, self.strip.numPixels(), 3):
                    self.strip.setPixelColor(i + q, self.wheel((i + j) % 255))
                self.strip.show()
                time.sleep(wait_ms / 1000.0)
                for i in range(0, self.strip.numPixels(), 3):
                    self.strip.setPixelColor(i + q, 0)
            j += 1