def __init__(self, hat=None): if hat is None: try: spidev.SpiDev(0, 0) hat = 'mini' except FileNotFoundError: hat = 'phat' if hat == 'mini': self.hat = UnicornHATMini() self.type = hat self.hat.set_brightness(0.5) self.hat.set_rotation(90) elif hat == 'dummy': self.hat = None self.type = 'none' else: self.hat = unicornhat self.type = hat self.hat.set_layout(unicornhat.PHAT) self.hat.brightness(0.5) self.hat.rotation(90) self.brightness = 0.5 self.rotation = 0 self.width, self.height = self.hat.get_shape()
def test_set_all(GPIO, spidev): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() unicornhatmini.set_all(255, 255, 255) assert unicornhatmini.disp == [[255 >> 2, 255 >> 2, 255 >> 2]] * (17 * 7)
def test_clear(GPIO, spidev): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() unicornhatmini.clear() assert unicornhatmini.disp == [[0, 0, 0]] * (17 * 7)
def __init__(self, brightness=0.5): """ @see _UnicornHatNotifier.__init__() """ super(UnicornHatMiniNotifier, self).__init__(brightness=brightness) from unicornhatmini import UnicornHATMini self._hat = UnicornHATMini()
def test_set_image_wrap(GPIO, spidev): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() image = mock.MagicMock() image.size = (3, 3) image.mode = "RGB" image.getpixel.return_value = (255, 255, 255) unicornhatmini.set_image(image, offset_x=0, offset_y=0, wrap=True)
def __init__(self): self.uni = UnicornHATMini() self.uni.clear() self.uni.set_rotation(0) self.uni.set_brightness(0.1) display_width, display_height = self.uni.get_shape() self.display_width = display_width self.display_height = display_height self.font = ImageFont.truetype( os.path.dirname(os.path.realpath(__file__)) + "/5x7.ttf", 8)
def __init__(self, color_provider): hat = UnicornHATMini() hat.set_rotation(self.DEFAULT_ROTATION) hat.set_brightness(self.DEFAULT_BRIGHTNESS) self.display_width, self.display_height = hat.get_shape() self.unicornhatmini = hat self.color_provider = color_provider
def __init__(self): self.modes_data = get_mode_data() self.mode = None self.unicornhatmini = UnicornHATMini() self.config = get_config() mode_id = self.config.get('GENERAL', 'INITIAL_MODE_ID', fallback='clock_mode') if mode_id not in get_valid_mode_ids(): print( f'initial mode id of {mode_id} is not a valid, clock_mode is being used instead' ) mode_id = 'clock_mode' self.mode_id = mode_id self.mode_update_needed = False self.running = False self.mode_custom_options = None
def test_set_rotation(GPIO, spidev): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() shapes = {0: (17, 7), 90: (7, 17), 180: (17, 7), 270: (7, 17)} for rotation in (0, 90, 180, 270): unicornhatmini.set_rotation(rotation) assert unicornhatmini.get_shape() == shapes[rotation] unicornhatmini.set_pixel(0, 0, 255, 255, 255)
def test_setup(GPIO, spidev): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() spidev.SpiDev.assert_has_calls(( mock.call(0, 0), mock.call(0, 1) ), any_order=True) GPIO.setwarnings.assert_called_once_with(False) GPIO.setmode.assert_called_once_with(GPIO.BCM) del unicornhatmini
def test_set_image(GPIO, spidev): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() image = mock.MagicMock() image.size = (17, 7) image.getpixel.return_value = (255, 255, 255) image.convert.return_value = image unicornhatmini.set_image(image, offset_x=0, offset_y=0) image.mode = "RGB" unicornhatmini.set_image(image, offset_x=0, offset_y=0)
import time import requests from PIL import Image from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() unicornhatmini.set_brightness(0.5) temp_color = 0 settings = { 'api_key': 'your_key_here', 'zip_code': '94112', 'country_code': 'us', 'temp_unit': 'imperial' } #unit can be metric, imperial, or kelvin BASE_URL = "http://api.openweathermap.org/data/2.5/weather?appid={0}&zip={1},{2}&units={3}" while True: final_url = BASE_URL.format(settings["api_key"], settings["zip_code"], settings["country_code"], settings["temp_unit"]) weather_data = requests.get(final_url).json() temperature = weather_data["main"]["temp"] print(temperature) temp_color = int(temperature) if temperature >= 85:
import time from colorsys import hsv_to_rgb from unicornhatmini import UnicornHATMini print("""Unicorn HAT Mini: fps.py Attempts to refresh the Unicorn HAT Mini display as fast as possible with a horizontal rainbow and displays the frames per second refresh rate. Press Ctrl+C to exit! """) unicornhatmini = UnicornHATMini() unicornhatmini.set_brightness(0.1) unicornhatmini.set_rotation(0) width, height = unicornhatmini.get_shape() frames = 0 t_start = time.time() t_report = time.time() report_freq = 5.0 print("Please wait...") while True: for y in range(height): for x in range(width):
def test_set_brightness(GPIO, spidev): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() unicornhatmini.set_brightness(0.5)
def test_show(GPIO, spidev): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() unicornhatmini.show()
def test_set_pixel(GPIO, spidev): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() unicornhatmini.set_pixel(0, 0, 255, 255, 255)
class UnicornHatMiniNotifier(_UnicornHatNotifier): """ A notifier for the Unicorn HAT Mini. """ def __init__(self, brightness=0.5): """ @see _UnicornHatNotifier.__init__() """ super(UnicornHatMiniNotifier, self).__init__(brightness=brightness) from unicornhatmini import UnicornHATMini self._hat = UnicornHATMini() def _brightness(self, brightness): """ @see _UnicornHatNotifier._brightness """ self._hat.set_brightness(brightness) def _rotation(self, rotation): """ @see _UnicornHatNotifier._rotation """ self._hat.set_rotation(rotation) def _get_shape(self): """ @see _UnicornHatNotifier._get_shape """ return self._hat.get_shape() def _set_pixel(self, x, y, r, g, b): """ @see _UnicornHatNotifier._set_pixel """ self._hat.set_pixel(x, y, r, g, b) def _show(self): """ @see _UnicornHatNotifier._show """ self._hat.show() def _off(self): """ @see _UnicornHatNotifier._off """ self._hat.clear() self._hat.show()
def test_shutdown(GPIO, spidev, atexit): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() atexit.register.assert_called_once_with(unicornhatmini._exit) unicornhatmini._exit()
def draw(data): uni = UnicornHATMini() uni.clear() uni.set_rotation(0) uni.set_brightness(0.1) display_width, display_height = uni.get_shape() for x in range(display_width): r = g = 0 if len(data) > x: if data[x] == 1: g = 255 elif data[x] == 2: r = 255 elif data[x] == 3: r = 255 g = 150 for y in range(display_height): uni.set_pixel(x, y, r, g, 0) uni.show() time.sleep(2) uni.clear() uni.show()
def draw(): uni = UnicornHATMini() uni.clear() uni.set_rotation(0) uni.set_brightness(0.1) display_width, display_height = uni.get_shape() interval = 60 / 17 interval = 5 while True: data = getData() for x in range(display_width): if x >= len(data): r = g = 0 else: r = 255 if data[x] == 0 else 0 g = 255 if data[x] == 1 else 0 for y in range(display_height): uni.set_pixel(x, y, r, g, 0) uni.show() time.sleep(interval)
class UnicornWrapper: def __init__(self, hat=None): if hat is None: try: spidev.SpiDev(0, 0) hat = 'mini' except FileNotFoundError: hat = 'phat' if hat == 'mini': self.hat = UnicornHATMini() self.type = hat self.hat.set_brightness(0.5) self.hat.set_rotation(90) elif hat == 'dummy': self.hat = None self.type = 'none' else: self.hat = unicornhat self.type = hat self.hat.set_layout(unicornhat.PHAT) self.hat.brightness(0.5) self.hat.rotation(90) self.brightness = 0.5 self.rotation = 0 self.width, self.height = self.hat.get_shape() def getType(self): return self.type def getHat(self): return self.hat def clear(self): return self.hat.clear() def getShape(self): return self.hat.get_shape() def setAll(self, r, g, b): self.hat.set_all(r, g, b) def getBrightness(self): if self.type == 'phat': return self.hat.get_brightness() return self.brightness def setBrightness(self, brightness): self.brightness = brightness if self.type == 'phat': f = io.StringIO() with contextlib.redirect_stdout(f): self.hat.brightness(brightness) elif self.type == 'mini': self.hat.set_brightness(brightness) def setPixel(self, x, y, r, g, b): self.hat.set_pixel(x, y, r, g, b) def setColour(self, r=None, g=None, b=None, RGB=None): if RGB is not None: r = RGB[0] g = RGB[1] b = RGB[2] self.hat.clear() for x in range(self.width): for y in range(self.height): self.setPixel(x, y, r, g, b) self.hat.show() def setRotation(self, r=0): if self.type == 'phat': self.hat.rotation(r) elif self.type == 'mini': self.hat.set_rotation(r) self.rotation = r def getRotation(self): return self.rotation def show(self): self.hat.show() def off(self): self.hat.clear() self.hat.show() # Colour converstion operations as we only understand RGB def hsvIntToRGB(self, h, s, v): h = h / 360 s = s / 100 v = v / 100 return tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h, s, v)) def htmlToRGB(self, html): if len(html) is 6: r = int(f"{html[0]}{html[1]}", 16) g = int(f"{html[2]}{html[3]}", 16) b = int(f"{html[4]}{html[5]}", 16) elif len(html) > 6: r = int(f"{html[1]}{html[2]}", 16) g = int(f"{html[3]}{html[4]}", 16) b = int(f"{html[5]}{html[6]}", 16) else: raise Exception( "The Hex value is not in the correct format it should RRGGBB or #RRGGBB the same as HTML" ) return tuple(r, g, b)
import requests settings = { 'api_key': 'your_key_here', 'zip_code': '94112', 'country_code': 'us', 'temp_unit': 'imperial' } #unit can be metric, imperial, or kelvin BASE_URL = "http://api.openweathermap.org/data/2.5/weather?appid={0}&zip={1},{2}&units={3}" # The text we want to display. You should probably keep this line and replace it below # That way you'll have a guide as to what characters are supported! text = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 #@&!?{}<>[]();:.,'%*=+-=$_\\/ :-)" unicornhatmini = UnicornHATMini() rotation = 0 if len(sys.argv) > 1: try: rotation = int(sys.argv[1]) except ValueError: print("Usage: {} <rotation>".format(sys.argv[0])) sys.exit(1) unicornhatmini.set_rotation(rotation) display_width, display_height = unicornhatmini.get_shape() print("{}x{}".format(display_width, display_height)) unicornhatmini.set_brightness(0.1)
class Writer(): def __init__(self): self.uni = UnicornHATMini() self.uni.clear() self.uni.set_rotation(0) self.uni.set_brightness(0.1) display_width, display_height = self.uni.get_shape() self.display_width = display_width self.display_height = display_height self.font = ImageFont.truetype( os.path.dirname(os.path.realpath(__file__)) + "/5x7.ttf", 8) def drawText(self, text): text_width, text_height = self.font.getsize(text) image = Image.new('P', (text_width + self.display_width + self.display_width, self.display_height), 0) draw = ImageDraw.Draw(image) draw.text((self.display_width, -1), text, font=self.font, fill=255) return image def getColour(self, s): if s == "Rainbow": return s mapValue = { "Red": "255,10,0", "Green": "0,255,10", "Blue": "0,10,255", "White": "255,255,255", "Black": "0,0,0" }[s] try: r, g, b = mapValue.split(",") except NameError: r, g, b = s.split(",") return [int(r), int(g), int(b)] def scroll(self, text, colour="Rainbow", show_total=1): image = self.drawText(text) show_count = 0 offset_x = 0 if colour != "Rainbow": r, g, b = self.getColour(colour) while show_count < show_total: for y in range(self.display_height): for x in range(self.display_width): hue = (time.time() / 10.0) + (x / float(self.display_width * 2)) if colour == "Rainbow": r, g, b = [ int(c * 255) for c in hsv_to_rgb(hue, 1.0, 1.0) ] if image.getpixel((x + offset_x, y)) == 255: self.uni.set_pixel(x, y, r, g, b) else: self.uni.set_pixel(x, y, 0, 0, 0) offset_x += 1 if offset_x + self.display_width > image.size[0]: offset_x = 0 show_count = show_count + 1 self.uni.show() time.sleep(0.05) def clear(self): self.uni.clear() self.uni.show() time.sleep(0.05)
def test_set_rotation_invalid(GPIO, spidev): from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() with pytest.raises(ValueError): unicornhatmini.set_rotation(99)
import random from unicornhatmini import UnicornHATMini nums = [None] * 10 nums[0] = [1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1] nums[1] = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1] nums[2] = [1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1] nums[3] = [1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1] nums[4] = [1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1] nums[5] = [1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1] nums[6] = [1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1] nums[7] = [1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1] nums[8] = [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1] nums[9] = [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1] unicornhatmini = UnicornHATMini() unicornhatmini.set_brightness(0.2) unicornhatmini.set_rotation(180) async def main(): old_M0 = -1 while True: now = dt.now() H0 = now.hour % 10 H1 = int(now.hour / 10) M0 = now.minute % 10 M1 = int(now.minute / 10) cur_time = [H1, H0, M1, M0] show_colon = (now.second % 2) == 0
#!/usr/bin/env python3 import time import random from gpiozero import Button from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() unicornhatmini.set_rotation(270) class Game: def __init__(self, display): self.display = display self.playing_field = [[(0, 0, 0) for x in range(7)] for y in range(17)] self.remove = [[0 for x in range(7)] for y in range(17)] self.current = None self.drop_speed = 6 # Pixels per second self._move = False self._rotate = False self.new_column() def new_column(self): self.current = Column(3, -3) def update(self, fps=50.0): if self._move: self.current.move(self.playing_field, 1.0, 0) self._move = False if self._rotate:
#!/usr/bin/env python3 import time import math import random import colorsys from gpiozero import Button from unicornhatmini import UnicornHATMini unicornhatmini = UnicornHATMini() unicornhatmini.set_brightness(0.5) # Digits as 3x5 pixel elements stored as 15bits # MSB is top-left, each 5 bits are a column digits_5x3 = [ 0b111111000111111, # 0 0b100011111100001, # 1 0b101111010111101, # 2 0b101011010111111, # 3 0b111000010011111, # 4 0b111011010110111, # 5 0b111111010100111, # 6 0b100001000011111, # 7 0b111111010111111, # 8 0b111001010011111 # 9 ] R = 0 G = 1 B = 2
# modified from forest fire demo code from random import randint from gpiozero import Button import random import time from unicornhatmini import UnicornHATMini print(""" Unicorn HAT Mini: The game of life Press Ctrl+C to exit! """) # Avoid retina-searage! unicornhatmini = UnicornHATMini() unicornhatmini.set_brightness(0.1) unicornhatmini.set_rotation(0) # The height and width of the forest. width, height = unicornhatmini.get_shape() # Initial probability of a grid square having a tree initial_life = 0.25 # p = probability of life growing, f = probability of fire p = 0.0001 f = 0.0005 # Each square's neighbour coordinates hood = ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1))
#!/usr/bin/env python3 import time from colorsys import hsv_to_rgb from unicornhatmini import UnicornHATMini print("""Unicorn HAT Mini: colour-cycle.py Cycles through colour hues across all of Unicorn HAT Mini's pixels. Press Ctrl+C to exit! """) unicornhatmini = UnicornHATMini() unicornhatmini.set_brightness(0.1) while True: hue = (time.time() / 10.0) r, g, b = [int(c * 255) for c in hsv_to_rgb(hue, 1.0, 1.0)] unicornhatmini.set_all(r, g, b) unicornhatmini.show() time.sleep(1.0 / 60)
class DisplayController: '''used to controll switching between the different dispaly modes''' def __init__(self): self.modes_data = get_mode_data() self.mode = None self.unicornhatmini = UnicornHATMini() self.config = get_config() mode_id = self.config.get('GENERAL', 'INITIAL_MODE_ID', fallback='clock_mode') if mode_id not in get_valid_mode_ids(): print( f'initial mode id of {mode_id} is not a valid, clock_mode is being used instead' ) mode_id = 'clock_mode' self.mode_id = mode_id self.mode_update_needed = False self.running = False self.mode_custom_options = None def set_mode(self, new_mode_id, custom_options=None): '''sets the current mode''' if new_mode_id not in get_valid_mode_ids(): print( f'cannot change to mode with id: {new_mode_id} as it is invalid or disabled' ) return self.mode_id = new_mode_id self.mode_custom_options = custom_options self.mode_update_needed = True def update_mode(self): '''updates the current mode by instancating new mode instance''' # only passes custom options if it's not None if self.mode_custom_options is None: self.mode = self.modes_data[self.mode_id]['class_constructor']( self.unicornhatmini, self.config) else: self.mode = self.modes_data[self.mode_id]['class_constructor']( self.unicornhatmini, self.config, self.mode_custom_options) self.mode_update_needed = False def run(self): '''used to start running the led display''' self.unicornhatmini.set_brightness( self.config.getfloat('GENERAL', 'BRIGHTNESS', fallback=0.1)) self.unicornhatmini.set_rotation( self.config.getint('GENERAL', 'ROTATION', fallback=0)) self.update_mode() self.running = True frame_interval = 1.0 / 30 while self.running: start_time = time.time() frame_interval = 1.0 / self.mode.display_frame() end_time = time.time() if end_time - start_time < frame_interval: time.sleep(frame_interval - (end_time - start_time)) if self.mode_update_needed is True: self.update_mode() if not self.running: print('display controller shutting down') self.unicornhatmini.clear() self.unicornhatmini.show() def stop(self): '''used to stop execution of the display controller''' self.running = False