Template Sensor showing seconds cannot be in graphical form?

There is an issue internally in my network for something that should always take place every 16 seconds but sometimes it is 32 seconds or something different. After some noodling around I set up a template sensor that, every 16 seconds, shows what the interval was between the last two events, in seconds. However when I look at the history it has always showed like this - a colored line - so I decided to format the sensor (as it might be more than one minute but unlikely) so show in the format “00:00:16”. Even back when I set it as an integer, it still showed as a colored line.

What I would much prefer is a graph like this (I can change the sensor back to an integer, but I think the system still thinks the number is ‘text’ still (?)):

What am I missing in order to correct this?

You need to add a unit_of_measurement.

@rccoleman , I tried your suggestion but it’s not working… here is my code. Currently it shows an output in the format “0:00:16” (meaning 16 seconds). If I add any kind of “unit_of_masurement” at all, the sensor just changes to “unknown”:

sensor:
# Sendor to validate latest weewx tranmission intervals (which should be 16 seconds)
  - platform: template
    sensors:
     latest_weewx_data_interval:
        friendly_name: Latest WEEWX data transmission receipt interval
        value_template: >-
          {% set olddatetime = strptime(states("input_text.previous_weewx_receipt") + " " + "{}".format(now().year), "%a %m/%d %H:%M:%S%p %Y") %}
          {% set newdatetime = strptime(states("input_text.latest_weewx_receipt") + " " + "{}".format(now().year), "%a %m/%d %H:%M:%S%p %Y") %}
          {{ newdatetime - olddatetime }}
#        unit_of_measurement: "Seconds"
        icon_template: >-
          mdi:data-matrix
        unique_id: latest_weewx_data_interval   

So, what are your thoughts?

It’s because subtracting two datetimes gives you a timedelta object, which typically would have a device class of duration, leading to the automatic behaviour you see. So, use this instead:


        value_template: >-
          {% set olddatetime = strptime(states("input_text.previous_weewx_receipt") + " " + "{}".format(now().year), "%a %m/%d %H:%M:%S%p %Y") %}
          {% set newdatetime = strptime(states("input_text.latest_weewx_receipt") + " " + "{}".format(now().year), "%a %m/%d %H:%M:%S%p %Y") %}
          {{ (newdatetime - olddatetime).total_seconds() }}
        unit_of_measurement: s

Ok thank you, I changed to the small letter s as the unit_of_measurement. I restarted HA and it still shows as a colored line instead of the line graph. Any ideas? Is it that the old data needs to be cleared out now, or more time is needed for collecting a starting new set of data, or - ?

Did you read the previous post in full and change the value_template?

If the state is now showing a number, it will become a graph once the old data has been pushed out of the history. Try making a plot of just the last few minutes, since the change.

You don’t need to restart HA: Settings / YAML / reload template entities.

Thank you, this did fix my problem (but exposed another which I resolved below) -

In a related automation I assigned to record the values so I have both to compare in the template sensor - essentially, the automation first sets this to the current value:

input_text.previous_weewx_receipt=input_text.latest_weewx_receipt

…and only then updates input_text.latest_weewx_receipt to the new value -

This exposed a situation that the template sensor would be fired off twice each time, first with a value of 0.0 - when the old and new briefly matched, so I have to insert a goofy if statement to ignore the 0.0 values in the chart, so the code ended up being:

sensor:
  - platform: template
    sensors:
     latest_weewx_data_interval:
        friendly_name: Latest WEEWX data transmission receipt interval
        value_template: >-
          {% set olddatetime = strptime(states("input_text.previous_weewx_receipt") + " " + "{}".format(now().year), "%a %m/%d %H:%M:%S%p %Y") %}
          {% set newdatetime = strptime(states("input_text.latest_weewx_receipt") + " " + "{}".format(now().year), "%a %m/%d %H:%M:%S%p %Y") %}
          {% set newdiff = (newdatetime - olddatetime).total_seconds() %}
          {% if newdiff | float == 0 %}
            {{ states('sensor.latest_weewx_data_interval') }}
          {% else %}
            {{ newdiff }}
          {% endif %}
        unit_of_measurement: Sec
        icon_template: >-
          mdi:data-matrix
        unique_id: latest_weewx_data_interval   
1 Like

I think you must change this to a trigger-based template sensor that triggers only on one entity. I think your issue is that the template sensor subscribes to all the entities used, so as each of them update the template will be reevaluated. That said, if the resulting sensor value doesn’t change it shouldn’t trigger automations where you use this.

he can just add {% set _ = now() %} and it’ll update once a minute

I agree - it would be more efficient that way. How can I have it trigger on just input_text.latest_weewx_receipt changing but show the difference each time (therefore still including the input_text.previous_weewx_receipt in the calculation but not tirgger on that one changing? Suggestion/s?

Yes but the graphical history would only be updated once each minute, and would miss the times it changes within each minute. I want to capture every time the diference changes -

You just put that entity under the trigger section. The other entities used in the template won’t trigger the sensor to update.

The code for the sensor above doesn’t have a trigger section - the only trigger is in the aforementioned automation that is called when when a different command line sensor changes value (note where I said above - “essentially, the automation first sets this to the current value: input_text.previous_weewx_receipt=input_text.latest_weewx_receipt …and only then updates input_text.latest_weewx_receipt to the new value -”)

Whenever the “latest_weewx_data_interval” changes as shown in the above code, the if statement was required so that it did not show “0” - in the graphical representation of that “latest_weewx_data_interval” sensor’s history (since “previous_weewx_receipt” does change first so the old value is not lost - but causes the difference between the two to briefly be 0…)…

How better to code that template sensor without the if statement then?

:crazy_face:

Yeah, I know. :slight_smile: You need to convert it: Template - Home Assistant (home-assistant.io).

Ok, now able to get rid of the if statement and much more elegant. Thank you folks!

template:
  - trigger:
      - platform: state
        entity_id: input_text.latest_weewx_receipt
    sensor:
      - name: Latest WEEWX data transmission receipt interval
        state: >
          {% set olddatetime = strptime(states("input_text.previous_weewx_receipt") + " " + "{}".format(now().year), "%a %m/%d %H:%M:%S%p %Y") %}
          {% set newdatetime = strptime(states("input_text.latest_weewx_receipt") + " " + "{}".format(now().year), "%a %m/%d %H:%M:%S%p %Y") %}
          {{ (newdatetime - olddatetime).total_seconds() }}
        unit_of_measurement: Sec
        icon: mdi:data-matrix
        unique_id: latest_weewx_data_interval   
1 Like