NHL API Custom Component - Track your favorite hockey team in Home Assistant!

would love to help. I would just need some guidance first… I want to learn and am eager.

Hopefully I’m not missing something.

I am looking for a simple automation. A Sharks game starts, which triggers a light coming on. When the game is over, that light turns off.

Is there something in this api that can do that? Thanks!

You can absolutely do that. Create a state-based automation trigger leaving the “from” field blank and entering “Pre-Game” or “In Progress” in the “to” field. Select the sensor as the trigger device. When the sensor’s state changes over to “Pre-Game” or “In Progress” (depending on how early you want the automation to fire), it will trigger the action you choose in the automation.

To turn off the light, do the same but enter “Game Over” in the “to” field.

Hope that helps!

Some more info on this issue. After the below happens the sensor ceases to work until a HA restart, no more updates from the sensor - the scores and all attributes are frozen in time. Seems like there might be an issue with the handling of an exception.

2021-11-06 19:17:51 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nhl_leafs is taking over 10 seconds
2021-11-06 19:19:33 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.nhl_leafs fails
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 382, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 1010, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 416, in connect
    self.sock = ssl_wrap_socket(
  File "/usr/local/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 449, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(
  File "/usr/local/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 493, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/local/lib/python3.9/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/usr/local/lib/python3.9/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/usr/local/lib/python3.9/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ConnectionResetError: [Errno 104] Connection reset by peer

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 755, in urlopen
    retries = retries.increment(
  File "/usr/local/lib/python3.9/site-packages/urllib3/util/retry.py", line 532, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/usr/local/lib/python3.9/site-packages/urllib3/packages/six.py", line 769, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 382, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 1010, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 416, in connect
    self.sock = ssl_wrap_socket(
  File "/usr/local/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 449, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(
  File "/usr/local/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 493, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/local/lib/python3.9/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/usr/local/lib/python3.9/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/usr/local/lib/python3.9/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 438, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 633, in async_device_update
    await task
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/nhl_api/sensor.py", line 206, in update
    self.set_state()
  File "/config/custom_components/nhl_api/sensor.py", line 162, in set_state
    next_date_time = self.get_game_data()[1]
  File "/config/custom_components/nhl_api/sensor.py", line 105, in get_game_data
    games = Schedule(self._team_id).game_info()
  File "/config/deps/lib/python3.9/site-packages/pynhl/classes.py", line 34, in __init__
    self.response = requests.get(url)
  File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
2021-11-06 19:22:11 WARNING (MainThread) [homeassistant.helpers.entity] Update of sensor.nhl_leafs is taking over 10 seconds

Sorry, got pulled away from the thread. @jayblackedout, it’s working great for me and thank you for your time and effort in doing this.

Now, beyond that for the larger audience’s feedback, I am experimenting with push notifications at the end of each period and at the end of the game in Node Red to see the score. So I’m curious if anyone else has any ideas on that. I’m having trouble in the push notification pulling the specific number into the notification (I haven’t had time to play with it lately, but still thinking about it). For right now, at the end of the period the notification will say which game it is out of the two teams I monitor and for the two scores, it’ll report “None”. Again, still a work in progress and once I find a solution, I’ll post the Node Red code.

But until then, any ideas would be appreciated.

I’ve got a yaml automation setup to announce scores at the start of a new period. I also have an yaml automation setup to announce if my team won or lost. Maybe they will help with creating your node red code. I can’t take credit for writing the yaml code for these, but I can confirm they work.

automation:
  - alias: NHL - Dallas Stars Period
    trigger:

      - platform: template
        value_template: "{{ is_state_attr('sensor.dallas_stars', 'current_period', '2nd') }}"

      - platform: template
        value_template: "{{ is_state_attr('sensor.dallas_stars', 'current_period', '3rd') }}"

    action:
      - service: notify.sms
        data:
          title: 'Dallas Stars are playing {{ states.sensor.dallas_stars.attributes.current_period }} period!'
          message: 'Dallas Stars are playing {{ states.sensor.dallas_stars.attributes.current_period }} period! {{ states.sensor.dallas_stars.attributes.home_name }} {{ states.sensor.dallas_stars.attributes.home_score }} {{ states.sensor.dallas_stars.attributes.away_name }} {{ states.sensor.dallas_stars.attributes.away_score }} '
###############################################################################
  - alias: 'NHL - Dallas Stars Win'
    trigger:
    - platform: state
      entity_id: sensor.dallas_stars
      attribute: game_state
#      from: 'In Progress - Critical'
      to: 'Game Over'
    condition:
    - condition: or
      conditions:
      - condition: and
        conditions:
        - condition: template
          value_template: "{{ states.sensor.dallas_stars.attributes.home_score > states.sensor.dallas_stars.attributes.away_score }}"
        - condition: template
          value_template: "{{ is_state_attr('sensor.dallas_stars', 'home_id', 25) }}"
      - condition: and
        conditions:
        - condition: template
          value_template: "{{ states.sensor.dallas_stars.attributes.away_score > states.sensor.dallas_stars.attributes.home_score  }}"
        - condition: template
          value_template: "{{ is_state_attr('sensor.dallas_stars', 'away_id', 25) }}"
    action:
# Place your lights, audio, etc. here.
#      - service: tts.google_say
#        entity_id: media_player.mpd
#        data_template:
#          message: >
#            'Dallas Stars Win!'
      - wait_template: "{{ is_state('media_player.mpd', 'off') }}"
      - service: media_player.play_media
        data:
          entity_id: media_player.mpd
          media_content_id: local:track:dallas_stars_win_horn.mp3
          media_content_type: "audio/mp3"
      - service: notify.sms
        data:
          title: 'Dallas Stars WIN!'
          message: 'Dallas Stars WIN!  {{ states.sensor.dallas_stars.attributes.home_name }} {{ states.sensor.dallas_stars.attributes.home_score }} {{ states.sensor.dallas_stars.attributes.away_name }} {{ states.sensor.dallas_stars.attributes.away_score }} '
###############################################################################
  - alias: 'NHL - Dallas Stars LOSE'
    trigger:
    - platform: state
      entity_id: sensor.dallas_stars
      attribute: game_state
#      from: 'In Progress - Critical'
      to: 'Game Over'
    condition:
    - condition: or
      conditions:
      - condition: and
        conditions:
        - condition: template
          value_template: "{{ states.sensor.dallas_stars.attributes.home_score < states.sensor.dallas_stars.attributes.away_score }}"
        - condition: template
          value_template: "{{ is_state_attr('sensor.dallas_stars', 'home_id', 25) }}"
      - condition: and
        conditions:
        - condition: template
          value_template: "{{ states.sensor.dallas_stars.attributes.away_score < states.sensor.dallas_stars.attributes.home_score }}"
        - condition: template
          value_template: "{{ is_state_attr('sensor.dallas_stars', 'away_id', 25) }}"
    action:
      - wait_template: "{{ is_state('media_player.mpd', 'off') }}"
      - service: media_player.play_media
        data:
          entity_id: media_player.mpd
          media_content_id: local:track:dallas_stars_lose.mp3
          media_content_type: "audio/mp3"
      - delay: '00:00:02'
      - wait_template: "{{ is_state('media_player.mpd', 'off') }}"
      - service: media_player.play_media
        data:
          entity_id: media_player.mpd
          media_content_id: local:track:the_price_is_wrong.mp3
          media_content_type: "audio/mp3"
      - service: notify.sms_galahad
        data:
          title: 'Dallas Stars LOST!'
          message: 'Dallas Stars LOOSE! {{ states.sensor.dallas_stars.attributes.home_name }} {{ states.sensor.dallas_stars.attributes.home_score }} {{ states.sensor.dallas_stars.attributes.away_name }} {{ states.sensor.dallas_stars.attributes.away_score }} '
###############################################################################
1 Like

Getting this error in HA 2022.3.5. Seems like something has been deprecated/removed in the last few releases of HA.

2022-03-22 07:13:59 ERROR (MainThread) [custom_components.hacs] <Integration hacs/integration> timeout() got an unexpected keyword argument 'loop'
2022-03-22 07:13:59 ERROR (MainThread) [custom_components.hacs] <Integration JayBlackedOut/hass-nhlapi> timeout() got an unexpected keyword argument 'loop'
2022-03-22 09:13:59 ERROR (MainThread) [custom_components.hacs] <Integration hacs/integration> timeout() got an unexpected keyword argument 'loop'
2022-03-22 09:13:59 ERROR (MainThread) [custom_components.hacs] <Integration JayBlackedOut/hass-nhlapi> timeout() got an unexpected keyword argument 'loop'
2022-03-22 11:13:59 ERROR (MainThread) [custom_components.hacs] <Integration hacs/integration> timeout() got an unexpected keyword argument 'loop'
2022-03-22 11:13:59 ERROR (MainThread) [custom_components.hacs] <Integration JayBlackedOut/hass-nhlapi> timeout() got an unexpected keyword argument 'loop'
2022-03-22 13:13:59 ERROR (MainThread) [custom_components.hacs] <Integration hacs/integration> timeout() got an unexpected keyword argument 'loop'
2022-03-22 13:13:59 ERROR (MainThread) [custom_components.hacs] <Integration JayBlackedOut/hass-nhlapi> timeout() got an unexpected keyword argument 'loop'
2022-03-22 15:13:59 ERROR (MainThread) [custom_components.hacs] <Integration hacs/integration> timeout() got an unexpected keyword argument 'loop'
2022-03-22 15:13:59 ERROR (MainThread) [custom_components.hacs] <Integration JayBlackedOut/hass-nhlapi> timeout() got an unexpected keyword argument 'loop'
2022-03-22 17:13:59 ERROR (MainThread) [custom_components.hacs] <Integration hacs/integration> timeout() got an unexpected keyword argument 'loop'
2022-03-22 17:13:59 ERROR (MainThread) [custom_components.hacs] <Integration JayBlackedOut/hass-nhlapi> timeout() got an unexpected keyword argument 'loop'

Hmmm… I’m not getting this error in the logs on 2022.3.1
It looks like it has to do with hacs though.

Thanks, I downgraded and it’s working again. But it seems to be a common issue for components after the latest updates. I did see deprecation notices for ‘loop’ keyword in HA for the past couple months that said it would be removed in March.

Thank you all for keeping up on this integration. Much appreciated! Is there a tip jar anywhere?

My love of hockey, automation and this community keeps me going. No tips necessary!

1 Like

My sensor only updates once when home assistant starts, nothing after. This started after I updated HACS, so I downgraded back to the version I had but it didn’t resolve my issue. Here are my full HA logs during startup. Nothing really mentioning NHL API sensor specifically.

[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] done.
[services.d] starting services
[services.d] done.
2022-04-03 00:33:08 WARNING (SyncWorker_2) [homeassistant.loader] We found a custom integration nhl_api which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-04-03 00:33:08 WARNING (SyncWorker_1) [homeassistant.loader] We found a custom integration govee which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-04-03 00:33:08 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration hacs which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-04-03 00:33:18 WARNING (MainThread) [custom_components.govee] API is back online.
2022-04-03 00:33:19 WARNING (MainThread) [homeassistant.helpers.entity] Entity light.tv_lightstrip (<class 'custom_components.govee.light.GoveeLightEntity'>) implements device_state_attributes. Please report it to the custom component author.

Nothing special with sensor config.

sensor:
  - platform: nhl_api
    team_id: 10
    name: nhl_tor
  - platform: nhl_api
    team_id: 29
    name: nhl_cbj

Update:
Eventually, next game 2 days later it did start working by itself without any changes. I’m wondering if you restart HA in the middle of a game does the sensor still update? Not sure why it doesn’t work after HA restart, but eventually will begin updating (possibly only next game)

I am not much of a programmer, but have really loved HA. I have the sensor working great, but I was trying to figure out how to turn on a light if there is a game that day.

How can I pull this information out of the attributes and have a light turn on, then turn back off a few hours later?

Thanks for any and all help!

There’s a few ways to accomplish this. At what point during the day would you like the light to turn on? You can basically just check if the sensor’s next_game_date attribute is equal to today as a condition and use a time trigger or any other automation triggers of your choice.

Otherwise, you can use the sensor’s state as a trigger and turn on a light when it switches to Pre-Game.

I was hoping to turn it on at 6am and off at 9am. So I would see when I get downstairs and start getting ready for my day, then off once we leave for work/school.

I couldn’t figure out how to pull the ‘next_game_date’ field into an automation.

Thanks for the quick response!

I’ll walk you through how to create this automation using the UI. Keep in mind this is only one of the many ways to accomplish this.

  • Start by creating a new Automation.
  • Select “Time” under triggers. Select “Fixed time” as the mode and set the time to 6:00 AM.
  • Click the button to add a Condition.
  • Select “State” and select the sensor as the Entity, then select “Next game time” as the Attribute.
  • In the “State” field type: {{ (as_timestamp(now()) | timestamp_custom('%B %-d, %Y')) }}.
  • Under Actions, select “Call service”.
  • Select “Light: Turn On” and select your light as the target.
  • Click “Add Action”.
  • Select “Wait for time to pass (delay)”.
  • Type in 3 hours.
  • Click “Add Action”.
  • Select “Light: Turn Off” and select your light as the target.

Awesome. I’ve got it setup. Team plays tomorrow. We’ll see how it goes!

Thank you kindly!

Did not appear to work. Team played yesterday, but the light did not turn on. I tried to ‘debug automation’ and this is what I see.

Executed: April 19, 2022, 6:00:00 AM
Result:

result: false

entity_id/0

Executed: April 19, 2022, 6:00:00 AM
Result:

result: false state: April 19, 2022
wanted_state: ‘{{ (as_timestamp(now()) | timestamp_custom(’‘%B %-d, %Y’‘)) }}’

Beyond this information on the trace it shows

This node was not executed and so no further trace information is available.

But oddly enough if I click RUN ACTIONS on the Automatons page it appears to work properly, even if there is no game scheduled for that day.

This is what I have showing as the code after using the automation configurator.

id: blues_game_scheduled
alias: Blues Game Scheduled
description: ''
trigger:
  - platform: time
    at: '06:00:00'
condition:
  - condition: state
    entity_id: sensor.nhl_stl_blues
    attribute: next_game_date
    state: '{{ (as_timestamp(now()) | timestamp_custom(''%B %-d, %Y'')) }}'
action:
  - service: light.turn_on
    data:
      brightness_pct: 75
      rgb_color:
        - 0
        - 0
        - 255
    target:
      entity_id:
        - light.cabinet_colored_lights_micro
        - light.cabinet_colored_lights_pantry
        - light.cabinet_colored_lights_stove
  - delay:
      hours: 3
      minutes: 0
      seconds: 0
      milliseconds: 0
  - service: light.turn_off
    data: {}
    target:
      entity_id:
        - light.cabinet_colored_lights_micro
        - light.cabinet_colored_lights_pantry
        - light.cabinet_colored_lights_stove
mode: single

Yes, clicking this button will skip the trigger and conditions and only run the actions of the automation. The button is working as intended.

Since the trigger of the automation is unlikely to be the source of the error, it is likely in the condition I gave you. Apologies for that… I hadn’t tested it. I assume you cannot use a jinja template for the “state” portion of the state condition…

Changing your Condition from “State” to “Template” and entering the below will fix the issue:
{{ (as_timestamp(now()) | timestamp_custom('%B %-d, %Y')) == state_attr('sensor.nhl_stl_blues', 'next_game_date') }}

That template will evaluate to true when today’s date is equal to the value of the next_game_date attribute. When that happens, the automation actions will run.

Worked brilliantly!

Thank you again!

1 Like