Hello, I am playing with template and Jinja2 but I’m a really beginner and I’m try to learn taking some ideas and code example around.
I wrote this (incomplete) piece of code which works perfectly:
- platform: template
sensors:
forecast_1:
friendly_name_template: >
{%- set date = as_timestamp(now()) + (1 * 86400 ) -%}
{% set day = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] %}
{% set month = ["January", "February", "Marsh", "April", "May", "june", "July", "August", "September", "October", "November", "December"] %}
{% set m_ok = date | timestamp_custom("%m") | int %}
{% set g_ok = date | timestamp_custom("%w") | int %}
{{day[g_ok] + ' ' + date | timestamp_custom("%d") + ' ' + month[m_ok - 1]}}
value_template: "{{states.sensor.dark_sky_icon_1.state}}"
icon_template: >-
{% if states.sensor.dark_sky_icon_1.state == "clear-day" %}
mdi:weather-sunny
{% elif states.sensor.dark_sky_icon_1.state == "partly-cloudy-day" or states.sensor.dark_sky_icon_1.state == "partly-cloudy-night"%}
mdi:weather-partlycloudy
{% elif states.sensor.dark_sky_icon_1.state == "snow" %}
mdi:weather-snowy
{% elif states.sensor.dark_sky_icon_1.state == "fog" %}
mdi:weather-fog
{% else %}
mdi:help-circle
{%- endif %}
Because I have more forecast_n sensor I have to repeat that code for each sensor especially for the icon_template section. I was wondering if I could use a Jinja2 macro but I have no idea how to place it in the code.
unfortunately you have to repeat the same section of code many times if they aren’t in the same attribute. Macro’s don’t transfer between them because they are in their own environment. It’s super annoying.
But just to let you know, there are much better ways to do what you want to do. First, you can use strfttime or even custom timestamp to get your days and months. The only reason people use a list for days and months is when they aren’t dealing with english.
%A gives day %B gives month
All these attributes are documented in python here, you just need to scroll to the grid at the bottom of the page.
Also, if you want to shorten up the number of locations that you are changing 1 to 2, you can make a dictionary that that maps values to other values instead of using if statements. This will make it so you only need to change the number in the fewest amount of places.
- platform: template
sensors:
forecast_1:
friendly_name_template: >
{{ (as_timestamp(now()) + (1 * 86400)) | timestamp_custom('%A %d %B') }}
value_template: >
{{ states('sensor.dark_sky_icon_1') }}
icon_template: >
{%- set current = states('sensor.dark_sky_icon_1') %}
{%- set mapper = {'clear-day':'sunny', 'partly-cloudy-day':'partlycloudy', 'partly-cloudy-night':'partlycloudy', 'snow':'snowy', 'fog':'fog'} %}
{{ 'mdi:weather-'+mapper[current] if current in mapper else 'mdi:help-circle' %}
EDIT: changed friendly_name_template based on conversation below
So, you’d just copy and paste the code and replace the 2 dark_sky sensor names. Also, if you know python, you can just make a string format and have it write the code for you.
If you have questions about what is being done, i’m glad to answer them. Some of the code in this is advanced.
I remember to have tried something similar but I gave up because I got some error similiar to the error I get using the code you wrote:
2019-01-24 19:21:10 INFO (MainThread) [homeassistant.core] Starting Home Assistant
2019-01-24 19:21:10 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.forecast_1 fails
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
await self.async_device_update()
File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 347, in async_device_update
await self.async_update()
File "/usr/local/lib/python3.6/site-packages/homeassistant/components/sensor/template.py", line 215, in async_update
setattr(self, property_name, template.async_render())
File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/template.py", line 138, in async_render
return self._compiled.render(kwargs).strip()
File "/usr/local/lib/python3.6/site-packages/jinja2/asyncsupport.py", line 76, in render
return original_render(self, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/jinja2/environment.py", line 1008, in render
return self.environment.handle_exception(exc_info, True)
File "/usr/local/lib/python3.6/site-packages/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/jinja2/_compat.py", line 37, in reraise
raise value.with_traceback(tb)
File "<template>", line 1, in top-level template code
TypeError: unsupported operand type(s) for +: 'float' and 'str'
If I have to be honest, I don’t know python a lot but my best difficulty is understand how Python and Jinja2 ‘intersect’ home-assistant configuration code.
{%- set current = states('sensor.dark_sky_icon_1') %}
{%- set mapper = {'clear-day':'sunny', 'partly-cloudy-day':'partlycloudy', 'partly-cloudy-night':'partlycloudy', 'snow':'snowy', 'fog':'fog'} %}
{{ 'mdi:weather-'+mapper[current] if current in mapper else 'mdi:help-circle' %}