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_templatesat the same level as yourconfiguration.yamlfile. - copy
rinks.ninjainto thecustom_templatesdirectory
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_idfield- search
Rink ??? ??? - replace
Rink YOURVALUEHEREwith your designation
- search
- for the
namefield:- search
rink-???-???- - replace
rink-YOURVALUEHERE-
- search
- the original rest sensor name in the
decompose_line- note this value must come from the
restsection - search
sensor.rinks_mtl_??? - replace with the
namevalue 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.