def update_display(): # clear out existing icons while len(storm_icons): _ = storm_icons.pop() # get latest storm data try: storm_data = pyportal.fetch() except RuntimeError: return print("Number of storms:", len(storm_data)) # parse the storm data for storm in storm_data: # don't exceed max if len(storm_icons) >= MAX_STORMS: continue # get lat/lon lat = storm["latitudeNumeric"] lon = storm["longitudeNumeric"] # check if on map if (not LAT_RANGE[0] >= lat >= LAT_RANGE[1] or not LON_RANGE[0] <= lon <= LON_RANGE[1]): continue # OK, let's make a group for all the graphics storm_gfx = displayio.Group(max_size=3) # icon + label + arrow # convert to sreen coords x = int( map_range(lon, LON_RANGE[0], LON_RANGE[1], 0, board.DISPLAY.width - 1)) y = math.radians(lat) y = math.tan(math.pi / 4 + y / 2) y = math.log(y) y = (VIRTUAL_WIDTH * y) / (2 * math.pi) y = VIRTUAL_HEIGHT / 2 - y y = int(y - Y_OFFSET) # icon type if storm["classification"] in STORM_CLASS: storm_type = STORM_CLASS.index(storm["classification"]) else: storm_type = 0 # create storm icon icon = displayio.TileGrid( icons_bmp, pixel_shader=icons_pal, width=1, height=1, tile_width=16, tile_height=16, default_tile=storm_type, x=x - 8, y=y - 8, ) # add storm icon storm_gfx.append(icon) # add a label name = Label( terminalio.FONT, text=storm["name"], color=NAME_COLOR, background_color=NAME_BG_COLOR, ) name.anchor_point = (0.0, 1.0) name.anchored_position = (x + 8, y - 8) storm_gfx.append(name) # add direction arrow angle = math.radians(storm["movementDir"]) xd = x + int(ARROW_LENGTH * math.sin(angle)) yd = y - int(ARROW_LENGTH * math.cos(angle)) arrow = Line(x, y, xd, yd, color=ARROW_COLOR) storm_gfx.append(arrow) # add the storm graphics storm_icons.append(storm_gfx) # update time info_update.text = storm["lastUpdate"] # debug print("{} @ {},{}".format(storm["name"], storm["latitudeNumeric"], storm["longitudeNumeric"])) # no storms? at least say something if not len(storm_icons): print("No storms in map area.") storm_icons.append( Label( terminalio.FONT, scale=4, x=50, y=110, text="NO STORMS\n IN AREA", color=NAME_COLOR, background_color=NAME_BG_COLOR, ))
palette=displayio.Palette) for i, c in enumerate(icons_pal): if c == 0xFFFF00: icons_pal.make_transparent(i) storm_icons = displayio.Group(max_size=MAX_STORMS) pyportal.splash.append(storm_icons) STORM_CLASS = ("TD", "TS", "HU") # setup info label info_update = Label( terminalio.FONT, text="1984-01-01T00:00:00.000Z", color=NAME_COLOR, background_color=NAME_BG_COLOR, ) info_update.anchor_point = (0.0, 1.0) info_update.anchored_position = (10, board.DISPLAY.height - 10) pyportal.splash.append(info_update) # these are need for lat/lon to screen x/y mapping VIRTUAL_WIDTH = board.DISPLAY.width * 360 / (LON_RANGE[1] - LON_RANGE[0]) VIRTUAL_HEIGHT = board.DISPLAY.height * 360 / (LAT_RANGE[0] - LAT_RANGE[1]) Y_OFFSET = math.radians(LAT_RANGE[0]) Y_OFFSET = math.tan(math.pi / 4 + Y_OFFSET / 2) Y_OFFSET = math.log(Y_OFFSET) Y_OFFSET = (VIRTUAL_WIDTH * Y_OFFSET) / (2 * math.pi) Y_OFFSET = VIRTUAL_HEIGHT / 2 - Y_OFFSET def update_display(): # clear out existing icons
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) # Populate list of NextBus objects from STOPS[] and generate initial text # labels (these get positioned in a second pass later)... STOP_LIST = [] MAX_SIZE = (0, 0) # Pixel dimensions of largest route number for stop in STOPS: STOP_LIST.append( NextBus(NETWORK, stop[0], stop[1], stop[2], None, MAX_PREDICTIONS, MINIMUM_TIME)) TEXT = Label(FONT_LARGE, text=stop[1], color=0) # Keep track of the largest route label for positioning things later MAX_SIZE = (max(TEXT.width, MAX_SIZE[0]), max(TEXT.height, MAX_SIZE[1])) TEXT.anchor_point = (1.0, 1.0) # Bottom-right align route
display = board.DISPLAY scale_group = displayio.Group() FONT_0 = bitmap_font.load_font("/fonts/Helvetica-Bold-24.bdf") FONT_1 = bitmap_font.load_font("/fonts/OpenSans-16.bdf") FONT_2 = bitmap_font.load_font("/fonts/OpenSans-9.bdf") # Define displayio background and group elements print("*** Define displayio background and group elements") bkg = displayio.OnDiskBitmap("/clue_scale_dual_chan_bkg.bmp") _background = displayio.TileGrid(bkg, pixel_shader=bkg.pixel_shader, x=0, y=0) scale_group.append(_background) chan_1_label = Label(FONT_1, text=CHAN_1_LABEL, color=clue.CYAN) chan_1_label.anchor_point = (0.5, 0.5) chan_1_label.anchored_position = (40, 96) scale_group.append(chan_1_label) chan_2_label = Label(FONT_1, text=CHAN_2_LABEL, color=clue.CYAN) chan_2_label.anchor_point = (0.5, 0.5) chan_2_label.anchored_position = (199, 96) scale_group.append(chan_2_label) zero_1_button_label = Label(FONT_1, text="Z", color=clue.RED) zero_1_button_label.x = 8 zero_1_button_label.y = 150 scale_group.append(zero_1_button_label) zero_2_button_label = Label(FONT_1, text="Z", color=clue.RED) zero_2_button_label.x = 219
cell_x = (col * CELL_SIZE) + GRID_X_OFFSET cell_y = row * CELL_SIZE cell = Rect( x=cell_x, y=cell_y, width=CELL_SIZE, height=CELL_SIZE, fill=None, outline=None, stroke=0, ) image_group.append(cell) # Define labels and values status_label = Label(font_0, text="", color=None) status_label.anchor_point = (0.5, 0.5) status_label.anchored_position = ((WIDTH // 2) + (GRID_X_OFFSET // 2), HEIGHT // 2) image_group.append(status_label) # image_group[225] alarm_label = Label(font_0, text="alm", color=WHITE) alarm_label.anchor_point = (0, 0) alarm_label.anchored_position = (1, 16) image_group.append(alarm_label) # image_group[226] max_label = Label(font_0, text="max", color=RED) max_label.anchor_point = (0, 0) max_label.anchored_position = (1, 46) image_group.append(max_label) # image_group[227] min_label = Label(font_0, text="min", color=CYAN) min_label.anchor_point = (0, 0)
size=(display.width, display.height), disp_rotation=display.rotation, touch_flip=_touch_flip, ) # Define the graphic objects if REPL_ONLY = False. if not REPL_ONLY: # Define the text graphic objects font_0 = terminalio.FONT coordinates = Label( font=font_0, text="calib: ((x_min, x_max), (y_min, y_max))", color=WHITE, ) coordinates.anchor_point = (0.5, 0.5) coordinates.anchored_position = (display.width // 2, display.height // 4) display_rotation = Label( font=font_0, text="rotation: " + str(display.rotation), color=WHITE, ) display_rotation.anchor_point = (0.5, 0.5) display_rotation.anchored_position = (display.width // 2, display.height // 4 - 30) # Define graphic objects for the screen fill, boundary, and touch pen. target_palette = displayio.Palette(1) target_palette[0] = BLUE_DK screen_fill = vectorio.Rectangle( pixel_shader=target_palette,