could you post the dashboard changes?
Sure - It includes a NASCAR tab as well. I had added the F1 card (pull it from HACS or load following instructions here - GitHub - marcokreeft87/formulaone-card: Present the data of Formula One in a pretty way) as well.
Here is what the F1 tab looks like now -
So other place holder data is in there that I haven’t finished up yet. Play, fix, improve, share.
Here is the code:
decluttering_templates:
f1_standings:
card:
type: custom:flex-table-card
title: '[[title]]'
css:
table+: 'padding: 0px; width: 100%; border-collapse: collapse; margin-top:12px;'
tbody tr td:first-child: 'width: 1%;'
tbody tr td:nth-child(2): 'width: 1%;'
tbody tr td:nth-child(3): 'width: 3%;'
tbody tr td:nth-child(n+4): 'width: 1%;'
tbody tr td:nth-child(5): 'color: green;'
tbody tr td:nth-child(6): 'color: yellow;'
tbody tr td:nth-child(7): 'color: red;'
tbody tr td:nth-child(10): 'background-color: green; color: white;'
tbody tr:hover: 'background-color: dimgrey!important; color:white!important;'
tbody tr:nth-child(4): 'border-bottom: 2px solid green!important;'
tbody tr:nth-child(5): 'border-bottom: 2px solid dodgerblue!important;'
tbody tr:nth-child(6): 'border-bottom: 2px solid dodgerblue!important;'
tbody tr:nth-child(15): 'border-bottom: 2px solid yellow!important;'
tbody tr:nth-child(16): 'border-bottom: 2px solid crimson!important;'
card_mod:
style:
.: |
ha-card {
overflow: auto;
}
$: |
.card-header {
padding-top: 6px!important;
padding-bottom: 4px!important;
font-size: 14px!important;
line-height: 14px!important;
font-weight: bold!important;
}
sort_by:
- entries+
entities:
include: '[[entity]]'
columns:
- name: Rank
data: entries
modify: x.stats.find(y=>y.name == 'rank').displayValue
- name: Country
data: entries
modify: >
(typeof x.athlete.flag !== 'undefined' && typeof x.athlete.flag.alt
!== 'undefined') ? x.athlete.flag.alt : '-'
- name: Driver
data: entries
modify: >-
'<div>' + (typeof x.athlete.flag !== 'undefined' ? '<img src="' +
x.athlete.flag.href + '"
style="width:20px;height:20px;margin-right:5px;">' : '') +
x.athlete.displayName + '</div>'
- name: Championship Points
data: entries
modify: x.stats.find(y=>y.name == 'championshipPts').displayValue
f1_constructor_standings:
card:
type: custom:flex-table-card
title: '[[title]]'
css:
table+: 'padding: 0px; width: 100%; border-collapse: collapse; margin-top:12px;'
tbody tr td:first-child: 'width: 1%;'
tbody tr td:nth-child(2): 'width: 90%;'
tbody tr:hover: 'background-color: dimgrey!important; color:white!important;'
card_mod:
style:
.: |
ha-card {
overflow: auto;
}
$: |
.card-header {
padding-top: 6px!important;
padding-bottom: 4px!important;
font-size: 14px!important;
line-height: 14px!important;
font-weight: bold!important;
}
sort_by:
- entries+
entities:
include: '[[entity]]'
columns:
- name: Rank
data: entries
modify: x.stats.find(y=>y.name == 'rank').displayValue
- name: Team Name
data: entries
modify: >-
'<div style="background-color:#' + x.team.color + ';padding:5px;">'
+ x.team.displayName + '</div>'
f1_calendar:
card:
type: custom:flex-table-card
title: '[[title]]'
css:
table+: 'padding: 0px; width: 100%; border-collapse: collapse; margin-top:12px;'
tbody tr td:first-child: 'width: 10%;'
tbody tr td:nth-child(2): 'width: 20%;'
tbody tr td:nth-child(3): 'width: 20%;'
tbody tr td:nth-child(4): 'width: 20%;'
tbody tr td:nth-child(5): 'width: 20%;'
tbody tr:hover: 'background-color: dimgrey!important; color:white!important;'
card_mod:
style:
.: |
ha-card {
overflow: auto;
}
$: |
.card-header {
padding-top: 6px!important;
padding-bottom: 4px!important;
font-size: 14px!important;
line-height: 14px!important;
font-weight: bold!important;
}
sort_by:
- Date+
entities:
include: '[[entity]]'
columns:
- name: Date
data: Races
modify: x.date
- name: Race
data: Races
modify: x.Circuit.circuitName
- name: Location
data: Races
modify: >-
'<div>' + x.Circuit.Location.locality + " , " +
x.Circuit.Location.country + '</div>'
f1_standings_ergast:
card:
type: custom:flex-table-card
title: '[[title]]'
css:
table+: 'padding: 0px; width: 100%; border-collapse: collapse; margin-top:12px;'
tbody tr td:first-child: 'width: 1%;'
tbody tr td:nth-child(2): 'width: 10%;'
tbody tr td:nth-child(3+): 'width: 5%;'
tbody tr:hover: 'background-color: dimgrey!important; color:white!important;'
card_mod:
style:
.: |
ha-card {
overflow: auto;
}
$: |
.card-header {
padding-top: 6px!important;
padding-bottom: 4px!important;
font-size: 14px!important;
line-height: 14px!important;
font-weight: bold!important;
}
sort_by:
- MRDatat+
entities:
include: '[[entity]]'
columns:
- name: Rank
data: DriverStandings
modify: x.position
- name: Driver
data: DriverStandings
modify: x.Driver.givenName + ' ' + x.Driver.familyName
- name: Age
data: DriverStandings
modify: >
const birthDate = new Date(x.Driver.dateOfBirth); const today = new
Date(); let age = today.getFullYear() - birthDate.getFullYear();
const monthDiff = today.getMonth() - birthDate.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate()))
{ age--; }
age;
- name: Nationality
data: DriverStandings
modify: x.Driver.nationality
- name: Points
data: DriverStandings
modify: x.points
- name: Wins
data: DriverStandings
modify: x.wins
- name: Logo
data: DriverStandings
modify: >-
const constructorLogos = {
red_bull: "https://cdn.racingnews365.com/Teams/Red-Bull/_503xAUTO_crop_center-center_none/f1_2021_redbull_logo.png?v=1643808334",
mercedes: "https://cdn.racingnews365.com/Teams/Mercedes/_503xAUTO_crop_center-center_none/f1_2021_mercedes_logo.png?v=1643808334",
ferrari: "https://cdn.racingnews365.com/Teams/Ferrari/_503xAUTO_crop_center-center_none/f1_2021_ferrari_logo.png?v=1643808334",
mclaren: "https://cdn.racingnews365.com/Teams/McLaren/_503xAUTO_crop_center-center_none/f1_2021_mclaren_logo.png?v=1643808334",
alpine: "https://cdn.racingnews365.com/Teams/Alpine/_503xAUTO_crop_center-center_none/f1_2021_alpine_logo.png?v=1643808334",
aston_martin: "https://cdn.racingnews365.com/Teams/Aston-Martin/_503xAUTO_crop_center-center_none/f1_2021_astonmartin_logo.png?v=1643808334",
williams: "https://cdn.racingnews365.com/Teams/Williams/_503xAUTO_crop_center-center_none/f1_2021_williams_logo.png?v=1643808334",
alfa_romeo: "https://cdn.racingnews365.com/Teams/Alfa-Romeo/_503xAUTO_crop_center-center_none/f1_2021_alfaromeo_logo.png?v=1643808334",
haas: "https://cdn.racingnews365.com/Teams/Haas/_503xAUTO_crop_center-center_none/f1_2021_haas_logo.png?v=1643808334",
alphatauri: "https://cdn.racingnews365.com/Teams/AlphaTauri/_503xAUTO_crop_center-center_none/f1_2021_alphatauri_logo.png?v=1643808334",
sauber: "https://cdn-6.motorsport.com/images/amp/0L17d5W2/s6/logo-stakef1team-rgb-pos-1.jpg",
rb_f1_team: "https://cdn-8.motorsport.com/images/vmt/Dx6zJ6GR/s1/visa-cash-app-rb-logo-unveil-1.jpg",
}; '<div>' + (constructorLogos[x.Constructors[0].constructorId] ?
'<img src="' + constructorLogos[x.Constructors[0].constructorId] +
'" style="width:20px;height:20px;margin-right:5px;">' : '') +
'</div>'
- name: Team
data: DriverStandings
modify: x.Constructors[0].name
- name: Team Nation
data: DriverStandings
modify: x.Constructors[0].nationality
views:
- theme: Backend-selected
title: Sports
type: panel
icon: mdi:strategy
badges: []
cards:
- type: custom:mod-card
card_mod:
style:
tabbed-card $: |
mwc-tab {
background: black;
color: silver;
border-color: var(--ha-card-border-color, var(--divider-color, #e0e0e0));
border-width: 2px;
border-style: solid;
overflow: hidden;
width: 20%;
}
mwc-tab[active] {
background: white !important;
color: black !important;
}
card:
type: custom:tabbed-card
styles:
'--mdc-theme-primary': black
'--mdc-tab-text-label-color-default': silver
'--mdc-typography-button-font-size': 12px
tabs:
- attributes:
label: Racing
icon: mdi:car-sports
card:
type: custom:mod-card
card_mod:
style:
tabbed-card $: |
mwc-tab {
background: black;
border-color: silver;
border-width: 2px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-style: solid;
overflow: hidden;
width: 15%;
}
mwc-tab[active] {
background: white !important;
color: black !important
}
card:
type: custom:tabbed-card
card_mod: null
style:
tabbed-card $: |
mwc-tab {
background: black;
border-color: silver;
border-width: 2px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-style: solid;
overflow: hidden;
width: 10%;
}
mwc-tab[active] {
background: white !important;
color: black !important
}
tabs:
- attributes:
label: Leagues
icon: mdi:football
card:
type: custom:mod-card
card_mod:
style:
tabbed-card $: |
mwc-tab {
background: black;
border-color: silver;
border-width: 2px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-style: solid;
overflow: hidden;
width: 5%;
}
mwc-tab[active] {
background: white !important;
color: black !important;
}
card:
type: custom:tabbed-card
styles:
'--mdc-theme-primary': black
'--mdc-tab-text-label-color-default': silver
'--mdc-typography-button-font-size': 12px
tabs:
- attributes:
label: Formula 1 Racing
icon: mdi:account-group
card:
type: horizontal-stack
cards:
- type: vertical-stack
cards:
- type: markdown
content: |
<h1>F1 Driver Standings</h1>
- type: custom:decluttering-card
template: f1_standings
variables:
- title: F1 Driver Standings
- entity: sensor.f1_driver_standings
- attribute: entries
- type: custom:decluttering-card
template: f1_constructor_standings
variables:
- title: F1 Constructor Standings
- entity: sensor.f1_constructor_standings
- attribute: entries
- type: vertical-stack
cards:
- type: markdown
content: |
<h1>F1 Driver Standings Ergast</h1>
- type: custom:decluttering-card
template: f1_standings_ergast
variables:
- title: F1 Driver Standings
- entity: sensor.f1_driver_standings_ergast
- attribute: MRData
- type: vertical-stack
cards:
- type: markdown
content: |
<h1>F1 Calendar</h1>
- type: custom:decluttering-card
template: f1_calendar
variables:
- title: F1 Calendar Ergast
- entity: sensor.f1_races_ergast
- attribute: Races
- type: custom:formulaone-card
card_type: results
show_raceinfo: true
- attributes:
label: NASCAR Premier Racing
icon: mdi:account-group
card:
type: horizontal-stack
cards:
- type: vertical-stack
cards:
- type: markdown
content: |
<h1>NASCAR Driver Standings</h1>
- type: custom:decluttering-card
template: f1_standings
variables:
- title: NASCAR Driver Standings
- entity: sensor.nascar_premier_driver_standings
- attribute: entries
Bro, you are a true hero. I’ll tinker and get back to you. I do want to figure out how to merge the F1 stuff with my existing NHL stuff;
NHL Dash:
decluttering_templates:
nhl_settings:
card:
type: custom:flex-table-card
title: '[[title]]'
css:
table+: 'padding: 0px; width: 1600px;'
tbody tr td:first-child: 'width: 2%;'
tbody tr td:nth-child(2): 'width: 20%;'
tbody tr td:nth-child(n+3): 'width: 5%;'
tbody tr:hover: 'background-color: red!important; color:white!important;'
tbody tr td:nth-child(7): 'background-color: red; color: white;'
card_mod:
style:
.: |
ha-card {
overflow: auto;
}
$: |
.card-header {
padding-top: 6px!important;
padding-bottom: 4px!important;
font-size: 14px!important;
line-height: 14px!important;
font-weight: bold!important;
}
entities:
include: '[[entity]]'
exclude: '[[excluded_entities]]'
sort_by: entries-
columns:
- hidden: true
data: '[[attribute]]'
modify: '[[sort]]'
- name: <div>C</div>
data: '[[attribute]]'
modify: >-
if(typeof x.stats.find(y=>y.abbreviation == 'CLINCH') !==
'undefined' ){x.stats.find(y=>y.abbreviation ==
'CLINCH').displayValue}else{'-'}
- name: Team
data: '[[attribute]]'
modify: >-
'<div><a href="' + x.team.links[0].href + '" target="_blank"><img
src="' + x.team.logos[0].href + '" style="height:
20px;vertical-align:middle;"></a> ' + x.team.displayName +
'</div>'
- name: <div>GP</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'GP').displayValue
- name: <div>W</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'W').displayValue
- name: <div>L</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'L').displayValue
- name: <div>OTL</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'OTL').displayValue
- name: <div>PTS</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'PTS').displayValue
- name: <div>RW</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'RW').displayValue
- name: <div>ROW</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'ROW').displayValue
- name: <div>SOW</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'SOW').displayValue
- name: <div>SOL</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'SOL').displayValue
- name: <div>HOME</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'HOME').displayValue
- name: <div>AWAY</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'AWAY').displayValue
- name: <div>GF</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'GF').displayValue
- name: <div>GA</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'GA').displayValue
- name: <div>DIFF</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'DIFF').displayValue
- name: <div>L10</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'L10').summary
- name: <div>STRK</div>
data: '[[attribute]]'
modify: x.stats.find(y=>y.abbreviation == 'STRK').displayValue
game_stats:
card:
type: custom:auto-entities
unique: true
show_empty: false
card:
type: custom:layout-card
layout_type: masonry
width: 200px
max-columns: 5
card_param: cards
filter:
template: |
{%- for team in integration_entities("teamtracker") -%}
{%- if state_attr(team, "league") == "[[sport]]" -%}
{%- if states(team) == "[[status]]" -%}
{%- if state_attr(team, "team_homeaway") == "home" -%}
{%- else -%}
{{{"type": "custom:teamtracker-card",
"entity": team,
"home_side": "right"}}},
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
exclude:
- entity_id: '*team_tracker*'
sort:
method: attribute
attribute: date
views:
- theme: Backend-selected
title: Sports
type: panel
icon: mdi:strategy
badges: []
cards:
- type: custom:mod-card
card_mod:
style:
tabbed-card $: |
mwc-tab {
background: var(--ha-card-background, var(--card-background-color, white) );
border-color: var(--ha-card-border-color, var(--divider-color, #e0e0e0) );
border-width: 2px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-style: solid;
overflow: hidden;
width: 25%;
}
mwc-tab[active] {
background: #ffcccc !important;
}
card:
type: custom:tabbed-card
styles:
'--mdc-theme-primary': red
'--mdc-tab-text-label-color-default': silver
'--mdc-typography-button-font-size': 12px
tabs:
- attributes:
label: NHL
icon: mdi:hockey-puck
card:
type: custom:mod-card
card_mod:
style:
tabbed-card $: |
mwc-tab {
background: var(--ha-card-background, var(--card-background-color, white) );
border-color: var(--ha-card-border-color, var(--divider-color, #e0e0e0) );
border-width: 2px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-style: solid;
overflow: hidden;
width: 20%;
}
mwc-tab[active] {
background: #ffcccc !important;
}
card:
type: custom:tabbed-card
styles:
'--mdc-theme-primary': red
'--mdc-tab-text-label-color-default': silver
'--mdc-typography-button-font-size': 12px
tabs:
- attributes:
label: Games
icon: mdi:hockey-sticks
card:
type: custom:mod-card
card_mod:
style:
tabbed-card $: |
mwc-tab {
background: var(--ha-card-background, var(--card-background-color, white) );
border-color: var(--ha-card-border-color, var(--divider-color, #e0e0e0) );
border-width: 2px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-style: solid;
overflow: hidden;
width: 25%;
}
mwc-tab[active] {
background: #ffcccc !important;
}
card:
type: custom:tabbed-card
styles:
'--mdc-theme-primary': red
'--mdc-tab-text-label-color-default': silver
'--mdc-typography-button-font-size': 12px
tabs:
- attributes:
label: Pre, Live, Post Games
icon: mdi:hockey-sticks
card:
type: horizontal-stack
cards:
- type: vertical-stack
cards:
- type: markdown
content: |
<h1>NHL Pre-Games</h1>
- type: custom:decluttering-card
template: game_stats
variables:
- sport: NHL
- status: PRE
- type: markdown
content: |
<h1>NHL Live Games</h1>
- type: custom:decluttering-card
template: game_stats
variables:
- sport: NHL
- status: IN
- type: markdown
content: |
<h1>NHL Post-Games</h1>
- type: custom:decluttering-card
template: game_stats
variables:
- sport: NHL
- status: POST
- attributes:
label: Standings
icon: mdi:ballot
card:
type: custom:mod-card
card_mod:
style:
tabbed-card $: |
mwc-tab {
background: var(--ha-card-background, var(--card-background-color, white) );
border-color: var(--ha-card-border-color, var(--divider-color, #e0e0e0) );
border-width: 2px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-style: solid;
overflow: hidden;
width: 25%;
}
mwc-tab[active] {
background: #ffcccc !important;
}
card:
type: custom:tabbed-card
styles:
'--mdc-theme-primary': red
'--mdc-tab-text-label-color-default': silver
'--mdc-typography-button-font-size': 12px
tabs:
- attributes:
label: Division
card:
type: custom:stack-in-card
mode: vertical
cards:
- type: markdown
content: |
<h2>Eastern Conference</h2>
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Metropolitan
- entity: sensor.nhl_east_metropolitan
- attribute: entries
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- excluded_entities:
- sensor.nhl_starting_goalies
- sensor.nhl_wildcard
- sensor.nhl_wildcard_standings
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Atlantic
- entity: sensor.nhl_east_atlantic
- attribute: entries
- excluded_entities:
- sensor.nhl_starting_goalies
- sensor.nhl_wildcard
- sensor.nhl_wildcard_standings
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: markdown
content: |
<h2>Western Conference</h2>
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Central
- entity: sensor.nhl_west_central
- attribute: entries
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- excluded_entities:
- sensor.nhl_starting_goalies
- sensor.nhl_wildcard
- sensor.nhl_wildcard_standings
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Pacific
- entity: sensor.nhl_west_pacific
- attribute: entries
- excluded_entities:
- sensor.nhl_starting_goalies
- sensor.nhl_wildcard
- sensor.nhl_wildcard_standings
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- excluded_entities:
- sensor.nhl_starting_goalies
- sensor.nhl_wildcard
- sensor.nhl_wildcard_standings
- attributes:
label: Conference
card:
type: custom:stack-in-card
mode: vertical
cards:
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Eastern
- entity: sensor.nhl_east_*
- attribute: entries
- excluded_entities:
- sensor.nhl_starting_goalies
- sensor.nhl_wildcard
- sensor.nhl_wildcard_standings
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Western
- entity: sensor.nhl_west_*
- attribute: entries
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- excluded_entities:
- sensor.nhl_starting_goalies
- sensor.nhl_wildcard
- sensor.nhl_wildcard_standings
- attributes:
label: League
card:
type: custom:decluttering-card
template: nhl_settings
variables:
- title: League
- entity: sensor.nhl_*_*
- attribute: entries
- excluded_entities:
- sensor.nhl_starting_goalies
- sensor.nhl_wildcard
- sensor.nhl_wildcard_standings
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- attributes:
label: Wildcard
card:
type: custom:stack-in-card
mode: vertical
cards:
- type: markdown
content: |
<h2>Eastern Conference</h2>
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Metropolitan Leaders
- entity: sensor.nhl_wildcard_standings
- attribute: east_metropolitan_top
- excluded_entities:
- sensor.nhl_starting_goalies
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Atlantic Leaders
- entity: sensor.nhl_wildcard_standings
- attribute: east_atlantic_top
- excluded_entities:
- sensor.nhl_starting_goalies
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Wildcards
- entity: sensor.nhl_wildcard_standings
- attribute: east_wildcard
- excluded_entities:
- sensor.nhl_starting_goalies
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: In The Hunt
- entity: sensor.nhl_wildcard_standings
- attribute: east_hunt
- excluded_entities:
- sensor.nhl_starting_goalies
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Eliminated
- entity: sensor.nhl_wildcard_standings
- attribute: east_eliminated
- excluded_entities:
- sensor.nhl_starting_goalies
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: markdown
content: |
<h2>Western Conference</h2>
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Central Leaders
- entity: sensor.nhl_wildcard_standings
- attribute: west_central_top
- excluded_entities:
- sensor.nhl_starting_goalies
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Pacific Leaders
- entity: sensor.nhl_wildcard_standings
- attribute: west_pacific_top
- excluded_entities:
- sensor.nhl_starting_goalies
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Wildcards
- entity: sensor.nhl_wildcard_standings
- attribute: west_wildcard
- excluded_entities:
- sensor.nhl_starting_goalies
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: In The Hunt
- entity: sensor.nhl_wildcard_standings
- attribute: west_hunt
- excluded_entities:
- sensor.nhl_starting_goalies
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
- type: custom:decluttering-card
template: nhl_settings
variables:
- title: Eliminated
- entity: sensor.nhl_wildcard_standings
- attribute: west_eliminated
- excluded_entities:
- sensor.nhl_starting_goalies
- sort: >-
x.stats.find(y=>y.shortDisplayName ==
'PTS').value
subview: true
title: Sports Standings and Scores
F1 (Basically yours, with minor tweaks) ;
decluttering_templates:
f1_standings:
card:
type: custom:flex-table-card
title: '[[title]]'
css:
table+: 'padding: 0px; width: 100%; border-collapse: collapse; margin-top:12px;'
tbody tr td:first-child: 'width: 1%;'
tbody tr td:nth-child(2): 'width: 1%;'
tbody tr td:nth-child(3): 'width: 3%;'
tbody tr td:nth-child(n+4): 'width: 1%;'
tbody tr td:nth-child(5): 'color: green;'
tbody tr td:nth-child(6): 'color: yellow;'
tbody tr td:nth-child(7): 'color: red;'
tbody tr td:nth-child(10): 'background-color: green; color: white;'
tbody tr:hover: 'background-color: dimgrey!important; color:white!important;'
tbody tr:nth-child(4): 'border-bottom: 2px solid green!important;'
tbody tr:nth-child(5): 'border-bottom: 2px solid dodgerblue!important;'
tbody tr:nth-child(6): 'border-bottom: 2px solid dodgerblue!important;'
tbody tr:nth-child(15): 'border-bottom: 2px solid yellow!important;'
tbody tr:nth-child(16): 'border-bottom: 2px solid crimson!important;'
card_mod:
style:
.: |
ha-card {
overflow: auto;
}
$: |
.card-header {
padding-top: 6px!important;
padding-bottom: 4px!important;
font-size: 14px!important;
line-height: 14px!important;
font-weight: bold!important;
}
sort_by:
- entries+
entities:
include: '[[entity]]'
columns:
- name: Rank
data: entries
modify: x.stats.find(y=>y.name == 'rank').displayValue
- name: Country
data: entries
modify: >
(typeof x.athlete.flag !== 'undefined' && typeof x.athlete.flag.alt
!== 'undefined') ? x.athlete.flag.alt : '-'
- name: Driver
data: entries
modify: >-
'<div>' + (typeof x.athlete.flag !== 'undefined' ? '<img src="' +
x.athlete.flag.href + '"
style="width:20px;height:20px;margin-right:5px;">' : '') +
x.athlete.displayName + '</div>'
- name: Championship Points
data: entries
modify: x.stats.find(y=>y.name == 'championshipPts').displayValue
f1_constructor_standings:
card:
type: custom:flex-table-card
title: '[[title]]'
css:
table+: 'padding: 0px; width: 100%; border-collapse: collapse; margin-top:12px;'
tbody tr td:first-child: 'width: 1%;'
tbody tr td:nth-child(2): 'width: 90%;'
tbody tr:hover: 'background-color: dimgrey!important; color:white!important;'
card_mod:
style:
.: |
ha-card {
overflow: auto;
}
$: |
.card-header {
padding-top: 6px!important;
padding-bottom: 4px!important;
font-size: 14px!important;
line-height: 14px!important;
font-weight: bold!important;
}
sort_by:
- entries+
entities:
include: '[[entity]]'
columns:
- name: Rank
data: entries
modify: x.stats.find(y=>y.name == 'rank').displayValue
- name: Team Name
data: entries
modify: >-
'<div style="background-color:#' + x.team.color + ';padding:5px;">'
+ x.team.displayName + '</div>'
f1_calendar:
card:
type: custom:flex-table-card
title: '[[title]]'
css:
table+: 'padding: 0px; width: 100%; border-collapse: collapse; margin-top:12px;'
tbody tr td:first-child: 'width: 10%;'
tbody tr td:nth-child(2): 'width: 20%;'
tbody tr td:nth-child(3): 'width: 20%;'
tbody tr td:nth-child(4): 'width: 20%;'
tbody tr td:nth-child(5): 'width: 20%;'
tbody tr:hover: 'background-color: dimgrey!important; color:white!important;'
card_mod:
style:
.: |
ha-card {
overflow: auto;
}
$: |
.card-header {
padding-top: 6px!important;
padding-bottom: 4px!important;
font-size: 14px!important;
line-height: 14px!important;
font-weight: bold!important;
}
sort_by:
- Date+
entities:
include: '[[entity]]'
columns:
- name: Date
data: Races
modify: x.date
- name: Race
data: Races
modify: x.Circuit.circuitName
- name: Location
data: Races
modify: >-
'<div>' + x.Circuit.Location.locality + " , " +
x.Circuit.Location.country + '</div>'
f1_standings_ergast:
card:
type: custom:flex-table-card
title: '[[title]]'
css:
table+: 'padding: 0px; width: 100%; border-collapse: collapse; margin-top:12px;'
tbody tr td:first-child: 'width: 1%;'
tbody tr td:nth-child(2): 'width: 10%;'
tbody tr td:nth-child(3+): 'width: 5%;'
tbody tr:hover: 'background-color: dimgrey!important; color:white!important;'
card_mod:
style:
.: |
ha-card {
overflow: auto;
}
$: |
.card-header {
padding-top: 6px!important;
padding-bottom: 4px!important;
font-size: 14px!important;
line-height: 14px!important;
font-weight: bold!important;
}
sort_by:
- MRDatat+
entities:
include: '[[entity]]'
columns:
- name: Rank
data: DriverStandings
modify: x.position
- name: Driver
data: DriverStandings
modify: x.Driver.givenName + ' ' + x.Driver.familyName
- name: Age
data: DriverStandings
modify: >
const birthDate = new Date(x.Driver.dateOfBirth); const today = new
Date(); let age = today.getFullYear() - birthDate.getFullYear();
const monthDiff = today.getMonth() - birthDate.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate()))
{ age--; }
age;
- name: Nationality
data: DriverStandings
modify: x.Driver.nationality
- name: Points
data: DriverStandings
modify: x.points
- name: Wins
data: DriverStandings
modify: x.wins
- name: Logo
data: DriverStandings
modify: >-
const constructorLogos = {
red_bull: "https://cdn.racingnews365.com/Teams/Red-Bull/_503xAUTO_crop_center-center_none/f1_2021_redbull_logo.png?v=1643808334",
mercedes: "https://cdn.racingnews365.com/Teams/Mercedes/_503xAUTO_crop_center-center_none/f1_2021_mercedes_logo.png?v=1643808334",
ferrari: "https://cdn.racingnews365.com/Teams/Ferrari/_503xAUTO_crop_center-center_none/f1_2021_ferrari_logo.png?v=1643808334",
mclaren: "https://cdn.racingnews365.com/Teams/McLaren/_503xAUTO_crop_center-center_none/f1_2021_mclaren_logo.png?v=1643808334",
alpine: "https://cdn.racingnews365.com/Teams/Alpine/_503xAUTO_crop_center-center_none/f1_2021_alpine_logo.png?v=1643808334",
aston_martin: "https://cdn.racingnews365.com/Teams/Aston-Martin/_503xAUTO_crop_center-center_none/f1_2021_astonmartin_logo.png?v=1643808334",
williams: "https://cdn.racingnews365.com/Teams/Williams/_503xAUTO_crop_center-center_none/f1_2021_williams_logo.png?v=1643808334",
alfa_romeo: "https://cdn.racingnews365.com/Teams/Alfa-Romeo/_503xAUTO_crop_center-center_none/f1_2021_alfaromeo_logo.png?v=1643808334",
haas: "https://cdn.racingnews365.com/Teams/Haas/_503xAUTO_crop_center-center_none/f1_2021_haas_logo.png?v=1643808334",
alphatauri: "https://cdn.racingnews365.com/Teams/AlphaTauri/_503xAUTO_crop_center-center_none/f1_2021_alphatauri_logo.png?v=1643808334",
sauber: "https://cdn-6.motorsport.com/images/amp/0L17d5W2/s6/logo-stakef1team-rgb-pos-1.jpg",
rb_f1_team: "https://cdn-8.motorsport.com/images/vmt/Dx6zJ6GR/s1/visa-cash-app-rb-logo-unveil-1.jpg",
}; '<div>' + (constructorLogos[x.Constructors[0].constructorId] ?
'<img src="' + constructorLogos[x.Constructors[0].constructorId] +
'" style="width:20px;height:20px;margin-right:5px;">' : '') +
'</div>'
- name: Team
data: DriverStandings
modify: x.Constructors[0].name
- name: Team Nation
data: DriverStandings
modify: x.Constructors[0].nationality
views:
- theme: Backend-selected
title: Sports
type: panel
icon: mdi:strategy
badges: []
cards:
- type: custom:mod-card
card_mod:
style:
tabbed-card $: |
mwc-tab {
background: black;
color: silver;
border-color: var(--ha-card-border-color, var(--divider-color, #e0e0e0));
border-width: 2px;
border-style: solid;
overflow: hidden;
width: 20%;
}
mwc-tab[active] {
background: white !important;
color: black !important;
}
card:
type: custom:tabbed-card
styles:
'--mdc-theme-primary': black
'--mdc-tab-text-label-color-default': silver
'--mdc-typography-button-font-size': 12px
tabs:
- attributes:
label: Racing
icon: mdi:car-sports
card:
type: custom:mod-card
card_mod:
style:
tabbed-card $: |
mwc-tab {
background: black;
border-color: silver;
border-width: 2px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-style: solid;
overflow: hidden;
width: 15%;
}
mwc-tab[active] {
background: white !important;
color: black !important
}
card:
type: custom:tabbed-card
card_mod: null
style:
tabbed-card $: |
mwc-tab {
background: black;
border-color: silver;
border-width: 2px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-style: solid;
overflow: hidden;
width: 10%;
}
mwc-tab[active] {
background: white !important;
color: black !important
}
tabs:
- attributes:
label: Formula 1
icon: mdi:racing-helmet
card:
type: custom:mod-card
card_mod:
style:
tabbed-card $: |
mwc-tab {
background: black;
border-color: silver;
border-width: 2px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-style: solid;
overflow: hidden;
width: 5%;
}
mwc-tab[active] {
background: white !important;
color: black !important;
}
card:
type: custom:tabbed-card
styles:
'--mdc-theme-primary': black
'--mdc-tab-text-label-color-default': silver
'--mdc-typography-button-font-size': 12px
tabs:
- attributes:
label: Standings
icon: mdi:ballot
card:
type: horizontal-stack
cards:
- type: vertical-stack
cards:
- type: markdown
content: |
<h1>F1 Constructor Standings</h1>
- type: custom:decluttering-card
template: f1_standings
variables:
- title: F1 Driver Standings
- entity: sensor.f1_driver_standings
- attribute: entries
- type: custom:decluttering-card
template: f1_constructor_standings
variables:
- title: F1 Constructor Standings
- entity: sensor.f1_constructor_standings
- attribute: entries
- type: vertical-stack
cards:
- type: markdown
content: |
<h1>F1 Driver Standings</h1>
- type: custom:decluttering-card
template: f1_standings_ergast
variables:
- title: F1 Driver Standings
- entity: sensor.f1_driver_standings_ergast
- attribute: MRData
- attributes:
label: Calendar & Results
icon: mdi:calendar-blank-outline
card:
type: horizontal-stack
cards:
- type: custom:formulaone-card
card_type: countdown
f1_font: true
show_raceinfo: true
hide_racedatetimes: false
- type: vertical-stack
cards:
- type: markdown
content: |
<h1>F1 Calendar</h1>
- type: custom:decluttering-card
template: f1_calendar
variables:
- title: F1 Calendar Ergast
- entity: sensor.f1_races_ergast
- attribute: Races
- type: custom:formulaone-card
card_type: last_result
show_raceinfo: true
The idea would be to have NHL/Racing as the top two tabs, NHL would tree down as the dashboard is already. Racing would tree down as F1, NASCAR, etc then to Calendar and Results, Standings
Thoughts?
Working on an NHL/Formula 1 merge right now. Had a thought, i know its hard to test at the moment, as the season has finished…but do you think there’s a sensor somewhere that might be able to pull live timing information and possibly a track map with live positioning data?
This might be a possibility for data streams, not sure if it would work tho. Check it out…Discord link
Have a merge dashboard ready to go, let me know if you want it, its currently too big to post.
As far as combining them yeah just adjust the tab attributes and code accordingly. My guidance would be to create a new dashboard and then copy the decluttering and nhl tabs over to the new dashboard. Clean up and then add F1 piecemeal. That way you don’t mess up your original card and only add the items you want.
Haven’t looked at F1 but a couple items: there is a chat about the F1 Card over at Formula One Card
and @newneo discusses it on this link:
Looking forward to seeing what you create.
any reason this sensor isnt working that im missing?
##
## Formula 1 Constructors Standings
##
- platform: rest
scan_interval: 36000
name: f1_constructor_standings
unique_id: sensor.f1_constructor_standings
resource: https://api.jolpi.ca/ergast/f1/current/constructorstandings.json
value_template: "{{ now() }}"
json_attributes_path: "$.MRData.StandingsTable.StandingsLists[0]"
json_attributes:
- ConstructorStandings
Nothing stands out. Do you have duplicate f1_constructor_standings? I renamed yours because I had a f1_constructor_standings sensor other than that looks good - I used this:
##
## Formula 1 Constructors Standings ehcah
##
- platform: rest
scan_interval: 36000
name: f1_constructor_standings_ehcah
unique_id: sensor.f1_constructor_standings_ehcah
resource: https://api.jolpi.ca/ergast/f1/current/constructorstandings.json
value_template: "{{ now() }}"
json_attributes_path: "$.MRData.StandingsTable.StandingsLists[0]"
json_attributes:
- ConstructorStandings
And this is what I am showing:
displays nothing when loaded into the dashboard
even tried copying the same “layout” from the driver’s standing card…nothing
Start with data please. Do you actually get any data like above?
This looks wrong:
- type: custom:decluttering-card
template: f1_standings
variables:
- title: F1 Driver Standings
- entity: sensor.f1_driver_standings
- attribute: entries
Ain’t no attribute “entries” … maybe “ConstrutorStandings” but way too much to diagnose. Set up a simple example
yes, i get the data, just no output
You use:
json_attributes:
- ConstructorStandings
where does “entries” come from or are you merely copying from NHL?
was working off of what @bburwell had put together. tweaking that and seeing what i could come up with. “entries” comes from the espn api sensor, that has since been changed to the ergast sensor. I adjusted the attribute on the sensor, but not in the dash code
When I copy your code and put it into a new/blank dashboard I am seeing data - see below. I have not altered your code, I am using Kbrown’s NHL sensors and I am using the F1/NASCAR sensors I posted in this thread above.
To kbrown’s point - what are you seeing on your dashboard? Are you seeing NHL Data and not F1 or are you not seeing either?
This is what I am seeing.
Well it is totally unclear, none of you have would work.
“entries” exists as that is in the sensor for other sports.
It is repeating element for rows.
Yours is not “entries”.
Then you are trying to get children to that like
x.stats.find(y=>y.name == 'rank').displayValue
“rank” does not exist.
so you re trying to iterate over nothing and get nothing … so it returns nothing. You need to study in depth how things are wrapped together, you cannot just paste things in. It took months to standardize all those for NHL, MLB, NFL, NBA … others are will not just work the same.
just the Constructor’s standings info…everything else is functioning correctly…its the constructors standings info that isn’t generating any output on the dashboard.
got ya. I’ll continue to tinker with it.
Well my ESPN Constructor does have entries but MonsterBandit your constructor has ConstructorStandings. So the attribute you are passing needs to be ConstructorStandings
- platform: rest
scan_interval: 36000
name: f1_constructor_standings
unique_id: sensor.f1_constructor_standings
resource: https://site.web.api.espn.com/apis/v2/sports/racing/f1/standings?seasontype=1&type=0&level=3
value_template: "{{ now() }}"
json_attributes_path: "$.[1]['standings']"
json_attributes:
- entries
Your Constructor would need to pass ConstructorStandings and the layout is different from the ESPN Constructor that I grab. So you would need to create a decluttering template for that data or you would need to just put the data into a Flex-Table card. The Constructor data I have on the card comes from ESPN
This is what my F1 looks like right now - but I haven’t touched (and need to clean up) in a while
Monster - the items that you are looking for aren’t in your ConstructorStandings sensor.
I changed the sensor so this is the rest sensor I am calling so it doesn’t overlap with my ESPN sensor:
- platform: rest
scan_interval: 36000
name: f1_constructor_standings_monsterbandit
unique_id: sensor.f1_constructor_standings_monsterbandit
resource: https://api.jolpi.ca/ergast/f1/current/constructorstandings.json
value_template: "{{ now() }}"
json_attributes_path: "$.MRData.StandingsTable.StandingsLists[0]"
json_attributes:
- ConstructorStandings
In that sensor you see it doesn’t have things like team color, so you can’t have those in your decluttering template it wont show anything:
So here is something you can build off:
Decluttering:
f1_constructor_standings_monster:
card:
type: custom:flex-table-card
title: '[[title]]'
css:
table+: 'padding: 0px; width: 100%; border-collapse: collapse; margin-top:12px;'
tbody tr td:first-child: 'width: 1%;'
tbody tr td:nth-child(2): 'width: 90%;'
tbody tr:hover: 'background-color: dimgrey!important; color:white!important;'
card_mod:
style:
.: |
ha-card {
overflow: auto;
}
$: |
.card-header {
padding-top: 6px!important;
padding-bottom: 4px!important;
font-size: 14px!important;
line-height: 14px!important;
font-weight: bold!important;
}
sort_by:
- ConstructorStandings+
entities:
include: '[[entity]]'
columns:
- name: Rank
data: ConstructorStandings
modify: x.position
- name: Team Name
data: ConstructorStandings
modify: x.Constructor.constructorId
And to call it here is something that you can start with:
- type: custom:decluttering-card
template: f1_constructor_standings_monster
variables:
- title: F1 Constructor Standings
- entity: >-
sensor.f1_constructor_standings_monsterbandit
- attribute: ConstructorStandings
This is all that is displaying with this code but you can build on it. The new code shows up at the bottom of the screen shot - the top is using the ESPN API and decluttering card I posted before