forked from MLB-LED-Scoreboard/mlb-led-scoreboard
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
executable file
·173 lines (135 loc) · 5.42 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import sys
from data.screens import ScreenType
import debug
if sys.version_info <= (3, 5):
debug.error("Please run with python3")
sys.exit(1)
import statsapi
statsapi_version = tuple(map(int, statsapi.__version__.split(".")))
if statsapi_version < (1, 5, 1):
debug.error("We require MLB-StatsAPI 1.5.1 or higher. You may need to re-run install.sh")
sys.exit(1)
elif statsapi_version < (1, 6, 1):
debug.warning("We recommend MLB-StatsAPI 1.6.1 or higher. You may want to re-run install.sh")
import logging
import os
import threading
import time
from PIL import Image
# Important! Import the driver first to initialize it, then import submodules as needed.
import driver
from driver import RGBMatrix, __version__
from utils import args, led_matrix_options
from data import Data
from data.config import Config
from renderers.main import MainRenderer
from version import SCRIPT_NAME, SCRIPT_VERSION
def main(matrix, config_base):
# Read scoreboard options from config.json if it exists
config = Config(config_base, matrix.width, matrix.height)
logger = logging.getLogger("mlbled")
if config.debug:
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.WARNING)
# Print some basic info on startup
debug.info("%s - v%s (%sx%s)", SCRIPT_NAME, SCRIPT_VERSION, matrix.width, matrix.height)
if driver.is_emulated():
if driver.hardware_load_failed:
debug.log("rgbmatrix not installed, falling back to emulator!")
debug.log("Using RGBMatrixEmulator version %s", __version__)
else:
debug.log("Using rgbmatrix version %s", __version__)
# Draw startup screen
logo_path = os.path.abspath("./assets/mlb-w" + str(matrix.width) + "h" + str(matrix.height) + ".png")
# MLB image disabled when using renderer, for now.
# see: https://github.com/ty-porter/RGBMatrixEmulator/issues/9#issuecomment-922869679
if os.path.exists(logo_path) and driver.is_hardware():
logo = Image.open(logo_path)
matrix.SetImage(logo.convert("RGB"))
logo.close()
# Create a new data object to manage the MLB data
# This will fetch initial data from MLB
data = Data(config)
# create render thread
render = threading.Thread(target=__render_main, args=[matrix, data], name="render_thread", daemon=True)
time.sleep(1)
render.start()
screen = data.get_screen_type()
if screen == ScreenType.ALWAYS_NEWS:
__refresh_news(render, data)
elif screen == ScreenType.ALWAYS_STANDINGS:
__refresh_standings(render, data)
elif screen == ScreenType.LEAGUE_OFFDAY or screen == ScreenType.PREFERRED_TEAM_OFFDAY:
__refresh_offday(render, data)
else:
__refresh_gameday(render, data)
def __refresh_news(render_thread, data): # type: (threading.Thread, Data) -> None
debug.log("Main has selected the news to refresh")
while render_thread.is_alive():
time.sleep(30)
data.refresh_weather()
data.refresh_news_ticker()
def __refresh_standings(render_thread, data): # type: (threading.Thread, Data) -> None
if data.standings.populated():
debug.log("Main has selected the standings to refresh")
while render_thread.is_alive():
time.sleep(30)
data.refresh_standings()
else:
__refresh_news(render_thread, data)
def __refresh_offday(render_thread, data): # type: (threading.Thread, Data) -> None
debug.log("Main has selected the offday information to refresh")
while render_thread.is_alive():
time.sleep(30)
data.refresh_standings()
data.refresh_weather()
data.refresh_news_ticker()
def __refresh_gameday(render_thread, data): # type: (threading.Thread, Data) -> None
debug.log("Main has selected the gameday information to refresh")
starttime = time.time()
promise_game = data.schedule.games_live()
while render_thread.is_alive():
time.sleep(0.5)
data.refresh_schedule()
if not data.schedule.games_live():
cont = False
if data.config.standings_no_games:
data.refresh_standings()
cont = True
if data.config.news_no_games:
data.refresh_news_ticker()
data.refresh_weather()
cont = True
if cont:
continue
# make sure a game is populated
elif not promise_game:
promise_game = True
data.advance_to_next_game()
rotate = data.should_rotate_to_next_game()
if data.schedule.games_live() and not rotate:
data.refresh_game()
endtime = time.time()
time_delta = endtime - starttime
rotate_rate = data.config.rotate_rate_for_status(data.current_game.status())
if time_delta >= rotate_rate and data.scrolling_finished:
starttime = time.time()
if rotate:
data.advance_to_next_game()
def __render_main(matrix, data):
MainRenderer(matrix, data).render()
if __name__ == "__main__":
# Check for led configuration arguments
command_line_args = args()
matrixOptions = led_matrix_options(command_line_args)
# Initialize the matrix
matrix = RGBMatrix(options=matrixOptions)
try:
config, _ = os.path.splitext(command_line_args.config)
main(matrix, config)
except:
debug.exception("Untrapped error in main!")
sys.exit(1)
finally:
matrix.Clear()