Ability to see the state and condition of ice rinks in Montreal.

The left is a typical rink widget, the right has an additional row for debugging.
- If you don't already have one, create a directory
custom_templates
at the same level as yourconfiguration.yaml
file. - copy
rinks.ninja
into thecustom_templates
directory
There are other tools to find nearby rinks but if you know the name you can find it in the XML file:
http://www2.ville.montreal.qc.ca/services_citoyens/pdf_transfert/L29_PATINOIRE.xml
Different rinks at the same facility will have distinctions, like PPL and PSE for patin libre and sports, respectively. PPL will not have boards, PSE is for hockey with boards. Two rinks at the same parc may not be in the same condition.
This selects which rinks will be imported from the XML file.
In configuration.yaml
if you don't already have a rest
stanza add one as following. If you already have one, append it to the existing entries as new list item under rest
.
A scan interval
of 90000 (seconds) is about 25 hours - which is a long, very-safe/generous time interval. There's probably not much benefit to checking too often and I wouldn't go below 1800s/30 minutes.
rest:
- scan_interval: 90000
resource: http://www2.ville.montreal.qc.ca/services_citoyens/pdf_transfert/L29_PATINOIRE.xml
sensor:
Now in the sensor
add for each rink a stanza that looks like:
- name: "rinks_mtl_ndg_gsp_pse"
value_template: >
{% from 'rinks.jinja' import compose_rink_conditions %}
{% set rink_name = '.*Georges-Saint-Pierre.*PSE.*' %}
{{ compose_rink_conditions( value_json.patinoires.patinoire | selectattr('nom', 'match', rink_name) | list | first ) }}
Each name
must be unique and you'll use it later for the break out sensors.
Customize the rink_name
with an expression that selects your rink. The value is a regular expression
where .*
is a wildcard for any character. Only the first rink will be selected if your wildcards grab more than one.
If you restart HA now and your configuration above is correct you will be able to see the composite entity which is decomposed into each sensor that represents the state of the rink. You won't yet be able to add these to a card.
This translates the composite value imported into the separate sensors which are visualizable. At least originally when this was written it could not be done in one step.
Now for each rink you must add 6 template sensors. In the template
section of configuration.yaml
this can be added as a template:
template:
- sensor:
- unique_id: "rink-???-???-m"
name: "Rink ??? ??? Mise-a-Jour"
state: >
{% from 'rinks.jinja' import decompose_rink_last_update %}
{{ decompose_rink_last_update('sensor.rinks_mtl_???') }}
device_class: "timestamp"
- sensor:
- unique_id: "rink-???-???-c"
name: "Rink ??? ??? Condition"
state: >
{% from 'rinks.jinja' import decompose_rink_conditions %}
{{ decompose_rink_conditions('sensor.rinks_mtl_???') }}
- binary_sensor:
- unique_id: "rink-???-???-o"
name: "Rink ??? ??? Ouvert"
state: >
{% from 'rinks.jinja' import decompose_rink_open %}
{{ decompose_rink_open('sensor.rinks_mtl_???') }}
icon: >
{% from 'rinks.jinja' import decompose_rink_open_icon %}
{{ decompose_rink_open_icon(states(this.entity_id)) }}
- binary_sensor:
- unique_id: "rink-???-???-a"
name: "Rink ??? ??? Arrose"
state: >
{% from 'rinks.jinja' import decompose_rink_flooded %}
{{ decompose_rink_flooded('sensor.rinks_mtl_???') }}
icon: >
{% from 'rinks.jinja' import decompose_rink_flooded_icon %}
{{ decompose_rink_flooded_icon(states(this.entity_id)) }}
- binary_sensor:
- unique_id: "rink-???-???-d"
name: "Rink ??? ??? Deblaye"
state: >
{% from 'rinks.jinja' import decompose_rink_cleared %}
{{ decompose_rink_cleared('sensor.rinks_mtl_???') }}
icon: >
{% from 'rinks.jinja' import decompose_rink_cleared_icon %}
{{ decompose_rink_cleared_icon(states(this.entity_id)) }}
- binary_sensor:
- unique_id: "rink-???-???-r"
name: "Rink ??? ??? Resurface"
state: >
{% from 'rinks.jinja' import decompose_rink_resurface %}
{{ decompose_rink_resurface('sensor.rinks_mtl_???') }}
icon: >
{% from 'rinks.jinja' import decompose_rink_resurface_icon %}
{{ decompose_rink_resurface_icon(states(this.entity_id)) }}
Note: each unique_id
and name
must be unique! The names don't matter but I found something semi-structured like above help me keep order.
Replace the question marks with values that make sense. Being consistent will make changes later easier.
I'd recommend using search and replace to replace the following terms:
- for the
unique_id
field- search
Rink ??? ???
- replace
Rink YOURVALUEHERE
with your designation
- search
- for the
name
field:- search
rink-???-???-
- replace
rink-YOURVALUEHERE-
- search
- the original rest sensor name in the
decompose_
line- note this value must come from the
rest
section - search
sensor.rinks_mtl_???
- replace with the
name
value from rest section.
- note this value must come from the
It might help to do each template for each rink in a separate text editor and then paste it in complete into the configuration.yaml. (There might be a clever way to compose files?)
Once these are all entered you can restart HA. I haven't found a faster way to iterate here.
Once restarted you can check the individual entities in the appropriate HA Settings page. Searching by rink
usually does the trick.
The rest
integration sensors should look like some variation on 0|N/A|0|0|0|2024-12-15 14:17:14-05:00
, the names are the ones you set for them.
The template
sensors should be broken out appropriately and have icons shown in the settings list.
You're now ready to add the UI elements.
Edit the dashboard you want to add the card to and click Add Card
and the at the bottom of the choices choose Manual
.
Delete the existing lines and paste this template into the text box:
type: entities
entities:
- entity: sensor.???
name: Condition
secondary_info: last-changed
- entity: sensor.rink_???_???_mise_a_jour
name: " City Updated"
- entity: binary_sensor.rink_???_???_ouvert
name: Open
- entity: binary_sensor.rink_???_???_deblaye
name: Cleared
- entity: binary_sensor.rink_???_???_resurface
name: Resurfaced
- entity: binary_sensor.rink_???_???_arrose
name: Flooded
title: ???
state_color: true
and then similarly replace the question marks with values from the template
section.