107 lines
3.3 KiB
Python
107 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
|
|
from glob import glob
|
|
import pygame
|
|
from pygame.locals import *
|
|
from time import sleep
|
|
from dublinbus_soap_client import DublinBusSoapClient
|
|
import queue
|
|
from arrival_times import ArrivalTime
|
|
|
|
# Constants
|
|
# The font is JD LCD Rounded by Jecko Development
|
|
# https://fontstruct.com/fontstructions/show/459792/jd_lcd_rounded
|
|
TEXT_FONT = 'jd_lcd_rounded.ttf'
|
|
LINE_COUNT = 5
|
|
COLOR_LCD : pygame.Color = pygame.Color(244, 203, 96)
|
|
COLOR_BACKGROUND = pygame.Color(0, 0, 0)
|
|
UPDATE_INTERVAL_SECONDS = 30
|
|
TEXT_SIZE = 80 # Size of the font in pixels
|
|
STOPS = [
|
|
2410, # College Drive
|
|
1114 # Priory Walk
|
|
]
|
|
|
|
# Offsets of each part within a line
|
|
XOFFSET_ROUTE = 12 # 1920x720 -> 24
|
|
XOFFSET_DESTINATION = 150 # 1920x720 -> 300
|
|
XOFFSEET_TIME_LEFT = 803 # 1920x720 -> 1606
|
|
INTER_LINE_SPACE = 0 # 1920x720 -> 0
|
|
|
|
# Some global variables
|
|
window : pygame.Surface = None
|
|
font: pygame.font.Font = None
|
|
update_queue = queue.Queue(maxsize=10)
|
|
dublinbus_client = DublinBusSoapClient(stops=STOPS, update_queue=update_queue, update_interval_seconds=UPDATE_INTERVAL_SECONDS)
|
|
|
|
|
|
def get_line_offset(line: int) -> int:
|
|
global font
|
|
return line * (font.get_height() + INTER_LINE_SPACE)
|
|
|
|
def write_entry(line: int,
|
|
route: str = '', destination: str = '', time_left: str = '',
|
|
time_color: Color = COLOR_LCD, text_color: Color = COLOR_LCD):
|
|
# Step 1: Render the fragments
|
|
route_img = font.render(route[0:4], True, text_color)
|
|
destination_img = font.render(destination[0:21], True, text_color)
|
|
time_left_img = font.render(time_left[0:5], True, time_color)
|
|
|
|
# Compose the line
|
|
vertical_offset = get_line_offset(line)
|
|
window.blit(route_img, dest=(XOFFSET_ROUTE, vertical_offset))
|
|
window.blit(destination_img, dest=(XOFFSET_DESTINATION, vertical_offset))
|
|
window.blit(time_left_img, dest=(XOFFSEET_TIME_LEFT, vertical_offset))
|
|
|
|
def update_screen(updates: list[ArrivalTime]) -> None:
|
|
""" Repaint the screen with the new arrival times """
|
|
updates = updates[0:LINE_COUNT] # take the first X lines
|
|
for line_num, update in enumerate(updates):
|
|
write_entry(
|
|
line=line_num,
|
|
route=update.route_id,
|
|
destination=update.destination,
|
|
time_left='Due' if update.isDue() else f'{update.due_in_minutes}min',
|
|
time_color=COLOR_LCD
|
|
)
|
|
|
|
def clear_screen() -> None:
|
|
pygame.draw.rect(surface=window, color=COLOR_BACKGROUND, width=0, rect=(0, 0, window.get_width(), window.get_height()))
|
|
|
|
|
|
|
|
def main():
|
|
global font
|
|
global window
|
|
|
|
""" Main method. Initialise graph """
|
|
pygame.init()
|
|
pygame.display.init()
|
|
pygame.font.init()
|
|
window = pygame.display.set_mode(size=(960, 360), flags=DOUBLEBUF, display=1)
|
|
font = pygame.font.Font(TEXT_FONT, TEXT_SIZE)
|
|
|
|
# Paint black
|
|
clear_screen()
|
|
pygame.display.flip()
|
|
dublinbus_client.start()
|
|
|
|
# Main event loop
|
|
running = True
|
|
while running:
|
|
pygame.event.wait(timeout=1)
|
|
for e in pygame.event.get():
|
|
if e.type == pygame.QUIT:
|
|
running = False
|
|
#end event handling
|
|
if update_queue.not_empty:
|
|
clear_screen()
|
|
updates = update_queue.get()
|
|
update_screen(updates)
|
|
pygame.display.flip()
|
|
|
|
pygame.quit()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |