Understanding device class duration better

The duration device class was added in HA 2022.5. I’ve been experimenting with it to replace older sensors where I’ve been parsing the datetime to e.g. display an HH:MM duration string. In this case, I’m using the sun2 integration to get the duration of daylight.

This is my old template sensor using the sensor.daylight sensor as provided by sun2.

- platform: template
  sensors:
    daylight_hm:
      friendly_name: "Daylight Length"
      value_template: >-
        {{ state_attr('sensor.daylight', 'today_hms')[:5] }}
      icon_template: >-
        mdi:weather-sunny

I thought I’d get rid of it, and simply add the following to customize.yaml:

sensor.daylight:
  state_class: measurement
  unit_of_measurement: h

I expected this to display the daylight length in HH:MM:SS, but alas:

As one can see, it just displays the float value with a unit of h.

I then created another template sensor that simply wraps sensor.daylight:

- platform: template
  sensors:
    test_duration:
      friendly_name: "Test Duration"
      device_class: duration
      unit_of_measurement: h
      value_template: "{{ states('sensor.daylight') }}"

This works as expected:

Can someone explain why customising the parent sensor doesn’t work as expected?

Some related posts I’ve read:

PS: I’m aware I can request from the sun2 maintainer that the device class and UoM gets added to that sensor, but that’s not really the point here. I have other cases too, so this is just an easy example.

How are you adding device_class: duration to the parent sensor? I don’t see it in the template or customization config you shared.

This part, as above. The sensor sensor.daylight is the one provided by sun2, which I’ve referred to as the parent sensor.

The main state for duration needs to be what the units are. I.e. your units are hours, so the state should be 10.5 for 10:30:00. I.e. you won’t be able to just customize the device-class

I’m not sure I follow what you mean and how it’s different to my example. In my example above, the state value is 10.432 hours and it does get displayed correctly using the wrapper sensor as 10:25. For both the device class and UoM is specified, but only the latter gets “translated”.

I could be missing something very obvious here, but I’ve stared at this for a very long time (read: days).

I didn’t realize that. It’s probably caching then. Ctrl+f5.

Right but that snippet of customize doesn’t mention device_class at all. Nor does this bit:

If that’s just a copy and paste error then no problem. Just want to make sure it’s not the obvious solution (add device_class: duration).

1 Like

2022.7.7
In my tests this code did not change anything after reloading templates & customizations (did it several times):

homeassistant:
  customize:
    sensor.test_sun2_daylight:
      device_class: duration
      state_class: measurement
      unit_of_measurement: h

It only affected after HA restart.

Before customization:

After customization:

1 Like

Thank you for testing this, Ildar. I’m running 2022.7.6. In my case this wasn’t working as expected before my last upgrade. On other words, there’s also been several restarts since.

Always good to check the basics. In this case, the issue exists across various browsers, including the iOS app, and I’ve performed upgrades and restarts since. It doesn’t seem to be a caching issue. Nonetheless, I went back, opened the dev console and disabled the cache and there was no change.

Of course.

I think I can do a better job at explaining the issue. I’ll post a follow-up now. Turns out I missed the obvious…

1 Like

well, if you’re providing a device_class: and the unit_of_measurement, it should be converting in the frontend.

1 Like

And this is the point where I put my foot in my mouth: With all my experimentation I missed adding device_class: duration to the original sun2 sensor (I had it everywhere else). No issue, and no inconsistencies.

1 Like

Anyway, in my tests the customization affected after HA restart only, which is not right.

1 Like

Customizations can be reloaded from the UI on Developer Tools → YAML tab, they fall under “Location & Customizations”. However unlike all the other things you can UI reload on that page they don’t take effect immediately which is a bit confusing. From the warning at the bottom of the doc:

New customize information will be applied the next time the state of the entity gets updated.

This is the behavior I see. Nothing happens immediately after I reload customizations but next time the state of the entity I customized is changed for any reason then I see my new customizations. Is that what you see?

1 Like

Starting from now I will observe it with a more attention.

What I observed so far:

  1. I customized some template sensor in a yaml file (homeaasistant / customize); let it be an icon.
  2. Then reloaded customization (Dev tools → yaml → reload).
  3. Not affected, the icon not changed.
  4. Reloaded template sensors.
  5. Now I see that the icon is changed.

One time I started thinking that oddly customizations are applied after template reloading - even was thinking about writing an issue about it.
Now I think that reloading templates affected their states somehow - and then it made customizations to apply.

Reload removes the entities from the system and then readds them with the new config. Anytime an entity is added to the system it counts as a state change and thus new customizations are applied. Even if from your perspective the state hasn’t changed to HA it has.

If you check last_updated you’ll see it’s set to the time you clicked reload. Same thing happens when you restart HA, every entity gets an updated last_updated value even if nothing else seems to have changed.

1 Like

Thanks a lot for explanations!

On my system didn’t make any visual difference
Before
image

and after multiple restarts too, the state was being updated too.
image

It looks like you’re showing me a sensor that is correctly outputting the result of your template. What does that have to do with customization and what I said?