That data structure looks quite complex, so I won’t promise that this will be easy, but basically you can loop like this (I haven’t tested this with the actual json) to extract the section of the json you’re interested in. And then you may need another couple of template sensors to extract the relevant data:
value_template: >
{% for entry in value_json.dates.games %}
{% if entry.teams.home.team.name == 'my team' %}
{{ entry.value }}
{% endif %}
{% endfor %}
I think you’ll need to set aside the idea of solving this with a value_template. There’s a 255-character limit for the data and your source easily exceeds it.
The workaround is to call an external script to do the processing and have it return the desired results. You may find this thread helpful because it has a nearly identical requirement:
EDIT
So very wrong …
See finity’s post below. Only state is limited to holding 255 characters, not attributes, and not the value_template’s ability to process the incoming data.
See suggestion made by lmamakos below for solution.
the data itself is not limited to 255 characters. Only the final value that is stored in the “state” of the entity. Even attributes can be over 255 characters. Only the state is limited.
I used to use a rest call for my NWS alerts and the data I was parsing in the template was almost always longer than 255 characters and since the template always cut the data down to a few characters the state always showed the correct value.
I can show you my template but it won’t help you in using a loop thru the data. I always wanted to extract a specific value from the json no matter how many times the key value appeared.
That did not work but I had another idea. For testing purposes I took data that had lots of games. In this case 15. I managed to pull the total games which is 15 with this code:
What I’m offering isn’t a complete solution but, perhaps, one step closer to it.
You don’t need to have separate sensors, one to get the total number of games, and another to process the data using the ‘total games’ value. It can be done in one shot.
This is just to demonstrate that totalGames can be acquired then used to control the iterations of the for-loop. The result will be 15 team names playing away games (not what you want but it’s just something for the loop to do). You’ll need to modify what the loop does to suit your needs (extracting the details of your chosen team’s away games and storing them in an attribute).
sensor:
- platform: rest
resource: https://statsapi.web.nhl.com/api/v1/schedule?startDate=2019-04-06&endDate=2019-04-06&hydrate=linescore
name: nhl_teams_away
scan_interval:
hours: 24
value_template: >-
{% for x in range(value_json.totalGames) %}
{{ value_json["dates"][0]["games"][x]["teams"]["away"]["team"]["name"] }}
{% endfor %}
is there a way to create a counter variable, and make this sensors value_template = that counter which will actually be the x value of when the loop detects the name.
Something like this but not sure of the format:
value_template: >-
{% for x in range(value_json.totalGames) %}
{% if (value_json["dates"][0]["games"][x]["teams"]["home"]["team"]["name"] == states.input_select.nhl_fav_team.state) OR (value_json["dates"][0]["games"][x]["teams"]["away"]["team"]["name"] == states.input_select.nhl_fav_team.state) %}
x
{% endif %}
{% endfor %}
nhl_teams_away should actually be nhl_teams_index…
Wrap the lone x (the loop index) in double braces:
{{x}}
{% endif %}
{% endfor %}
When the loop’s if gets a match, {{x}} will report the value of the loop index.
Be advised that range(value_json.totalGames) is zero-based. If totalGames is 15, the loop counts from 0 to 14 so x will be one less than what you may expect. Therefore what you may want to display is {{x+1}}.
Also be aware that the scope of x is limited to within the loop. If you want to calculate a value within the loop for use outside the loop, it requires creating a (global) variable with greater scope. I won’t open that can of worms any further unless you say you need a global variable.
sensor:
- platform: rest
resource: https://statsapi.web.nhl.com/api/v1/schedule
name: nhl_teams_index
scan_interval:
hours: 24
value_template: >-
{% for x in range(value_json.totalGames) %}
{% if value_json["dates"][0]["games"][x]["teams"]["home"]["team"]["name"] == states.input_select.nhl_fav_team.state %}
{{ x }}
{% elif value_json["dates"][0]["games"][x]["teams"]["away"]["team"]["name"] == states.input_select.nhl_fav_team.state %}
{{ x }}
{% else %}
No Game
{% endif %}
Wanted to add a “No Game” if it doesn’t detect anything but it doesn’t work.
When there is no game it outputs it twice: No Game No Game
When there are 2 games it does the following:
When the game is at index 0 it outputs: 0 No Game
When the game is at index 1 it outputs: No Game 1
Also am I doing this correctly:
nhl_home_score:
value_template: >-
{% if states('sensor.nhl_teams_index') == 'No Game' %}
No Game
{% else %}
{{ states.sensor.nhl_teams_index.attributes.dates[0]["games"][sensor.nhl_teams_index]["teams"]["home"]["score"] }}
{% endif %}
If you want to use the state (the value) of sensor.nhl_team_index, you have to get the state. Just dropping sensor.nhl_team_index into the template won’t get its state.
This gets an entity’s state (you used this elsewhere):
states('sensor.nhl_team_index')
If you need to use it several times, assign it to a variable and then use the variable in the template.