From a231686523eab3c35ee93c2e63307d4f711eef24 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 6 Nov 2022 12:20:17 -0500 Subject: [PATCH] v0.5.0 Release Candidate (#15) - Added support for the following non-team sports: - Golf - MMA - Racing - Tennis - Ability to configure card to display league abbreviation at top of card --- README.md | 4 +- dist/ha-teamtracker-card.js | 216 ++++++++++++++++++++++++------- dist/localize/languages/en.js | 40 +++++- dist/localize/languages/en_US.js | 40 +++++- 4 files changed, 247 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index b730eb8..121081f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Home Assistant Real-Time Sports Score Card -A Home Assistant frontend custom card that will display real-time updates for teams tracked with the [ha-teamtracker](https://github.com/vasqued2/ha-teamtracker) integration by @vasqued2. Has custom in-game layouts for football, baseball, basketball, and soccer. +A Home Assistant frontend custom card that will display real-time updates for teams tracked with the [ha-teamtracker](https://github.com/vasqued2/ha-teamtracker) integration by @vasqued2. Has custom in-game layouts for football, baseball, basketball, soccer, hockey, volleyball, golf, tennis, mma, and racing. This card was strongly based on the fantastic [ha-nfl-card](https://github.com/D34DC3N73R/ha-nfl-card) by @D34DC3N73R. @@ -63,6 +63,8 @@ Add a Manual card to the dashboard and enter the YAML to configure it as desired | `outline_color` | Specifies outline color. | `white` | No | CSS color or hex value | | `show_timeouts` | Specifies if timeout indicators should be shown. | `true` | No | `true` `false` | | `show_rank` | Specifies if team rank should be shown. | `true` | No | `true` `false` | +| `show_league` | Specifies if league should be shown at the top of the card. | `false` | No | `true` `false` | + ### Examples #### Example 1 diff --git a/dist/ha-teamtracker-card.js b/dist/ha-teamtracker-card.js index 67b86aa..a0b5172 100644 --- a/dist/ha-teamtracker-card.js +++ b/dist/ha-teamtracker-card.js @@ -22,9 +22,21 @@ class TeamTrackerCard extends LitElement { return html``; } + var lang = this.hass.selectedLanguage || this.hass.language || navigator.language || "en" + var t = new Translator(lang); + const stateObj = this.hass.states[this._config.entity]; + var sport = stateObj.attributes.sport; + if (!(["baseball", "basketball","football","hockey", "soccer", "volleyball", "golf", "mma", "racing", "tennis"].includes(sport))) { + sport = "default" + } + const outline = this._config.outline; const outlineColor = this._config.outline_color; + const showLeague = this._config.show_league; + const showTicker = this._config.show_ticker; + const homeSide = this._config.home_side; + var teamProb = 0; if (stateObj.attributes.team_win_probability) { var teamProb = (stateObj.attributes.team_win_probability * 100).toFixed(0); @@ -64,11 +76,6 @@ class TeamTrackerCard extends LitElement { var gameMonth = dateForm.toLocaleDateString(lang, { month: 'short' }); var gameDate = dateForm.toLocaleDateString(lang, { day: '2-digit' }); var outColor = outlineColor; - - var sport = stateObj.attributes.sport; - if (!(["baseball", "basketball","football","hockey", "soccer","volleyball"].includes(sport))) { - sport = "default" - } if (outline == true) { var clrOut = 1; @@ -101,10 +108,14 @@ class TeamTrackerCard extends LitElement { var teamColor = stateObj.attributes.team_colors[0]; var oppoColor = stateObj.attributes.opponent_colors[1]; } - if (stateObj.attributes.team_homeaway == 'away') { + else if (stateObj.attributes.team_homeaway == 'away') { var teamColor = stateObj.attributes.team_colors[1]; var oppoColor = stateObj.attributes.opponent_colors[0]; } + else { + var teamColor = '#ffffff'; + var oppoColor = '#000000'; + } if (stateObj.attributes.possession == stateObj.attributes.team_id) { var teamPoss = 1; @@ -133,13 +144,30 @@ class TeamTrackerCard extends LitElement { // var byeTerm = t.translate("common.byeTerm"); + var title = null + if (showLeague) { + title = stateObj.attributes.league + } + var teamLogo = stateObj.attributes.team_logo + var teamLogoBG = teamLogo + var oppoLogo = stateObj.attributes.opponent_logo + var oppoLogoBG = oppoLogo + if (showLeague) { + teamLogoBG = stateObj.attributes.league_logo + oppoLogoBG = stateObj.attributes.league_logo + } + var finalTerm = t.translate("common.finalTerm", "%s", gameMonth + " " + gameDate); var startTerm = t.translate(sport + ".startTerm"); + var context1 = stateObj.attributes.venue; + var context2 = stateObj.attributes.location; var overUnder = ''; if (stateObj.attributes.overunder) { overUnder = t.translate(sport + ".overUnder", "%s", String(stateObj.attributes.overunder)); } + var odds = stateObj.attributes.odds; + var gameStat1 = ''; if (stateObj.attributes.down_distance_text) { gameStat1 = t.translate(sport + ".gameStat1", "%s", stateObj.attributes.down_distance_text); @@ -151,19 +179,21 @@ class TeamTrackerCard extends LitElement { var gameStat3 = ''; var gameBar = t.translate(sport + ".gameBar"); - var teamBarLabel = t.translate(sport + ".teamBarLabel", "%s", teamProb); - var oppoBarLabel = t.translate(sport + ".oppoBarLabel", "%s", oppoProb); + var teamBarLabel = t.translate(sport + ".teamBarLabel", "%s", String(teamProb)); + var oppoBarLabel = t.translate(sport + ".oppoBarLabel", "%s", String(oppoProb)); var lastPlay = stateObj.attributes.last_play; var lastPlaySpeed = 18; if (lastPlay) { lastPlaySpeed = 18 + Math.floor(lastPlay.length/40) * 5; } - var notFoundTeamBG = stateObj.attributes.league_logo; - var notFoundTeam = stateObj.attributes.league_logo; + var notFoundLogo = stateObj.attributes.league_logo; + var notFoundLogoBG = notFoundLogo; var playClock = stateObj.attributes.clock; var outsDisplay = 'none'; var basesDisplay = 'none'; + var probDisplay = 'inherit'; + var probWrapDisplay = "flex"; var teamTimeouts = stateObj.attributes.team_timeouts; var oppoTimeouts = stateObj.attributes.opponent_timeouts; @@ -178,7 +208,7 @@ class TeamTrackerCard extends LitElement { } var notFoundTerm1 = stateObj.attributes.league + ": " + stateObj.attributes.team_abbr; - var notFoundTerm2 = "" + var notFoundTerm2 = "NOT_FOUND" if (stateObj.attributes.api_message) { notFoundTerm2 = t.translate("common.api_error") var apiTail = stateObj.attributes.api_message.substring(stateObj.attributes.api_message.length - 17) @@ -187,7 +217,7 @@ class TeamTrackerCard extends LitElement { notFoundTerm2 = t.translate("common.no_upcoming_games", "%s", lastDateForm.toLocaleDateString(lang)) } } - + // // MLB Specific Changes // @@ -230,6 +260,18 @@ class TeamTrackerCard extends LitElement { timeoutsDisplay = 'none'; } +// +// Hockey Specific Changes +// +if (sport.includes("hockey")) { + teamProb = stateObj.attributes.team_shots_on_target; + oppoProb = stateObj.attributes.opponent_shots_on_target; + teamBarLabel = t.translate("hockey.teamBarLabel", "%s", String(stateObj.attributes.team_shots_on_target)); + oppoBarLabel = t.translate("hockey.oppoBarLabel", "%s", String(stateObj.attributes.opponent_shots_on_target)); + + timeoutsDisplay = 'none'; +} + // // Volleyball Specific Changes // @@ -247,33 +289,102 @@ class TeamTrackerCard extends LitElement { // // Basketball Specific Changes // - if (sport.includes("basketball")) { -// insert basketball specific changes here +if (sport.includes("basketball")) { + // insert basketball specific changes here + } + +// +// Tennis Specific Changes +// + if (sport.includes("tennis")) { + context2 = t.translate("common.tourney" + stateObj.attributes.odds) + odds = null + gameBar = t.translate("tennis.gameBar", "%s", stateObj.attributes.clock); + teamProb = stateObj.attributes.team_score; + oppoProb = stateObj.attributes.opponent_score; + if (stateObj.attributes.team_shots_on_target) { + gameBar = t.translate("tennis.gameBar", "%s", stateObj.attributes.clock + "(tiebreak)"); + teamBarLabel = t.translate("tennis.teamBarLabel", "%s", stateObj.attributes.team_score +'(' + stateObj.attributes.team_shots_on_target + ')'); + } + else { + teamBarLabel = t.translate("tennis.teamBarLabel", "%s", String(stateObj.attributes.team_score)); + } + if (stateObj.attributes.team_shots_on_target) { + gameBar = t.translate("tennis.gameBar", "%s", stateObj.attributes.clock + "(tiebreak)"); + oppoBarLabel = t.translate("tennis.oppoBarLabel", "%s", stateObj.attributes.opponent_score +'(' + stateObj.attributes.opponent_shots_on_target + ')'); + } + else { + oppoBarLabel = t.translate("tennis.oppoBarLabel", "%s", String(stateObj.attributes.opponent_score )); + } + teamTimeouts = stateObj.attributes.team_sets_won; + oppoTimeouts = stateObj.attributes.opponent_sets_won; + title = stateObj.attributes.event_name + " - " + context2; + + timeoutsDisplay = 'inline'; } + // -// Hockey Specific Changes +// MMA Specific Changes +// + if (sport.includes("mma")) { + title = stateObj.attributes.event_name; + timeoutsDisplay = 'none'; + probDisplay = "none"; + var probWrapDisplay = "none"; + + } + +// +// Racing Specific Changes +// +if (sport.includes("racing")) { + title = stateObj.attributes.event_name; +} + + // - if (sport.includes("hockey")) { +// Golf Specific Changes +// + if (sport.includes("golf")) { teamProb = stateObj.attributes.team_shots_on_target; oppoProb = stateObj.attributes.opponent_shots_on_target; - teamBarLabel = t.translate("hockey.teamBarLabel", "%s", String(stateObj.attributes.team_shots_on_target)); - oppoBarLabel = t.translate("hockey.oppoBarLabel", "%s", String(stateObj.attributes.opponent_shots_on_target)); - + teamBarLabel = t.translate("golf.teamBarLabel", "%s", stateObj.attributes.team_total_shots +'(' + stateObj.attributes.team_shots_on_target + ')'); + oppoBarLabel = t.translate("golf.oppoBarLabel", "%s", stateObj.attributes.opponent_total_shots +'(' + stateObj.attributes.opponent_shots_on_target + ')'); + finalTerm = stateObj.attributes.clock; + title = stateObj.attributes.event_name; timeoutsDisplay = 'none'; } + if (sport.includes("golf") || sport.includes("racing")) { + if (Boolean(stateObj.state == 'POST') && Number(tScr) < Number(oScr)) { + oppoScore = 0.6; + teamScore = 1; + } + if (Boolean(stateObj.state == 'POST') && Number(tScr) > Number(oScr)) { + oppoScore = 1; + teamScore = 0.6; + } + if (Boolean(stateObj.state == 'POST') && Number(tScr) == Number(oScr)) { + oppoScore = 1; + teamScore = 1; + } + } + + + // // NCAA Specific Changes // if (stateObj.attributes.league.includes("NCAA")) { - notFoundTeam = 'https://a.espncdn.com/i/espn/misc_logos/500/ncaa.png' + notFoundLogo = 'https://a.espncdn.com/i/espn/misc_logos/500/ncaa.png' } if (stateObj.state == 'POST') { return html`
- - +
${title}
+ +
- +
${stateObj.attributes.team_rank} ${stateObj.attributes.team_name}
${stateObj.attributes.team_record}
${tScr}
-
-
+
   
${oScr}
- +
${stateObj.attributes.opponent_rank} ${stateObj.attributes.opponent_name}
${stateObj.attributes.opponent_record}
@@ -316,7 +428,8 @@ class TeamTrackerCard extends LitElement { if (stateObj.state == 'IN') { return html`
- - +
${title}
+ +
- +
${stateObj.attributes.team_rank} ${stateObj.attributes.team_name}
${stateObj.attributes.team_record}
@@ -377,11 +491,11 @@ class TeamTrackerCard extends LitElement {
${stateObj.attributes.team_score}
-
-
+
   
${stateObj.attributes.opponent_score}
- +
${stateObj.attributes.opponent_rank} ${stateObj.attributes.opponent_name}
${stateObj.attributes.opponent_record}
@@ -403,11 +517,11 @@ class TeamTrackerCard extends LitElement {
${gameStat3}
-
${stateObj.attributes.venue}
+
${context1}
${gameStat1}
-
${stateObj.attributes.location}
+
${context2}
${gameStat2}
@@ -431,7 +545,8 @@ class TeamTrackerCard extends LitElement { if (stateObj.state == 'PRE') { return html`
- - +
${title}
+ +
- +
${stateObj.attributes.team_rank} ${stateObj.attributes.team_name}
${stateObj.attributes.team_record}
@@ -466,7 +582,7 @@ class TeamTrackerCard extends LitElement {
${gameTime}
- +
${stateObj.attributes.opponent_rank} ${stateObj.attributes.opponent_name}
${stateObj.attributes.opponent_record}
@@ -474,14 +590,14 @@ class TeamTrackerCard extends LitElement {
${startTerm} ${stateObj.attributes.kickoff_in}
-
${stateObj.attributes.odds}
+
${odds}
-
${stateObj.attributes.venue}
+
${context1}
${overUnder}
-
${stateObj.attributes.location}
+
${context2}
${stateObj.attributes.tv_network}
@@ -503,10 +619,10 @@ class TeamTrackerCard extends LitElement {
- +
- +
${stateObj.attributes.team_name}
${byeTerm}
@@ -531,10 +647,10 @@ class TeamTrackerCard extends LitElement {
- +
- +
${notFoundTerm1}

${notFoundTerm2}
@@ -544,4 +660,4 @@ class TeamTrackerCard extends LitElement { } } -customElements.define("teamtracker-card", TeamTrackerCard); +customElements.define("teamtracker-card", TeamTrackerCard); \ No newline at end of file diff --git a/dist/localize/languages/en.js b/dist/localize/languages/en.js index af5b124..7abdbc0 100644 --- a/dist/localize/languages/en.js +++ b/dist/localize/languages/en.js @@ -3,7 +3,15 @@ export const en = { "api_error": "API Error", "no_upcoming_games": "No upcoming games through %s", "finalTerm": "%s - Final", - "byeTerm": "BYE" + "byeTerm": "BYE", + "tourney2": "Final", + "tourney4": "Semifinals", + "tourney8": "Quarterfinals", + "tourney16": "Round of 16", + "tourney32": "Round of 32", + "tourney64": "Round of 64", + "tourney128": "Early Rounds", + "tourney256": "Early Rounds" }, "baseball": { "startTerm": "First Pitch", @@ -35,6 +43,16 @@ export const en = { "teamBarLabel": "%s%", "oppoBarLabel": "%s%" }, + "golf": { + "startTerm": "Round Starts", + "overUnder": "O/U: %s", + "gameStat1": "%s", + "gameStat2": "%s", + "gameStat3": "", + "gameBar": "Shots (Thru)", + "teamBarLabel": "%s", + "oppoBarLabel": "%s" + }, "hockey": { "startTerm": "Puck Drop", "overUnder": "O/U: %s", @@ -45,6 +63,16 @@ export const en = { "teamBarLabel": "%s", "oppoBarLabel": "%s" }, + "mma": { + "startTerm": "Start", + "overUnder": "O/U: %s", + "gameStat1": "%s", + "gameStat2": "%s", + "gameStat3": "", + "gameBar": "Win Probability", + "teamBarLabel": "%s%", + "oppoBarLabel": "%s%" + }, "soccer": { "startTerm": "Kickoff", "overUnder": "O/U: %s", @@ -55,6 +83,16 @@ export const en = { "teamBarLabel": "%s", "oppoBarLabel": "%s" }, + "tennis": { + "startTerm": "First Serve", + "overUnder": "O/U: %s", + "gameStat1": "%s", + "gameStat2": "%s", + "gameStat3": "", + "gameBar": "%s", + "teamBarLabel": "%s", + "oppoBarLabel": "%s" + }, "volleyball": { "startTerm": "First Serve", "overUnder": "O/U: %s", diff --git a/dist/localize/languages/en_US.js b/dist/localize/languages/en_US.js index 902609c..6e7dd64 100644 --- a/dist/localize/languages/en_US.js +++ b/dist/localize/languages/en_US.js @@ -3,7 +3,15 @@ export const en_US = { "api_error": "API Error", "no_upcoming_games": "No upcoming games through %s", "finalTerm": "%s - Final", - "byeTerm": "BYE" + "byeTerm": "BYE", + "tourney2": "Final", + "tourney4": "Semifinals", + "tourney8": "Quarterfinals", + "tourney16": "Round of 16", + "tourney32": "Round of 32", + "tourney64": "Round of 64", + "tourney128": "Early Rounds", + "tourney256": "Early Rounds" }, "baseball": { "startTerm": "First Pitch", @@ -35,6 +43,16 @@ export const en_US = { "teamBarLabel": "%s%", "oppoBarLabel": "%s%" }, + "golf": { + "startTerm": "Round Starts", + "overUnder": "O/U: %s", + "gameStat1": "%s", + "gameStat2": "%s", + "gameStat3": "", + "gameBar": "Shots (Thru)", + "teamBarLabel": "%s", + "oppoBarLabel": "%s" + }, "hockey": { "startTerm": "Puck Drop", "overUnder": "O/U: %s", @@ -45,6 +63,16 @@ export const en_US = { "teamBarLabel": "%s", "oppoBarLabel": "%s" }, + "mma": { + "startTerm": "Start", + "overUnder": "O/U: %s", + "gameStat1": "%s", + "gameStat2": "%s", + "gameStat3": "", + "gameBar": "Win Probability", + "teamBarLabel": "%s%", + "oppoBarLabel": "%s%" + }, "soccer": { "startTerm": "Kickoff", "overUnder": "O/U: %s", @@ -55,6 +83,16 @@ export const en_US = { "teamBarLabel": "%s", "oppoBarLabel": "%s" }, + "tennis": { + "startTerm": "First Serve", + "overUnder": "O/U: %s", + "gameStat1": "%s", + "gameStat2": "%s", + "gameStat3": "", + "gameBar": "%s", + "teamBarLabel": "%s", + "oppoBarLabel": "%s" + }, "volleyball": { "startTerm": "First Serve", "overUnder": "O/U: %s",