from weather.weather_info_wunderground import hourlyForecast apiKey = "6d48850a7f579fe7" weather = hourlyForecast("Saint Louis", "MO", apiKey) months = ["NONE", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] for hour in weather: time = hour["time"] # print(type(time.month)) hourString = "{:02d} ".format(time.day) + months[time.month] + ", " + "{:02d}{:02d}".format(time.hour, time.minute) hourString += " -- " + hour["temp"] + u'\N{DEGREE SIGN}' + " F" + " -- " + hour["condition"] print(hourString)
def __init__(self): FPS = 30 # Split the screen up into these virtual rows and columns. Use these # to determine where to position each element. This lets the elements # automatically resize on different sized monitors numColumns = 30 numRows = 20 columns = [] rows = [] for i in range(numColumns): columns.append(int(screen.get_width() / numColumns * i)) for i in range(numRows): rows.append(int(screen.get_height() / numRows * i)) columnWidth = columns[1] - columns[0] rowWidth = rows[1] - rows[0] timePanelX1 = columns[1] timePanelY1 = rows[1] timePanelX2 = columns[13] timePanelY2 = rows[6] weatherPanelX1 = columns[1] weatherPanelY1 = rows[7] weatherPanelX2 = columns[9] weatherPanelY2 = rows[19] gameScorePanelX1 = columns[14] gameScorePanelY1 = rows[1] gameScorePanelX2 = columns[29] gameScorePanelY2 = rows[6] gamePreviewPanelX1 = gameScorePanelX1 gamePreviewPanelY1 = gameScorePanelY1 gamePreviewPanelX2 = gameScorePanelX2 gamePreviewPanelY2 = gameScorePanelY2 boxScorePanelX1 = columns[10] boxScorePanelY1 = rows[7] boxScorePanelX2 = columns[29] boxScorePanelY2 = rows[13] firstPitchCountdownPanelX1 = boxScorePanelX1 firstPitchCountdownPanelY1 = boxScorePanelY1 firstPitchCountdownPanelX2 = boxScorePanelX2 firstPitchCountdownPanelY2 = boxScorePanelY2 timePanel = TimePanel(timePanelX2 - timePanelX1, timePanelY2 - timePanelY1) weatherPanel = WeatherPanel(weatherPanelX2 - weatherPanelX1, weatherPanelY2 - weatherPanelY1) gameScorePanel = GameScorePanel(gameScorePanelX2 - gameScorePanelX1, gameScorePanelY2 - gameScorePanelY1) gamePreviewPanel = GamePreviewPanel(gamePreviewPanelX2 - gamePreviewPanelX1, gamePreviewPanelY2 - gamePreviewPanelY1) boxScorePanel = BoxScorePanel(boxScorePanelX2 - boxScorePanelX1, boxScorePanelY2 - boxScorePanelY1) firstPitchCountdownPanel = FirstPitchCountdownPanel(firstPitchCountdownPanelX2 - firstPitchCountdownPanelX1, firstPitchCountdownPanelY2 - firstPitchCountdownPanelY1) # Store the time of when we last requested these things. This # is used to make our requests at a reasonable rate. weatherQueryMade = False # (This hour) lastGameQueryTime = 0 lastDivisionQueryTime = 0 weatherQueryMinuteMark = 40 # Query at XX:40 # Add a few seconds to some of the cooldowns to try to prevent # all the queries from happening in the same second and # lowering the framerate (since queries are synchronous) gameNonLiveQueryCooldown = 302 # Once per 5 minutes gameAlmostLiveQueryCooldown = 60 # Once per minute gameLiveQueryCooldown = 20 # Once per 20 seconds divisionQueryCooldown = 907 # Once per 15 minutes movie = pg.movie.Movie('moving_background.mpg') movie_screen = pg.Surface(movie.get_size()).convert() movie.set_display(movie_screen) clock = pg.time.Clock() appLive = True firstLoop = True now = datetime.now() previousTime = now movie.play() while appLive: # Get current date and wall clock time now = datetime.now() # Get program execution time (separate from wall time... not # affected by leapyear, timezones, etc.) executionTime = time.time() # Loop video if it ended if not movie.get_busy(): movie.rewind() movie.play() # Query game information gameAlmostStarted = False if not firstLoop and game["status"] == GameStatus.Pre: timeUntilGame = game["adjustedDateTime"] - datetime.now() if timeUntilGame.total_seconds() < gameNonLiveQueryCooldown: gameAlmostStarted = True if (firstLoop) or (game["status"] == GameStatus.Live and executionTime - lastGameQueryTime >= gameLiveQueryCooldown) or ( gameAlmostStarted and executionTime - lastGameQueryTime >= gameAlmostLiveQueryCooldown) or ( executionTime - lastGameQueryTime >= gameNonLiveQueryCooldown): # Don't update to todays game until 4am. If it is # before 4am, show yesterday's game if now.hour < 4: dateOfInterest = now - timedelta(days=1) else: dateOfInterest = now game = mlb.getGameInfo(TEAM_OF_INTEREST, dateOfInterest) # If no game found for today, look ahead up to 10 days # until we find a game lookaheadDays = 0 while game["status"] == GameStatus.NoGame and lookaheadDays < 10: lookaheadDays += 1 dateOfInterest = dateOfInterest + timedelta(days=1) game = mlb.getGameInfo(TEAM_OF_INTEREST, dateOfInterest) # Adjust game time to the current timezone if game["status"] == GameStatus.Pre: rawDateTime = game["startTime"]["time"] hoursToAdjust = timezones.index(RASPBERRY_PI_TIMEZONE) - timezones.index(game["startTime"]["timeZone"]) adjustedDateTime = rawDateTime + timedelta(hours=hoursToAdjust) game["adjustedDateTime"] = adjustedDateTime firstPitchCountdownPanel.setTargetTime(adjustedDateTime) if game["status"] in (GameStatus.Live, GameStatus.Post): gameScorePanel.setScore(game) gameScoreOrPreviewPanelSurface = gameScorePanel.update() boxScoreOrCountdownSurface = boxScorePanel.update() else: gamePreviewPanel.setPreview(game) gameScoreOrPreviewPanelSurface = gamePreviewPanel.update() boxScoreOrCountdownSurface = firstPitchCountdownPanel.update() lastGameQueryTime = executionTime # Update day/time panel, as well as first pitch countdown # panel once per second if firstLoop or now.second != previousTime.second: timePanel.setTime(now) timePanelSurface = timePanel.update() if game["status"] == GameStatus.Pre: boxScoreOrCountdownSurface = firstPitchCountdownPanel.update() # Weather query not yet made this hour... but wait for the # minute mark to make it. if now.minute <= weatherQueryMinuteMark: weatherQueryMade = False # Update weather panel if firstLoop or (now.minute >= weatherQueryMinuteMark and not weatherQueryMade): weatherQueryMade = True weatherInfo = hourlyForecast("Saint Louis", "MO", wundergroundApiKey) weatherInfoToDisplay = [] # Only display up to 12 hours, using the following rules. # # 1. Next 3 hours are always displayed # 2. Only even hours are displayed (except when rule 1) # 3. 00:00 - 05:59 are not displayed (except when rule 1) for i, hour in enumerate(weatherInfo): if len(weatherInfoToDisplay) == 12: break if i < 3: weatherInfoToDisplay.append(hour) elif hour["time"].hour % 2 == 0 and hour["time"].hour > 5: weatherInfoToDisplay.append(hour) weatherPanel.setWeather(weatherInfoToDisplay) weatherPanelSurface = weatherPanel.update() # Stretch video to fit display. Transfer the stretched video onto # the screen. pg.transform.scale(movie_screen, screen.get_size(), screen) # Blit various panels on top of the video background screen.blit(timePanelSurface, (timePanelX1, timePanelY1)) screen.blit(weatherPanelSurface, (weatherPanelX1, weatherPanelY1)) screen.blit(gameScoreOrPreviewPanelSurface, (gameScorePanelX1, gameScorePanelY1)) screen.blit(boxScoreOrCountdownSurface, (firstPitchCountdownPanelX1, firstPitchCountdownPanelY1)) pg.display.update() # Check for quit event or ESC key press for event in pg.event.get(): if event.type == pg.QUIT or (event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE): movie.stop() appLive = False previousTime = now firstLoop = False # Sleep to keep application running at 30 FPS clock.tick(FPS) pg.quit()