Sports Standings and Scores

Okay - so if You follow what @kbrown01 has you will need to make sure that your template.yaml file has the conferences. Make sure you grab his template.yaml from his github - at the top of this thread.

I moved the conferences from templates.yaml to my sensors because I ran into a limitation with Templates in college football. So I have moved away from templates.

So either use kevin’s template.yaml config or put the following in your sensor.yaml file.

I also put the leagues in their own yaml. So for NFL I have a nfl_sensors.yaml file in a sensors directory. You can see it in the thread above. Here is what I have for NFL in my nfl_sensors.yaml. You could problably put these in your senors.yaml but if you are going to follow a lot of sports it may become unruly.

##
## NFL Standings
##
- platform: rest
  scan_interval: 604800
  name: NFL Standings
  unique_id: sensor.nfl_standings
  resource: https://site.web.api.espn.com/apis/v2/sports/football/nfl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes:
      - children
      
- platform: rest
  scan_interval: 604800
  name: NFL AFC East
  unique_id: sensor.nfl_afc_east
  resource: https://site.web.api.espn.com/apis/v2/sports/football/nfl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes_path: "$.[0]['children'][0]['standings']"
  json_attributes: 
   - entries   

- platform: rest
  scan_interval: 604800
  name: NFL AFC North
  unique_id: sensor.nfl_afc_north
  resource: https://site.web.api.espn.com/apis/v2/sports/football/nfl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes_path: "$.[0]['children'][1]['standings']"
  json_attributes: 
   - entries 
   
- platform: rest
  scan_interval: 604800
  name: NFL AFC South
  unique_id: sensor.nfl_afc_south
  resource: https://site.web.api.espn.com/apis/v2/sports/football/nfl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes_path: "$.[0]['children'][2]['standings']"
  json_attributes: 
   - entries 
   
- platform: rest
  scan_interval: 604800
  name: NFL AFC West
  unique_id: sensor.nfl_afc_west
  resource: https://site.web.api.espn.com/apis/v2/sports/football/nfl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes_path: "$.[0]['children'][3]['standings']"
  json_attributes: 
   - entries 
   
- platform: rest
  scan_interval: 604800
  name: NFL NFC East
  unique_id: sensor.nfl_nfc_east
  resource: https://site.web.api.espn.com/apis/v2/sports/football/nfl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes_path: "$.[1]['children'][0]['standings']"
  json_attributes: 
   - entries 
   
- platform: rest
  scan_interval: 604800
  name: NFL NFC North
  unique_id: sensor.nfl_nfc_north
  resource: https://site.web.api.espn.com/apis/v2/sports/football/nfl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes_path: "$.[1]['children'][1]['standings']"
  json_attributes: 
   - entries 
   
- platform: rest
  scan_interval: 604800
  name: NFL NFC South
  unique_id: sensor.nfl_nfc_south
  resource: https://site.web.api.espn.com/apis/v2/sports/football/nfl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes_path: "$.[1]['children'][2]['standings']"
  json_attributes: 
   - entries 
   
- platform: rest
  scan_interval: 604800
  name: NFL NFC West
  unique_id: sensor.nfl_nfc_west
  resource: https://site.web.api.espn.com/apis/v2/sports/football/nfl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes_path: "$.[1]['children'][3]['standings']"
  json_attributes: 
   - entries  

You need an entry for each conference

Thank you so much. I started getting data now for NFL.

So i just tried for NHL following the same but getting null again:

##
## NHL Standings
##
- platform: rest
  scan_interval: 604800
  name: NHL Standings
  unique_id: sensor.nhl_standings
  resource: https://site.web.api.espn.com/apis/v2/sports/hockey/nhl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes:
    - children

###
### NHL Divisions
###
- platform: rest
  scan_interval: 604800
  name: NHL East Atlantic
  unique_id: sensor.nhl_east_atlantic
  resource: https://site.web.api.espn.com/apis/v2/sports/hockey/nhl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes:
    entries: "{{ state_attr('sensor.nhl_standings','children')[0]['children'][0]['standings']['entries'] }}"

- platform: rest
  scan_interval: 604800
  name: NHL East Metropolitan
  unique_id: sensor.nhl_east_metropolitan
  resource: https://site.web.api.espn.com/apis/v2/sports/hockey/nhl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes:
    entries: "{{ state_attr('sensor.nhl_standings','children')[0]['children'][1]['standings']['entries'] }}"

- platform: rest
  scan_interval: 604800
  name: NHL West Central
  unique_id: sensor.nhl_west_central
  resource: https://site.web.api.espn.com/apis/v2/sports/hockey/nhl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes:
    entries: "{{ state_attr('sensor.nhl_standings','children')[1]['children'][0]['standings']['entries'] }}"

- platform: rest
  scan_interval: 604800
  name: NHL West Pacific
  unique_id: sensor.nhl_west_pacific
  resource: https://site.web.api.espn.com/apis/v2/sports/hockey/nhl/standings?seasontype=2&type=0&level=3
  value_template: "{{ now() }}"
  json_attributes:
    json_entries: "{{ state_attr('sensor.nhl_standings','children')[1]['children'][1]['standings']['entries'] }}"
###
### NHL Wildcard
###
- platform: rest
  scan_interval: 604800
  name: NHL Wildcard Standings
  unique_id: sensor.nhl_wildcard_standings
  resource: https://site.web.api.espn.com/apis/v2/sports/hockey/nhl/standings?region=us&lang=en&contentorigin=espn&type=3&level=2&sort=playoffseed%3Aasc%2Cpoints%3Adesc%2Cgamesplayed%3Aasc%2Crotwins%3Adesc&seasontype=2
  value_template: "{{ now() }}"
  json_attributes:
    east_atlantic_top: "{{ state_attr('sensor.nhl_wildcard','overall')[0]['children'][0]['standings']['entries'] }}"
    east_metropolitan_top: "{{ state_attr('sensor.nhl_wildcard','overall')[0]['children'][1]['standings']['entries'] }}"
    east_wildcard: "{{ state_attr('sensor.nhl_wildcard','children')[0]['standings']['entries'][:2] }}"
    east_hunt: >
      {% set hteams = namespace(hteam=[]) %}
      {% for team in state_attr('sensor.nhl_wildcard','children')[0]['standings']['entries'][2:] %}
        {% for stat in team['stats'] | selectattr('name','eq','clincher') %}
        {% else %}
              {% set hteams.hteam = hteams.hteam + [team] %}
        {% endfor %}
      {% endfor %}
      {{ hteams.hteam }}
    east_eliminated: >
      {% set eteams = namespace(eteam=[]) %}
      {% for team in state_attr('sensor.nhl_wildcard','children')[0]['standings']['entries'][2:] %}
        {% for stat in team['stats'] %}
          {% if stat.name == 'clincher' %}
              {% set eteams.eteam = eteams.eteam + [team] %}
          {% endif %}
        {% endfor %}
      {% endfor %}
      {{ eteams.eteam }}
    west_central_top: "{{ state_attr('sensor.nhl_wildcard','overall')[1]['children'][0]['standings']['entries'] }}"
    west_pacific_top: "{{ state_attr('sensor.nhl_wildcard','overall')[1]['children'][1]['standings']['entries'] }}"
    west_wildcard: "{{ state_attr('sensor.nhl_wildcard','children')[1]['standings']['entries'][:2] }}"
    west_hunt: >
      {% set hteams = namespace(hteam=[]) %}
      {% for team in state_attr('sensor.nhl_wildcard','children')[1]['standings']['entries'][2:] %}
        {% for stat in team['stats'] | selectattr('name','eq','clincher') %}
        {% else %}
              {% set hteams.hteam = hteams.hteam + [team] %}
        {% endfor %}
      {% endfor %}
      {{ hteams.hteam }}
    west_eliminated: >
      {% set eteams = namespace(eteam=[]) %}
      {% for team in state_attr('sensor.nhl_wildcard','children')[1]['standings']['entries'][2:] %}
        {% for stat in team['stats'] %}
          {% if stat.name == 'clincher' %}
              {% set eteams.eteam = eteams.eteam + [team] %}
          {% endif %}
        {% endfor %}
      {% endfor %}
      {{ eteams.eteam }}
type or paste code here

In template editor if i search for any NHL Entity, it gives back a null/none statement. [Ran out of photos I could post]

The status for all my NHL Entities is down as well:

I figured out the above - my sensor code in NHL was incorrect and needed to be chagned properly for each entity in NHL Sensors for the below:

  json_attributes_path: "$.[0]['children'][0]['standings']"
  json_attributes:
    - entries

Thank you to this forum for your time and patience to help! @bburwell

I figured that since I post some of the snippets of the code that I have built off of kbrown’s excellent foundation over the past few months, that it might be useful to create a github site with my sensors/dashboard/code so those that may be looking to compare or might need it would be able to grab.

I have also added some notes on troubleshooting and will update when I can.

Here is link to my github site that may be of some use:
GitHub - bburwell/HA-Sports-Scores: HA Sports Scores, Standings, Sensors and Dashboards

@kbrown01 - please let me know if you want me to delete this post and create a new community thread. Completely understand if you want me to pull this post.

1 Like

keep going!
I’ll cycle back now and again, just finishing my TV remotes that now have DirecTV, Vizio and Samsung

Thanks @kbrown01

Here is what is currently posted on my github:

Here is link to my github site that may be of some use:
GitHub - bburwell/HA-Sports-Scores: HA Sports Scores, Standings, Sensors and Dashboards

Yaml and dashboard configuration for Sports Scores.

I orginally found Kbrowns code because I was trying to get a sports ticker setup and ran across the community site that he started. That is why you will see marquee text scrolling on some of the dashboards.

My goal was to have a single place to look at scores quickly thorugh HA. This is a work in progress and based on the excellent work Kbrown started and others have contributed to. I am just riding coat-tails, go to the thread below to see those who are working to make this project great - Sports Standings and Scores

I would also encourage reviewing the:

They are all a part of this project.

Setup vs Kbrowns

My setup has changed from Kbrowns in that he uses Templates (which work for most sports) where I moved most to REST sensors. The reason was that NCAA conferences sometimes exhausted the limits and wouldn’t return anything. In the sensors directory I have the sensors I populate and are broken out, where possible, by sport.

Dashboards directory has the following dashboard code:

  • US Sports (NHL/NFL/MLB/NBA/WNBA)
  • Soccer (Premier/Championship/English League 1/English League 2/ENL/Budesliga/Bundesliga2/MSL/NWSL)
  • US College NCAA (Mens Football/Mens Basketball)
  • Racing - F1/NASCAR

Sensors directory has the following sesnsor yaml’s broken up by sport:

  • US Sports
    • nhl_sensors.yaml
    • nfl_sensors.yaml
    • mlb_sensors.yaml
    • nba_sensors.yaml
    • wnba_sensors.yaml
  • Soccer
    • soccer_sensors.yaml includes all -Premier/Championship/English League 1/English League 2/ENL/Budesliga/Bundesliga2/MSL/NWSL
  • US College NCAA
    • ncaaf_sensors.yaml (Mens Football)
    • ncaam_sensors.yaml (Mens Basketball)
  • Racing
    • racing_sensors.yaml (F1/NASCAR)

Template.yaml

I also have template.yaml that is used for items that I haven’t converted yet or need to be in the template.yaml.

Configuration.yaml to split up individual sensors

I have added the configuration.yaml section that I use to call the sensors.

Sandbox

I create Sandbox dashboards to test what I am trying to create without messing up my existing dashboards. Because of that I have also included the sandbox code I use and you will see in the sensors/dashboards. Some of it is commented out, some isn’t used, and some are placeholders. I am including the code because I am lazy :wink: and figured some may want to explore some of the items I have done.

Troubleshooting

Lots of good info in the thread above on trouble-shooting and I may add more later.

What I will say is when you run into problems try to figure where some of the basics firsts.

  1. Make sure that the configuration yamls are correct and check your logs. HA needs everything pretty and will let you know in logs (most of the time) where it is having a problem.
  2. Double-check your configuration against my config, kbrown’s or others that may have contributed to the community thread above.
  3. Use the Home Assistant Developer tools (states and template) mostly to check your sensors and see if the data is in the sensor and use template to test code if it isn’t showing up in your dashboard.

Here is an example when I wanted to scroll the data that was included in the nhl_starting_goalies sensor and I wanted to see how it was formatted and if it was there so I tested in the Template first.

You can see that I am using that data with marquee wrapped around to scroll across the header

  1. If there isn’t data in the sensor but you know it is setup correctly, take a look at Settings->Devices & Services->Entities. You can see if there is an error or possibly a duplicate. There have been times that I made a change and HA created a 2nd, duplicate sensor and threw a _2 at the end of it. If this happens, delete the original and then go in and edit the entity and remove the _2. Here is what an error looks like as an example

  2. Be patient on the intial load - if may take a bit to populate the sensors the first time.

  3. Sometimes ESPN changes their formatting and you will most likely need to go in and change the decluttering template.

  4. Ask questions on the community but please use the formatting tools for your code, and show what isn’t working. A bunch of us can test quickly in our environment and possibly help.

  5. 99% of the people on the community want to help. Harsh words may be a language translation thing or if they are being mean the village normally rises up.

Pictures

Here are a couple pics of the dashboards that use the code in the dashboard and sensors directories. Feel free to pull anything out of it you don’t need or won’t use:




3 Likes

@bburwell thanks for your work. I stumbled across the org. GitHub repo yesterday and today I saw your updated one.
But I have some questions/issues on my setup.

I uploaded all yamls from the sensor folder to my sensor folder. Restarted HA and it seems that all sensors are working fine.
I am most interested in the NFL ones so I focus on NFL now.
I created a new Dashboard + edited the dashboard via the raw editor and pasted the content of Sports_US_Professional inside.
Reloaded the page and voila it looks like it works.

BUT there are some missing things
NFL - Standings - Overall → empty site
NFL - Standings - Schedules → only Denver Broncos which I can unfold, but empty again
NFL - Standings - NFL Playoffs → some errors related to templates missing
NFL - Live/Pre/Post… → Empty

See below screenshots



Maybe you can enlighten me how to fix them.
Thanks!

Yeah - sorry playoffs is a work in progress - I was doing it at the same time that I was working on the NCAA CFP so didn’t really finish either yet.

As far as schedules go, I see that ESPN changed their data and they are no longer showing attendance, or rushing for the schedules. So I did a couple changes and the dashboard is updated on github.

The changes:

  • Cleaned up the Playoffs tab so no errors will show by pulling sandbox code.

Schedules Tab for NHL(added) & NFL

  • Schedules (at least for NHL and NFL) follow the same format, so I changed the NFL_team_schedules to just team_schedules
  • removed attendance
  • removed leaders
  • changed code in dashboard to call team_schedules
  • added a tab in NHL(I only have Dallas Stars in sensors, but easy enough add others)

So you should see the following:


There are only 4 teams left in the NFL season playing this weekend and Pre/Live/Post use Teamtracker to get data. Here is what I am showing today on that tab:

Please let me know if you

Hello @bburwell
Indeed I do see the Team Schedules (may add the other teams so I see all), but unfortunately I do not see the scheduled games.
I digged a bit and it seems I do not have sensor.nfl_red_zone as entity which is needed when I check the code

Furthermore I guess that bit of code in the sensor is for testing purposes - seeing it’s your local HA instance?

Well shoot sorry, yeah my template file would be helpful. Just added it to github and tried to pull some of the sandbox items.

The data that Teamtracker uses is created by the sensor. For example the Washington Commanders play this weekend. So teamtracker uses this data:

- platform: teamtracker
  league_id: NFL
  team_id: WSH
  name: Washington Commanders

to create the sensor sensor.washington_commanders which the teamtracker card uses the data in there to populate the card. This is what my sensor is showing right now.

Guessing you are showing that sensor and the data, but the red_zone isn’t there.
That is why you will see in this thread for those that don’t have the NFL data, they also don’t see any data because HA hits red_zone and errors out.

Try adding the template data and let me know if that works. If it doesn’t check the sensor and let us see what you are seeing.

Indeed that works now!
So all is fine except the Overall page somehow. It does work only for WNBA + NBA and not the rest

Using e.g. sensor.nfl_*_* in dev tools it shows data

Yeah - I noticed that as well but I am not certain why yet. It is pulling the same sensor data as divisional/conference.

I’ll try to glance at it later - maybe something with the flex-table card - not sure

Updated the Sports_US_Professional dashboard on github to fix the overall tab not showing data.

I wasn’t excluding some sensors. Since we are using a wildcard on Overall (NHL/NFL) I missed that I had added team schedules to my sensors so I also had a sensor called sensor.nhl_schedule… as an example and it was trying to parse this which kept it from populating.

I am still hitting a snag with MLB and will look at it later and WNBA when the stats populate.

1 Like

Hi there, I’m trying to take this same approach for the Belgan Pro League (Sports Standings and Scores - #177 by kbrown01) and apply it to tennis rankings for both the ATP & WTA (https://site.web.api.espn.com/apis/site/v2/sports/tennis/atp/rankings?region=us&lang=en)

I successfully tested the approach for the Belgian league so I know that I have everything set-up/installed correctly.

What isn’t working is that my dashboard populates with my two test columns but has 'undefinedundefinedundefined' in each of the two test fields.

image

I’ve created a rest sensor, which is populating data:

##
## ATP Rankings
## 
- platform: rest
  scan_interval: 36000
  name: Tennis ATP Ranking
  unique_id: sensor.tennis_atp_ranking
  resource: https://site.web.api.espn.com/apis/site/v2/sports/tennis/atp/rankings?region=us&lang=en
  value_template: "{{ now() }}"
  json_attributes:
    - rankings

And I have a template sensor (which I do not believe is populating with data):

###
### Tennis ATP Ranking
###
  - name: ATP Ranking
    unique_id: sensor.tennis_atp_ranking_list
    state: "{{ now() }}"
    attributes:
      entries: "{{ state_attr('sensor.tennis_atp_ranking','rankings')[0]['ranks'] }}"

And the dashboard code which is pointing at my rest sensor:

decluttering_templates:
  bpl_settings:
    card:
      type: custom:flex-table-card
      title: '[[title]]'
      css:
        table+: 'padding: 0px; width: 1600px;'
        tbody tr td:first-child: 'width: 5%;'
        tbody tr td:nth-child(2): 'width: 30%;'
        tbody tr td:nth-child(n+3): 'width: 5%;'
        tbody tr:hover: 'background-color: green!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;
             }
      entities:
        include: '[[entity]]'
      sort_by: ranks
      columns:
        - name: Rank
          data: ranks
          modify: x.current
        - name: Previous
          data: ranks
          modify: x.previous
views:
  - title: Tennis Rankings
    icon: mdi:tennis
    type: panel
    badges: []
    cards:
      - type: custom:decluttering-card
        template: bpl_settings
        variables:
          - title: ATP
          - entity: sensor.tennis_atp_ranking

I think I have two problems:

  1. my template sensor isn’t formatted correctly
  2. my dashboard code isn’t parsing the json properly

Would appreciate any help steering me in the right direction.

I am really interested to this project, so please, let me know if you get the solution. I already created the sensor and the dashboard…

@jasonkjennings - your code worked for me but as I have stated I don’t use templates and honestly you don’t need them here. Just pull the data from the sensor.

With that said a couple notes:

  • You can simplify the code by just using the sensor to jump to the level you want.
    For example here is how I wrote your sensor. (As I note earlier in this thread I use individual sensors for each sport so I created a tennis.yaml file to test what you are doing). Here is what is in my tennis.yaml file:
##
## ATP Rankings
## 
- platform: rest
  scan_interval: 36000
  name: Tennis ATP Ranking
  unique_id: sensor.tennis_atp_ranking
  resource: https://site.web.api.espn.com/apis/site/v2/sports/tennis/atp/rankings?region=us&lang=en
  value_template: "{{ now() }}"
  json_attributes_path: "$.['rankings'][0]"
  json_attributes:
    - ranks
    
  • When you create the sensor you are essentially getting the data at that starting point. So I can test that in developers tools:

  • I threw your code into a sandbox dashboard and it came up with the rankings
    image

  • Since I was looking at the sensor anyway I added a couple items for S&G’s so this is what the sandbox looks like now:

Here is the sandbox code if you want it

decluttering_templates:
  bpl_settings:
    card:
      type: custom:flex-table-card
      title: '[[title]]'
      css:
        table+: 'padding: 0px; width: 1600px;'
        tbody tr td:first-child: 'width: 3%;'
        tbody tr td:nth-child(2): 'width: 3%;'
        tbody tr td:nth-child(3): 'width: 3%;'
        tbody tr td:nth-child(n+4): 'width: 20%;'
        tbody tr:hover: 'background-color: green!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;
             }
      entities:
        include: '[[entity]]'
      sort_by: ranks
      columns:
        - name: Rank
          data: ranks
          modify: x.current
        - name: Previous
          data: ranks
          modify: x.previous
        - name: Country
          data: ranks
          modify: >-
            '<div>' + (typeof x.athlete.flag !== 'undefined' ? '<img src="' +
            x.athlete.flag + '"
            style="width:20px;height:20px;margin-right:5px;">' : '') +
            x.athlete.flagAltText + '</div>'
        - name: Athlete
          data: ranks
          modify: >-
            '<div>' + (typeof x.athlete.headshot !== 'undefined' ? '<img src="'
            + x.athlete.headshot + '"
            style="width:20px;height:20px;margin-right:5px;">' : '') + 
            x.athlete.displayName + '</div>'
views:
  - title: Tennis Rankings
    icon: mdi:tennis
    type: panel
    badges: []
    cards:
      - type: custom:decluttering-card
        template: bpl_settings
        variables:
          - title: ATP
          - entity: sensor.tennis_atp_ranking

Can’t wait to see what you come up when you share your updates!!

Thanks so much for this!

I knew I wasn’t doing something right with parsing the json – having it in the right spot to start makes it much easier.

Thanks again, and yes, I’ll share when I get it completed – going to add tabs to toggle between the men/women’s rankings.

(and thanks for kick-starting the ‘if no flag/headshot’ is available!)

It works great, but it’s really quite impossible to see in mobile view…Is there a way to make the dashboard visible also on mobile?

What isn’t working? Is it that it is too wide and you need to squish it together?

I don’t do a lot on mobile @ehcah does maybe he has some ideas but here a squishier dashboard. You need to play with width: 400px, child widths and what you really want to show. For example you could combine rank/previous into a single column

decluttering_templates:
  bpl_settings:
    card:
      type: custom:flex-table-card
      title: '[[title]]'
      css:
        table+: 'padding: 0px; width: 400px;'
        tbody tr td:first-child: 'width: 1%;'
        tbody tr td:nth-child(2): 'width: 1%;'
        tbody tr td:nth-child(3): 'width: 10%;'
        tbody tr:hover: 'background-color: green!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;
             }
      entities:
        include: '[[entity]]'
      sort_by: ranks
      columns:
        - name: Rank
          data: ranks
          modify: x.current
        - name: Previous
          data: ranks
          modify: x.previous
        - name: Athlete
          data: ranks
          modify: >-
            '<div
            style="display:flex;justify-content:space-between;align-items:center;">'
            + '<div style="display:flex;align-items:center;">' + (typeof
            x.athlete.headshot !== 'undefined' ? '<img src="' +
            x.athlete.headshot + '"
            style="width:20px;height:20px;margin-right:5px;">' : '') +
            x.athlete.displayName + '</div>' + '<div>' + (typeof x.athlete.flag
            !== 'undefined' ? '(' + '<img src="' + x.athlete.flag + '"
            style="width:20px;height:20px;margin-right:5px;">' +
            x.athlete.flagAltText + ')' : '') + '</div>' + '</div>'
views:
  - title: Tennis Rankings
    icon: mdi:tennis
    type: panel
    badges: []
    cards:
      - type: custom:decluttering-card
        template: bpl_settings
        variables:
          - title: ATP
          - entity: sensor.tennis_atp_ranking

Yes, that’s what i mean…
Changing to 400px now is ok with the mobile view… but i will play with the child widths to have the best view also on mobile.
Thanks for you help…