I was sniffing around Reddit and the people on /r/NFLstatheads have been looking for a replacement for feeds they were using to scrape play by play data. Someone found that replacing “feeds” with “static” in the subdomain worked for a lot of the URLs.
Have a look and see if you can parse it. I was having some issues because of the distinct gameIDs being used.
I have a solution working. If I bring the scorestrip xml into a rest sensor, HA will automatically convert it into json. So, this is what I have to get the game status.
platform: rest
resource: https://static.nfl.com/liveupdate/scorestrip/ss.xml
name: nfl_game_status
value_template: >
{% for game in value_json.ss.gms.g %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{% if game['@q'] == 'P' %}
Pregame
{% elif game['@q'] == '1' or game['@q'] == '2' or game['@q'] == '3' or game['@q'] == '4' or game['@q'] == 'O' or game['@q'] == 'H' %}
In Progress
{% elif game['@q'] == 'FO' %}
F(OT)
{% elif game['@q'] == 'F' %}
Final
{% elif game['@q'] == 'S' %}
Suspended
{% endif %}
{% endif %}
{% endfor %}
json_attributes:
- ss
game[’@q’] can have the following values:
P is pregame
1-4 is the quarter the game is in
H is halftime
O is overtime
F is final
FO is overtime final
S is suspended/delayed
Some hidden datasets that only appear when a game is live which you might be interested in:
k=“xx:xx” shows the game clock when the game is in progress.
p=“XXX” shows the team in possession of the ball and using the three letter team abbreviation.
Let me know if you guys have any questions. I’m still tweaking things on my end, but I’m happy to provide more examples of what I’m pulling into HA.
these are awesome. thanks for putting them together. do you know how often we can send requests to the feed? i notice you put the scan interval at 120 min.
That’s actually 120 seconds – I figured calling every 2 minutes might work, but have also done it every 5 minutes, really just depends how immediately you need the data. I generally wouldn’t go lower than 2 minutes though .
I’m using this to pick up the scores, quarter, and time. So yesterday, I had an automation to update every 10 seconds while the game was in progress and it mostly worked fine, though I noticed the feed was updating about every 30 seconds or so. Going to play around with this to see what the optimal interval is.
I am still a NOOB when it comes templating. Is there a way to just pull in the data for one of the games? i would love to have one sensor for my team’s score and then another for their opponents. I am thinking something similar to what they have done on the MLB
Yah, it would be pretty straightforward to create a sensor whose attributes are all the different attributes of a game (eg. is one team in the red zone, what are the scores, etc). I’ve been thinking of something like that (flash lights when Russell is in the red zone – oh wait, it doesn’t matter because he’s a threat way before then ). I can try to put together a sensor template for that tomorrow, though I suspect @yguns31 may post a solution before I get the chance to .
Here are the sensors I have set up to pull in data for my team’s games. I am pulling in team names, score, time, qtr and possession. Just swap in your team’s abbreviation in the code.
platform: rest
resource: https://static.nfl.com/liveupdate/scorestrip/ss.xml
name: nfl_game_status
value_template: >
{% for game in value_json.ss.gms.g %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{% if game['@q'] == 'P' %}
Pregame
{% elif game['@q'] == '1' or game['@q'] == '2' or game['@q'] == '3' or game['@q'] == '4' or game['@q'] == 'O' or game['@q'] == 'H' %}
In Progress
{% elif game['@q'] == 'FO' %}
F(OT)
{% elif game['@q'] == 'F' %}
Final
{% elif game['@q'] == 'S' %}
Suspended
{% endif %}
{% endif %}
{% endfor %}
json_attributes:
- ss
scan_interval:
hours: 24
platform: template
sensors:
nfl_home_score:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{{ game['@hs'] }}
{% endif %}
{% endfor %}
friendly_name_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{{ game['@h'] }}
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
nfl_home_name:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{{ game['@h'] }}
{% endif %}
{% endfor %}
friendly_name_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{{ game['@hnn'] }}
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
platform: template
sensors:
nfl_away_score:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{{ game['@vs'] }}
{% endif %}
{% endfor %}
friendly_name_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{{ game['@v'] }}
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
nfl_away_name:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{{ game['@v'] }}
{% endif %}
{% endfor %}
friendly_name_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{{ game['@vnn'] }}
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
platform: template
sensors:
nfl_time_status:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{% if states.sensor.nfl_game_status.state == 'Pregame' %}
{{ game['@t'] }}
{% else %}
{% if game['@q'] == 'H' or game['@q'] == 'F' or game['@q'] == 'FO' %}
{% else %}
{% if game['@k'][:1] == "0" %}
{{ game['@k'][1:] }}
{% else %}
{{ game['@k'] }}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
friendly_name_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{{ game['@q'] }}
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
nfl_period_status:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{% if game['@q'] == 'P' or game['@q'] == 'S' %}
0
{% elif game['@q'] == 'F' or game['@q'] == 'FO' %}
-1
{% elif game['@q'] == 'H' %}
2
{% elif game['@q'] == 'O' %}
5
{% else %}
{{ game['@q'] }}
{% endif %}
{% endif %}
{% endfor %}
friendly_name_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{% if game['@q'] == 'P' %}
Pregame
{% elif game['@q'] == 'F' %}
Final
{% elif game['@q'] == '1' %}
1st
{% elif game['@q'] == '2' %}
2nd
{% elif game['@q'] == '3' %}
3rd
{% elif game['@q'] == 'H' %}
Half
{% elif game['@q'] == 'O' %}
OT
{% elif game['@q'] == 'FO' %}
F(OT)
{% else %}
{{ game['@q'] }}th
{% endif %}
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
nfl_possession:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'SF' or game['@v'] == 'SF' %}
{% if game['@h'] == game['@p'] %}
H
{% elif game['@v'] == game['@p'] %}
A
{% endif %}
{% endif %}
{% endfor %}
friendly_name: NFL Possession
entity_id: sensor.nfl_game_status
Thanks to @yguns31 and @zacs This is amazing. Been trying to figure out how to get live NFL data in to HA for quite some time. Now I’m furiously working away to get ready for my team’s game Sunday. I messed around with some test automations with the game last night and everything worked great!
Hopefully I can figure out how to annoy my wife with some automated touchdown/win celebrations!
Last night I tested using the homeassistant.update_entity service in an automation to update the rest sensor every 10 seconds. I was monitoring the nfl.com resource manually to see how quickly it was updating, and it seemed to be where the (30 secondish) lag in updating might have been coming from. I barely caught the end of the game (last 5 minutes or so) so it was a small sample size. Out of curiosity, I also had twitter’s live scoreboard resource up to see how my HA sensors matched up, and they were identical timing-wise for the most part. I’ll try to do more testing and report back after Sunday if it’s helpful.
I haven’t done automation triggers for the NFL yet, but I do have them for hockey. Here is the code for a goal.
id: maple_leafs_goal
alias: Maple Leafs Goal
trigger:
- platform: state
entity_id: sensor.nhl_home_score
- platform: state
entity_id: sensor.nhl_away_score
condition:
- condition: template
value_template: >
{{ trigger.to_state is not none and trigger.from_state is not none and
trigger.to_state.state|int > trigger.from_state.state|int
and "TOR" in trigger.from_state.attributes.friendly_name
}}
Probably needs an additional condition in the condition template where the trigger.to state is > 5 from the trigger.from state so that the automation only triggers for a touchdown and not just any score.
This is the win automation for NHL.
id: maple_leafs_win
alias: Maple Leafs Win
trigger:
- platform: state
entity_id: sensor.nhl_game_status
from: 'In Progress'
to: 'Final'
- platform: state
entity_id: sensor.nhl_game_status
from: 'In Progress - Critical'
to: 'Final'
- platform: state
entity_id: sensor.nhl_game_status
from: 'In Progress'
to: 'Game Over'
- platform: state
entity_id: sensor.nhl_game_status
from: 'In Progress - Critical'
to: 'Game Over'
condition:
- condition: template
value_template: >
{{ (states("sensor.nhl_home_score")|int < states("sensor.nhl_away_score")|int
and is_state_attr("sensor.nhl_away_score", "friendly_name", "TOR")) or
(states("sensor.nhl_home_score")|int > states("sensor.nhl_away_score")|int
and is_state_attr("sensor.nhl_home_score", "friendly_name", "TOR"))
}}
The triggers can probably be simplified for NFL since there aren’t as many game states as the NHL feed I’m using.
Here’s what I did with your automation for a touchdown:
id: saints_touchdown
alias: Saints Touchdown
trigger:
- platform: state
entity_id: sensor.nfl_home_score
- platform: state
entity_id: sensor.nfl_away_score
condition:
- condition: template
value_template: >
{{ trigger.to_state is not none and trigger.from_state is not none and
trigger.to_state.state|int > (trigger.from_state.state|int + 5)
and "NO" in trigger.from_state.attributes.friendly_name
}}
That seems to do the trick in testing. (And saves me a lot of time, thank you again!)
if anyone is interested. I modified some of the sensors, templates, automations, scripts, and lovelace card. shout out to @BigBlackBear, @yguns31, and @zacs. You guys did awesome work.
#####################
CALENDAR
#####################
I am using google calendar to publish various sports team that I follow. You can add your teams by following this video.
Then bring this calendar into HA by following.
#####################
# SENSORS #
#####################
#Dallas Cowboys sensors
- platform: rest
resource: https://static.nfl.com/liveupdate/scorestrip/ss.xml
name: nfl_game_status
value_template: >
{% for game in value_json.ss.gms.g %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{% if game['@q'] == 'P' %}
Pregame
{% elif game['@q'] == '1' or game['@q'] == '2' or game['@q'] == '3' or game['@q'] == '4' or game['@q'] == 'O' or game['@q'] == 'H' %}
In Progress
{% elif game['@q'] == 'FO' %}
F(OT)
{% elif game['@q'] == 'F' %}
Final
{% elif game['@q'] == 'S' %}
Suspended
{% endif %}
{% endif %}
{% endfor %}
json_attributes:
- ss
scan_interval:
hours: 24
- platform: template
sensors:
cowboys_home_score:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{{ game['@hs'] }}
{% endif %}
{% endfor %}
friendly_name_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{{ game['@h'] }}
{% endif %}
{% endfor %}
entity_picture_template: >-
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
/local/logos/nfl/{{ game['@h'] }}.svg
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
cowboys_away_score:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{{ game['@vs'] }}
{% endif %}
{% endfor %}
friendly_name_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{{ game['@v'] }}
{% endif %}
{% endfor %}
entity_picture_template: >-
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
/local/logos/nfl/{{ game['@v'] }}.svg
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
- platform: template
sensors:
nfl_time_status:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{% if states.sensor.nfl_game_status.state == 'Pregame' %}
{{ game['@t'] }}
{% else %}
{% if game['@q'] == 'H' or game['@q'] == 'F' or game['@q'] == 'FO' %}
{% else %}
{% if game['@k'][:1] == "0" %}
{{ game['@k'][1:] }}
{% else %}
{{ game['@k'] }}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
friendly_name_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{{ game['@q'] }}
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
nfl_period_status:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{% if game['@q'] == 'P' or game['@q'] == 'S' %}
0
{% elif game['@q'] == 'F' or game['@q'] == 'FO' %}
-1
{% elif game['@q'] == 'H' %}
2
{% elif game['@q'] == 'O' %}
5
{% else %}
{{ game['@q'] }}
{% endif %}
{% endif %}
{% endfor %}
friendly_name_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{% if game['@q'] == 'P' %}
Pregame
{% elif game['@q'] == 'F' %}
Final
{% elif game['@q'] == '1' %}
1st
{% elif game['@q'] == '2' %}
2nd
{% elif game['@q'] == '3' %}
3rd
{% elif game['@q'] == 'H' %}
Half
{% elif game['@q'] == 'O' %}
OT
{% elif game['@q'] == 'FO' %}
F(OT)
{% else %}
{{ game['@q'] }}th
{% endif %}
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
nfl_possession:
value_template: >
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{% if game['@h'] == game['@p'] %}
{{ game['@h'] }}
{% elif game['@v'] == game['@p'] %}
{{ game['@v'] }}
{% endif %}
{% endif %}
{% endfor %}
friendly_name: NFL Possession
entity_picture_template: >-
{% for game in states.sensor.nfl_game_status.attributes['ss']['gms']['g'] %}
{% if game['@h'] == 'DAL' or game['@v'] == 'DAL' %}
{% if game['@h'] == game['@p'] %}
/local/logos/nfl/{{ game['@h'] }}.svg
{% elif game['@v'] == game['@p'] %}
/local/logos/nfl/{{ game['@v'] }}.svg
{% endif %}
{% endif %}
{% endfor %}
entity_id: sensor.nfl_game_status
#########################
# AUTOMATIONS #
#########################
- id: dallas_scheduled
alias: Dallas - Scheduled
trigger:
- platform: time_pattern
minutes: /10
condition:
- condition: or
conditions:
- condition: state
entity_id: sensor.nfl_game_status
state: Pregame
- condition: state
entity_id: sensor.nfl_game_status
state: Suspended
action:
- service: script.turn_on
entity_id: script.cowboys_update
mode: single
- id: dallas_in_progress
alias: Dallas - In Progress
trigger:
- entity_id: sensor.nfl_game_status
platform: state
to: In Progress
condition: []
action:
- data: {}
entity_id: automation.dallas_game_on
service: automation.turn_on
- data: {}
entity_id: automation.dallas_game_on_with_lights
service: automation.turn_on
mode: single
- id: dallas_game_on
alias: Dallas - Game On
trigger:
- minutes: /1
platform: time_pattern
condition:
- condition: template
value_template: '{{ not is_state(''sensor.nfl_game_status'', ''Pregame'') }}'
- condition: template
value_template: '{{ not is_state(''sensor.nfl_game_status'', ''F(OT)'') }}'
- condition: template
value_template: '{{ not is_state(''sensor.nfl_game_status'', ''Final'') }}'
- condition: template
value_template: '{{ not is_state(''sensor.nfl_game_status'', ''Suspended'') }}'
- condition: state
entity_id: input_boolean.cowboys
state: 'off'
action:
- entity_id: script.cowboys_update
service: script.turn_on
mode: single
- id: dallas_game_on_with_lights
alias: Dallas - Game On - With Lights
description: ''
trigger:
- platform: time_pattern
seconds: /2
condition:
- condition: template
value_template: '{{ not is_state(''sensor.nfl_game_status'', ''Pregame'') }}'
- condition: template
value_template: '{{ not is_state(''sensor.nfl_game_status'', ''F(OT)'') }}'
- condition: template
value_template: '{{ not is_state(''sensor.nfl_game_status'', ''Final'') }}'
- condition: template
value_template: '{{ not is_state(''sensor.nfl_game_status'', ''Suspended'') }}'
- condition: state
entity_id: input_boolean.cowboys
state: 'on'
action:
- entity_id: script.cowboys_update
service: script.turn_on
mode: single
- id: dallas_game_over
alias: Dallas - Game Over
trigger:
- entity_id: sensor.nfl_game_status
platform: state
to: Final
- entity_id: sensor.nfl_game_status
platform: state
to: F(OT)
- entity_id: sensor.nfl_game_status
platform: state
to: Suspended
condition: []
action:
- entity_id: input_boolean.cowboys
service: input_boolean.turn_off
- data: {}
entity_id: automation.dallas_game_on
service: automation.turn_off
- data: {}
entity_id: automation.dallas_game_on_with_lights
service: automation.turn_off
- delay: 01:00:00
- data: {}
entity_id: script.cowboys_update
service: script.turn_on
mode: single
- id: dallas_run_celebration
alias: Dallas - Run Celebration
trigger:
- entity_id: sensor.cowboys_home_score
platform: state
- entity_id: sensor.cowboys_away_score
platform: state
condition:
- condition: template
value_template: "{{ trigger.to_state is not none and trigger.from_state is not\
\ none and\n trigger.to_state.state|int > (trigger.from_state.state|int\
\ + 5) \n and \"DAL\" in trigger.from_state.attributes.friendly_name\n\
}}\n"
action:
- service: script.cowboys
entity_id: media_player.upstairs_echo_dot
data: {}
mode: single
- id: check_cowboys_schedule
alias: Check Cowboys schedule
trigger:
- platform: state
entity_id: calendar.dallas_cowboys
to: 'on'
action:
- service: script.cowboyskickoff
data: {}
- service: script.turn_on
entity_id: script.cowboys_update
mode: single
- id: check_cowboys_schedule_and_at_home
alias: Cowboys Game Start at Home Check
description: ''
trigger:
- platform: state
entity_id: calendar.dallas_cowboys
to: 'on'
condition:
- condition: state
entity_id: person.ryan_locey
state: home
- condition: device
device_id: 5361af66347a4b18a2c1f4c6d548debb
domain: media_player
entity_id: media_player.ryan_s_fire_tv
type: is_on
action:
- service: input_boolean.turn_on
data: {}
entity_id: input_boolean.cowboys
mode: single
#########################
# SCRIPTS #
#########################
cowboys_update:
alias: Update Cowboys Game Info
sequence:
- service: homeassistant.update_entity
entity_id: sensor.nfl_game_status
- service: homeassistant.update_entity
entity_id: sensor.cowboys_away_score
- service: homeassistant.update_entity
entity_id: sensor.cowboys_home_score
mode: single
cowboys:
alias: Cowboys TD
mode: queued
sequence:
- service: media_player.play_media
data:
entity_id: media_player.upstairs_echo_dot
media_content_id: Baseball Crowd Cheering
media_content_type: AMAZON_MUSIC
- repeat:
count: '3'
sequence:
- service: light.turn_on
data:
rgb_color:
- 134
- 147
- 151
entity_id: light.ryans_light
- service: light.turn_on
entity_id: light.monicas_light
data:
rgb_color:
- 0
- 34
- 68
- service: light.turn_on
data:
rgb_color:
- 0
- 34
- 68
entity_id: light.ryans_light
- service: light.turn_on
entity_id: light.monicas_light
data:
rgb_color:
- 134
- 147
- 151
- service: light.turn_on
data:
rgb_color:
- 255
- 255
- 255
entity_id: light.ryans_light
- service: light.turn_on
data:
rgb_color:
- 255
- 255
- 255
entity_id: light.monicas_light
max: 10
cowboyskickoff:
alias: Cowboys Kickoff
mode: queued
sequence:
- service: notify.alexa_media_upstairs_echo_dot
data:
data:
type: tts
message: It's Game Time
- repeat:
count: '3'
sequence:
- service: light.turn_on
data:
rgb_color:
- 134
- 147
- 151
entity_id: light.ryans_light
- service: light.turn_on
entity_id: light.monicas_light
data:
rgb_color:
- 0
- 34
- 68
- service: light.turn_on
data:
rgb_color:
- 0
- 34
- 68
entity_id: light.ryans_light
- service: light.turn_on
entity_id: light.monicas_light
data:
rgb_color:
- 134
- 147
- 151
- service: light.turn_on
data:
rgb_color:
- 255
- 255
- 255
entity_id: light.monicas_light
- service: light.turn_on
data:
rgb_color:
- 255
- 255
- 255
entity_id: light.ryans_light
max: 10
#########################
# LOVELACE #
#########################
type: entities
entities:
- entity: sensor.cowboys_away_score
- entity: sensor.cowboys_home_score
- entity: sensor.nfl_time_status
- entity: sensor.nfl_period_status
- entity: sensor.nfl_possession
state_color: false