|
| 1 | +# SPDX-FileCopyrightText: 2024 Liz Clark for Adafruit Industries |
| 2 | +# |
| 3 | +# SPDX-License-Identifier: MIT |
| 4 | + |
| 5 | +import os |
| 6 | +import ssl |
| 7 | +import time |
| 8 | +import microcontroller |
| 9 | +import wifi |
| 10 | +import socketpool |
| 11 | +import adafruit_requests |
| 12 | +import board |
| 13 | +import displayio |
| 14 | +import keypad |
| 15 | +from adafruit_ticks import ticks_ms, ticks_add, ticks_diff |
| 16 | +from adafruit_display_text import outlined_label |
| 17 | +from adafruit_bitmap_font import bitmap_font |
| 18 | +from adafruit_qualia.graphics import Graphics, Displays |
| 19 | + |
| 20 | +urls = [{'name': "Epcot", |
| 21 | + 'url': "https://queue-times.com/en-US/parks/5/queue_times.json"}, |
| 22 | + {'name': "Magic Kingdom", |
| 23 | + 'url': "https://queue-times.com/en-US/parks/6/queue_times.json"}, |
| 24 | + {'name': "Hollywood Studios", |
| 25 | + 'url': "https://queue-times.com/en-US/parks/7/queue_times.json"}, |
| 26 | + {'name': "Animal Kingdom", |
| 27 | + 'url': "https://queue-times.com/en-US/parks/8/queue_times.json"}, |
| 28 | + ] |
| 29 | +bitmap = displayio.OnDiskBitmap("/park-bg.bmp") |
| 30 | + |
| 31 | +key = keypad.Keys((board.A0,), value_when_pressed=False, pull=True) |
| 32 | + |
| 33 | +wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD")) |
| 34 | +print(f"Connected to {os.getenv('CIRCUITPY_WIFI_SSID')}") |
| 35 | + |
| 36 | +context = ssl.create_default_context() |
| 37 | +pool = socketpool.SocketPool(wifi.radio) |
| 38 | +requests = adafruit_requests.Session(pool, context) |
| 39 | + |
| 40 | +graphics = Graphics(Displays.ROUND40, default_bg=None, auto_refresh=True) |
| 41 | + |
| 42 | +grid = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader) |
| 43 | +group = displayio.Group() |
| 44 | +group.append(grid) |
| 45 | + |
| 46 | +font = bitmap_font.load_font("/Roboto-Regular-47.pcf") |
| 47 | +ride_text = [] |
| 48 | +wait_text = [] |
| 49 | +for i in range(5): |
| 50 | + text_ride = outlined_label.OutlinedLabel(font, text=" ", |
| 51 | + outline_color=0x000000, |
| 52 | + outline_size=3, |
| 53 | + padding_left=4, |
| 54 | + padding_right=4, |
| 55 | + padding_top=4, |
| 56 | + padding_bottom=4) |
| 57 | + ride_text.append(text_ride) |
| 58 | + text_wait = outlined_label.OutlinedLabel(font, text=" ", |
| 59 | + outline_color=0x000000, |
| 60 | + outline_size=3, |
| 61 | + padding_left=4, |
| 62 | + padding_right=4, |
| 63 | + padding_top=4, |
| 64 | + padding_bottom=4) |
| 65 | + wait_text.append(text_wait) |
| 66 | + group.append(text_ride) |
| 67 | + group.append(text_wait) |
| 68 | + |
| 69 | +text_park = outlined_label.OutlinedLabel(font, text=urls[0]['name'], |
| 70 | + outline_color = 0x000000, |
| 71 | + outline_size=3, |
| 72 | + padding_left=4, |
| 73 | + padding_right=4, |
| 74 | + padding_top=4, |
| 75 | + padding_bottom=4) |
| 76 | +text_park.x = (graphics.display.width - text_park.width) // 2 |
| 77 | +text_park.y = graphics.display.height - (text_park.height * 2) |
| 78 | +group.append(text_park) |
| 79 | + |
| 80 | +def center(g, b): |
| 81 | + # center the image |
| 82 | + g.x -= (b.width - graphics.display.width) // 2 |
| 83 | + g.y -= (b.height - graphics.display.height) // 2 |
| 84 | + |
| 85 | +center(grid, bitmap) |
| 86 | + |
| 87 | +graphics.display.root_group = group |
| 88 | + |
| 89 | +def sort_rides(data): |
| 90 | + y = 30 |
| 91 | + x = [135, 55, 15, 25, 45] |
| 92 | + all_rides = [] |
| 93 | + for land in data['lands']: |
| 94 | + all_rides.extend(land['rides']) |
| 95 | + sorted_rides = sorted(all_rides, key=lambda x: x['wait_time'], reverse=True) |
| 96 | + for ride in sorted_rides: |
| 97 | + r = sorted_rides.index(ride) |
| 98 | + if r > 4: |
| 99 | + break |
| 100 | + #print(wait_text[r]) |
| 101 | + ride_text[r].text = f"{ride['name']:.20}" |
| 102 | + if len(ride['name']) > 20: |
| 103 | + ride_text[r].text = ride_text[r].text + ".." |
| 104 | + ride_text[r].x = x[r] |
| 105 | + ride_text[r].y = y + 70 |
| 106 | + wait_text[r].text = f"{ride['wait_time']} Minutes" |
| 107 | + wait_text[r].x = 400 |
| 108 | + wait_text[r].y = ride_text[r].y + wait_text[r].height + 20 |
| 109 | + y += wait_text[r].height * 2 + 30 |
| 110 | + |
| 111 | +clock_timer = 5 * 60 * 1000 |
| 112 | +clock_clock = ticks_ms() |
| 113 | +park_index = 0 |
| 114 | +update = True |
| 115 | + |
| 116 | +while True: |
| 117 | + try: |
| 118 | + event = key.events.get() |
| 119 | + if event: |
| 120 | + if event.pressed: |
| 121 | + print("updating display") |
| 122 | + park_index = (park_index + 1) % len(urls) |
| 123 | + text_park.text=urls[park_index]['name'] |
| 124 | + text_park.x = (graphics.display.width - text_park.width) // 2 |
| 125 | + text_park.y = graphics.display.height - (text_park.height * 2) |
| 126 | + update = True |
| 127 | + if ticks_diff(ticks_ms(), clock_clock) >= clock_timer or update: |
| 128 | + response = requests.get(urls[park_index]['url']) |
| 129 | + # packs the response into a JSON |
| 130 | + response_data = response.json() |
| 131 | + sort_rides(response_data) |
| 132 | + update = False |
| 133 | + clock_clock = ticks_add(clock_clock, clock_timer) |
| 134 | + except Exception as error: # pylint: disable=broad-except |
| 135 | + print(f"error! {error} resetting..") |
| 136 | + time.sleep(5) |
| 137 | + microcontroller.reset() |
0 commit comments