What is the difference between states and state_attr

{{  now()  - states.sensor.helligkeit.last_updated   }}    
{{  now()  - state_attr('sensor.helligkeit','last_updated')   }}

Only the first one works, why is that?

0:01:14.568738
TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'NoneType'
1 Like

states.sensor.helligkeit is a ā€œstateā€ object.

state_attr('sensor.helligkeit','last_updated') is basically equivalent to states.sensor.helligkeit.attributes.last_updated. It is a template extension that accesses the attributes property of the state object.

Therefore, states.sensor.helligkeit.last_updated is not the same as states.sensor.helligkeit.attributes.last_updated.

See state object and state template extension docs.

So, there is nothing similar to states.sensor.helligkeit.last_updated in a state template extension?

I donā€™t see anything like that in the docs. What do you need one for? If you need to handle an undefined state (state is None), then you can just add on the default filter.

{{ states.sensor.helligkeit.last_updated | default('unknown') }}

Replace ā€œunknownā€ with your default value.

Or use some if/else template logic.

1 Like

Since Watchman doesnā€™t yet monitor state objects, I thought I could convert them. But I guess the plugin needs an update to do that.

Except last_updated is not an attribute it is a property. So that first one wont work.

I just explained it here:

would be interested to see an example of if/else logic for state_attr
as an example:

I have a door attr that is one of 3 thingsā€¦ true(closed), false(open), or unknown
image

Canā€™t seem to figure out the logic for a templateā€¦ (also trying to use the template tab in developer toolsā€¦ my brain just isnā€™t happening tonight.

- sensors:
  - name: "Sauna Door"
    state: >-
       {% if state_attr('sensor.sauna_status', 'door') %}
         Closed
       {% elif state_attr('sensor.sauna_status', 'door') %}
         Open
       {% else %}
         Unknown
       {% endif %}
template:
  - binary_sensor:
      - name: "Sauna Door"
        state: "{{ is_state_attr('sensor.sauna_status', 'door', 'open') }}"
        device_class: door

Or possibly this if your attribute value is capitalised:

template:
  - binary_sensor:
      - name: "Sauna Door"
        state: "{{ is_state_attr('sensor.sauna_status', 'door', 'Open') }}"
        device_class: door
2 Likes

got this far with your assistantā€¦

- sensor:
  - name: "Sauna Door"
    device_class: door
    state: >
       {% if is_state_attr('sensor.sauna_status', 'door', true) %}Closed
       {% elif is_state_attr('sensor.sauna_status', 'door', false) %}Open
       {% else %}Unknown{% endif %}
    icon: >
       {% if is_state_attr('sensor.sauna_status', 'door', true) %}mdi:door-closed
       {% elif is_state_attr('sensor.sauna_status', 'door', false) %}mdi:door-open
       {% endif %}

did see you put it as a binary sensor, Iā€™m still learning this part, so why not just a sensor?

1 Like

this helps a little moreā€¦ https://www.home-assistant.io/integrations/binary_sensor/

But having an ā€œUnknownā€ option, would that still classify as a binary sensor?

No but using the binary sensor device class ā€œdoorā€ considerably simplifies things. No need to specify the states or icons. They are all done automatically.

You can add an availability template for the unavailable state.

template:
  - binary_sensor:
      - name: "Sauna Door"
        state: "{{ is_state_attr('sensor.sauna_status', 'door', true) }}"
        availability: "{{ state_attr('sensor.sauna_status') in [ true, false] }}"
        device_class: door
1 Like

that is even better! thanks for the tip

Just updated my post with the unavailable option.

I believe there is a syntax error in your availability line.


2022-05-24 23:11:24 ERROR (MainThread) [homeassistant.components.template.template_entity] TemplateError('TypeError: state_attr() missing 1 required positional argument: 'name'') while processing template 'Template("{{ state_attr('sensor.sauna_status') in [ true, false ] }}")' for attribute '_attr_available' in entity 'binary_sensor.sauna_door'

Updated it to this: (was missing the ā€˜nameā€™) of the attr.

- binary_sensor:
  - name: "Sauna Door"
    device_class: door
    state: "{{ is_state_attr('sensor.sauna_status', 'door', true) }}"
    availability: "{{ state_attr('sensor.sauna_status', 'door') in [ true, false ] }}"

howeverā€¦ this ended up showing the door as openā€¦ when it was really closed, so logic is backwards.
I ended up removing the availability line for now and went with this instead:

- binary_sensor:
  - name: "Sauna Door"
    device_class: door
    state: >
       {% if is_state_attr('sensor.sauna_status', 'door', true) %}Closed
       {% elif is_state_attr('sensor.sauna_status', 'door', false) %}Open
       {% else %}Unknown{% endif %}

It was. Good catch.

That is not valid. Binary sensor templates can only resolve to true or false. If you want to use the binary sensor and want the unavailable state you have to use the availability template.

1 Like

got it to thisā€¦


- binary_sensor:
  - name: "Sauna Door"
    device_class: door
    state: >
       {% if is_state_attr('sensor.sauna_status', 'door', true) %}Closed
       {% elif is_state_attr('sensor.sauna_status', 'door', false) %}Open
       {% endif %}
    availability: "{{ state_attr('sensor.sauna_status', 'door') in [ true, false ] }}"
1 Like

Again, no.

Your state template is resloving to Closed or Open, not true or false, as is required for binary sensor templates. The true or false state of the binary sensor template will be converted to on or off by the binary sensor platform, which will then be translated to Open or Closed by the device class. You donā€™t define the state as Open or Closed in the template. Only true or false.

This will do:

state: "{{ is_state_attr('sensor.sauna_status', 'door', true) }}"
availability: "{{ state_attr('sensor.sauna_status') in [ true, false] }}"
device_class: door

Ideally you could use just:

state: "{{ state_attr('sensor.sauna_status', 'door') }}"
availability: "{{ state_attr('sensor.sauna_status') in [ true, false] }}"
device_class: door

As the attribute has the true/false state already. However the unavailable state will cause an error (as the template should only resolve to true or false for a binary sensor). I think there was talk of not evaluating state templates unless the availability template resolved true first but donā€™t think this has been implemented yet.

You could do this:

state: "{{ state_attr('sensor.sauna_status', 'door')|bool(0) }}"
availability: "{{ state_attr('sensor.sauna_status') in [ true, false] }}"
device_class: door

The boolean filter with default false (0) will not generate an error for the attribute unavailable state. And the availability template will take over in that case.

1 Like