-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
2,433 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
{ | ||
"preferred": { | ||
"teams": ["Cubs"], | ||
"divisions": ["NL Central", "NL Wild Card"] | ||
}, | ||
"news_ticker": { | ||
"team_offday": true, | ||
"always_display": false, | ||
"preferred_teams": true, | ||
"display_no_games_live": false, | ||
"traderumors": true, | ||
"mlb_news": true, | ||
"countdowns": true, | ||
"date": true, | ||
"date_format": "%A, %B %-d" | ||
}, | ||
"standings": { | ||
"team_offday": false, | ||
"mlb_offday": true, | ||
"always_display": false, | ||
"display_no_games_live": true | ||
}, | ||
"rotation": { | ||
"enabled": true, | ||
"scroll_until_finished": true, | ||
"only_preferred": false, | ||
"only_live": true, | ||
"rates": { | ||
"live": 15.0, | ||
"final": 15.0, | ||
"pregame": 15.0 | ||
}, | ||
"while_preferred_team_live": { | ||
"enabled": false, | ||
"during_inning_breaks": false | ||
} | ||
}, | ||
"weather": { | ||
"apikey": "YOUR_API_KEY_HERE", | ||
"location": "Chicago,il,us", | ||
"metric_units": false | ||
}, | ||
"time_format": "12h", | ||
"end_of_day": "00:00", | ||
"full_team_names": true, | ||
"short_team_names_for_runs_hits": true, | ||
"preferred_game_update_delay_in_10s_of_seconds": 0, | ||
"pregame_weather": true, | ||
"scrolling_speed": 2, | ||
"debug": false, | ||
"demo_date": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,68 @@ | ||
from utils.font import FontCache | ||
import json, os | ||
|
||
from config.layout import Layout | ||
|
||
from utils import logger as ScoreboardLogger | ||
from utils import deep_update, read_json | ||
|
||
|
||
class Config: | ||
def __init__(self): | ||
self.font_cache = FontCache() | ||
def __init__(self, config_filename, width, height): | ||
self.width = width | ||
self.height = height | ||
self.dimensions = (width, height) | ||
|
||
config = self.__fetch_config(config_filename) | ||
self.__parse_config(config) | ||
|
||
self.layout = Layout(width, height) | ||
|
||
def __fetch_config(self, name): | ||
""" | ||
Loads a config (JSON-formatted) with a custom filename. Falls back to a default if not found. | ||
""" | ||
filename = f"{name}.json" | ||
reference_filename = f"config.json.example" | ||
|
||
custom_config = read_json(filename) | ||
reference_config = read_json(reference_filename) | ||
|
||
if custom_config: | ||
# Retain only the values that are valid. | ||
config = deep_update(reference_config, custom_config) | ||
|
||
return config | ||
|
||
return reference_config | ||
|
||
def __parse_config(self, config): | ||
""" | ||
Convert a JSON config file to callable attributes on the Config class. | ||
If the key is nested, the top level key serves as its attribute prefix, i.e.: | ||
{ | ||
"type": { | ||
"key1": 1, | ||
"key2": { "one": 1, "two": 2 } | ||
} | ||
} | ||
config.type_key1 | ||
#=> 1 | ||
config.type_key2 | ||
#=> { "one": 1, "two": 2 } | ||
If not nested, returns the result with no namespace, i.e.: | ||
{ "type": "config" } | ||
def font(self, font_name): | ||
return self.font_cache.fetch_font(font_name) | ||
config.type | ||
#=> "config" | ||
""" | ||
for key in config: | ||
if isinstance(config[key], dict): | ||
for value in config[key]: | ||
setattr(self, f"{key}_{value}", config[key][value]) | ||
else: | ||
setattr(self, key, config[key]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import os, sys | ||
|
||
from utils import logger as ScoreboardLogger | ||
from utils.font import FontCache | ||
from utils import deep_update, read_json | ||
|
||
|
||
class Layout: | ||
LAYOUT_DIRECTORY = os.path.abspath(os.path.join("../../coordinates")) | ||
FONTNAME_DEFAULT = "4x6" | ||
|
||
def __init__(self, width, height): | ||
self.width = width | ||
self.height = height | ||
|
||
self.font_cache = FontCache(self.FONTNAME_DEFAULT) | ||
|
||
self._json = self.__fetch_layout() | ||
|
||
def font(self, font_name): | ||
""" | ||
Fetches a font from the font cache. | ||
""" | ||
return self.font_cache.fetch_font(font_name) | ||
|
||
def font_size(self, font_name): | ||
return self.font_cache.font_size(font_name) | ||
|
||
@property | ||
def default_font(self): | ||
return self.font_cache.default_font | ||
|
||
def __fetch_layout(self): | ||
filename = "coordinates/w{}h{}.json".format(self.width, self.height) | ||
reference_filename = "{}.example".format(filename) | ||
reference_layout = read_json(reference_filename) | ||
if not reference_layout: | ||
# Unsupported coordinates | ||
ScoreboardLogger.error( | ||
"Invalid matrix dimensions provided. See top of README for supported dimensions." | ||
"\nIf you would like to see new dimensions supported, please file an issue on GitHub!" | ||
) | ||
sys.exit(1) | ||
|
||
# Load and merge any layout customizations | ||
custom_layout = read_json(filename) | ||
if custom_layout: | ||
ScoreboardLogger.info( | ||
"Custom '%dx%d.json' found. Merging with default reference layout.", self.width, self.height | ||
) | ||
layout = deep_update(reference_layout, custom_layout) | ||
|
||
return layout | ||
|
||
return reference_layout |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
These JSON files are named in correspondence to the dimensions of the LED board used when running the software. A file, located in the `coordinates` directory with a filename `w<cols>h<rows>.json.example` tells the scoreboard that those dimensions are officially supported. This `.example` file is required and you will need to copy one of the existing files into a file that matches your dimensions. | ||
|
||
# Custom Coordinates | ||
You can edit these coordinates to display parts of the scoreboard in any way you choose. Simply copy the file corresponding to your board's dimensions to `w<cols>h<rows>.json`. This JSON file only needs to contain the parts you wish to override but it's often easier to just make a copy of the full example file and edit the values you want to change. | ||
|
||
## Example | ||
If you have a 64x32 board, copy `w64h32.json.example` to a new file called `w64h32.json`, then edit the coordinates in that file as you see fit. Your customized coordinates will always take precedence. | ||
|
||
## Fonts | ||
Any scoreboard element that prints text can accept a `"font_name"` attribute. Supported fonts need to be named with `<width>x<height>.bdf` (or `<width>x<height>B.bdf` for bold fonts). The font loader will search `assets/` first for the specified font and then it will fall back to searching `matrix/fonts/` if one was not found. | ||
|
||
## States | ||
The layout can have a couple of different states where things are rendered differently. Adding an object named for the layout state and giving it the same properties from the parent object will change the positioning of that parent object only when that state is found. For instance, when a game enters the `Warmup` state, the text `Warmup` appears under the time and the scrolling text is moved down. | ||
* `warmup` will only render on the `pregame` screen and appears when a game enters the `Warmup` status. This usually happens 15-20 minutes before a game begins. | ||
* `nohit` and `perfect_game` will only render on the live game screen and appears when a game returns that it is currently a no hitter or perfect game and the `innings_until_display` of `nohitter` has passed. | ||
* The `runs_hits_errors` section enables the addition of hits and errors to the game screen. | ||
* `show` turns this feature on or off. | ||
* `compress_digits` will reduce the space between digits when the number of runs or hits is > 9. | ||
* `spacing` is the number of pixels between the runs/hits and hits/errors. | ||
|
||
## Pitch Data | ||
* `enabled` (true/false) turn feature on/off | ||
* `mph` (true/false) When rendering pitch speed add mph after (99 mph) | ||
* `desc_length` (short/long) The short or long pitch type description, you can change both the short and long description to your liking in data/pitches as long as you do not change the index value. | ||
|
||
## Play Result | ||
* `enabled` (true/false) turn feature on/off | ||
* `desc_length` (short/long) The short or long play result description. You can change both the short and long description to your liking in data/plays. | ||
|
||
## Updates | ||
The software develops and releases features with full support for the default layouts, so custom layouts may look unsatisfactory if you update to later versions of the scoreboard. If you as a user decide to create a custom layout file, you are responsible for tweaking the coordinates to your liking with each update. | ||
|
||
## Current Issues | ||
A couple of things are not completely implemented or have some implementation details you should understand. | ||
|
||
* `bases` currently requires an even `size` value to be rendered correctly | ||
* Not all options are enabled on all board sizes by default. For example pitch count and pitch type are not enabled by default on boards smaller than 64x64. Options are "disabled" by forcing them to render outside the board, by setting X and Y coordinates less than 0 or greater than the height or width of the board. | ||
|
Oops, something went wrong.