Icon_template issue

HI,

using:

  - platform: template
    sensors:
      utc_offset:
        friendly_name: Utc offset
        value_template: >
          {{ now().utcoffset().total_seconds()/3600}}
        icon_template: >
          {% if is_state('sensor.utc_offset','1.0') %} mdi:numeric-1
          {% elif is_state('sensor.utc_offset','2.0') %} mdi:numeric-2
          {% else %} mdi:help
          {% endif %}

I should have mdi:numeric-1 for the icon, since the state == 1.0.

proof:

however:

50

and

not used to not being able to customize the icons, I must be not-seeing something… please check what’s wrong?

It’s probably due to a comparison between a number and a string.
Entities’ state are saved as a string.
try this:

  - platform: template
    sensors:
      utc_offset:
        friendly_name: Utc offset
        value_template: >
          {{ now().utcoffset().total_seconds()/3600}}
        icon_template: >
          {% if states('sensor.utc_offset') | int == 1 %} mdi:numeric-1
          {% elif states('sensor.utc_offset') | int == 2 %} mdi:numeric-2
          {% else %} mdi:help
          {% endif %}

yes, thanks, Ive thought about that, and my reasoning was the sensor’ state is a string (everything is a string unless you explicitly state it isn’t ) and the quoted ‘1.0’ is a string… so, no need to create floats or ints because of that?

if needed, maybe I would be better of using an int’ed value_template?

btw: Doesn’t change:

renders:

16

Why this doesn’t work is yet to be explained…

Maybe this could be used with the int’ed sensor (but it is essentially the same as your suggestion…):

well, im stuck really, I can test various formats in the dev-template and they all show the correct mdi icon, and when in frontend it keeps showing the mdi:help…

maybe @petro would you understand what’s going on here?

       {% if states.sensor.utc_offset.state|int == 1 %} mdi:numeric-1
       {% elif states.sensor.utc_offset.state|int == 2 %} mdi:numeric-2
       {% else %} mdi:help
       {% endif %}
          {% if states.sensor.utc_offset.state == '1.0' %} mdi:numeric-1
          {% elif states.sensor.utc_offset.state == '2.0' %} mdi:numeric-2
          {% else %} mdi:help
          {% endif %}

tried it with customize:

sensor.utc_offset:
  templates:
    icon: >
      if (state === 1.0) return 'mdi:numeric-1';
      if (state === 2.0) return 'mdi:numeric-2';
      return mdi:help;

and

sensor.utc_offset:
  templates:
    icon: >
      if (state === '1.0') return 'mdi:numeric-1';
      if (state === '2.0') return 'mdi:numeric-2';
      return mdi:help;

nothing customizes:

37

even tried this:

      utc_offset:
        friendly_name: Utc offset
        value_template: >
          {{ (now().utcoffset().total_seconds()/3600)|int}}
        icon_template: >
          {% if states.sensor.utc_offset.state|int == 1 %} mdi:numeric-1
          {% elif states.sensor.utc_offset.state|int == 2 %} mdi:numeric-2
          {% else %} mdi:help
          {% endif %}

still the icon displayed is mdi:help,

while dev_template shows correctly:

@pnbruckner please could you see what/why ?

trying this as a last option:

        icon_template: >
          {% set offset = states.sensor.utc_offset.state %}
            mdi:numeric-{{offset}}

didn’t work…
this might be a hint:

47

Update2

bingo:

the base template needs parentheses to make it a true number. Havent seen that before, and hope to see some explanation pointers…

this works:

        icon_template: >
          {% if (now().utcoffset().total_seconds()/3600) == 1.0 %} mdi:numeric-1
          {% elif (now().utcoffset().total_seconds()/3600) == 2.0 %} mdi:numeric-2
          {% else %} mdi:help
          {% endif %}

44

Sorry I didn’t get to this earlier. I think you’re drawing the wrong conclusion here. The issue is operator precedence. is number is a test, and it takes precedence over divide. So it basically did 3600 is number first, then used that in the denominator of the division. That’s why you got an unexpected result when you tried that in the template editor. In that particular case you do need to use parentheses to get the divide to happen first, and then apply the is number test to the result of the divide.

But == has lower precedence than divide, so you don’t need the parentheses. This:

now().utcoffset().total_seconds()/3600 == 1.0

produces the same result as:

(now().utcoffset().total_seconds()/3600) == 1.0

I suspect your original problem had more to do with trying to use the result of the value_template in the icon_template. If you look back, all your non-working template sensor examples used the state of the sensor in the icon_template. It didn’t work until you used now() instead. But that’s just a guess since I really don’t use icom_template.

HI!
Thanks for this, much appreciated, and very informative. Didn’t realize the precedence issue indeed. Will take note of that and be careful.

However…
this is the only template up to now, where I must use the value template itself and can’t use the state of the sensor for templating. And, don’t want to be stubborn, I do need the parentheses for the icon_template to work. If I read correctly, this can’t be explained by what you’ve just tought me. It might even be a bug, and I will see if posting an issue on this could be helpful.

Im using regular icon_template here, builtin HA, so no custom-ui.

this is my final setup now:

  - platform: template
    sensors:
      utc_offset:
        friendly_name: Utc offset
        value_template: >
          {{ now().utcoffset().total_seconds()/3600}}
        icon_template: >
          {% set offset = (now().utcoffset().total_seconds()/3600) %}
          {% if offset == 1.0 %} mdi:numeric-1
          {% elif offset == 2.0 %} mdi:numeric-2
          {% else %} mdi:help
          {% endif %}

you can copy and try for yourself. take out the parenthesis in the {% set offset = (now().utcoffset().total_seconds()/3600) %} line and it will fail.
Not in dev-template, like all the others that showed correctly there, but in actual HA .

I adjusted your template sensor for my time zone and tested it with and without the parentheses and it worked in both cases (using version 0.89 in docker).

      utc_offset:
        friendly_name: Utc offset
        value_template: >
          {{ now().utcoffset().total_seconds()/3600 }}
        icon_template: >
          {% set offset = now().utcoffset().total_seconds()/3600 %}
          {% if offset == -5.0 %} mdi:numeric-1
          {% elif offset == -6.0 %} mdi:numeric-2
          {% else %} mdi:help
          {% endif %}

UTC%20sensor

:thinking:

you should really use:

{% if offset == -5.0 %} mdi:numeric-5
          {% elif offset == -6.0 %} mdi:numeric-6

:slight_smile:

well, that’s surprising. Don’t know what is going on then. Will try again, but have done so many times already…

since {{ now().utcoffset().total_seconds()/3600 }} is the state of the sensor, would you be so kind to test

   utc_offset:
        friendly_name: Utc offset
        value_template: >
          {{ now().utcoffset().total_seconds()/3600 }}
        icon_template: >
          {% set offset = states('sensor.utc_offset') %}
          {% if offset == -5.0 %} mdi:numeric-5
          {% elif offset == -6.0 %} mdi:numeric-6
          {% else %} mdi:help
          {% endif %}

for me? In the end that would be the way I’d hope to create these templates, as I do everywhere else in the HA setup.

this:

        icon_template: >
          {% set offset = states('sensor.utc_offset') %}
            mdi:numeric-{{offset}}

thought this would require the result to be a string and not a number (my original post about the parentheses reiterating …)

would be the simplest setup, maybe used with |abs to cater for the -utc setups

So now that I look at your OP again, your issue is that there are no entities to get it to be re-evaluated. It’s only evaluated once at startup. Do you see this warning in your log:

Log Details (WARNING)
Sun Mar 10 2019 07:36:34 GMT-0500 (Central Daylight Time)
Template sensor utc_offset has no entity ids configured to track nor were we able to extract the entities to track from the value template(s). This entity will only be able to be updated manually.

When the sensor is updated at restart, it has no state in the state machine yet. So when it evaluates value_template and icon_template, states.sensor.utc_offset does not exist yet. This results in the icon_template being evaluated as mdi:help.

To solve your original problem, and to solve the problem you didn’t realize you had – namely that when there is a utcoffset switch, like today, the sensor isn’t updated until the next restart – add entity_id. So something like:

  - platform: template
    sensors:
      utc_offset:
        friendly_name: Utc offset
        entity_id: sensor.time
        value_template: >
          {{ now().utcoffset().total_seconds()/3600 }}
        icon_template: "mdi:numeric-{{ states('sensor.utc_offset')|int|abs }}"

Came back to report exactly what Phil did: No entity_id to track.

2019-03-10 09:00:43 WARNING (MainThread) [homeassistant.components.sensor.template] Template sensor utc_offset has no entity ids configured to track nor were we able to extract the entities to track from the value, icon template(s). This entity will only be able to be updated manually.

I was seeing it “work” only because I restarted my test system (docker-based) after I added the template sensor to the config file. Only reason the template sensor worked again this morning (showing correct offset for DST) was because, yet again, I started the test system which is normally off.

must confess I had thought about that tbh, but since I didn’t see the famous error in the log, stopped worrying about that.

I’ve added the sensor.time now and rebooting as I write this. #fingerscrossed

and yes! this works. Thank you very much!

1 Like

BTW, if you watch closely, you’ll see that right after restart the icon is mdi:numeric-0 until the sensor updates again. That’s because at first the state doesn’t exist, so the int filter returns 0. Then on the next update it changes to the expected value. This is going to happen all the time. I.e., the icon will always be one update behind the state. But since that’s only for one minute, and only will be an issue for one minute twice a year, and probably while you’re sleeping, might not be worth changing. :wink:

1 Like

well, now that I have made this automation, I will be rembered of your assistance in the matter for ever :wink:

automation:
  - alias: 'Utc Offset change'
    id: 'Utc Offset change'
    initial_state: 'on'
    trigger:
      platform: state
      entity_id: sensor.utc_offset
    condition:
      - condition: template
        value_template: >
          {{ trigger.to_state.state != trigger.from_state.state }}
#      - condition: template
#        value_template: >
#          {{ is_state('input_boolean.notify_system', 'on')}}
    action:
      service: notify.notify
      data_template:
        message: >
         {{as_timestamp(now()) | timestamp_custom("%X") }} Utc Offset changed to {{states('sensor.utc_offset')}}.
         Check if time is set correctly in Python scripts, and day-time sensors.

that is, until I uncomment my system notifications of course…

What is the purpose of this template sensor?

For example, if it’s for indicating time-changes as a result of Daylight Saving Time, then that only happens twice a year (and the sensor need not check for it every clock-tick).

Please see this thread: Substitute hardcoded timedifference with dynamic in python script?

in short: I needed an automated way to set my python scripts on the correct timeDifference. I am on CET +1, but daylights savings times are not synchronous.

our Summertime starts on march 21st, while I think even today Daylight savings changes in the python time :wink:

so, its not always +1…

Hope to have it covered thanks to @pnbruckners help with the utc offset template.