Templating Help

really sorry, but it still is not correct:

when set for later today (0 days):

set for next monday (3 days):

set for tomorrow (1 day):

its confusing…

what do you get in the template editor if you do just this

{{ now().strftime('%j') }}

you templating wizards are great to watch in action :slight_smile:

1 Like

For me it reports 130 (i.e. number of days since the beginning of the year).

Screenshot%20from%202019-05-10%2015-15-00

that results in
130

I’m not sure. I did find an error but it was because I was using the wrong timezone and it wouldn’t impact the result outside of being off by a day.

          {% set timezone = '-04:00' %}
          {% set delta = states('sensor.number_of_days_next_alarm_macro') %}
          {% if delta == 'Not set' %} {{ delta }}
          {% else %}
            {% set delta = delta | int %}
            {% set time = now() %}
            {% set mapper = [ 'Today', 'Tomorrow', 'The day after tomorrow,' ] %}
            {% set disabled = is_state('input_boolean.alarmclock_wd_enabled','off') and is_state('input_boolean.alarmclock_we_enabled','off') %}
            {% set daystring = 'Not set' if disabled else mapper[delta] if delta < mapper | length else 'Next' %}
            {% set time = now() %}
            {% set current = time.strftime('%j') | int %}
            {% set next = current + delta  if current + delta <= 365 else (current + delta)-365 %}
            {% set year = time.year if current + delta <= 365 else time.year + 1 %}
            {% set next = '{} {} 00:00:00{}'.format(year, next, timezone) %}
            {% set next = as_timestamp(strptime(next, '%Y %j %H:%M:%S%z')) | timestamp_custom('%A, %-d %B') %}
            {{ daystring }} {{ next }}
          {% endif %}

what is next set to between the format and the strptime on your system?

you mean this?

Well i don’t know what to tell you. It’s failing on the next line and the next line parses it properly. For shits and giggles what does this give you

{{ strptime('2019 130 00:00:00+01:00', '%Y %j %H:%M:%S%z') }}

gives me

2019-05-10 00:00:00+01:00

So to hijack my thread back :wink: I have a new challenge I want to take a list of sensors and return the top 3 highest values.

Hmm, that one is actually quite challenging. It’s only challenging because states are strings and we need numbers. You could make a python script to do this though, and it would be easy.

there’s no days returned in your setup??

what version of HA are you running?

above was on 84.3,

this is 92.2:

how is that possible ??

Upgrade your stuff and the template will work :wink:

I will on the 92.2 system.
the thing is, my main and most robust system is on 84.3…

maybe if id understand the difference I could see to try and adjust the template.

though even on that system the template has some peculiarities, see what happens, with alarm weekend set to Off and no number_of_days_macro sensor ;-)):

this might be caused by the delta|int which is always 0 if the delta is None…

nothing to adjust. Strptime in the old version doesn’t support %j or the timezone

Would you be able to help if I provide list of entities?

understand. won’t try again until 92.2 has arrived on my main system.

please see if this current template uses the best logic then in the 84.2 setting:

        value_template: >
          {% set day_delta = states('sensor.number_of_days_next_alarm_macro') %}
          {% set day = now().day %}
          {% set month = now().month %}
          {% set month_days = states('sensor.days_current_month')|int %}
          {% set month_delta = 1 if month < 12  else 1-12 %}

          {% if is_state('input_boolean.alarmclock_wd_enabled','off') and
                is_state('input_boolean.alarmclock_we_enabled','off') %} {% set daytype = 'Not set' %}
          {% elif day_delta == '0' %} {% set daytype = 'Today,'%}
          {% elif day_delta == '1' %} {% set daytype = 'Tomorrow,' %}
          {% elif day_delta == '2' %} {% set daytype = 'The day after tomorrow,' %}
          {% elif day_delta > '2' %} {% set daytype = 'Next' %}
          {% endif %}

          {% if day_delta == 'Not set' %} Not set
          {% elif day + day_delta|int > month_days %}
             {{daytype}} {{ as_timestamp(now().replace(month= month + month_delta).replace(day=(day + 
                                                day_delta|int - month_days))) | timestamp_custom('%A, %-d %B')}}
          {% else %}
             {{daytype}} {{ as_timestamp(now().replace(day=(day + day_delta|int )))| timestamp_custom('%A, %-d %B') }}
          {% endif %}

focussing on the day replacement in the elif part, (not so much the daytype, which is fine I think like this).

It’s not really a matter of having a list, it’s that you can’t create a list in jinja. So the problem lies in the fact that we need to sort the numbers numerically. Well we can’t do that because a devices state is a string. So it can only be sorted based on a string. Well that doesn’t work well because string sorting looks at the first number and sorts off that. So 9 would be greater than 10, because 9 is greater than 1. So our only recourse is to convert the list into a list of numbers. In order to do that, we need to create a new list. And that’s the road block. Creating a list and adding to it is not possible in jinja. Pretty much need to use a python script to generate the list.

Now if you just want the max item without getting the top 3 you can just use the min/max sensor

Otherwise, gotta go the python script route with an automation that triggers the script to run when an entity changes.

if you put all the sensors in a group, this script should give you the top 3 entities. You’d need to figure out where you want to store this info. Typically mqtt or a input_text.

input_text = 'input_text.max_sensors'
sensors = ['sensor.a','sensor.b','sensor.c','sensor.d']

class sortsensor:
    def __init__(self, name, state):
        self.name = name
        try:
            self.state = float(state)
        except ValueError:
            self.state = 0

sensors = [ sortsensor(sensor, hass.states.get(sensor).state) for sensor in sensors ]
sensors.sort(key=lambda x: x.state)

top = ', '.join([sensor.name for sensor in sensors[:3]])
hass.states.set(input_text, top)

EDIT: Let me know if this works. If it does, i’ll help you with the automations and the sensors that display friendly names and states.

1 Like