Created
July 23, 2016 23:19
-
-
Save tusing/89f773fece6e1edbd9c6ecfc763aa077 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Display a list of user-defined color bars; | |
# fill the remaining area with sparkles. | |
# Designed for the Unicorn pHAT. | |
# By tusing. | |
import unicornhat as unicorn | |
from random import randint | |
import time | |
import os | |
import subprocess | |
import sys | |
# Initialization | |
unicorn.set_layout(unicorn.AUTO) | |
unicorn.rotation(0) | |
unicorn.brightness(0.3) # Tune to your preferences. | |
width,height=unicorn.get_shape() | |
def main(): | |
# A list of defined functions. Each function will display a single bar of | |
# color depending on their output. | |
function_list = [internet_color] | |
# Fill the rest of the remaining area with sparkles. | |
if len(function_list) < width: | |
random_sparkles(function_list=function_list, update_rate=5) | |
def function_bars(function_list): | |
""" Take in a list of functions. Set "bars" of color based off of the return | |
value of each function. | |
Args: | |
function_list: A list of color functions, to return a (R, G, B) color value | |
tuple. | |
""" | |
for width_val, color_function in enumerate(function_list): | |
color = color_function() | |
for height_val in range(height): | |
unicorn.set_pixel(width - width_val - 1, height_val, *color) | |
return | |
def random_sparkles(function_list=None, color_function=None, time_limit=None, update_rate=5): | |
""" Fill the rest of the area with randomly-generated rainbow sparkles. Sparkles increase | |
in frequency with load: frequency = load^2 for load > 1, else frequency = 1. | |
Args: | |
function_list: A list of functions you'll be using for function bars. | |
color_function: Define a custom function for the sparkles' color, instead of a | |
random rainbow. | |
time_limit: Quit after a defined amount of time. | |
update_rate: How often you want to refresh the values of your defined function. | |
""" | |
# Utilize the remaining area not taken up by bars. | |
max_width = width if function_list is None else width - len(function_list) | |
def random_pixel(color): | |
""" Generate a randomly positioned pixel with the given color; if no | |
color is defined, generate a random color. | |
Args: | |
color: (R, G, B) value tuple. | |
""" | |
def random(): | |
""" Generate the random pixel. """ | |
nonlocal color | |
x = randint(0, (max_width-1)) | |
y = randint(0, (height-1)) | |
if color is None: | |
r = randint(0, 255) | |
g = randint(0, 255) | |
b = randint(0, 255) | |
color = (r,g,b) | |
return [(x,y), (x,y) + color] | |
selected = random() | |
''' Aesthetic: If the randomly generated pixel is currently lit, | |
turn it off and try with a new pixel. Also works as sort of a | |
population control on how many pixels will be lit. ''' | |
while sum(unicorn.get_pixel(*selected[0])) > 0: | |
unicorn.set_pixel(*(selected[0] + (0, 0, 0))) | |
selected = random() | |
unicorn.set_pixel(*selected[1]) | |
return | |
''' Actually loop through everything. This outer loop runs every update_rate | |
seconds: in other words, load value and color function values are updated | |
every update_rate seconds. ''' | |
while True: | |
# Define a load-based tick-rate (how often sparkles will, well, sparkle.) | |
# Limit at load=12 to avoid a runaway effect. | |
tick = 1 | |
if os.getloadavg()[0] > 1: | |
tick = 1/(os.getloadavg()[0]**2) if os.getloadavg()[0] < 12 else 1/144 | |
# Fetch the color function's current value. (For the sparkles.) | |
color = None if color_function is None else color_function() | |
# Update all our color bars. | |
if function_list is not None: | |
function_bars(function_list) | |
# If no time_limit is defined, run forever. | |
if time_limit is None: | |
for i in range(int(update_rate/tick)): | |
random_pixel(color) | |
unicorn.show() | |
time.sleep(tick) | |
# Otherwise, run until the time_limit runs down to zero. | |
else: | |
if time_limit <= 0: | |
break | |
for i in range(int(update_rate/tick)): | |
random_pixel(color) | |
unicorn.show() | |
time.sleep(tick) | |
time_limit -= update_rate/tick | |
def internet_color(): | |
""" Example color function: tests internet connectivity. | |
Returns: (R, G, B) tuple: White if connected to internet; orange if not. | |
""" | |
# Ping a Google DNS server to check for internet connectivity. | |
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "8.8.8.8"], stdout=subprocess.PIPE).stdout.read() | |
return (255, 255, 255) if "1 received" in str(ping_response) else (255, 127, 80) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment