From 6a133900e77d7f4155bf62009701fd2d3141790c Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Mon, 25 Apr 2022 15:42:33 -0400 Subject: [PATCH 01/24] Truncate team name if Runs or Hits > 9 --- data/game.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/data/game.py b/data/game.py index 30b994eb..67c30064 100644 --- a/data/game.py +++ b/data/game.py @@ -65,13 +65,18 @@ def datetime(self): return datetime.fromisoformat(time.replace("Z", "+00:00")) def home_name(self): - return self._data["gameData"]["teams"]["home"]["teamName"] - + if (self._data["liveData"]["linescore"]["teams"]["home"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["home"].get("hits", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("hits", 0) > 9 ): + return self._data["gameData"]["teams"]["home"]["teamName"][0:8] + else: + return self._data["gameData"]["teams"]["home"]["teamName"] def home_abbreviation(self): return self._data["gameData"]["teams"]["home"]["abbreviation"] def away_name(self): - return self._data["gameData"]["teams"]["away"]["teamName"] + if (self._data["liveData"]["linescore"]["teams"]["home"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["home"].get("hits", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("hits", 0) > 9 ): + return self._data["gameData"]["teams"]["away"]["teamName"][0:8] + else: + return self._data["gameData"]["teams"]["away"]["teamName"] def away_abbreviation(self): return self._data["gameData"]["teams"]["away"]["abbreviation"] From 1fb2f7fa80a277d93543c378fd99931465761e21 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Mon, 25 Apr 2022 16:49:53 -0400 Subject: [PATCH 02/24] changed to abbreviation instead of truncate team name --- data/game.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/game.py b/data/game.py index 67c30064..d4c957f8 100644 --- a/data/game.py +++ b/data/game.py @@ -66,7 +66,7 @@ def datetime(self): def home_name(self): if (self._data["liveData"]["linescore"]["teams"]["home"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["home"].get("hits", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("hits", 0) > 9 ): - return self._data["gameData"]["teams"]["home"]["teamName"][0:8] + self._data["gameData"]["teams"]["home"]["abbreviation"] else: return self._data["gameData"]["teams"]["home"]["teamName"] def home_abbreviation(self): @@ -74,7 +74,7 @@ def home_abbreviation(self): def away_name(self): if (self._data["liveData"]["linescore"]["teams"]["home"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["home"].get("hits", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("hits", 0) > 9 ): - return self._data["gameData"]["teams"]["away"]["teamName"][0:8] + return self._data["gameData"]["teams"]["away"]["abbreviation"] else: return self._data["gameData"]["teams"]["away"]["teamName"] From 3c1bae3eab910bf3957959e016254c1ee81ac7fb Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Mon, 25 Apr 2022 18:54:01 -0400 Subject: [PATCH 03/24] Moved to renderer and added config option --- config.json.example | 1 + data/config/__init__.py | 1 + data/game.py | 11 +++-------- renderers/games/teams.py | 12 +++++++----- renderers/main.py | 1 + 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config.json.example b/config.json.example index cd37681b..5b75c53c 100644 --- a/config.json.example +++ b/config.json.example @@ -42,6 +42,7 @@ "time_format": "12h", "end_of_day": "00:00", "full_team_names": true, + "short_team_names_for_runs_hits": true, "scrolling_speed": 2, "debug": false, "demo_date": false diff --git a/data/config/__init__.py b/data/config/__init__.py index 6c25d2e2..8ac308bf 100644 --- a/data/config/__init__.py +++ b/data/config/__init__.py @@ -62,6 +62,7 @@ def __init__(self, filename_base, width, height): self.time_format = json["time_format"] self.end_of_day = json["end_of_day"] self.full_team_names = json["full_team_names"] + self.short_team_names_for_runs_hits = json["short_team_names_for_runs_hits"] self.debug = json["debug"] self.demo_date = json["demo_date"] # Make sure the scrolling speed setting is in range so we don't crash diff --git a/data/game.py b/data/game.py index d4c957f8..b5fda372 100644 --- a/data/game.py +++ b/data/game.py @@ -65,18 +65,13 @@ def datetime(self): return datetime.fromisoformat(time.replace("Z", "+00:00")) def home_name(self): - if (self._data["liveData"]["linescore"]["teams"]["home"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["home"].get("hits", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("hits", 0) > 9 ): - self._data["gameData"]["teams"]["home"]["abbreviation"] - else: - return self._data["gameData"]["teams"]["home"]["teamName"] + return self._data["gameData"]["teams"]["home"]["teamName"] + def home_abbreviation(self): return self._data["gameData"]["teams"]["home"]["abbreviation"] def away_name(self): - if (self._data["liveData"]["linescore"]["teams"]["home"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("runs", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["home"].get("hits", 0) > 9) or (self._data["liveData"]["linescore"]["teams"]["away"].get("hits", 0) > 9 ): - return self._data["gameData"]["teams"]["away"]["abbreviation"] - else: - return self._data["gameData"]["teams"]["away"]["teamName"] + return self._data["gameData"]["teams"]["away"]["teamName"] def away_abbreviation(self): return self._data["gameData"]["teams"]["away"]["abbreviation"] diff --git a/renderers/games/teams.py b/renderers/games/teams.py index 290a5403..1083a6a1 100644 --- a/renderers/games/teams.py +++ b/renderers/games/teams.py @@ -4,7 +4,7 @@ from RGBMatrixEmulator import graphics -def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_team_names): +def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_team_names, short_team_names_for_runs_hits,): default_colors = team_colors.color("default") away_colors = __team_colors(team_colors, away_team.abbrev) @@ -53,8 +53,8 @@ def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_t y_offset = accent_coords[team]["y"] canvas.SetPixel(x + x_offset, y + y_offset, color["r"], color["g"], color["b"]) - __render_team_text(canvas, layout, away_colors, away_team, "away", full_team_names, default_colors) - __render_team_text(canvas, layout, home_colors, home_team, "home", full_team_names, default_colors) + __render_team_text(canvas, layout, away_colors, away_team, "away", full_team_names, default_colors, short_team_names_for_runs_hits) + __render_team_text(canvas, layout, home_colors, home_team, "home", full_team_names, default_colors, short_team_names_for_runs_hits) # Number of characters in each score. score_spacing = { @@ -74,14 +74,16 @@ def __team_colors(team_colors, team_abbrev): return team_colors -def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, default_colors): +def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, default_colors, short_team_names_for_runs_hits): text_color = colors.get("text", default_colors["text"]) text_color_graphic = graphics.Color(text_color["r"], text_color["g"], text_color["b"]) coords = layout.coords("teams.name.{}".format(homeaway)) font = layout.font("teams.name.{}".format(homeaway)) team_text = "{:3s}".format(team.abbrev.upper()) - if full_team_names and canvas.width > 32: + if full_team_names and canvas.width > 32 and short_team_names_for_runs_hits == False: team_text = "{:13s}".format(team.name) + if full_team_names and canvas.width > 32 and short_team_names_for_runs_hits and (team.runs > 9 or team.hits > 9 ) : + team_text = "{:3s}".format(team.abbrev.upper()) graphics.DrawText(canvas, font["font"], coords["x"], coords["y"], text_color_graphic, team_text) diff --git a/renderers/main.py b/renderers/main.py index 46fb2479..b605e6a3 100644 --- a/renderers/main.py +++ b/renderers/main.py @@ -157,6 +157,7 @@ def __draw_game(self): scoreboard.home_team, scoreboard.away_team, self.data.config.full_team_names, + self.data.config.short_team_names_for_runs_hits, ) if status.is_pregame(game.status()): # Draw the pregame information From 094aea285e94d2cda1317816e3c727d8b6fa4293 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Mon, 25 Apr 2022 19:06:52 -0400 Subject: [PATCH 04/24] Incorporated BW changes, appears to be working --- renderers/games/teams.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/renderers/games/teams.py b/renderers/games/teams.py index 1083a6a1..d2927fb6 100644 --- a/renderers/games/teams.py +++ b/renderers/games/teams.py @@ -80,10 +80,8 @@ def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, coords = layout.coords("teams.name.{}".format(homeaway)) font = layout.font("teams.name.{}".format(homeaway)) team_text = "{:3s}".format(team.abbrev.upper()) - if full_team_names and canvas.width > 32 and short_team_names_for_runs_hits == False: + if full_team_names and canvas.width > 32 and not (short_team_names_for_runs_hits and (team.runs > 9 or team.hits > 9)): team_text = "{:13s}".format(team.name) - if full_team_names and canvas.width > 32 and short_team_names_for_runs_hits and (team.runs > 9 or team.hits > 9 ) : - team_text = "{:3s}".format(team.abbrev.upper()) graphics.DrawText(canvas, font["font"], coords["x"], coords["y"], text_color_graphic, team_text) From 7923dbb17f067808a40ab81ed9dae816f1b3405a Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Tue, 26 Apr 2022 15:10:39 -0400 Subject: [PATCH 05/24] added option to show pregame weather to pitcher vs scroll --- config.json.example | 1 + data/config/__init__.py | 1 + data/game.py | 12 ++++++++++-- data/scoreboard/pregame.py | 1 + renderers/games/pregame.py | 11 +++++++---- renderers/main.py | 2 +- 6 files changed, 21 insertions(+), 7 deletions(-) diff --git a/config.json.example b/config.json.example index 5b75c53c..64acf580 100644 --- a/config.json.example +++ b/config.json.example @@ -43,6 +43,7 @@ "end_of_day": "00:00", "full_team_names": true, "short_team_names_for_runs_hits": true, + "pregame_weather": true, "scrolling_speed": 2, "debug": false, "demo_date": false diff --git a/data/config/__init__.py b/data/config/__init__.py index 8ac308bf..f8db6031 100644 --- a/data/config/__init__.py +++ b/data/config/__init__.py @@ -63,6 +63,7 @@ def __init__(self, filename_base, width, height): self.end_of_day = json["end_of_day"] self.full_team_names = json["full_team_names"] self.short_team_names_for_runs_hits = json["short_team_names_for_runs_hits"] + self.pregame_weather = json["pregame_weather"] self.debug = json["debug"] self.demo_date = json["demo_date"] # Make sure the scrolling speed setting is in range so we don't crash diff --git a/data/game.py b/data/game.py index b5fda372..69bb2bd1 100644 --- a/data/game.py +++ b/data/game.py @@ -11,7 +11,7 @@ + "reason,probablePitchers,teams,home,away,abbreviation,teamName,players,id,boxscoreName,fullName,liveData,plays," + "currentPlay,result,eventType,description,decisions,winner,loser,save,id,linescore,outs,balls,strikes,note," + "inningState,currentInning,currentInningOrdinal,offense,batter,inHole,onDeck,first,second,third,defense,pitcher," - + "boxscore,teams,runs,players,seasonStats,pitching,wins,losses,saves,era,hits,errors" + + "boxscore,teams,runs,players,seasonStats,pitching,wins,losses,saves,era,hits,errors,weather,condition,temp,wind" ) SCHEDULE_API_FIELDS = "dates,date,games,status,detailedState,abstractGameState,reason" @@ -69,7 +69,15 @@ def home_name(self): def home_abbreviation(self): return self._data["gameData"]["teams"]["home"]["abbreviation"] - + + def pregame_weather(self): + try: + wx = self._data["gameData"]["weather"]["condition"] + " and " + self._data["gameData"]["weather"]["temp"] + u"\N{DEGREE SIGN}" + " wind " + self._data["gameData"]["weather"]["wind"] + except KeyError: + return None + else: + return wx + def away_name(self): return self._data["gameData"]["teams"]["away"]["teamName"] diff --git a/data/scoreboard/pregame.py b/data/scoreboard/pregame.py index 7ae0e466..121ca767 100644 --- a/data/scoreboard/pregame.py +++ b/data/scoreboard/pregame.py @@ -9,6 +9,7 @@ class Pregame: def __init__(self, game: Game, time_format): self.home_team = game.home_abbreviation() self.away_team = game.away_abbreviation() + self.pregame_weather = game.pregame_weather() self.time_format = time_format try: diff --git a/renderers/games/pregame.py b/renderers/games/pregame.py index 0613de0f..9f75354b 100644 --- a/renderers/games/pregame.py +++ b/renderers/games/pregame.py @@ -10,8 +10,8 @@ from utils import center_text_position -def render_pregame(canvas, layout: Layout, colors: Color, pregame: Pregame, probable_starter_pos): - text_len = _render_probable_starters(canvas, layout, colors, pregame, probable_starter_pos) +def render_pregame(canvas, layout: Layout, colors: Color, pregame: Pregame, probable_starter_pos, pregame_weather): + text_len = _render_probable_starters(canvas, layout, colors, pregame, probable_starter_pos, pregame_weather) if layout.state_is_warmup(): _render_warmup(canvas, layout, colors, pregame) @@ -39,12 +39,15 @@ def _render_warmup(canvas, layout, colors, pregame): graphics.DrawText(canvas, font["font"], warmup_x, coords["y"], color, warmup_text) -def _render_probable_starters(canvas, layout, colors, pregame, probable_starter_pos): +def _render_probable_starters(canvas, layout, colors, pregame, probable_starter_pos, pregame_weather): coords = layout.coords("pregame.scrolling_text") font = layout.font("pregame.scrolling_text") color = colors.graphics_color("pregame.scrolling_text") bgcolor = colors.graphics_color("default.background") - pitchers_text = pregame.away_starter + " vs " + pregame.home_starter + if pregame_weather and pregame.pregame_weather: + pitchers_text = pregame.away_starter + " vs " + pregame.home_starter + " Weather: " + pregame.pregame_weather + else : + pitchers_text = pregame.away_starter + " vs " + pregame.home_starter return scrollingtext.render_text( canvas, coords["x"], coords["y"], coords["width"], font, color, bgcolor, pitchers_text, probable_starter_pos ) diff --git a/renderers/main.py b/renderers/main.py index b605e6a3..de2d5056 100644 --- a/renderers/main.py +++ b/renderers/main.py @@ -163,7 +163,7 @@ def __draw_game(self): if status.is_pregame(game.status()): # Draw the pregame information self.__max_scroll_x(layout.coords("pregame.scrolling_text")) pregame = Pregame(game, self.data.config.time_format) - pos = pregamerender.render_pregame(self.canvas, layout, colors, pregame, self.scrolling_text_pos) + pos = pregamerender.render_pregame(self.canvas, layout, colors, pregame, self.scrolling_text_pos, self.data.config.pregame_weather) self.__update_scrolling_text_pos(pos, self.canvas.width) elif status.is_complete(game.status()): # Draw the game summary From 02a8529622a1062b0195e7ce792db236cbe1bb66 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Wed, 27 Apr 2022 11:29:49 -0400 Subject: [PATCH 06/24] Changed to truncate both team names when triggered, updated readme --- README.md | 1 + renderers/games/teams.py | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 69fd4c43..bdb79208 100755 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ A default `config.json.example` file is included for reference. Copy this file t "time_format" String Sets the preferred hour format for displaying time. Accepted values are "12h" or "24h" depending on which you prefer. "end_of_day" String A 24-hour time you wish to consider the end of the previous day before starting to display the current day's games. Uses local time from your pi. "full_team_names" Bool If true and on a 64-wide board, displays the full team name on the scoreboard instead of their abbreviation. This config option is ignored on 32-wide boards. Defaults to true when on a 64-wide board. +"short_team_names_for_runs_hits" Bool If true and full_team_names is true and Runs Hits Errors is enabled, will use abreviated team names when Runs or Hits > 9 "scrolling_speed" Integer Supports an integer between 0 and 4. Sets how fast the scrolling text scrolls. "debug" Bool Game and other debug data is written to your console. "demo_date" String A date in the format YYYY-MM-DD from which to pull data to demonstrate the scoreboard. A value of `false` will disable demo mode. diff --git a/renderers/games/teams.py b/renderers/games/teams.py index d2927fb6..e4a4978b 100644 --- a/renderers/games/teams.py +++ b/renderers/games/teams.py @@ -53,8 +53,8 @@ def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_t y_offset = accent_coords[team]["y"] canvas.SetPixel(x + x_offset, y + y_offset, color["r"], color["g"], color["b"]) - __render_team_text(canvas, layout, away_colors, away_team, "away", full_team_names, default_colors, short_team_names_for_runs_hits) - __render_team_text(canvas, layout, home_colors, home_team, "home", full_team_names, default_colors, short_team_names_for_runs_hits) + __render_team_text(canvas, layout, away_colors, away_team, "away", full_team_names, default_colors, short_team_names_for_runs_hits, home_team) + __render_team_text(canvas, layout, home_colors, home_team, "home", full_team_names, default_colors, short_team_names_for_runs_hits, away_team) # Number of characters in each score. score_spacing = { @@ -74,13 +74,13 @@ def __team_colors(team_colors, team_abbrev): return team_colors -def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, default_colors, short_team_names_for_runs_hits): +def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, default_colors, short_team_names_for_runs_hits, vs_team): text_color = colors.get("text", default_colors["text"]) text_color_graphic = graphics.Color(text_color["r"], text_color["g"], text_color["b"]) coords = layout.coords("teams.name.{}".format(homeaway)) font = layout.font("teams.name.{}".format(homeaway)) team_text = "{:3s}".format(team.abbrev.upper()) - if full_team_names and canvas.width > 32 and not (short_team_names_for_runs_hits and (team.runs > 9 or team.hits > 9)): + if full_team_names and canvas.width > 32 and not (short_team_names_for_runs_hits and (team.runs > 9 or team.hits > 9 or vs_team.runs > 9 or vs_team.hits > 9)): team_text = "{:13s}".format(team.name) graphics.DrawText(canvas, font["font"], coords["x"], coords["y"], text_color_graphic, team_text) From 4e58d15c2fed81d35b858bb9ef10a4fa4c0c6b8b Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Wed, 27 Apr 2022 21:15:37 -0400 Subject: [PATCH 07/24] Add pitch data to pitches scoreboard item --- data/game.py | 14 ++++++++++---- data/scoreboard/pitches.py | 10 ++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/data/game.py b/data/game.py index 30b994eb..ad4ad1da 100644 --- a/data/game.py +++ b/data/game.py @@ -9,9 +9,10 @@ API_FIELDS = ( "gameData,game,id,datetime,dateTime,officialDate,flags,noHitter,perfectGame,status,detailedState,abstractGameState," + "reason,probablePitchers,teams,home,away,abbreviation,teamName,players,id,boxscoreName,fullName,liveData,plays," - + "currentPlay,result,eventType,description,decisions,winner,loser,save,id,linescore,outs,balls,strikes,note," - + "inningState,currentInning,currentInningOrdinal,offense,batter,inHole,onDeck,first,second,third,defense,pitcher," - + "boxscore,teams,runs,players,seasonStats,pitching,wins,losses,saves,era,hits,errors" + + "currentPlay,result,eventType,playEvents,isPitch,pitchData,startSpeed,details,type,code,description,decisions," + + "winner,loser,save,id,linescore,outs,balls,strikes,note,inningState,currentInning,currentInningOrdinal,offense," + + "batter,inHole,onDeck,first,second,third,defense,pitcher,boxscore,teams,runs,players,seasonStats,pitching,wins," + + "losses,saves,era,hits,errors" ) SCHEDULE_API_FIELDS = "dates,date,games,status,detailedState,abstractGameState,reason" @@ -77,7 +78,7 @@ def away_abbreviation(self): return self._data["gameData"]["teams"]["away"]["abbreviation"] def status(self): - return self._status["detailedState"] + return "In Progress" # self._status["detailedState"] def home_score(self): return self._data["liveData"]["linescore"]["teams"]["home"].get("runs", 0) @@ -217,6 +218,11 @@ def strikes(self): def outs(self): return self._data["liveData"]["linescore"].get("outs", 0) + def last_pitch(self): + play = self._data["liveData"]["plays"].get("currentPlay", {}).get("playEvents", [{}])[-1] + if play.get("isPitch", False): + return play["pitchData"].get("startSpeed", 0), play["details"]["type"]["code"] + def note(self): try: return self._data["liveData"]["linescore"]["note"] diff --git a/data/scoreboard/pitches.py b/data/scoreboard/pitches.py index cbbe34d9..9af48be5 100644 --- a/data/scoreboard/pitches.py +++ b/data/scoreboard/pitches.py @@ -5,3 +5,13 @@ class Pitches: def __init__(self, game: Game): self.balls = game.balls() self.strikes = game.strikes() + last_pitch = game.last_pitch() + if last_pitch is None: + self.last_pitch_speed = "0" + self.last_pitch_type = "UK" + else: + self.last_pitch_speed = f"{round(last_pitch[0])}" + self.last_pitch_type = last_pitch[1] + + def __str__(self) -> str: + return f"Count: {self.balls} - {self.strikes}. Last pitch: {self.last_pitch_speed}mph {self.last_pitch_type}" From 4aa3911d6ba029482af9a8ec2616a3c3a585a2cd Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Thu, 28 Apr 2022 20:49:37 -0400 Subject: [PATCH 08/24] Integrated BW's pitch speeed into 128x64, added to colors, coordinates --- colors/scoreboard.json.example | 5 +++++ data/game.py | 12 +++++++----- data/scoreboard/pitches.py | 4 +++- renderers/games/game.py | 23 +++++++++++++++++++++-- renderers/main.py | 1 - 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/colors/scoreboard.json.example b/colors/scoreboard.json.example index b7eeb96b..b4d340b5 100644 --- a/colors/scoreboard.json.example +++ b/colors/scoreboard.json.example @@ -114,6 +114,11 @@ "g": 235, "b": 59 }, + "pitch": { + "r": 255, + "g": 255, + "b": 255 + }, "strikeout": { "r": 255, "g": 235, diff --git a/data/game.py b/data/game.py index ad4ad1da..9278c750 100644 --- a/data/game.py +++ b/data/game.py @@ -78,7 +78,7 @@ def away_abbreviation(self): return self._data["gameData"]["teams"]["away"]["abbreviation"] def status(self): - return "In Progress" # self._status["detailedState"] + return self._status["detailedState"] def home_score(self): return self._data["liveData"]["linescore"]["teams"]["home"].get("runs", 0) @@ -219,10 +219,12 @@ def outs(self): return self._data["liveData"]["linescore"].get("outs", 0) def last_pitch(self): - play = self._data["liveData"]["plays"].get("currentPlay", {}).get("playEvents", [{}])[-1] - if play.get("isPitch", False): - return play["pitchData"].get("startSpeed", 0), play["details"]["type"]["code"] - + try: + play = self._data["liveData"]["plays"].get("currentPlay", {}).get("playEvents", [{}])[-1] + if play.get("isPitch", False): + return play["pitchData"].get("startSpeed", 0), play["details"]["type"]["code"], play["details"]["type"]["description"] + except: + return None def note(self): try: return self._data["liveData"]["linescore"]["note"] diff --git a/data/scoreboard/pitches.py b/data/scoreboard/pitches.py index 9af48be5..23689b56 100644 --- a/data/scoreboard/pitches.py +++ b/data/scoreboard/pitches.py @@ -9,9 +9,11 @@ def __init__(self, game: Game): if last_pitch is None: self.last_pitch_speed = "0" self.last_pitch_type = "UK" + self.last_pitch_type_long = "Unknown" else: self.last_pitch_speed = f"{round(last_pitch[0])}" self.last_pitch_type = last_pitch[1] + self.last_pitch_type_long = last_pitch[2] def __str__(self) -> str: - return f"Count: {self.balls} - {self.strikes}. Last pitch: {self.last_pitch_speed}mph {self.last_pitch_type}" + return f"Count: {self.balls} - {self.strikes}. Last pitch: {self.last_pitch_speed}mph {self.last_pitch_type} {self.last_pitch_long}" diff --git a/renderers/games/game.py b/renderers/games/game.py index 810656a4..0701ad53 100644 --- a/renderers/games/game.py +++ b/renderers/games/game.py @@ -28,6 +28,7 @@ def render_live_game(canvas, layout: Layout, colors: Color, scoreboard: Scoreboa scoreboard.strikeout(), scoreboard.strikeout_looking(), (animation_time // 6) % 2, + scoreboard.pitches ) # Check if we're deep enough into a game and it's a no hitter or perfect game @@ -49,8 +50,9 @@ def render_live_game(canvas, layout: Layout, colors: Color, scoreboard: Scoreboa # --------------- at-bat --------------- -def _render_at_bat(canvas, layout, colors, atbat: AtBat, text_pos, strikeout, looking, animation): +def _render_at_bat(canvas, layout, colors, atbat: AtBat, text_pos, strikeout, looking, animation, pitches: Pitches): plength = __render_pitcher_text(canvas, layout, colors, atbat.pitcher, text_pos) + __render_pitch_text(canvas, layout, colors, pitches) if strikeout: if animation: __render_strikeout(canvas, layout, colors, looking) @@ -108,7 +110,24 @@ def __render_pitcher_text(canvas, layout, colors, pitcher, text_pos): graphics.DrawText(canvas, font["font"], coords["x"], coords["y"], color, "P:") return pos - +def __render_pitch_text(canvas, layout, colors, pitches: Pitches): +#def __render_pitch_text(canvas, layout, colors): + coords = layout.coords("atbat.pitch") + color = colors.graphics_color("atbat.pitch") + font = layout.font("atbat.pitch") + bgcolor = colors.graphics_color("default.background") + if(int(pitches.last_pitch_speed) > 0 and layout.coords("atbat.pitch")["enabled"]): + mph= " " + if(layout.coords("atbat.pitch")["mph"]): + mph="mph " + if(layout.coords("atbat.pitch")["desc_length"]=="Long"): + pitch_text = str(pitches.last_pitch_speed) + mph + pitches.last_pitch_type_long[0:23] + elif(layout.coords("atbat.pitch")["desc_length"]=="Short"): + pitch_text = str(pitches.last_pitch_speed) + mph + pitches.last_pitch_type + else: + pitch_text = None + graphics.DrawText(canvas, font["font"], coords["x"], coords["y"], color, pitch_text) + # --------------- bases --------------- def _render_bases(canvas, layout, colors, bases: Bases, home_run, animation): base_runners = bases.runners diff --git a/renderers/main.py b/renderers/main.py index 46fb2479..7768ad0e 100644 --- a/renderers/main.py +++ b/renderers/main.py @@ -146,7 +146,6 @@ def __draw_game(self): game = self.data.current_game bgcolor = self.data.config.scoreboard_colors.color("default.background") self.canvas.Fill(bgcolor["r"], bgcolor["g"], bgcolor["b"]) - scoreboard = Scoreboard(game) layout = self.data.config.layout colors = self.data.config.scoreboard_colors From 2512ab384cece925ccda105474faed1589711edb Mon Sep 17 00:00:00 2001 From: pawptart Date: Thu, 28 Apr 2022 23:37:21 -0400 Subject: [PATCH 09/24] Add issue template and version information --- ISSUE_TEMPLATE.md | 35 +++++++++++++++++++++++++++++++++++ README.md | 9 ++++++++- main.py | 5 +---- version.py | 6 ++++++ 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 ISSUE_TEMPLATE.md create mode 100644 version.py diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..159dff7f --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,35 @@ + + +## This issue is a + +- [ ] Bug Report +- [ ] Feature Request + + + +## Hardware Configuration + +- Raspberry Pi Revision (4B+/3B+/Zero/etc.): +- Operating System: +- Matrix size: +- Display adapter (HAT/Bonnet/etc.): + - Additional information: +- Power source(s): + + + +## Software Configuration + + + +- MLB LED Scoreboard Version: +- Commands/arguments used to start the scoreboard: + +## Expected behavior + + +## Actual behavior + + +## Additional Information + diff --git a/README.md b/README.md index 69fd4c43..ef18d8ec 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# mlb-led-scoreboard [![Join Slack](https://img.shields.io/badge/slack-join-blue.svg)](https://mlb-led-scoreboard.herokuapp.com/) +# mlb-led-scoreboard +![Current Version](https://img.shields.io/github/v/release/MLB-LED-Scoreboard/MLB-LED-Scoreboard) [![Join Slack](https://img.shields.io/badge/slack-join-blue.svg)](https://mlb-led-scoreboard.herokuapp.com/) --------------- @@ -104,6 +105,12 @@ It will also install the following python libraries that are required for certai That should be it! Your latest version should now be working with whatever new fangled features were just added. +#### Version Information + +You can check the version information for your installation of mlb-led-scoreboard by running `python3 version.py`. + +The latest version of the software is available [here](https://github.com/MLB-LED-Scoreboard/mlb-led-scoreboard/releases). + #### Time Zones Make sure your Raspberry Pi's timezone is configured to your local time zone. They'll often have London time on them by default. You can change the timezone of your raspberry pi by running `sudo raspi-config`. diff --git a/main.py b/main.py index 51adcc4f..58d372b5 100755 --- a/main.py +++ b/main.py @@ -16,6 +16,7 @@ from data.config import Config from renderers.main import MainRenderer from utils import args, led_matrix_options +from version import SCRIPT_NAME, SCRIPT_VERSION try: from rgbmatrix import RGBMatrix, __version__ @@ -27,10 +28,6 @@ emulated = True -SCRIPT_NAME = "MLB LED Scoreboard" -SCRIPT_VERSION = "5.0.4" - - def main(matrix, config_base): # Read scoreboard options from config.json if it exists diff --git a/version.py b/version.py new file mode 100644 index 00000000..e040bcf2 --- /dev/null +++ b/version.py @@ -0,0 +1,6 @@ +SCRIPT_NAME = "MLB LED Scoreboard" +SCRIPT_VERSION = "5.0.4" + + +if __name__ == "__main__": + print(f"{SCRIPT_NAME} v{SCRIPT_VERSION}") \ No newline at end of file From bd82303bbe32097668d3690c242b905468de2420 Mon Sep 17 00:00:00 2001 From: pawptart Date: Thu, 28 Apr 2022 23:39:04 -0400 Subject: [PATCH 10/24] Fix newline --- version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.py b/version.py index e040bcf2..1322e7b0 100644 --- a/version.py +++ b/version.py @@ -3,4 +3,4 @@ if __name__ == "__main__": - print(f"{SCRIPT_NAME} v{SCRIPT_VERSION}") \ No newline at end of file + print(f"{SCRIPT_NAME} v{SCRIPT_VERSION}") From 022adabedad86bcd0f75eee5064ec5a84bf5050b Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Fri, 29 Apr 2022 09:15:17 -0400 Subject: [PATCH 11/24] Added PITCH_LONG and PITCH_SHORT configurable dict --- data/pitches.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 data/pitches.py diff --git a/data/pitches.py b/data/pitches.py new file mode 100644 index 00000000..64de0516 --- /dev/null +++ b/data/pitches.py @@ -0,0 +1,45 @@ +#A list of mlb pitch types appearing in statcast +#https://www.daktronics.com/en-us/support/kb/DD3312647 +#Dont change the index, but feel free to change +#the long descriptions + +PITCH_LONG = { + "AB": "Automatic Ball", + "AS": "Automatic Strike", + "CH": "Change-up", + "EP": "Eephus", + "FC": "Cutter", + "FF": "4 Seam Fastball", #MLB default is "Four-Seam Fastball" + "FO": "Forkball", + "FS": "Splitter", + "FT": "2 Seam Fastball", #MLB default is "Two-Seam Fastball" + "GY": "Gyroball", + "IN": "Intentional Ball", + "KC": "Knuckle Curve", + "KN": "Knuckleball", + "NP": "No Pitch", + "SC": "Screwball", + "SI": "Sinker", + "SL": "Slider", + "UN": "Unknown" +} +PITCH_SHORT = { + "AB": "AB", + "AS": "AS", + "CH": "CH", + "EP": "EP", + "FC": "FC", + "FF": "FF", + "FO": "FO", + "FS": "FS", + "FT": "FT", + "GY": "GY", + "IN": "IN", + "KC": "KC", + "KN": "KN", + "NP": "NP", + "SC": "SC", + "SI": "SI", + "SL": "SL", + "UN": "UN" +} \ No newline at end of file From 772c212af2e15af438c67a2a1026a0b575a68800 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Fri, 29 Apr 2022 09:15:56 -0400 Subject: [PATCH 12/24] Commit --- data/scoreboard/pitches.py | 6 +++--- renderers/games/game.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/scoreboard/pitches.py b/data/scoreboard/pitches.py index 23689b56..917f0598 100644 --- a/data/scoreboard/pitches.py +++ b/data/scoreboard/pitches.py @@ -1,5 +1,5 @@ from data.game import Game - +import data.pitches class Pitches: def __init__(self, game: Game): @@ -12,8 +12,8 @@ def __init__(self, game: Game): self.last_pitch_type_long = "Unknown" else: self.last_pitch_speed = f"{round(last_pitch[0])}" - self.last_pitch_type = last_pitch[1] - self.last_pitch_type_long = last_pitch[2] + self.last_pitch_type = data.pitches.PITCH_SHORT[last_pitch[1]] + self.last_pitch_type_long = data.pitches.PITCH_LONG[last_pitch[1]] def __str__(self) -> str: return f"Count: {self.balls} - {self.strikes}. Last pitch: {self.last_pitch_speed}mph {self.last_pitch_type} {self.last_pitch_long}" diff --git a/renderers/games/game.py b/renderers/games/game.py index 0701ad53..411453ef 100644 --- a/renderers/games/game.py +++ b/renderers/games/game.py @@ -121,7 +121,7 @@ def __render_pitch_text(canvas, layout, colors, pitches: Pitches): if(layout.coords("atbat.pitch")["mph"]): mph="mph " if(layout.coords("atbat.pitch")["desc_length"]=="Long"): - pitch_text = str(pitches.last_pitch_speed) + mph + pitches.last_pitch_type_long[0:23] + pitch_text = str(pitches.last_pitch_speed) + mph + pitches.last_pitch_type_long elif(layout.coords("atbat.pitch")["desc_length"]=="Short"): pitch_text = str(pitches.last_pitch_speed) + mph + pitches.last_pitch_type else: From 3788dfe2be842eec22129b9a0bf64c142909047f Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Fri, 29 Apr 2022 09:23:25 -0400 Subject: [PATCH 13/24] Update renderers/games/teams.py Co-authored-by: Tyler Porter --- renderers/games/teams.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/renderers/games/teams.py b/renderers/games/teams.py index e4a4978b..2adf8038 100644 --- a/renderers/games/teams.py +++ b/renderers/games/teams.py @@ -53,8 +53,10 @@ def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_t y_offset = accent_coords[team]["y"] canvas.SetPixel(x + x_offset, y + y_offset, color["r"], color["g"], color["b"]) - __render_team_text(canvas, layout, away_colors, away_team, "away", full_team_names, default_colors, short_team_names_for_runs_hits, home_team) - __render_team_text(canvas, layout, home_colors, home_team, "home", full_team_names, default_colors, short_team_names_for_runs_hits, away_team) + use_full_team_names = can_use_full_team_names(canvas, full_team_names, short_team_names_for_runs_hits, [home_team, away_team]) + + __render_team_text(canvas, layout, away_colors, away_team, "away", use_full_team_names, default_colors) + __render_team_text(canvas, layout, home_colors, home_team, "home", use_full_team_names, default_colors) # Number of characters in each score. score_spacing = { From 7dfc4f08358acb39c0ec88972576291f09696996 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Fri, 29 Apr 2022 09:23:40 -0400 Subject: [PATCH 14/24] Update renderers/games/teams.py Co-authored-by: Tyler Porter --- renderers/games/teams.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/renderers/games/teams.py b/renderers/games/teams.py index 2adf8038..eb1e5361 100644 --- a/renderers/games/teams.py +++ b/renderers/games/teams.py @@ -82,7 +82,7 @@ def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, coords = layout.coords("teams.name.{}".format(homeaway)) font = layout.font("teams.name.{}".format(homeaway)) team_text = "{:3s}".format(team.abbrev.upper()) - if full_team_names and canvas.width > 32 and not (short_team_names_for_runs_hits and (team.runs > 9 or team.hits > 9 or vs_team.runs > 9 or vs_team.hits > 9)): + if use_full_team_names: team_text = "{:13s}".format(team.name) graphics.DrawText(canvas, font["font"], coords["x"], coords["y"], text_color_graphic, team_text) From 693d9182d4fe54ed59f04d4263f13a648c702d50 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Fri, 29 Apr 2022 13:55:45 -0400 Subject: [PATCH 15/24] Added __can_use_full_team_names --- renderers/games/teams.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/renderers/games/teams.py b/renderers/games/teams.py index eb1e5361..357769d8 100644 --- a/renderers/games/teams.py +++ b/renderers/games/teams.py @@ -86,6 +86,15 @@ def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, team_text = "{:13s}".format(team.name) graphics.DrawText(canvas, font["font"], coords["x"], coords["y"], text_color_graphic, team_text) +def __can_use_full_team_names(canvas, enabled, abbreviate_on_overflow, teams): + if enabled and canvas.width > 32: + if abbreviate_on_overflow: + for team in teams: + if team.runs > 9 or team.hits > 9: + return False + else: + return True + return False def __render_score_component(canvas, layout, colors, homeaway, default_colors, coords, component_val, width_chars): # The coords passed in are the rightmost pixel. From 20ab1c4f82dd547638d116f77ee79423db78e565 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Fri, 29 Apr 2022 14:01:10 -0400 Subject: [PATCH 16/24] added can_use_full_team_names --- renderers/games/teams.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/renderers/games/teams.py b/renderers/games/teams.py index 357769d8..43f2488d 100644 --- a/renderers/games/teams.py +++ b/renderers/games/teams.py @@ -3,7 +3,6 @@ except ImportError: from RGBMatrixEmulator import graphics - def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_team_names, short_team_names_for_runs_hits,): default_colors = team_colors.color("default") @@ -55,8 +54,8 @@ def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_t use_full_team_names = can_use_full_team_names(canvas, full_team_names, short_team_names_for_runs_hits, [home_team, away_team]) - __render_team_text(canvas, layout, away_colors, away_team, "away", use_full_team_names, default_colors) - __render_team_text(canvas, layout, home_colors, home_team, "home", use_full_team_names, default_colors) + __render_team_text(canvas, layout, away_colors, away_team, "away", use_full_team_names, default_colors, use_full_team_names) + __render_team_text(canvas, layout, home_colors, home_team, "home", use_full_team_names, default_colors, use_full_team_names) # Number of characters in each score. score_spacing = { @@ -67,6 +66,15 @@ def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_t __render_team_score(canvas, layout, away_colors, away_team, "away", default_colors, score_spacing) __render_team_score(canvas, layout, home_colors, home_team, "home", default_colors, score_spacing) +def can_use_full_team_names(canvas, enabled, abbreviate_on_overflow, teams): + if enabled and canvas.width > 32: + if abbreviate_on_overflow: + for team in teams: + if team.runs > 9 or team.hits > 9: + return False + else: + return True + return False def __team_colors(team_colors, team_abbrev): try: @@ -76,7 +84,7 @@ def __team_colors(team_colors, team_abbrev): return team_colors -def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, default_colors, short_team_names_for_runs_hits, vs_team): +def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, default_colors, use_full_team_names): text_color = colors.get("text", default_colors["text"]) text_color_graphic = graphics.Color(text_color["r"], text_color["g"], text_color["b"]) coords = layout.coords("teams.name.{}".format(homeaway)) @@ -86,16 +94,6 @@ def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, team_text = "{:13s}".format(team.name) graphics.DrawText(canvas, font["font"], coords["x"], coords["y"], text_color_graphic, team_text) -def __can_use_full_team_names(canvas, enabled, abbreviate_on_overflow, teams): - if enabled and canvas.width > 32: - if abbreviate_on_overflow: - for team in teams: - if team.runs > 9 or team.hits > 9: - return False - else: - return True - return False - def __render_score_component(canvas, layout, colors, homeaway, default_colors, coords, component_val, width_chars): # The coords passed in are the rightmost pixel. font = layout.font(f"teams.runs.{homeaway}") From e429320c6a0aab70b5ec52ce5dca3bb186545c09 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Fri, 29 Apr 2022 14:47:44 -0400 Subject: [PATCH 17/24] Update 128x64 bord layout to show pitches --- coordinates/w128h64.json.example | 92 ++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 39 deletions(-) diff --git a/coordinates/w128h64.json.example b/coordinates/w128h64.json.example index b823ebec..cf0537e2 100644 --- a/coordinates/w128h64.json.example +++ b/coordinates/w128h64.json.example @@ -1,22 +1,22 @@ { "defaults": { - "font_name": "9x18B" + "font_name": "7x13" }, "bases": { "1B": { "x": 112, "y": 42, - "size": 14 + "size": 10 }, "2B": { "x": 103, "y": 33, - "size": 14 + "size": 10 }, "3B": { "x": 94, "y": 42, - "size": 14 + "size": 10 } }, "final": { @@ -46,7 +46,7 @@ }, "due_up": { "due": { - "font_name": "7x13B", + "font_name": "5x7", "x": 38, "y": 44 }, @@ -55,13 +55,13 @@ "y": 56 }, "divider": { - "draw": true, + "draw": false, "x": 36, "y_start": 32, "y_end": 64 }, "leadoff": { - "font_name": "7x13B", + "font_name": "7x13", "x": 64, "y": 42 }, @@ -76,8 +76,8 @@ } }, "number": { - "x": 93, - "y": 45, + "x": 87, + "y": 42, "nohit": { "x": 93, "y": 42 @@ -88,46 +88,56 @@ } }, "arrow": { - "size": 7, + "size": 6, "up": { - "x_offset": -12, - "y_offset": -10 + "x_offset": -11, + "y_offset": -8 }, "down": { - "x_offset": -12, - "y_offset": -2 + "x_offset": -11, + "y_offset": -4 } } }, "outs": { "1": { - "x": 102, - "y": 58, - "size": 4 + "x": 95, + "y": 56, + "size": 5 }, "2": { - "x": 108, - "y": 58, - "size": 4 + "x": 106, + "y": 56, + "size": 5 }, "3": { - "x": 114, - "y": 58, - "size": 4 + "x": 118, + "y": 56, + "size": 5 } }, "atbat": { "batter": { - "font_name": "7x13B", + "font_name": "5x7", "x": 1, "y": 60, "width": 41 }, "pitcher": { - "font_name": "7x13B", + "font_name": "5x7", "x": 1, - "y": 44, - "width": 48 + "y": 40, + "width": 41 + }, + "pitch": { + "font_name": "4x6", + "x": 1, + "y": 50, + "width": 41, + "enabled": true, + "mph": true, + "desc_length": "Long" + }, "loop": 68, "strikeout": { @@ -137,7 +147,7 @@ }, "batter_count": { "x": 66, - "y": 60, + "y": 62, "nohit": { "x": 66, "y": 64 @@ -246,27 +256,31 @@ }, "name": { "away": { + "font_name": "9x18B", "x": 4, - "y": 12 + "y": 13 }, "home": { + "font_name": "9x18B", "x": 4, - "y": 28 + "y": 29 } }, "runs": { "runs_hits_errors": { - "show": false, - "compress_digits": false, - "spacing": 3 - }, + "show": true, + "compress_digits": true, + "spacing": 5 + }, "away": { - "x": 120, - "y": 12 + "font_name": "9x18B", + "x": 126, + "y": 13 }, "home": { - "x": 120, - "y": 28 + "font_name": "9x18B", + "x": 126, + "y": 29 } } }, @@ -321,4 +335,4 @@ "y": 31 } } -} \ No newline at end of file +} From b8713cffdb4da24f30372fe3f0e664663cc3af22 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Fri, 29 Apr 2022 14:58:29 -0400 Subject: [PATCH 18/24] Updated readme's for pitch data --- README.md | 2 ++ coordinates/README.md | 5 +++++ coordinates/w128h64.json.example | 1 - data/pitches.py | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 69fd4c43..0bbb0d9d 100755 --- a/README.md +++ b/README.md @@ -169,6 +169,8 @@ A default `config.json.example` file is included for reference. Copy this file t ### Additional Features * Runs/Hits/Errors - Runs are always shown on the games screen, but you can enable or adjust spacing of a "runs, hits, errors" display. Take a look at the [coordinates readme file](/coordinates/README.md) for details. +* Pitch Data - Pitch data can be shown on the game screen, See the [coordinates readme file](/coordinates/README.md) for details. In addition, the Short and Long pitch description can be changed in data/pitches.py + ### Flags You can configure your LED matrix with the same flags used in the [rpi-rgb-led-matrix](https://github.com/hzeller/rpi-rgb-led-matrix) library. More information on these arguments can be found in the library documentation. diff --git a/coordinates/README.md b/coordinates/README.md index 6672ead3..c500b32f 100644 --- a/coordinates/README.md +++ b/coordinates/README.md @@ -18,6 +18,11 @@ The layout can have a couple of different states where things are rendered diffe * `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. + ## 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. diff --git a/coordinates/w128h64.json.example b/coordinates/w128h64.json.example index cf0537e2..b21d82ee 100644 --- a/coordinates/w128h64.json.example +++ b/coordinates/w128h64.json.example @@ -137,7 +137,6 @@ "enabled": true, "mph": true, "desc_length": "Long" - }, "loop": 68, "strikeout": { diff --git a/data/pitches.py b/data/pitches.py index 64de0516..eab04246 100644 --- a/data/pitches.py +++ b/data/pitches.py @@ -1,7 +1,7 @@ #A list of mlb pitch types appearing in statcast #https://www.daktronics.com/en-us/support/kb/DD3312647 #Dont change the index, but feel free to change -#the long descriptions +#the descriptions PITCH_LONG = { "AB": "Automatic Ball", From ff8fe0a7a3ec38d46deecea297ba1cef95de0ee1 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Fri, 29 Apr 2022 15:07:05 -0400 Subject: [PATCH 19/24] pitch data not display on all except 128x64 by default --- coordinates/w128h32.json.example | 9 +++++++++ coordinates/w32h32.json.example | 9 +++++++++ coordinates/w64h32.json.example | 9 +++++++++ coordinates/w64h64.json.example | 9 +++++++++ 4 files changed, 36 insertions(+) diff --git a/coordinates/w128h32.json.example b/coordinates/w128h32.json.example index 81bbdf4c..d0aefb87 100644 --- a/coordinates/w128h32.json.example +++ b/coordinates/w128h32.json.example @@ -167,6 +167,15 @@ "y": 30, "width": 40 }, + "pitch": { + "font_name": "4x6", + "x": 1, + "y": 50, + "width": 41, + "enabled": false, + "mph": false, + "desc_length": "Short" + }, "loop": 64, "strikeout": { "x": 84, diff --git a/coordinates/w32h32.json.example b/coordinates/w32h32.json.example index 86401cc7..e4e88529 100644 --- a/coordinates/w32h32.json.example +++ b/coordinates/w32h32.json.example @@ -147,6 +147,15 @@ "y": 33, "width": 12 }, + "pitch": { + "font_name": "4x6", + "x": 1, + "y": 50, + "width": 41, + "enabled": false, + "mph": false, + "desc_length": "Short" + }, "loop": 16, "strikeout": { "x": 33, diff --git a/coordinates/w64h32.json.example b/coordinates/w64h32.json.example index 72574d0b..108819ab 100644 --- a/coordinates/w64h32.json.example +++ b/coordinates/w64h32.json.example @@ -125,6 +125,15 @@ "y": 21, "width": 24 }, + "pitch": { + "font_name": "4x6", + "x": 1, + "y": 50, + "width": 41, + "enabled": false, + "mph": false, + "desc_length": "Short" + }, "loop": 36, "strikeout": { "x": 15, diff --git a/coordinates/w64h64.json.example b/coordinates/w64h64.json.example index f5340894..bb752760 100644 --- a/coordinates/w64h64.json.example +++ b/coordinates/w64h64.json.example @@ -123,6 +123,15 @@ "y": 28, "width": 50 }, + "pitch": { + "font_name": "4x6", + "x": 1, + "y": 50, + "width": 41, + "enabled": false, + "mph": false, + "desc_length": "Short" + }, "loop": 64, "strikeout": { "x": 31, From bb60e72a1bbe89bd50415bcee86cfae84c83baa5 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Fri, 29 Apr 2022 20:24:02 -0400 Subject: [PATCH 20/24] Skipped CU (curveball) entry --- data/pitches.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/pitches.py b/data/pitches.py index eab04246..a66606ce 100644 --- a/data/pitches.py +++ b/data/pitches.py @@ -7,6 +7,7 @@ "AB": "Automatic Ball", "AS": "Automatic Strike", "CH": "Change-up", + "CU": "Curveball", "EP": "Eephus", "FC": "Cutter", "FF": "4 Seam Fastball", #MLB default is "Four-Seam Fastball" @@ -27,6 +28,7 @@ "AB": "AB", "AS": "AS", "CH": "CH", + "CU": "CU", "EP": "EP", "FC": "FC", "FF": "FF", From 6a5f6e78ae71c8c7636a225e4648caf850c096b4 Mon Sep 17 00:00:00 2001 From: pawptart Date: Tue, 3 May 2022 16:54:39 -0400 Subject: [PATCH 21/24] Fix double logger in RGBME --- debug.py | 1 + 1 file changed, 1 insertion(+) diff --git a/debug.py b/debug.py index d628bbb5..6c6cc12d 100644 --- a/debug.py +++ b/debug.py @@ -5,6 +5,7 @@ strmhdl = logging.StreamHandler() strmhdl.setFormatter(fmter) logger.addHandler(strmhdl) +logger.propagate = False info = logger.info From c321189598b4504a6855bfa0a8af4d7eaa879920 Mon Sep 17 00:00:00 2001 From: pawptart Date: Tue, 3 May 2022 21:10:04 -0400 Subject: [PATCH 22/24] Fix name abbreviation function --- renderers/games/teams.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/renderers/games/teams.py b/renderers/games/teams.py index 43f2488d..a245540b 100644 --- a/renderers/games/teams.py +++ b/renderers/games/teams.py @@ -3,7 +3,7 @@ except ImportError: from RGBMatrixEmulator import graphics -def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_team_names, short_team_names_for_runs_hits,): +def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_team_names, short_team_names_for_runs_hits): default_colors = team_colors.color("default") away_colors = __team_colors(team_colors, away_team.abbrev) @@ -54,8 +54,8 @@ def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_t use_full_team_names = can_use_full_team_names(canvas, full_team_names, short_team_names_for_runs_hits, [home_team, away_team]) - __render_team_text(canvas, layout, away_colors, away_team, "away", use_full_team_names, default_colors, use_full_team_names) - __render_team_text(canvas, layout, home_colors, home_team, "home", use_full_team_names, default_colors, use_full_team_names) + __render_team_text(canvas, layout, away_colors, away_team, "away", use_full_team_names, default_colors) + __render_team_text(canvas, layout, home_colors, home_team, "home", use_full_team_names, default_colors) # Number of characters in each score. score_spacing = { @@ -72,8 +72,9 @@ def can_use_full_team_names(canvas, enabled, abbreviate_on_overflow, teams): for team in teams: if team.runs > 9 or team.hits > 9: return False - else: - return True + else: + return True + return False def __team_colors(team_colors, team_abbrev): @@ -84,13 +85,13 @@ def __team_colors(team_colors, team_abbrev): return team_colors -def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, default_colors, use_full_team_names): +def __render_team_text(canvas, layout, colors, team, homeaway, full_team_names, default_colors): text_color = colors.get("text", default_colors["text"]) text_color_graphic = graphics.Color(text_color["r"], text_color["g"], text_color["b"]) coords = layout.coords("teams.name.{}".format(homeaway)) font = layout.font("teams.name.{}".format(homeaway)) team_text = "{:3s}".format(team.abbrev.upper()) - if use_full_team_names: + if full_team_names: team_text = "{:13s}".format(team.name) graphics.DrawText(canvas, font["font"], coords["x"], coords["y"], text_color_graphic, team_text) From e7d8f1d02b2b51d6cfbc58a783566c5330d1b638 Mon Sep 17 00:00:00 2001 From: pawptart Date: Tue, 3 May 2022 21:12:38 -0400 Subject: [PATCH 23/24] Add missing return value --- renderers/games/teams.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/renderers/games/teams.py b/renderers/games/teams.py index a245540b..0b09cae0 100644 --- a/renderers/games/teams.py +++ b/renderers/games/teams.py @@ -72,6 +72,8 @@ def can_use_full_team_names(canvas, enabled, abbreviate_on_overflow, teams): for team in teams: if team.runs > 9 or team.hits > 9: return False + + return True else: return True From 9a47aeeeaf90bbb74eed18eddd972593deef4e25 Mon Sep 17 00:00:00 2001 From: pawptart Date: Tue, 3 May 2022 21:15:46 -0400 Subject: [PATCH 24/24] Document nested conditionals --- renderers/games/teams.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/renderers/games/teams.py b/renderers/games/teams.py index 0b09cae0..5f595006 100644 --- a/renderers/games/teams.py +++ b/renderers/games/teams.py @@ -67,16 +67,25 @@ def render_team_banner(canvas, layout, team_colors, home_team, away_team, full_t __render_team_score(canvas, layout, home_colors, home_team, "home", default_colors, score_spacing) def can_use_full_team_names(canvas, enabled, abbreviate_on_overflow, teams): + # Settings enabled and size is able to display it if enabled and canvas.width > 32: + + # If config enabled for abbreviating if runs or hits takes up an additional column (i.e. 9 -> 10) if abbreviate_on_overflow: + + # Iterate through the teams to see if we should abbreviate for team in teams: if team.runs > 9 or team.hits > 9: return False + # Else use full names if no stats column has overflowed return True + + # If config for abbreviating is not set, use full name else: return True + # Fallback to abbreviated names for all cases return False def __team_colors(team_colors, team_abbrev):