Skip to content

Instantly share code, notes, and snippets.

@tusing
Created July 23, 2016 23:19
Show Gist options
  • Save tusing/89f773fece6e1edbd9c6ecfc763aa077 to your computer and use it in GitHub Desktop.
Save tusing/89f773fece6e1edbd9c6ecfc763aa077 to your computer and use it in GitHub Desktop.
#!/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