Living in a city with snow emergency rules, like Minneapolis, can be tricky when the emergency rules are in effect. They are quick to tow your vehicle if you park in the wrong spot. So I decided to work on my HA skills and try to save myself from getting towed this year.
I feel like I have a lot of duplicate code, and would love to get feedback on how I can simplify the sensors and templates. I’m using 6 rest sensors for the same JSON file. How can I consolidate these into a single sensor? The notices
array only contains 1 element when there is no emergency, and 6 if a snow emergency has been declared. I’m not sure what it looks like during the non winter months (we have like 5 of those…).
The json resource for my templates come from the city’s website, specifically this JSON.
Resource JSON
{
"notices": [
{
"publishDate": "2021-11-16T12:58:00-06:00",
"expireDate": "",
"html": "<section class=\"organism organism--inline-alert\" data-id=\"snow-emergency-html\" data-version=\"202202224709851.0\"> <div class=\"grid-container fluid\"> <div class=\"grid-x grid-margin-x\"> <div class=\"cell\"> <div class=\"inline-alert notice\"> <div class=\"grid-x grid-margin-x align-middle\"> <div class=\"cell large-shrink\">\n <div class=\"inline-alert--date\">\n\n <div\n class=\"atom atom--time text-center\"\n data-time\n data-time-format=\"h:mma\"\n data-time-content=\".time--content\"\n data-time-clock=\".time--clock\"\n >\n <div class=\"fa fa-circle time--clock\">\n <div class=\"time--minute time--arms\"><\/div>\n <div class=\"time--hour time--arms\"><\/div>\n <\/div>\n <div class=\"time--content\">...<\/div>\n <\/div>\n\n <\/div>\n <\/div>\n <div class=\"cell large-auto\"> <div class=\"inline-alert--message\"> <div aria-live=\"polite\" role=\"alert\"> <h3 class=\"headline\"><i class=\"fal fa-Normal parking (low res)\" aria-hidden=\"true\"><\/i>No Snow Emergency declared<\/h3> <div>There’s currently no Snow Emergency. Normal parking rules apply.<\/div> <\/div> <\/div> <\/div> <div class=\"cell large-shrink\"> <div class=\"inline-alert--link\"> <a href=\"https://www.minneapolismn.gov/getting-around/snow/snow-emergencies/snow-parking-rules/\" class=\"atom atom--shadow-button button tiny short\" tabindex=\"0\"> Snow Emergency Parking Rules <\/a> <\/div> <\/div> <\/div> <\/div> <\/div> <\/div> <\/div> <\/section>",
"id": "snow-emergency-html",
"noticetype": "notice",
"version": "202202224709850.0"
},
{
"date": "2022-02-22T15:16:40-06:00",
"noticetype": "warning",
"publishDate": "2022-02-22T15:12:00-06:00",
"expireDate": "2022-02-22T21:00:00-06:00",
"html": "<span id=\"d.en.25223\"><\/span>\n<section class=\"organism organism--inline-alert\" data-id=\"snow-emergency-html\" data-version=\"2522323.0\">\n <div class=\"grid-container fluid\">\n <div class=\"grid-x grid-margin-x\">\n <div class=\"cell\">\n <div class=\"inline-alert warning\">\n <div class=\"grid-x grid-margin-x align-middle\">\n\n <div class=\"cell large-shrink\">\n <div class=\"inline-alert--date\">\n\n <div\n class=\"atom atom--time text-center\"\n data-time\n data-time-format=\"h:mma\"\n data-time-content=\".time--content\"\n data-time-clock=\".time--clock\"\n >\n <div class=\"fa fa-circle time--clock\">\n <div class=\"time--minute time--arms\"><\/div>\n <div class=\"time--hour time--arms\"><\/div>\n <\/div>\n <div class=\"time--content\">...<\/div>\n <\/div>\n\n <\/div>\n <\/div>\n\n <div class=\"cell large-auto\">\n <div class=\"inline-alert--message\">\n <div aria-live=\"polite\" role=\"alert\">\n <h3 class=\"headline\">Snow Emergency declared<\/h3>\n <div>Day 1 rules begin at 9 p.m. tonight. Do not park on either side of Snow Emergency Routes.<\/div>\n <\/div>\n <\/div>\n <\/div>\n\n <div class=\"cell large-shrink\">\n <div class=\"inline-alert--link\">\n\n\n <a href=\"https://www.minneapolismn.gov/getting-around/snow/snow-emergencies/snow-parking-rules/\" class=\"atom atom--shadow-button button tiny short\" tabindex=\"0\">Snow Emergency Parking Rules<\/a>\n\n <\/div>\n <\/div>\n\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n<\/section>",
"id": "snow-emergency-html",
"version": "2522323.0"
},{
"date": "2022-02-22T15:16:41-06:00",
"noticetype": "warning",
"publishDate": "2022-02-22T21:00:00-06:00",
"expireDate": "2022-02-23T08:00:00-06:00",
"html": "<span id=\"d.en.23856\"><\/span>\n<section class=\"organism organism--inline-alert\" data-id=\"snow-emergency-html\" data-version=\"2385630.0\">\n <div class=\"grid-container fluid\">\n <div class=\"grid-x grid-margin-x\">\n <div class=\"cell\">\n <div class=\"inline-alert warning\">\n <div class=\"grid-x grid-margin-x align-middle\">\n\n <div class=\"cell large-shrink\">\n <div class=\"inline-alert--date\">\n\n <div\n class=\"atom atom--time text-center\"\n data-time\n data-time-format=\"h:mma\"\n data-time-content=\".time--content\"\n data-time-clock=\".time--clock\"\n >\n <div class=\"fa fa-circle time--clock\">\n <div class=\"time--minute time--arms\"><\/div>\n <div class=\"time--hour time--arms\"><\/div>\n <\/div>\n <div class=\"time--content\">...<\/div>\n <\/div>\n\n <\/div>\n <\/div>\n\n <div class=\"cell large-auto\">\n <div class=\"inline-alert--message\">\n <div aria-live=\"polite\" role=\"alert\">\n <h3 class=\"headline\">Snow Emergency in effect. Day 1 rules apply.<\/h3>\n <div>Snow Emergency Day 1 rules are in effect from 9 p.m. until 8 a.m. (overnight). Do not park on either side of Snow Emergency Routes.<\/div>\n <\/div>\n <\/div>\n <\/div>\n\n <div class=\"cell large-shrink\">\n <div class=\"inline-alert--link\">\n\n\n <a href=\"https://www.minneapolismn.gov/getting-around/snow/snow-emergencies/snow-parking-rules/\" class=\"atom atom--shadow-button button tiny short\" tabindex=\"0\">Snow Emergency Parking Rules<\/a>\n\n <\/div>\n <\/div>\n\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n<\/section>",
"id": "snow-emergency-html",
"version": "2385630.0"
},{
"date": "2022-02-22T15:16:42-06:00",
"noticetype": "warning",
"publishDate": "2022-02-23T08:00:00-06:00",
"expireDate": "2022-02-23T20:00:00-06:00",
"html": "<span id=\"d.en.23844\"><\/span>\n<section class=\"organism organism--inline-alert\" data-id=\"snow-emergency-html\" data-version=\"2384425.0\">\n <div class=\"grid-container fluid\">\n <div class=\"grid-x grid-margin-x\">\n <div class=\"cell\">\n <div class=\"inline-alert warning\">\n <div class=\"grid-x grid-margin-x align-middle\">\n\n <div class=\"cell large-shrink\">\n <div class=\"inline-alert--date\">\n\n <div\n class=\"atom atom--time text-center\"\n data-time\n data-time-format=\"h:mma\"\n data-time-content=\".time--content\"\n data-time-clock=\".time--clock\"\n >\n <div class=\"fa fa-circle time--clock\">\n <div class=\"time--minute time--arms\"><\/div>\n <div class=\"time--hour time--arms\"><\/div>\n <\/div>\n <div class=\"time--content\">...<\/div>\n <\/div>\n\n <\/div>\n <\/div>\n\n <div class=\"cell large-auto\">\n <div class=\"inline-alert--message\">\n <div aria-live=\"polite\" role=\"alert\">\n <h3 class=\"headline\">Snow Emergency in effect. Day 2 rules apply.<\/h3>\n <div>Snow Emergency Day 2 rules are in effect from 8 a.m. until 8 p.m. tonight. Do not park on the even side of streets that are not Snow Emergency Routes. Do not park on either side of parkways.<\/div>\n <\/div>\n <\/div>\n <\/div>\n\n <div class=\"cell large-shrink\">\n <div class=\"inline-alert--link\">\n\n\n <a href=\"https://www.minneapolismn.gov/getting-around/snow/snow-emergencies/snow-parking-rules/\" class=\"atom atom--shadow-button button tiny short\" tabindex=\"0\">Snow Emergency Parking Rules<\/a>\n\n <\/div>\n <\/div>\n\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n<\/section>",
"id": "snow-emergency-html",
"version": "2384425.0"
},{
"date": "2022-02-22T15:16:43-06:00",
"noticetype": "warning",
"publishDate": "2022-02-23T20:00:00-06:00",
"expireDate": "2022-02-24T08:00:00-06:00",
"html": "<span id=\"d.en.28150\"><\/span>\n<section class=\"organism organism--inline-alert\" data-id=\"snow-emergency-html\" data-version=\"281508.0\">\n <div class=\"grid-container fluid\">\n <div class=\"grid-x grid-margin-x\">\n <div class=\"cell\">\n <div class=\"inline-alert warning\">\n <div class=\"grid-x grid-margin-x align-middle\">\n\n <div class=\"cell large-shrink\">\n <div class=\"inline-alert--date\">\n\n <div\n class=\"atom atom--time text-center\"\n data-time\n data-time-format=\"h:mma\"\n data-time-content=\".time--content\"\n data-time-clock=\".time--clock\"\n >\n <div class=\"fa fa-circle time--clock\">\n <div class=\"time--minute time--arms\"><\/div>\n <div class=\"time--hour time--arms\"><\/div>\n <\/div>\n <div class=\"time--content\">...<\/div>\n <\/div>\n\n <\/div>\n <\/div>\n\n <div class=\"cell large-auto\">\n <div class=\"inline-alert--message\">\n <div aria-live=\"polite\" role=\"alert\">\n <h3 class=\"headline\">Snow Emergency in effect. Day 2 ended at 8 p.m. Day 3 rules begin at 8 a.m.<\/h3>\n <div>A Snow Emergency is in effect. Between 8 p.m. - 8 a.m., move your vehicle from the odd side of streets that are not Snow Emergency Routes. Day 3 rules begin at 8 a.m.<\/div>\n <\/div>\n <\/div>\n <\/div>\n\n <div class=\"cell large-shrink\">\n <div class=\"inline-alert--link\">\n\n\n <a href=\"https://www.minneapolismn.gov/getting-around/snow/snow-emergencies/snow-parking-rules/\" class=\"atom atom--shadow-button button tiny short\" tabindex=\"0\">Snow Emergency Parking Rules<\/a>\n\n <\/div>\n <\/div>\n\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n<\/section>",
"id": "snow-emergency-html",
"version": "281508.0"
},{
"date": "2022-02-22T15:16:44-06:00",
"noticetype": "warning",
"publishDate": "2022-02-24T08:00:00-06:00",
"expireDate": "2022-02-24T20:00:00-06:00",
"html": "<span id=\"d.en.23900\"><\/span>\n<section class=\"organism organism--inline-alert\" data-id=\"snow-emergency-html\" data-version=\"2390014.0\">\n <div class=\"grid-container fluid\">\n <div class=\"grid-x grid-margin-x\">\n <div class=\"cell\">\n <div class=\"inline-alert warning\">\n <div class=\"grid-x grid-margin-x align-middle\">\n\n <div class=\"cell large-shrink\">\n <div class=\"inline-alert--date\">\n\n <div\n class=\"atom atom--time text-center\"\n data-time\n data-time-format=\"h:mma\"\n data-time-content=\".time--content\"\n data-time-clock=\".time--clock\"\n >\n <div class=\"fa fa-circle time--clock\">\n <div class=\"time--minute time--arms\"><\/div>\n <div class=\"time--hour time--arms\"><\/div>\n <\/div>\n <div class=\"time--content\">...<\/div>\n <\/div>\n\n <\/div>\n <\/div>\n\n <div class=\"cell large-auto\">\n <div class=\"inline-alert--message\">\n <div aria-live=\"polite\" role=\"alert\">\n <h3 class=\"headline\">Snow Emergency declared. Day 3 rules apply.<\/h3>\n <div>Snow Emergency Day 3 rules are in effect from 8 a.m. until 8 p.m. tonight. Do not park on the odd side of streets that are not Snow Emergency Routes.<\/div>\n <\/div>\n <\/div>\n <\/div>\n\n <div class=\"cell large-shrink\">\n <div class=\"inline-alert--link\">\n\n\n <a href=\"https://www.minneapolismn.gov/getting-around/snow/snow-emergencies/snow-parking-rules/\" class=\"atom atom--shadow-button button tiny short\" tabindex=\"0\">Snow Emergency Parking Rules<\/a>\n\n <\/div>\n <\/div>\n\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n<\/section>",
"id": "snow-emergency-html",2522323
"version": "2390014.0"
},
{
"": ""
}
]
}
Senors and Templates
sensor:
- platform: rest
name: Snow Emergency Notice
resource: https://www.minneapolismn.gov/media/minneapolismngov/site-assets/javascript/snow-emergency/emergency-en-1.json
value_template: "OK"
json_attributes_path: "$.notices[0]"
json_attributes:
- date
- noticetype
- publishDate
- expireDate
- html
- id
- version
- platform: rest
name: Snow Emergency Declared
resource: https://www.minneapolismn.gov/media/minneapolismngov/site-assets/javascript/snow-emergency/emergency-en-1.json
value_template: "OK"
json_attributes_path: "$.notices[1]"
json_attributes:
- date
- noticetype
- publishDate
- expireDate
- html
- id
- version
- platform: rest
name: Snow Emergency Day1
resource: https://www.minneapolismn.gov/media/minneapolismngov/site-assets/javascript/snow-emergency/emergency-en-1.json
value_template: "OK"
json_attributes_path: "$.notices[2]"
json_attributes:
- date
- noticetype
- publishDate
- expireDate
- html
- id
- version
- platform: rest
name: Snow Emergency Day2
resource: https://www.minneapolismn.gov/media/minneapolismngov/site-assets/javascript/snow-emergency/emergency-en-1.json
value_template: "OK"
json_attributes_path: "$.notices[3]"
json_attributes:
- date
- noticetype
- publishDate
- expireDate
- html
- id
- version
- platform: rest
name: Snow Emergency Day2 Ended
resource: https://www.minneapolismn.gov/media/minneapolismngov/site-assets/javascript/snow-emergency/emergency-en-1.json
value_template: "OK"
json_attributes_path: "$.notices[4]"
json_attributes:
- date
- noticetype
- publishDate
- expireDate
- html
- id
- version
- platform: rest
name: Snow Emergency Day3
resource: https://www.minneapolismn.gov/media/minneapolismngov/site-assets/javascript/snow-emergency/emergency-en-1.json
value_template: "OK"
json_attributes_path: "$.notices[5]"
json_attributes:
- date
- noticetype
- publishDate
- expireDate
- html
- id
- version
- platform: template
sensors:
snow_emergency_state:
value_template: >-
{% set cur = as_timestamp(now()) %}
{% set notice_pub = as_timestamp(state_attr('sensor.snow_emergency_notice', 'publishDate')) %}
{% set notice_exp = as_timestamp(state_attr('sensor.snow_emergency_notice', 'expireDate')) %}
{% set declared_pub = as_timestamp(state_attr('sensor.snow_emergency_declared', 'publishDate')) %}
{% set declared_exp = as_timestamp(state_attr('sensor.snow_emergency_declared', 'expireDate')) %}
{% set day1_pub = as_timestamp(state_attr('sensor.snow_emergency_day1', 'publishDate')) %}
{% set day1_exp = as_timestamp(state_attr('sensor.snow_emergency_day1', 'expireDate')) %}
{% set day2_pub = as_timestamp(state_attr('sensor.snow_emergency_day2', 'publishDate')) %}
{% set day2_exp = as_timestamp(state_attr('sensor.snow_emergency_day2', 'expireDate')) %}
{% set day2_ended_pub = as_timestamp(state_attr('sensor.snow_emergency_day2_ended', 'publishDate')) %}
{% set day2_ended_exp = as_timestamp(state_attr('sensor.snow_emergency_day2_ended', 'expireDate')) %}
{% set day3_pub = as_timestamp(state_attr('sensor.snow_emergency_day3', 'publishDate')) %}
{% set day3_exp = as_timestamp(state_attr('sensor.snow_emergency_day3', 'expireDate')) %}
{% if (cur > declared_pub) and (cur < declared_exp) %}
DECLARED
{% elif (cur > day1_pub) and (cur < day1_exp) %}
DAY1
{% elif (cur > day2_pub) and (cur < day2_exp) %}
DAY2
{% elif (cur > day2_ended_pub) and (cur < day2_ended_exp) %}
DAY2_ENDED
{% elif (cur > day3_pub) and (cur < day3_exp) %}
DAY3
{% elif (cur > notice_pub) %}
NOTICE
{% else %}
NOT WINTER
{% endif %}
icon_template: >
{% set state = states('sensor.snow_emergency_state') %}
{% if state == 'DECARED' %}
mdi:snowflake-alert
{% elif state == 'DAY1' %}
mdi:snowflake-alert
{% elif state == 'DAY2' %}
mdi:snowflake-variant
{% elif state == 'DAY2_ENDED' %}
mdi:snowflake-melt
{% elif state == 'DAY3' %}
mdi:snowflake-melt
{% elif state == 'NOTICE' %}
mdi:snowflake
{% elif state == 'NOT WINTER' %}
mdi:sun-snowflake
{% else %}
mdi:alert-box
{% endif %}
Vertical Stack with custom:html-template-card
type: vertical-stack
cards:
- type: button
entity: sensor.snow_emergency_state
show_state: true
- type: custom:html-template-card
ignore_line_breaks: true
content: >
{% if states('sensor.snow_emergency_state') == "DECLARED" %}
{{ state_attr('sensor.snow_emergency_declared', 'html') }}
{% elif states('sensor.snow_emergency_state') == "DAY1" %}
{{ state_attr('sensor.snow_emergency_day1', 'html') }}
{% elif states('sensor.snow_emergency_state') == "DAY2" %}
{{ state_attr('sensor.snow_emergency_day2', 'html') }}
{% elif states('sensor.snow_emergency_state') == "DAY2_ENDED" %}
{{ state_attr('sensor.snow_emergency_day2_ended', 'html') }}
{% elif states('sensor.snow_emergency_state') == "DAY3" %}
{{ state_attr('sensor.snow_emergency_day3', 'html') }}
{% elif states('sensor.snow_emergency_state') == "NOTICE" %}
{{ state_attr('sensor.snow_emergency_notice', 'html') }}
{% elif states('sensor.snow_emergency_state') == "NO WINTER" %}
NO WINTER
{% else %}
FAIL
{% endif %}
<a href="https://apps.minneapolismn.gov/SnowEmergencyMapApp/"
target="_blank"> Parking Map </a>