def set_strip_colours(self, tweet_list, twinkle_ratio = 0.25, tweeter_filter = None): for pixel in range (0, len(tweet_list)): #print(colour_list[pixel]) #print(pixel, tweet_list[pixel].name) twinkle_on_off = random.random() #print(twinkle_on_off) # If no filter, the show all pixels. if tweeter_filter is None: if float(twinkle_on_off) < float(twinkle_ratio): self.strip.setPixelColor(pixel, rpi_ws281x.Color(0, 0, 0)) else: self.strip.setPixelColor(pixel, rpi_ws281x.Color(*tweet_list[pixel].colour)) # Check against the filter elif tweet_list[pixel].id is tweeter_filter.id: self.strip.setPixelColor(pixel, rpi_ws281x.Color(*tweet_list[pixel].colour)) # Otherwise set to off. else: self.strip.setPixelColor(pixel, rpi_ws281x.Color(0,0,0)) #self.strip.setPixelColor(pixel, rpi_ws281x.Color(*tweet_list[pixel].colour)) # The below commented out bit sets the rest to dark. for pixel in range(len(tweet_list), self.strip.numPixels()): self.strip.setPixelColor(pixel, rpi_ws281x.Color(0, 0, 0)) self.strip.show()
def sunrise_animation(strip, total_time=3600, reverse=False): steps = 256 dither_time = total_time / 2 brightening_time = total_time - dither_time for step in range(steps): frac = step / steps if reverse: frac = 1.0 - frac SKYBLUE = ws.Color( max(int(135 * frac), 1), max(int(206 * frac), 1), max(int(235 * frac), 1) ) SUNRISE = ws.Color( max(int(255 * frac), 1), max(int(191 * frac), 1), max(int(39 * frac), 1) ) sunrise_width = int(strip.numPixels() * 0.1) sunrise_start = int(frac * strip.numPixels()) sunrise_end = sunrise_start + sunrise_width sky_pixels = [i for i in range(strip.numPixels())] for pixel in range(sunrise_start, sunrise_end): if pixel in sky_pixels: sky_pixels.remove(pixel) strip.setPixelColor(pixel, SUNRISE) t_1 = time.time() dither_fade(strip, SKYBLUE, sky_pixels, (brightening_time - 1) / steps) t_2 = time.time() time_diff = t_2 - t_1 if time_diff < brightening_time / steps: time.sleep((brightening_time / steps) - time_diff) if reverse: for pixel in range(strip.numPixels()): strip.setPixelColor(pixel, 0)
def blend_image_to_strip(self, strip, im, ids, runtime=60, reverse=False): """ Slowly display the image on the strip with increasing brightness. Parameters --------- strip The LED strip to show im The image to show ids The indices of the pixels to change runtime how long the display should take reverse Should this go dark->light or light->dark """ colors = self.image_to_colors(im) NUM_STEPS = 256 TIME_PER_STEP = runtime / NUM_STEPS if reverse: # Remember that range doesn't include the end point. steps = range(NUM_STEPS - 1, -1, -1) else: steps = range(NUM_STEPS) for step in steps: color_arr = [ws.Color(0, 0, 0) for _ in range(strip.numPixels())] interp_colors = colors * (step / NUM_STEPS)**2.3 for i in range(colors.shape[0] - 1, 0, -1): color_arr[int(ids[i])] = ws.Color( *[int(round(item)) for item in interp_colors[i, :]]) dither_fade(strip, color_arr, dither_time=TIME_PER_STEP)
def main(strip): print(f"Good morning! Waking up at {time.time()}") owm = OWM(WEATHER_API_KEY) mgr = owm.weather_manager() observation = mgr.weather_at_place( "Oxford,GB" ) # the observation object is a box containing a weather object weather = observation.weather.status print(f"The current weather is {weather}") start_time = time.time() strip.begin() dither_fade(strip, ws.Color(0, 1, 1), leds_to_switch=None, dither_time=RUNTIME * 0.5) WEATHER_ANIMATIONS[weather](strip, RUNTIME) time.sleep(10 * 60) WEATHER_ANIMATIONS[weather](strip, RUNTIME, reverse=True) dither_fade(strip, ws.Color(0, 0, 0), leds_to_switch=None, dither_time=RUNTIME * 0.5) end_time = time.time() print( f"I hope you're awake! Closing down at {time.time()}. We spent {(end_time - start_time) // 60} minutes." )
def wheel(pos): """Generate rainbow colors across 0-255 positions.""" if pos < 85: return r.Color(pos * 3, 255 - pos * 3, 0) elif pos < 170: pos -= 85 return r.Color(255 - pos * 3, 0, pos * 3) else: pos -= 170 return r.Color(0, pos * 3, 255 - pos * 3)
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 get_rainbow_color(pos: int) -> ws.Color: """ Generate rainbow colors across 0-255 positions. :param pos: a position between 0 and 255 :return: a rainbow color for each position """ if pos < 85: return ws.Color(pos * 3, 255 - pos * 3, 0) elif pos < 170: pos -= 85 return ws.Color(255 - pos * 3, 0, pos * 3) else: pos -= 170 return ws.Color(0, pos * 3, 255 - pos * 3)
def random_color(): h = random.uniform(0.0, 1.0) s = random.uniform(0.5, 1.0) v = random.uniform(0.7, 1.0) color = colorsys.hsv_to_rgb(h, s, v) rgb255 = [int(x * 255) for x in color] return npx.Color(*rgb255)
def set_strip_colours(self, remaining_salt_ratio): # Start from a clear slate. self.pixel_clear() # Figure out which pixel to light and which colour to use. pixel_to_light = round( float(self.led_count - float(remaining_salt_ratio * self.led_count))) - 1 # Limiting the pixels to the available ones. Don't go below -1 when counting down. if pixel_to_light < -1: pixel_to_light = -1 minimum_pixels = self.led_count - 5 # Need at least 5 pixels to get a decent visual. Count from bottom of strip. # This is to ensure we get the minimum # of pixels otherwise hard to see or know the program is working. if pixel_to_light > minimum_pixels: pixel_to_light = minimum_pixels #print("go to {}, ratio {}" .format(pixel_to_light, remaining_salt_ratio)) # Scrolling down for pixel in range(self.led_count - 1, pixel_to_light, -1): self.strip.setPixelColor(pixel, rpi_ws281x.Color(0, 0, 0)) time.sleep(0.5) self.strip.show() # Pixel colour set according to the scheme defined in __init__ self.strip.setPixelColor(pixel, self.rgb_colour_list[pixel]) time.sleep(0.5) 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 change_time(): """ Set the regular time that the lights will come on. This is taken from a web page with two boxes, containing hours.data and minutes.data We write the times to a file to make sure that we keep them across running sessions. """ form = TimeForm() if form.validate_on_submit(): # Clear the schedule. schedule.clear() on_time = datetime.time(hour=form.hours.data, minute=form.minutes.data) # We can't meaningfully add times and time offsets without # dates getting involved... argh! off_time = (datetime.datetime.combine(datetime.date.today(), on_time) + datetime.timedelta(seconds=RUNTIME)).time() with open("./times.txt", "w") as fi: fi.write(on_time.strftime("%H:%M:%S") + "\n") fi.write(off_time.strftime("%H:%M:%S") + "\n") schedule.every().day.at(on_time.strftime("%H:%M:%S")).do( turn_lights_on, STRIP) schedule.every().day.at(off_time.strftime("%H:%M:%S")).do( turn_lights_off, STRIP) for i in range(STRIP.numPixels()): STRIP.setPixelColor(i, ws.Color(0, 0, 0)) STRIP.show() flash(f"The lights will come on at {on_time.strftime('%H:%M:%S')}") print(f"The lights will come on at {on_time.strftime('%H:%M:%S')}") return redirect("/") return render_template("timesetter.html", title="Light Time", form=form)
def show_char(self, c, color=None): led = ADDR_MAP.get(c, 26) # 26 is out of range, nothing will light up self.strip.setPixelColor(led, color if color else random_color()) self.strip.show() time.sleep(CHAR_ON_PERIOD) self.strip.setPixelColor(led, npx.Color(0, 0, 0)) self.strip.show()
def render(self, matrix): p = 0 for i in range(matrix.shape[0]): for j in range(matrix.shape[1]): col = int(ws.Color(*matrix[i, j])) self.strip.setPixelColor(p, col) p += 1 self.strip.show()
def render(self, frame): """Renders the supplied frame on the matrix. Args: frame: RGB representation of the frame. """ p = 0 for i in frame: for j in i: self.strip.setPixelColor(p, ws.Color(*j)) p += 1 self.strip.show()
def colour(self, value): '''When the colour value is updated, adjusts the pixel colour to match.''' if not self.broken: self._colour = value self.pixcolour = rpi_ws281x.Color(int(value[0]), int(value[1]), int(value[2])) pixels.setPixelColor(self.pix_pos, self.pixcolour) else: '''If the pixel is broken then the sphere will ignore instructions to update it's colour saves you from having to remember which pixels are broken. It also doesn't update the WS2812 as there would be no point and this would waste time.''' self._colour = (0, 0, 0)
def run(self): while True: for pix in range(0, 180): # determine if off or on and then multiply by a brightness self.strip.setPixelColor( pix, rpi_ws281x.Color( random.randint(0, 1) * random.randint(0, 255), 0, 0)) self.strip.show() time.sleep(self.wait)
def cleanup(): print("server module: executing cleanup()") colorWipe(ledStrip, rpi_ws281x.Color(0, 0, 0)) headlights.turn(headlights.BOTH, headlights.OFF) GPIO.cleanup() try: camera.close() except: print( "cleanup: caught known false picamera exception that it is ignoring" ) pass # ignore known random exception in picamera library print("cleanup: completed")
async def theater(self, params): """Run a theater marquee on the lights.""" # Only import if needed import rpi_ws281x as ws color = params.get('color', {'red': 0, 'green': 0, 'blue': 255}) color = ws.Color(color.get('red', 0), color.get('green', 0), color.get('blue', 0)) wait_ms = params.get('wait_ms', 200) try: while True: await self.lights.theater_chase(color, wait_ms=wait_ms) except KeyboardInterrupt: pass
def dun_dun(self, delay=1, scalar=0.85): addr = [x for x in range(len(ADDR_MAP))] for i in range(len(addr)): rand_addr = random.choice(addr) self.strip.setPixelColor(rand_addr, random_color()) self.strip.show() addr.remove(rand_addr) time.sleep(delay*scalar**i) time.sleep(3) addr = [x for x in range(len(ADDR_MAP))] for _ in range(len(addr)): a = random.choice(addr) addr.remove(a) self.strip.setPixelColor(a, npx.Color(0, 0, 0)) self.strip.show() time.sleep(0.03) time.sleep(0.3)
def image_to_strip(self, strip, im, ids): """ Display a given image on a strip. Parameters ---------- strip The LED strip to draw on im The image to show ids The index array linking the colours to the pixel addresses """ colors = self.image_to_colors(im) for i in range(colors.shape[0]): this_color = ws.Color(int(colors[i, 0]), int(colors[i, 1]), int(colors[i, 2])) strip.setPixelColor(int(ids[i]), this_color) strip.show()
def __init__(self, led_count, led_pin, led_freq_hz, led_dma, led_invert, led_brightness, led_msg_queue): super().__init__() self.led_count = led_count # Neopixel strip initialisation. self.strip = rpi_ws281x.Adafruit_NeoPixel(led_count, led_pin, led_freq_hz, led_dma, led_invert, led_brightness, gamma=gamma8) # Initialise the library (must be called once before other functions). self.strip.begin() self.led_msg_queue = led_msg_queue # create the colours to be used for the bar graph, spread evenly over hte total pixels low_colour = 0 full_colour = 0.4 colour_step = float((full_colour - low_colour) / self.led_count) hue = full_colour # start the hue at full as we count down. self.rgb_colour_list = [] # Create the colour mapping to use. Red at the bottom (empty), green at the top (full). for colour in range(0, self.led_count): hue = hue - colour_step if hue < low_colour: hue = low_colour rgb_colour = colorsys.hsv_to_rgb(hue, 1, 0.5) rgb_colour = [int(element * 255) for element in rgb_colour] #print(hue, rgb_colour) self.rgb_colour_list.append(rpi_ws281x.Color(*tuple(rgb_colour)))
async def wipe(self, params): """Wipe the lights with colors.""" # Only import if needed import rpi_ws281x as ws loop = params.get('loop', True) colors = params.get('colors', []) if len(colors) < 1: colors.append({ 'red': 0, 'green': 0, 'blue': 255, 'hold': 0, 'wait_ms': 40 }) if loop and len(colors) < 2: colors.append({ 'red': 0, 'green': 0, 'blue': 0, 'hold': 0, 'wait_ms': 40 }) led_colors = [(ws.Color(color.get('red', 0), color.get('green', 0), color.get('blue', 0)), color.get('wait_ms', 40), color.get('hold_ms', 0)) for color in colors] try: while True: for (led_color, wait_ms, hold_duration) in led_colors: await self.lights.color_wipe(led_color, wait_ms=wait_ms) await asyncio.sleep(hold_duration / 1000.0) if not loop: break except KeyboardInterrupt: pass
def pixel_clear(self): # Clear all the pixels for i in range(0, self.strip.numPixels()): # Green Red Blue self.strip.setPixelColor(i, rpi_ws281x.Color(0, 0, 0)) self.strip.show()
# Clear all the pixels for i in range(0, self.strip.numPixels()): # Green Red Blue self.strip.setPixelColor(i, rpi_ws281x.Color(0, 0, 0)) self.strip.show() if __name__ == "__main__": # LED strip configuration: LED_COUNT = 180 # 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 = 5 # DMA channel to use for generating signal (try 5) 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) tweet_strip = LedStripControl(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS) colours = [rpi_ws281x.Color(255,0,0) , rpi_ws281x.Color(255,0,0), rpi_ws281x.Color(255,255,0), rpi_ws281x.Color(0,255,0), rpi_ws281x.Color(0, 0, 255)] tweet_strip.pixel_clear() time.sleep(4) tweet_strip.set_strip_colours(colours)
def clear_pix(self, x, y): black = rpi_ws281x.Color(0, 0, 0) pos = self._pix_pos(x, y) self.strip.setPixelColor(pos, black)
def set_pix(self, x, y, color): pos = self._pix_pos(x, y) rpi_color = rpi_ws281x.Color(*color) self.strip.setPixelColor(pos, rpi_color)
def clear(self): for column in self: for pixel in column: pixel.color = r.Color(0, 0, 0) self.update()
# LED strip configuration: LED_COUNT = 180 # 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 = 5 # DMA channel to use for generating signal (try 5) 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) # Create NeoPixel object with appropriate configuration. strip = rpi_ws281x.Adafruit_NeoPixel(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(strip.numPixels()): # Green Red Blue strip.setPixelColor(i, rpi_ws281x.Color(0, 0, 0)) strip.show() #unicornhat.show() try: print("Press Ctrl-C to finish") # Keep cycling through various colours - assume the user will press Control-C to finish. while True: # Turn green on 100% for a couple of seconds and the off, #pi.set_PWM_dutycycle(pwm_control_pin, 255) #print("fan 100%")
def numpy_to_ws281x_pixel(numpy_pixel): return rpi_ws281x.Color(int(numpy_pixel[2]), int(numpy_pixel[1]), int(numpy_pixel[0]))
# Create NeoPixel object with appropriate configuration. strip = r.Adafruit_NeoPixel(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). strip.begin() print('Press Ctrl-C to quit.') if not args.clear: print('Use "-c" argument to clear LEDs on exit') try: while True: print('Color wipe animations.') colorWipe(strip, r.Color(255, 0, 0)) # Red wipe colorWipe(strip, r.Color(0, 255, 0)) # Blue wipe colorWipe(strip, r.Color(0, 0, 255)) # Green wipe print('Theater chase animations.') theaterChase(strip, r.Color(127, 127, 127)) # White theater chase theaterChase(strip, r.Color(127, 0, 0)) # Red theater chase theaterChase(strip, r.Color(0, 0, 127)) # Blue theater chase print('Rainbow animations.') rainbow(strip) rainbowCycle(strip) theaterChaseRainbow(strip) except KeyboardInterrupt: if args.clear: colorWipe(strip, r.Color(0, 0, 0), 10)