def advance(self) -> bool: """Displays the next image. Returns True when a new image was displayed, False otherwise.""" if self._file_name: self._fade_down() self._group.pop() self._file_name = None self._current_slide_index += self.direction # Try to load slides until a valid file is found or we run out of options. This # loop stops because we either set odb or reduce the length of _file_list. odb = None lbl = None while not odb and not lbl and self._file_list: if 0 <= self._current_slide_index < len(self._file_list): pass elif not self.loop: return False else: slide_count = len(self._file_list) if self._current_slide_index < 0: self._current_slide_index += slide_count elif self._current_slide_index >= slide_count: self._current_slide_index -= slide_count self._reorder_slides() self._file_name = self._file_list[self._current_slide_index] if self._file_name.endswith(".bmp"): try: odb = displayio.OnDiskBitmap(self._file_name) except ValueError: del self._file_list[self._current_slide_index] self._file_name = None elif self._file_name.endswith(".json"): lbl = self._create_label(self._file_name) if not odb and not lbl: raise RuntimeError("No valid images or text json files") if odb: if self._h_align == HorizontalAlignment.RIGHT: self._group.x = self._display.width - odb.width elif self._h_align == HorizontalAlignment.CENTER: self._group.x = round(self._display.width / 2 - odb.width / 2) else: self._group.x = 0 if self._v_align == VerticalAlignment.BOTTOM: self._group.y = self._display.height - odb.height elif self._v_align == VerticalAlignment.CENTER: self._group.y = round(self._display.height / 2 - odb.height / 2) else: self._group.y = 0 image_tilegrid = displayio.TileGrid( odb, pixel_shader=getattr(odb, "pixel_shader", displayio.ColorConverter()), # TODO: Once CP6 is no longer supported, replace the above line with below # pixel_shader=odb.pixel_shader, ) self._group.append(image_tilegrid) if lbl: self._group.append(lbl) self._fade_up() if hasattr(self._display, "refresh"): self._display.refresh() self._img_start = time.monotonic() return True
# Create the display object - the third color is red (0xff0000) display = adafruit_il91874.IL91874(display_bus, width=264, height=176, highlight_color=0xFF0000, rotation=90) # Create a display group for our screen objects g = displayio.Group() # Display a ruler graphic from the root directory of the CIRCUITPY drive f = open("/display-ruler.bmp", "rb") pic = displayio.OnDiskBitmap(f) # Create a Tilegrid with the bitmap and put in the displayio group t = displayio.TileGrid(pic, pixel_shader=displayio.ColorConverter()) g.append(t) # Place the display group on the screen (does not refresh) display.show(g) # Show the image on the display display.refresh() print("refreshed") # Do Not refresh the screen more often than every 180 seconds # for eInk displays! Rapid refreshes will damage the panel. time.sleep(180)
epd_busy = board.D6 display_bus = displayio.FourWire( spi, command=epd_dc, chip_select=epd_cs, reset=epd_reset, baudrate=1000000 ) time.sleep(1) display = adafruit_ssd1675.SSD1675( display_bus, width=250, height=122, rotation=270, busy_pin=epd_busy ) g = displayio.Group() with open("/display-ruler.bmp", "rb") as f: pic = displayio.OnDiskBitmap(f) # CircuitPython 6 & 7 compatible t = displayio.TileGrid( pic, pixel_shader=getattr(pic, "pixel_shader", displayio.ColorConverter()) ) # CircuitPython 7 compatible only # t = displayio.TileGrid(pic, pixel_shader=pic.pixel_shader) g.append(t) display.show(g) display.refresh() print("refreshed") time.sleep(120)
import displayio import terminalio import pulseio moist_level = 93 # adjust this value as needed for your plant board.DISPLAY.brightness = 0.8 clue.pixel.fill(0) # turn off NeoPixel clue_display = displayio.Group(max_size=4) # draw the dry plant dry_plant_file = open("dry.bmp", "rb") dry_plant_bmp = displayio.OnDiskBitmap(dry_plant_file) dry_plant_sprite = displayio.TileGrid(dry_plant_bmp, pixel_shader=displayio.ColorConverter()) clue_display.append(dry_plant_sprite) # draw the happy plant on top (so it can be moved out of the way when needed) happy_plant_file = open("happy.bmp", "rb") happy_plant_bmp = displayio.OnDiskBitmap(happy_plant_file) happy_plant_sprite = displayio.TileGrid( happy_plant_bmp, pixel_shader=displayio.ColorConverter()) clue_display.append(happy_plant_sprite) # Create text # first create the group text_group = displayio.Group(max_size=3, scale=3) # Make a label title_label = label.Label(terminalio.FONT, text="I'm Sunny", color=0x00FF22) # Position the label
# function to convert celsius degrees to fahrenheit def c_to_f(c_val): return (c_val * 9 / 5) + 32 # Open the background image file with open("/thermometer_background.bmp", "rb") as bitmap_file: # Setup the file as the bitmap data source bitmap = displayio.OnDiskBitmap(bitmap_file) # Create a TileGrid to hold the bitmap # CircuitPython 6 & 7 compatible tile_grid = displayio.TileGrid( bitmap, pixel_shader=getattr(bitmap, "pixel_shader", displayio.ColorConverter()), ) # CircuitPython 7 compatible only # tile_grid = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader) # Create a Group to hold the TileGrid group = displayio.Group() # Add the TileGrid to the Group group.append(tile_grid) # variable with initial text value, temperature rounded to 2 places text = "%.2f C" % (round(cp.temperature, 2)) # Create a Group for the text so we can scale it text_group = displayio.Group(scale=TEXT_SCALE, x=0, y=0)
else: panel.has_joystick = False # Must be PyBadge # Establish I2C interface for the AMG8833 Thermal Camera i2c = board.I2C() amg8833 = adafruit_amg88xx.AMG88XX(i2c) # Load the text font from the fonts folder font = bitmap_font.load_font("/fonts/OpenSans-9.bdf") # Display spash graphics and play startup tones with open("/thermal_cam_splash.bmp", "rb") as bitmap_file: bitmap = displayio.OnDiskBitmap(bitmap_file) splash = displayio.Group() splash.append( displayio.TileGrid(bitmap, pixel_shader=displayio.ColorConverter())) board.DISPLAY.show(splash) time.sleep(0.1) # Allow the splash to display panel.play_tone(440, 0.1) # A4 panel.play_tone(880, 0.1) # A5 # The image sensor's design-limited temperature range MIN_SENSOR_C = 0 MAX_SENSOR_C = 80 MIN_SENSOR_F = celsius_to_fahrenheit(MIN_SENSOR_C) MAX_SENSOR_F = celsius_to_fahrenheit(MAX_SENSOR_C) # Convert default alarm and min/max range values from config file ALARM_C = fahrenheit_to_celsius(ALARM_F) MIN_RANGE_C = fahrenheit_to_celsius(MIN_RANGE_F) MAX_RANGE_C = fahrenheit_to_celsius(MAX_RANGE_F)
def changeturtle(self, source=None, dimensions=(12, 12)): """ Change the turtle. if a string is provided, its a path to an image opened via OnDiskBitmap if a tilegrid is provided, it replace the default one for the turtle shape. if no argument is provided, the default shape will be restored """ if source is None: if self._turtle_pic is None: return if self._turtle_group: self._turtle_group.remove(self._turtle_alt_sprite) self._turtle_group.append(self._turtle_sprite) self._turtle_alt_sprite = None if self._turtle_odb is not None: self._turtle_odb_use -= 1 self._turtle_odb = None if self._turtle_odb_file is not None: if self._turtle_odb_use == 0: self._turtle_odb_file.close() self._turtle_odb_file = None self._turtle_pic = None self._drawturtle() return if isinstance(source, str): visible = self.isvisible() if self._turtle_pic is not None: if self._turtle_group: self._turtle_group.remove(self._turtle_alt_sprite) self._turtle_alt_sprite = None self._turtle_odb = None if not isinstance(self._turtle_pic, tuple): self._turtle_odb_file.close() self._turtle_odb_file = None self._turtle_odb_use -= 1 self._turtle_pic = None self._turtle_odb_file = open(source, "rb") try: self._turtle_odb = displayio.OnDiskBitmap( self._turtle_odb_file) except: self._turtle_odb_file.close() self._turtle_odb_file = None self._turtle_pic = None if visible: self._turtle_group.append(self._turtle_sprite) raise self._turtle_odb_use += 1 self._turtle_pic = True self._turtle_alt_sprite = displayio.TileGrid( self._turtle_odb, pixel_shader=displayio.ColorConverter()) if self._turtle_group: self._turtle_group.pop() if visible: self._turtle_group.append(self._turtle_alt_sprite) self._drawturtle() elif isinstance(source, displayio.TileGrid): if self._turtle_pic is not None: if self._turtle_odb_file is not None: self._turtle_odb_use -= 1 if self._turtle_odb_use == 0: self._turtle_odb_file.close() self._turtle_pic = dimensions self._turtle_alt_sprite = source if self._turtle_group: self._turtle_group.pop() self._turtle_group.append(self._turtle_alt_sprite) self._drawturtle() else: raise TypeError( 'Argument must be "str", a "displayio.TileGrid" or nothing.')
def set_background(self, file_or_color, position=None): """The background image to a bitmap file. :param file_or_color: The filename of the chosen background image, or a hex color. """ print("Set background to ", file_or_color) while self._bg_group: self._bg_group.pop() if not position: position = (0, 0) # default in top corner if not file_or_color: return # we're done, no background desired if self._bg_file: self._bg_file.close() if isinstance(file_or_color, str): # its a filenme: self._bg_file = open(file_or_color, "rb") background = displayio.OnDiskBitmap(self._bg_file) try: self._bg_sprite = displayio.TileGrid( background, pixel_shader=displayio.ColorConverter(), position=position, ) except TypeError: self._bg_sprite = displayio.TileGrid( background, pixel_shader=displayio.ColorConverter(), x=position[0], y=position[1], ) elif isinstance(file_or_color, int): # Make a background color fill color_bitmap = displayio.Bitmap( board.DISPLAY.width, board.DISPLAY.height, 1 ) color_palette = displayio.Palette(1) color_palette[0] = file_or_color try: self._bg_sprite = displayio.TileGrid( color_bitmap, pixel_shader=color_palette, position=(0, 0) ) except TypeError: self._bg_sprite = displayio.TileGrid( color_bitmap, pixel_shader=color_palette, x=position[0], y=position[1], ) else: raise RuntimeError("Unknown type of background") self._bg_group.append(self._bg_sprite) try: board.DISPLAY.refresh(target_frames_per_second=60) gc.collect() except AttributeError: board.DISPLAY.refresh_soon() gc.collect() board.DISPLAY.wait_for_frame()
def show_business_card(self, *, image_name=None, name_string=None, name_scale=1, name_font=terminalio.FONT, email_string_one=None, email_scale_one=1, email_font_one=terminalio.FONT, email_string_two=None, email_scale_two=1, email_font_two=terminalio.FONT): """Display a bitmap image and a text string, such as a personal image and email address. :param str image_name: REQUIRED. The name of the bitmap image including .bmp, e.g. ``"Blinka.bmp"``. :param str name_string: A name string to display along the bottom of the display, e.g. ``"Blinka"``. :param int name_scale: The scale of ``name_string``. Defaults to 1. :param name_font: The font for the name string. Defaults to ``terminalio.FONT``. :param str email_string_one: A string to display along the bottom of the display, e.g. ``"*****@*****.**"``. :param int email_scale_one: The scale of ``email_string_one``. Defaults to 1. :param email_font_one: The font for the first email string. Defaults to ``terminalio.FONT``. :param str email_string_two: A second string to display along the bottom of the display. Use if your email address is longer than one line or to add more space between the name and email address, e.g. (blinka@) ``"adafruit.com"``. :param int email_scale_two: The scale of ``email_string_two``. Defaults to 1. :param email_font_two: The font for the second email string. Defaults to ``terminalio.FONT``. """ business_card_splash = displayio.Group(max_size=30) self.display.show(business_card_splash) with open(image_name, "rb") as file_name: on_disk_bitmap = displayio.OnDiskBitmap(file_name) face_image = displayio.TileGrid( on_disk_bitmap, pixel_shader=displayio.ColorConverter()) business_card_splash.append(face_image) # self.display.wait_for_frame() #CP 4 self.display.refresh() #CP 5 if name_string: name_group = displayio.Group(scale=name_scale) name_label = Label(name_font, text=name_string) (_, _, width, height) = name_label.bounding_box name_label.x = ((self.display.width // (2 * name_scale)) - width // 2) name_label.y = int(height // (0.15 * name_scale)) name_label.color = 0xFFFFFF name_group.append(name_label) business_card_splash.append(name_group) if email_string_one: email_group_one = displayio.Group(scale=email_scale_one) email_label_one = Label(email_font_one, text=email_string_one) (_, _, width, height) = email_label_one.bounding_box email_label_one.width = self.display.width email_label_one.x = ((self.display.width // (2 * email_scale_one)) - width // 2) email_label_one.y = int(height // (0.13 * email_scale_one)) email_label_one.color = 0xFFFFFF email_group_one.append(email_label_one) business_card_splash.append(email_group_one) if email_string_two: email_group_two = displayio.Group(scale=email_scale_two) email_label_two = Label(email_font_two, text=email_string_two) (_, _, width, height) = email_label_two.bounding_box email_label_two.width = self.display.width email_label_two.x = ((self.display.width // (2 * email_scale_two)) - width // 2) email_label_two.y = int(height // (0.12 * email_scale_two)) email_label_two.color = 0xFFFFFF email_group_two.append(email_label_two) business_card_splash.append(email_group_two)
def advance(self): """Displays the next image. Returns True when a new image was displayed, False otherwise.""" if self._image_file: self._fade_down() self._group.pop() self._image_file.close() self._image_file = None self._current_image += self.direction # Try and load an OnDiskBitmap until a valid file is found or we run out of options. This # loop stops because we either set odb or reduce the length of _file_list. odb = None while not odb and self._file_list: if 0 <= self._current_image < len(self._file_list): pass elif not self.loop: return False else: image_count = len(self._file_list) if self._current_image < 0: self._current_image += image_count elif self._current_image >= image_count: self._current_image -= image_count self._reorder_images() image_name = self._file_list[self._current_image] self._image_file = open(image_name, "rb") try: odb = displayio.OnDiskBitmap(self._image_file) except ValueError: self._image_file.close() self._image_file = None del self._file_list[self._current_image] if not odb: raise RuntimeError("No valid images") if self._h_align == HorizontalAlignment.RIGHT: self._group.x = self._display.width - odb.width elif self._h_align == HorizontalAlignment.CENTER: self._group.x = round(self._display.width / 2 - odb.width / 2) else: self._group.x = 0 if self._v_align == VerticalAlignment.BOTTOM: self._group.y = self._display.height - odb.height elif self._v_align == VerticalAlignment.CENTER: self._group.y = round(self._display.height / 2 - odb.height / 2) else: self._group.y = 0 try: sprite = self._sprite_class( odb, pixel_shader=displayio.ColorConverter()) except TypeError: sprite = self._sprite_class( odb, pixel_shader=displayio.ColorConverter(), position=(0, 0)) self._group.append(sprite) self._fade_up() self._img_start = time.monotonic() return True
# prediction data)... DISPLAY.show(GROUP) DISPLAY.refresh() time.sleep(5) # Don't allow another refresh() too soon # Second group is the low battery display. Populate this one now, # then we'll get back to the main group with the stop data in a moment... BATT_GROUP = displayio.Group(max_size=3) BATT_GROUP.append(fillrect(0, 0, DISPLAY.width, DISPLAY.height, 0xFFFFFF)) try: # Attempt loading low-battery icon, centered on screen # pylint: disable=no-member FILE = open('bitmaps/lowbatt.bmp', 'rb') BATT_BITMAP = displayio.OnDiskBitmap(FILE) BATT_ICON_TILEGRID = displayio.TileGrid( BATT_BITMAP, pixel_shader=displayio.ColorConverter()) BATT_ICON_TILEGRID.x = (DISPLAY.width - BATT_BITMAP.width + 1) // 2 BATT_ICON_TILEGRID.y = (DISPLAY.height - BATT_BITMAP.height + 1) // 2 # onDiskBitmap seems to treat black as transparent...image won't # show correctly on white background, so make an in-between rect # to fill the area behind the battery icon with black. BATT_GROUP.append( fillrect(BATT_ICON_TILEGRID.x, BATT_ICON_TILEGRID.y, BATT_BITMAP.width, BATT_BITMAP.height, 0)) BATT_GROUP.append(BATT_ICON_TILEGRID) except: # If load fails, fall back on text low-batt message TEXT = Label(FONT_MEDIUM, text='LOW BATTERY', color=0) TEXT.anchor_point = (0.5, 0.5) TEXT.anchored_position = (DISPLAY.width // 2, DISPLAY.height // 2) BATT_GROUP.append(TEXT)
def cc_update(cc_state): #gc.collect() now = time.time() # Current epoch time in seconds # Sync with time server every ~2 hours #if NOW - LAST_SYNC > 2 * 60 * 60: # try: # DATETIME, UTC_OFFSET = update_time(TIMEZONE) # LAST_SYNC = time.mktime(DATETIME) # continue # Time may have changed; refresh NOW value # except: # update_time() can throw an exception if time server doesn't # respond. That's OK, keep running with our current time, and # push sync time ahead to retry in 30 minutes (don't overwhelm # the server with repeated queries). # LAST_SYNC += 30 * 60 # 30 minutes -> seconds # If PERIOD has expired, move data down and fetch new +24-hour data if NOW >= PERIOD[1].midnight: PERIOD[0] = PERIOD[1] PERIOD[1] = MoonData(time.localtime(), 24, UTC_OFFSET) # Determine weighting of tomorrow's phase vs today's, using current time RATIO = ((NOW - PERIOD[0].midnight) / (PERIOD[1].midnight - PERIOD[0].midnight)) # Determine moon phase 'age' # 0.0 = new moon # 0.25 = first quarter # 0.5 = full moon # 0.75 = last quarter # 1.0 = new moon if PERIOD[0].age < PERIOD[1].age: AGE = (PERIOD[0].age + (PERIOD[1].age - PERIOD[0].age) * RATIO) % 1.0 else: # Handle age wraparound (1.0 -> 0.0) # If tomorrow's age is less than today's, it indicates a new moon # crossover. Add 1 to tomorrow's age when computing age delta. AGE = (PERIOD[0].age + (PERIOD[1].age + 1 - PERIOD[0].age) * RATIO) % 1.0 # AGE can be used for direct lookup to moon bitmap (0 to 99) -- these # images are pre-rendered for a linear timescale (solar terminator moves # nonlinearly across sphere). FRAME = int(AGE * 100) % 100 # Bitmap 0 to 99 # Then use some trig to get percentage lit if AGE <= 0.5: # New -> first quarter -> full PERCENT = (1 - math.cos(AGE * 2 * math.pi)) * 50 else: # Full -> last quarter -> new PERCENT = (1 + math.cos((AGE - 0.5) * 2 * math.pi)) * 50 # Find next rise/set event, complicated by the fact that some 24-hour # periods might not have one or the other (but usually do) due to the # Moon rising ~50 mins later each day. This uses a brute force approach, # working backwards through the time periods to locate rise/set events # that A) exist in that 24-hour period (are not None), B) are still in # the future, and C) are closer than the last guess. What's left at the # end is the next rise or set (and the inverse of the event type tells # us whether Moon's currently risen or not). NEXT_EVENT = PERIOD[1].midnight + 100000 # Force first match for DAY in reversed(PERIOD): if DAY.rise and NEXT_EVENT >= DAY.rise >= NOW: NEXT_EVENT = DAY.rise RISEN = False if DAY.set and NEXT_EVENT >= DAY.set >= NOW: NEXT_EVENT = DAY.set RISEN = True if DISPLAY.rotation in (0, 180): # Horizontal 'landscape' orientation CENTER_X = 48 # Text along right MOON_Y = 0 # Moon at left TIME_Y = 6 # Time at top right EVENT_Y = 26 # Rise/set at bottom right else: # Vertical 'portrait' orientation CENTER_X = 16 # Text down center if RISEN: MOON_Y = 0 # Moon at top EVENT_Y = 38 # Rise/set in middle TIME_Y = 49 # Time/date at bottom else: TIME_Y = 6 # Time/date at top EVENT_Y = 26 # Rise/set in middle MOON_Y = 32 # Moon at bottom print() # Update moon image (GROUP[0]) FILENAME = '/BMPs/32/moon/moon' + '{0:0>2}'.format(FRAME) + '.bmp' BITMAP = displayio.OnDiskBitmap(open(FILENAME, 'rb')) TILE_GRID = displayio.TileGrid( BITMAP, pixel_shader=displayio.ColorConverter(), ) TILE_GRID.x = 0 TILE_GRID.y = MOON_Y GROUP[0] = TILE_GRID # Update percent value (5 labels: GROUP[1-4] for outline, [5] for text) if PERCENT >= 99.95: STRING = '100%' else: STRING = '{:.1f}'.format(PERCENT + 0.05) + '%' print(NOW, STRING, 'full') # Set element 5 first, use its size and position for setting others GROUP[5].text = STRING GROUP[5].x = 16 - GROUP[5].bounding_box[2] // 2 GROUP[5].y = MOON_Y + 16 for _ in range(1, 5): GROUP[_].text = GROUP[5].text GROUP[1].x, GROUP[1].y = GROUP[5].x, GROUP[5].y - 1 # Up 1 pixel GROUP[2].x, GROUP[2].y = GROUP[5].x - 1, GROUP[5].y # Left GROUP[3].x, GROUP[3].y = GROUP[5].x + 1, GROUP[5].y # Right GROUP[4].x, GROUP[4].y = GROUP[5].x, GROUP[5].y + 1 # Down # Update next-event time (GROUP[8] and [9]) # Do this before time because we need uncorrupted NOW value EVENT_TIME = time.localtime(NEXT_EVENT) # Convert to struct for later if COUNTDOWN: # Show NEXT_EVENT as countdown to event NEXT_EVENT -= NOW # Time until (vs time of) next rise/set MINUTES = NEXT_EVENT // 60 STRING = str(MINUTES // 60) + ':' + '{0:0>2}'.format(MINUTES % 60) else: # Show NEXT_EVENT in clock time STRING = hh_mm(EVENT_TIME) GROUP[9].text = STRING XPOS = CENTER_X - (GROUP[9].bounding_box[2] + 6) // 2 GROUP[8].x = XPOS if RISEN: # Next event is SET GROUP[8].text = '\u21A7' # Downwards arrow from bar GROUP[8].y = EVENT_Y - 2 print('Sets:', STRING) else: # Next event is RISE GROUP[8].text = '\u21A5' # Upwards arrow from bar GROUP[8].y = EVENT_Y - 1 print('Rises:', STRING) GROUP[9].x = XPOS + 6 GROUP[9].y = EVENT_Y # Show event time in green if a.m., amber if p.m. GROUP[8].color = GROUP[9].color = (0x00FF00 if EVENT_TIME.tm_hour < 12 else 0xC04000)
except (ConnectionError, ValueError, RuntimeError) as e: print("*** MagTag(), Some error occured, retrying! -", e) # Exit program and restart in 1 seconds. magtag.exit_and_deep_sleep(1) # displayio groups group = displayio.Group(max_size=30) tree_group = displayio.Group(max_size=30) circle_group = displayio.Group(max_size=30) # import tree bitmap tree = displayio.OnDiskBitmap(open("/atree.bmp", "rb")) tree_grid = displayio.TileGrid(tree, pixel_shader=displayio.ColorConverter()) # add bitmap to its group tree_group.append(tree_grid) # add tree group to the main group group.append(tree_group) # list of circle positions spots = ( (246, 53), (246, 75), (206, 42), (206, 64), (206, 86), (176, 31), (176, 53),
def initializeButtons(self): self.icon1Group = displayio.Group() self.icon1Group.x = 20 self.icon1Group.y = 20 # Button colors RED = (255, 0, 0) ORANGE = (255, 34, 0) YELLOW = (255, 170, 0) GREEN = (0, 255, 0) CYAN = (0, 255, 255) BLUE = (0, 0, 255) VIOLET = (153, 0, 255) MAGENTA = (255, 0, 51) PINK = (255, 51, 119) AQUA = (85, 125, 255) WHITE = (255, 255, 255) OFF = (0, 0, 0) self.buttonAttributes = [{ 'label': "1", 'pos': (10, 10), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "2", 'pos': (90, 10), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "3", 'pos': (170, 10), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "4", 'pos': (250, 10), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "5", 'pos': (10, 90), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "6", 'pos': (90, 90), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "7", 'pos': (170, 90), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "8", 'pos': (250, 90), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "9", 'pos': (10, 170), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "10", 'pos': (90, 170), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "11", 'pos': (170, 170), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }, { 'label': "12", 'pos': (250, 170), 'size': (60, 60), 'color': WHITE, 'iconGroup': None }] buttonFont = bitmap_font.load_font('/fonts/Arial-16.bdf') buttonFont.load_glyphs(b'0123456789CFabcdefghijklmnopqrstuvwxyz:') cardBackFile = open('/resources/images/cards/back.bmp', "rb") icon = displayio.OnDiskBitmap(cardBackFile) self.cardBackSprite = displayio.TileGrid( icon, pixel_shader=displayio.ColorConverter(), x=0, y=0) cardFile1 = open('/resources/images/cards/1.bmp', "rb") cardFileIcon1 = displayio.OnDiskBitmap(cardFile1) self.cardSprite1 = displayio.TileGrid( cardFileIcon1, pixel_shader=displayio.ColorConverter(), x=0, y=0) cardFile2 = open('/resources/images/cards/2.bmp', "rb") cardFileIcon2 = displayio.OnDiskBitmap(cardFile2) self.cardSprite2 = displayio.TileGrid( cardFileIcon2, pixel_shader=displayio.ColorConverter(), x=0, y=0) cardFile3 = open('/resources/images/cards/3.bmp', "rb") cardFileIcon3 = displayio.OnDiskBitmap(cardFile3) self.cardSprite3 = displayio.TileGrid( cardFileIcon3, pixel_shader=displayio.ColorConverter(), x=0, y=0) cardFile4 = open('/resources/images/cards/4.bmp', "rb") cardFileIcon4 = displayio.OnDiskBitmap(cardFile4) self.cardSprite4 = displayio.TileGrid( cardFileIcon4, pixel_shader=displayio.ColorConverter(), x=0, y=0) cardFile5 = open('/resources/images/cards/5.bmp', "rb") cardFileIcon5 = displayio.OnDiskBitmap(cardFile5) self.cardSprite5 = displayio.TileGrid( cardFileIcon5, pixel_shader=displayio.ColorConverter(), x=0, y=0) cardFile6 = open('/resources/images/cards/6.bmp', "rb") cardFileIcon6 = displayio.OnDiskBitmap(cardFile6) self.cardSprite6 = displayio.TileGrid( cardFileIcon6, pixel_shader=displayio.ColorConverter(), x=0, y=0) self.cardSprites = [ self.cardSprite1, self.cardSprite2, self.cardSprite3, self.cardSprite4, self.cardSprite5, self.cardSprite6 ] self.buttons = [] for attributes in self.buttonAttributes: button = Button(x=attributes['pos'][0], y=attributes['pos'][1], width=attributes['size'][0], height=attributes['size'][1], style=Button.SHADOWROUNDRECT, fill_color=attributes['color'], outline_color=0x222222, name=attributes['label'], label_font=buttonFont) iconGroup = displayio.Group() iconGroup.x = attributes['pos'][0] iconGroup.y = attributes['pos'][1] iconGroup.append(self.cardBackSprite) attributes['iconGroup'] = iconGroup button.group.append(iconGroup) self.pyportal.splash.append(button.group) self.buttons.append(button) self.pyportal.splash.append(self.icon1Group)
def tick(self, now): global alarm_armed, snooze_time, update_time, current_time # is the snooze button pushed? Cancel the snooze if so. if not snooze_button.value: if snooze_time: self.snooze_icon.pop() snooze_time = None alarm_armed = False # is snooze active and the snooze time has passed? Transition to alram is so. if snooze_time and ((now - snooze_time) >= snooze_interval): change_to_state('alarm') return # check light level and adjust background & backlight #self.adjust_backlight_based_on_light() # only query the online time once per hour (and on first run) if (not self.refresh_time) or ((now - self.refresh_time) > 3600): logger.debug('Fetching time') try: pyportal.get_local_time(location=secrets['timezone']) self.refresh_time = now except RuntimeError as e: self.refresh_time = now - 3000 # delay 10 minutes before retrying logger.error('Some error occured, retrying! - %s', str(e)) # only query the weather every 10 minutes (and on first run) if (not self.weather_refresh) or (now - self.weather_refresh) > 600: logger.debug('Fetching weather') try: value = pyportal.fetch() weather = json.loads(value) # set the icon/background weather_icon_name = weather['weather'][0]['icon'] try: self.weather_icon.pop() except IndexError: pass filename = "/icons/" + weather_icon_name + ".bmp" if filename: # CircuitPython 6 & 7 compatible if self.icon_file: self.icon_file.close() self.icon_file = open(filename, "rb") icon = displayio.OnDiskBitmap(self.icon_file) icon_sprite = displayio.TileGrid( icon, pixel_shader=getattr(icon, 'pixel_shader', displayio.ColorConverter()), x=0, y=0) # # CircuitPython 7+ compatible # icon = displayio.OnDiskBitmap(filename) # icon_sprite = displayio.TileGrid(icon, pixel_shader=icon.pixel_shader) self.weather_icon.append(icon_sprite) temperature = weather['main'][ 'temp'] - 273.15 # its...in kelvin if celcius: temperature_text = '%3d C' % round(temperature) else: temperature_text = '%3d F' % round( ((temperature * 9 / 5) + 32)) self.text_areas[2].text = temperature_text self.weather_refresh = now try: board.DISPLAY.refresh(target_frames_per_second=60) except AttributeError: board.DISPLAY.refresh_soon() board.DISPLAY.wait_for_frame() except RuntimeError as e: self.weather_refresh = now - 540 # delay a minute before retrying logger.error("Some error occured, retrying! - %s", str(e)) if (not update_time) or ((now - update_time) > 30): # Update the time update_time = now current_time = time.localtime() time_string = '%02d:%02d' % (current_time.tm_hour, current_time.tm_min) self.text_areas[0].text = time_string try: board.DISPLAY.refresh(target_frames_per_second=60) except AttributeError: board.DISPLAY.refresh_soon() board.DISPLAY.wait_for_frame() # Check if alarm should sound if current_time is not None and not snooze_time: minutes_now = current_time.tm_hour * 60 + current_time.tm_min minutes_alarm = alarm_hour * 60 + alarm_minute if minutes_now == minutes_alarm: if alarm_armed: change_to_state('alarm') else: alarm_armed = alarm_enabled
def show_business_card(self, *, image_name=None, name_string=None, name_scale=1, name_font=terminalio.FONT, font_color=0xFFFFFF, font_background_color=None, email_string_one=None, email_scale_one=1, email_font_one=terminalio.FONT, email_string_two=None, email_scale_two=1, email_font_two=terminalio.FONT): """Display a bitmap image and a text string, such as a personal image and email address. :param str image_name: REQUIRED. The name of the bitmap image including .bmp, e.g. ``"Blinka.bmp"``. :param str name_string: A name string to display along the bottom of the display, e.g. ``"Blinka"``. :param int name_scale: The scale of ``name_string``. Defaults to 1. :param name_font: The font for the name string. Defaults to ``terminalio.FONT``. :param str email_string_one: A string to display along the bottom of the display, e.g. ``"*****@*****.**"``. :param int email_scale_one: The scale of ``email_string_one``. Defaults to 1. :param email_font_one: The font for the first email string. Defaults to ``terminalio.FONT``. :param str email_string_two: A second string to display along the bottom of the display. Use if your email address is longer than one line or to add more space between the name and email address, e.g. (blinka@) ``"adafruit.com"``. :param int email_scale_two: The scale of ``email_string_two``. Defaults to 1. :param email_font_two: The font for the second email string. Defaults to ``terminalio.FONT``. .. code-block:: python from adafruit_pybadger import pybadger while True: pybadger.show_business_card(image_name="Blinka.bmp", name_string="Blinka", name_scale=2, email_string_one="blinka@", email_string_two="adafruit.com") """ business_card_label_groups = [] if name_string: name_group = self._create_label_group( text=name_string, font=name_font, color=font_color, scale=name_scale, height_adjustment=0.73, background_color=font_background_color, ) business_card_label_groups.append(name_group) if email_string_one: email_one_group = self._create_label_group( text=email_string_one, font=email_font_one, color=font_color, scale=email_scale_one, height_adjustment=0.84, background_color=font_background_color, ) business_card_label_groups.append(email_one_group) if email_string_two: email_two_group = self._create_label_group( text=email_string_two, font=email_font_two, color=font_color, scale=email_scale_two, height_adjustment=0.91, background_color=font_background_color, ) business_card_label_groups.append(email_two_group) business_card_splash = displayio.Group() self.display.show(business_card_splash) with open(image_name, "rb") as file_name: on_disk_bitmap = displayio.OnDiskBitmap(file_name) face_image = displayio.TileGrid( on_disk_bitmap, pixel_shader=getattr(on_disk_bitmap, "pixel_shader", displayio.ColorConverter()), # TODO: Once CP6 is no longer supported, replace the above line with below # pixel_shader=on_disk_bitmap.pixel_shader, ) business_card_splash.append(face_image) for group in business_card_label_groups: business_card_splash.append(group) self.display.refresh()
def show_business_card( self, *, image_name=None, name_string=None, name_scale=1, name_font=terminalio.FONT, email_string_one=None, email_scale_one=1, email_font_one=terminalio.FONT, email_string_two=None, email_scale_two=1, email_font_two=terminalio.FONT ): """Display a bitmap image and a text string, such as a personal image and email address. :param str image_name: REQUIRED. The name of the bitmap image including .bmp, e.g. ``"Blinka.bmp"``. :param str name_string: A name string to display along the bottom of the display, e.g. ``"Blinka"``. :param int name_scale: The scale of ``name_string``. Defaults to 1. :param name_font: The font for the name string. Defaults to ``terminalio.FONT``. :param str email_string_one: A string to display along the bottom of the display, e.g. ``"*****@*****.**"``. :param int email_scale_one: The scale of ``email_string_one``. Defaults to 1. :param email_font_one: The font for the first email string. Defaults to ``terminalio.FONT``. :param str email_string_two: A second string to display along the bottom of the display. Use if your email address is longer than one line or to add more space between the name and email address, e.g. (blinka@) ``"adafruit.com"``. :param int email_scale_two: The scale of ``email_string_two``. Defaults to 1. :param email_font_two: The font for the second email string. Defaults to ``terminalio.FONT``. .. code-block:: python from adafruit_pybadger import pybadger while True: pybadger.show_business_card(image_name="Blinka.bmp", name_string="Blinka", name_scale=2, email_string_one="blinka@", email_string_two="adafruit.com") """ business_card_label_groups = [] if name_string: name_group = self._create_label_group( text=name_string, font=name_font, scale=name_scale, height_adjustment=0.73, ) business_card_label_groups.append(name_group) if email_string_one: email_one_group = self._create_label_group( text=email_string_one, font=email_font_one, scale=email_scale_one, height_adjustment=0.84, ) business_card_label_groups.append(email_one_group) if email_string_two: email_two_group = self._create_label_group( text=email_string_two, font=email_font_two, scale=email_scale_two, height_adjustment=0.91, ) business_card_label_groups.append(email_two_group) business_card_splash = displayio.Group(max_size=4) self.display.show(business_card_splash) with open(image_name, "rb") as file_name: on_disk_bitmap = displayio.OnDiskBitmap(file_name) face_image = displayio.TileGrid( on_disk_bitmap, pixel_shader=displayio.ColorConverter() ) business_card_splash.append(face_image) for group in business_card_label_groups: business_card_splash.append(group) try: # Refresh display in CircuitPython 5 self.display.refresh() except AttributeError: # Refresh display in CircuitPython 4 self.display.wait_for_frame()
def load_map(mapname, x=0, y=0): f = open("/maps/" + mapname + "/" + mapname + ".bmp", "rb") odb = displayio.OnDiskBitmap(f) tg=displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter(), position=(0,0)) tg.position=(x,y) return tg
def wrap_in_tilegrid(filename: str): # CircuitPython 6 & 7 compatible odb = displayio.OnDiskBitmap(open(filename, "rb")) return displayio.TileGrid(odb, pixel_shader=getattr(odb, 'pixel_shader', displayio.ColorConverter()))
def update_display(data, tz_offset, t0, t1, t2): date = time.localtime(data["dt"]) sunrise = time.localtime(data["sunrise"] + tz_offset) sunset = time.localtime(data["sunset"] + tz_offset) group = displayio.Group(max_size=19) tile_grid = displayio.TileGrid(bitmap, pixel_shader=displayio.ColorConverter(), x=0, y=0) group.append(tile_grid) today_date = label.Label(font, text="?" * 30, color=COLOR_DATE) today_date.anchor_point = (0, 0) today_date.anchored_position = (30, 50) today_date.text = "{} {} {}, {}".format( DAYS[date.tm_wday].upper(), MONTHS[date.tm_mon - 1].upper(), date.tm_mday, date.tm_year, ) group.append(today_date) city_name = label.Label(font, text=secrets["openweather_location"], color=COLOR_CITY) city_name.anchor_point = (0, 0) city_name.anchored_position = (30, 100) group.append(city_name) today_icon = displayio.TileGrid( icons_large_bmp, pixel_shader=icons_large_pal, x=30, y=150, width=1, height=1, tile_width=70, tile_height=70, ) if (data is not None): today_icon[0] = ICON_MAP.index(data["weather"][0]["icon"][:2]) group.append(today_icon) td_y_pos = 180 td_x_pos = 155 td_x_pos_add = 55 today_morn_temp = label.Label(font, text="+100F", color=COLOR_TODAY_TEMPS) today_morn_temp.anchor_point = (0.5, 0) today_morn_temp.anchored_position = (td_x_pos, td_y_pos) if (data is not None): today_morn_temp.text = temperature_text(data["temp"]["morn"]) group.append(today_morn_temp) today_day_temp = label.Label(font, text="+100F", color=COLOR_TODAY_TEMPS) today_day_temp.anchor_point = (0.5, 0) today_day_temp.anchored_position = (td_x_pos + td_x_pos_add, td_y_pos) if (data is not None): today_day_temp.text = temperature_text(data["temp"]["day"]) group.append(today_day_temp) today_night_temp = label.Label(font, text="+100F", color=COLOR_TODAY_TEMPS) today_night_temp.anchor_point = (0.5, 0) today_night_temp.anchored_position = (td_x_pos + td_x_pos_add + td_x_pos_add, td_y_pos) if (data is not None): today_night_temp.text = temperature_text(data["temp"]["night"]) group.append(today_night_temp) td2_x_pos = 160 td2_y_pos = 240 td2_x_pos_add = 70 today_humidity = label.Label(font, text="100%", color=COLOR_TODAY_DATA) today_humidity.anchor_point = (0, 0.5) today_humidity.anchored_position = (td2_x_pos, td2_y_pos) if (data is not None): today_humidity.text = "{:3d} %".format(data["humidity"]) group.append(today_humidity) today_wind = label.Label(font, text="99m/s", color=COLOR_TODAY_DATA) today_wind.anchor_point = (0, 0.5) today_wind.anchored_position = (td2_x_pos + td2_x_pos_add, td2_y_pos) if (data is not None): today_wind.text = wind_text(data["wind_speed"]) group.append(today_wind) sun_x_pos = 70 sun_y_pos = 280 sun_y_pos_add = 120 today_sunrise = label.Label(font, text="12:12 PM", color=COLOR_SUN_TIMES) today_sunrise.anchor_point = (0, 0.5) today_sunrise.anchored_position = (sun_x_pos, sun_y_pos) today_sunrise.text = "{:2d}:{:02d} AM".format(sunrise.tm_hour, sunrise.tm_min) group.append(today_sunrise) today_sunset = label.Label(font, text="12:12 PM", color=COLOR_SUN_TIMES) today_sunset.anchor_point = (0, 0.5) today_sunset.anchored_position = (sun_x_pos + sun_y_pos_add, sun_y_pos) today_sunset.text = "{:2d}:{:02d} PM".format(sunset.tm_hour - 12, sunset.tm_min) group.append(today_sunset) X_POS = 335 Y_POS = 25 Y_POS_OFFSET = 30 for day, forecast in enumerate(forecast_data[1:6]): day_of_week = label.Label(font, text="DAY", color=COLOR_DAYS) day_of_week.anchor_point = (0, 0.5) day_of_week.anchored_position = (0, 14) icon = displayio.TileGrid( icons_small_bmp, pixel_shader=icons_small_pal, x=48, y=4, width=1, height=1, tile_width=20, tile_height=20, ) day_temp = label.Label(font, text="+100F", color=COLOR_TEMPS) day_temp.anchor_point = (0, 0.5) day_temp.anchored_position = (75, 14) if (forecast is not None): day_of_week.text = DAYS[time.localtime( forecast["dt"]).tm_wday][:3].upper() icon[0] = ICON_MAP.index(forecast["weather"][0]["icon"][:2]) day_temp.text = temperature_text(forecast["temp"]["day"]) group2 = displayio.Group(max_size=3, x=X_POS, y=Y_POS + (Y_POS_OFFSET * day)) group2.append(day_of_week) group2.append(icon) group2.append(day_temp) group.append(group2) FEED_X_POS = 390 FEED_Y_POS = 225 FEED_Y_POS_OFFSET = 30 feed0_label = label.Label(font, text="+100F", color=COLOR_FEED_DATA) feed0_label.anchor_point = (0, 0.5) feed0_label.anchored_position = (FEED_X_POS, FEED_Y_POS) if (t0 is not None): feed0_label.text = t0 + " F" group.append(feed0_label) feed1_label = label.Label(font, text="+100F", color=COLOR_FEED_DATA) feed1_label.anchor_point = (0, 0.5) feed1_label.anchored_position = (FEED_X_POS, FEED_Y_POS + FEED_Y_POS_OFFSET) if (t1 is not None): feed1_label.text = t1 + " F" group.append(feed1_label) feed2_label = label.Label(font, text="+100F", color=COLOR_FEED_DATA) feed2_label.anchor_point = (0, 0.5) feed2_label.anchored_position = (FEED_X_POS, FEED_Y_POS + FEED_Y_POS_OFFSET + FEED_Y_POS_OFFSET) if (t2 is not None): feed2_label.text = t2 + " F" group.append(feed2_label) board.DISPLAY.show(group)
# Set up accelerometer on I2C bus, 4G range: ACCEL = adafruit_lis3dh.LIS3DH_I2C(board.I2C(), address=0x18) ACCEL.range = adafruit_lis3dh.RANGE_4_G while True: shaken = False with open(images[i], "rb") as f: print("Image load {}".format(images[i])) try: odb = displayio.OnDiskBitmap(f) except ValueError: print("Image unsupported {}".format(images[i])) del images[i] continue face = displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter()) splash.append(face) # Wait for the image to load. board.DISPLAY.wait_for_frame() # Fade up the backlight for b in range(101): board.DISPLAY.brightness = b / 100 time.sleep(0.01) # default (0.01) # Wait until the board gets shaken while not shaken: try: ACCEL_Z = ACCEL.acceleration[2] # Read Z axis acceleration except OSError:
ACCEL.range = adafruit_lis3dh.RANGE_4_G while True: shaken = False print("Image load {}".format(images[i])) # CircuitPython 6 & 7 compatible try: f = open(images[i], "rb") odb = displayio.OnDiskBitmap(f) except ValueError: print("Image unsupported {}".format(images[i])) del images[i] continue face = displayio.TileGrid(odb, pixel_shader=getattr(odb, 'pixel_shader', displayio.ColorConverter())) # # CircuitPython 7+ compatible # try: # odb = displayio.OnDiskBitmap(images[i]) # except ValueError: # print("Image unsupported {}".format(images[i])) # del images[i] # continue # face = displayio.TileGrid(odb, pixel_shader=odb.pixel_shader) splash.append(face) # Wait for the image to load. try: board.DISPLAY.refresh(target_frames_per_second=60) except AttributeError:
magtag.exit_and_deep_sleep(1) # displayio groups group = displayio.Group() tree_group = displayio.Group() circle_group = displayio.Group() # import tree bitmap filename = "/atree.bmp" # CircuitPython 6 & 7 compatible tree = displayio.OnDiskBitmap(open(filename, "rb")) tree_grid = displayio.TileGrid( tree, pixel_shader=getattr(tree, 'pixel_shader', displayio.ColorConverter()) ) # # CircuitPython 7+ compatible # tree = displayio.OnDiskBitmap(filename) # tree_grid = displayio.TileGrid(tree, pixel_shader=tree.pixel_shader) # add bitmap to its group tree_group.append(tree_grid) # add tree group to the main group group.append(tree_group) # list of circle positions spots = ( (246, 53), (246, 75),
def __init__(self, display, *, am_pm=True, units="imperial"): super().__init__() self.am_pm = am_pm if units == "metric": self.celsius = True self.meters_speed = True else: self.celsius = False self.meters_speed = False self.display = display splash = displayio.Group() # CircuitPython 6 & 7 compatible background = displayio.OnDiskBitmap(open("loading.bmp", "rb")) bg_sprite = displayio.TileGrid( background, pixel_shader=getattr(background, 'pixel_shader', displayio.ColorConverter()), ) # # CircuitPython 7+ compatible # background = displayio.OnDiskBitmap("loading.bmp") # bg_sprite = displayio.TileGrid(background, pixel_shader=background.pixel_shader) splash.append(bg_sprite) display.show(splash) self.root_group = displayio.Group() self.root_group.append(self) self._icon_group = displayio.Group() self.append(self._icon_group) self._text_group = displayio.Group() self.append(self._text_group) self._scrolling_group = displayio.Group() self.append(self._scrolling_group) # The label index we're currently scrolling self._current_label = None # Load the icon sprite sheet # CircuitPython 6 & 7 compatible icons = displayio.OnDiskBitmap(open(icon_spritesheet, "rb")) self._icon_sprite = displayio.TileGrid(icons, pixel_shader=getattr( icons, 'pixel_shader', displayio.ColorConverter()), tile_width=icon_width, tile_height=icon_height) # # CircuitPython 7+ compatible # icons = displayio.OnDiskBitmap(icon_spritesheet) # self._icon_sprite = displayio.TileGrid( # icons, # pixel_shader=icons.pixel_shader, # tile_width=icon_width, # tile_height=icon_height # ) self.set_icon(None) self._scrolling_texts = [] self.small_font = bitmap_font.load_font(small_font) self.medium_font = bitmap_font.load_font(medium_font) glyphs = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,.: " self.small_font.load_glyphs(glyphs) self.medium_font.load_glyphs(glyphs) self.medium_font.load_glyphs( ("°", )) # a non-ascii character we need for sure self.city_text = None self.temp_text = Label(self.medium_font) self.temp_text.x = 20 self.temp_text.y = 7 self.temp_text.color = TEMP_COLOR self._text_group.append(self.temp_text) self.description_text = Label(self.small_font) self.description_text.color = DESCRIPTION_COLOR self._scrolling_texts.append(self.description_text) self.humidity_text = Label(self.small_font) self.humidity_text.color = HUMIDITY_COLOR # self._scrolling_texts.append(self.humidity_text) self.wind_text = Label(self.small_font) self.wind_text.color = WIND_COLOR self._scrolling_texts.append(self.wind_text)
#set up variables for "remembering" past readings reading1 = reading reading2 = reading1 reading3 = reading2 counter = 0 toggle = 1 # for on/off switch on button A displayOn = 1 # to turn the display on and off with button B clue.display.brightness = 0.8 clue_display = displayio.Group(max_size=4) # draw the rising image rising_file = open("rising.bmp", "rb") rising_bmp = displayio.OnDiskBitmap(rising_file) rising_sprite = displayio.TileGrid(rising_bmp, pixel_shader=displayio.ColorConverter()) clue_display.append(rising_sprite) # draw the sinking image sinking_file = open("sinking.bmp", "rb") sinking_bmp = displayio.OnDiskBitmap(sinking_file) sinking_sprite = displayio.TileGrid(sinking_bmp, pixel_shader=displayio.ColorConverter()) clue_display.append(sinking_sprite) # Create text # first create the group text_group = displayio.Group(max_size=5, scale=1) # Make a label reading_font = bitmap_font.load_font("/font/RacingSansOne-Regular-29.bdf") reading_font.load_glyphs(
def tick(self, now): global alarm_armed, snooze_time, update_time # is the snooze button pushed? Cancel the snooze if so. if not snooze_button.value: if snooze_time: self.snooze_icon.pop() snooze_time = None alarm_armed = False # is snooze active and the snooze time has passed? Transition to alram is so. if snooze_time and ((now - snooze_time) >= snooze_interval): change_to_state('alarm') return # check light level and adjust background & backlight #self.adjust_backlight_based_on_light() # only query the online time once per hour (and on first run) if (not self.refresh_time) or ((now - self.refresh_time) > 3600): try: pyportal.get_local_time(location=secrets['timezone']) self.refresh_time = now except RuntimeError as e: print('Some error occured, retrying! -', e) # only query the weather every 10 minutes (and on first run) if (not self.weather_refresh) or (now - self.weather_refresh) > 600: try: value = pyportal.fetch() weather = json.loads(value) # set the icon/background weather_icon_name = weather['weather'][0]['icon'] try: self.weather_icon.pop() except IndexError: pass filename = "/icons/" + weather_icon_name + ".bmp" if filename: if self.icon_file: self.icon_file.close() self.icon_file = open(filename, "rb") icon = displayio.OnDiskBitmap(self.icon_file) icon_sprite = displayio.TileGrid( icon, pixel_shader=displayio.ColorConverter(), position=(0, 0)) self.weather_icon.append(icon_sprite) temperature = weather['main'][ 'temp'] - 273.15 # its...in kelvin if celcius: temperature_text = '%3d C' % round(temperature) else: temperature_text = '%3d F' % round( ((temperature * 9 / 5) + 32)) self.text_areas[2].text = temperature_text self.weather_refresh = now board.DISPLAY.refresh_soon() board.DISPLAY.wait_for_frame() except RuntimeError as e: print("Some error occured, retrying! -", e) if (not update_time) or ((now - update_time) > 30): # Update the time update_time = now the_time = time.localtime() self.text_areas[0].text = '%02d:%02d' % ( the_time.tm_hour, the_time.tm_min) # set time textarea board.DISPLAY.refresh_soon() board.DISPLAY.wait_for_frame() # Check if alarm should sound if not snooze_time: minutes_now = the_time.tm_hour * 60 + the_time.tm_min minutes_alarm = alarm_hour * 60 + alarm_minute if minutes_now == minutes_alarm: if alarm_armed: change_to_state('alarm') else: alarm_armed = alarm_enabled
display = board.DISPLAY # the alarm sound file locations alarm_sound_trash = "/sounds/trash.wav" alarm_sound_bed = "/sounds/sleep.wav" alarm_sound_eat = "/sounds/eat.wav" # the alarm sounds in an array that matches the order of the gfx & alarm check-ins alarm_sounds = [alarm_sound_trash, alarm_sound_bed, alarm_sound_eat, alarm_sound_eat, alarm_sound_eat] # setting up the bitmaps for the alarms # sleep alarm sleep_bitmap = displayio.OnDiskBitmap(open("/sleepBMP.bmp", "rb")) sleep_tilegrid = displayio.TileGrid(sleep_bitmap, pixel_shader=getattr(sleep_bitmap, 'pixel_shader', displayio.ColorConverter())) group_bed = displayio.Group() group_bed.append(sleep_tilegrid) # trash alarm trash_bitmap = displayio.OnDiskBitmap(open("/trashBMP.bmp", "rb")) trash_tilegrid = displayio.TileGrid(trash_bitmap, pixel_shader=getattr(trash_bitmap, 'pixel_shader', displayio.ColorConverter())) group_trash = displayio.Group() group_trash.append(trash_tilegrid) # meal alarm eat_bitmap = displayio.OnDiskBitmap(open("/eatBMP.bmp", "rb")) eat_tilegrid = displayio.TileGrid(eat_bitmap, pixel_shader=getattr(eat_bitmap, 'pixel_shader', displayio.ColorConverter())) group_eat = displayio.Group() group_eat.append(eat_tilegrid)
# SPDX-License-Identifier: MIT import time import displayio from adafruit_gizmo import eink_gizmo display = eink_gizmo.EInk_Gizmo() # Use the below line instead for the 200x200 E-Ink Gizmo # display = eink_gizmo.EInk_HD_Gizmo() # Create a display group for our screen objects display_group = displayio.Group() # Display a ruler graphic from the root directory of the CIRCUITPY drive file = open("/display-ruler.bmp", "rb") picture = displayio.OnDiskBitmap(file) # Create a Tilegrid with the bitmap and put in the displayio group sprite = displayio.TileGrid(picture, pixel_shader=displayio.ColorConverter()) display_group.append(sprite) # Place the display group on the screen display.show(display_group) # Refresh the display to have it actually show the image # NOTE: Do not refresh eInk displays sooner than 180 seconds display.refresh() print("refreshed") time.sleep(180)
moist_level = 50 # adjust this value as needed for your plant board.DISPLAY.brightness = 0.8 clue.pixel.fill(0) # turn off NeoPixel clue_display = displayio.Group() # draw the dry plant dry_plant_file = open("dry.bmp", "rb") dry_plant_bmp = displayio.OnDiskBitmap(dry_plant_file) # CircuitPython 6 & 7 compatible dry_plant_sprite = displayio.TileGrid( dry_plant_bmp, pixel_shader=getattr(dry_plant_bmp, "pixel_shader", displayio.ColorConverter()), ) # CircuitPython 7 compatible # dry_plant_sprite = displayio.TileGrid( # dry_plant_bmp, pixel_shader=dry_plant_bmp.pixel_shader # ) clue_display.append(dry_plant_sprite) # draw the happy plant on top (so it can be moved out of the way when needed) happy_plant_file = open("happy.bmp", "rb") happy_plant_bmp = displayio.OnDiskBitmap(happy_plant_file) # CircuitPython 6 & 7 compatible happy_plant_sprite = displayio.TileGrid( happy_plant_bmp, pixel_shader=getattr(happy_plant_bmp, "pixel_shader", displayio.ColorConverter()),
LARGE_FONT.load_glyphs('0123456789:') SMALL_FONT.load_glyphs('0123456789:/.%') # Display group is set up once, then we just shuffle items around later. # Order of creation here determines their stacking order. GROUP = displayio.Group(max_size=10) # sets empty_group for night mode empty_group = displayio.Group() # Element 0 is a stand-in item, later replaced with the garbage can bitmap # pylint: disable=bare-except try: FILENAME = 'bmps/garbage-start-' + str(DISPLAY.rotation) + '.bmp' BITMAP = displayio.OnDiskBitmap(open(FILENAME, 'rb')) TILE_GRID = displayio.TileGrid(BITMAP, pixel_shader=displayio.ColorConverter(),) GROUP.append(TILE_GRID) except: GROUP.append(adafruit_display_text.label.Label(SMALL_FONT, color=0xFF0000, text='OOPS')) GROUP[0].x = (DISPLAY.width - GROUP[0].bounding_box[2] + 1) // 2 GROUP[0].y = DISPLAY.height // 2 - 1 # Elements 1-4 are an outline around the moon percentage -- text labels # offset by 1 pixel up/down/left/right. Initial position is off the matrix, # updated on first refresh. Initial text value must be long enough for # longest anticipated string later. for i in range(4): GROUP.append(adafruit_display_text.label.Label(SMALL_FONT, color=0, text='99.9%', y=-99)) # Element 5 is days until garbage out (on top of the outline labels) GROUP.append(adafruit_display_text.label.Label(SMALL_FONT, color=0xFFFF00,