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,
            ))
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
    while len(storm_icons):
    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
    GROUP.append(TEXT)
Beispiel #4
0
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
zero_2_button_label.y = 150
        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)
min_label.anchored_position = (1, 106)
        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,
        x=2,