Multi State Sensor using device_class ENUM

Continuing the discussion from Multi State Control:

I have a number of sensors from my Komfovent MHRV unit that have multiple states. I have been creating these sensors using a mapper template translating the number from MODBUS to a named state.

sensor:
  - platform: template
    sensors:
        unit_of_measurement: "State"
        value_template: >-
          {% set mapper =  {
              '0' : 'StayAtHome',
              '1' : 'WorkingWeek',
              '2' : 'Office',
              '3' : 'Custom'} %}
          {% set state =  states('sensor.komfovent_scheduler_num') %}
          {{ mapper[state] if state in mapper else 'Unknown' }}

These sensors have started to Error.

ValueError: Sensor sensor.komfovent_scheduler_mode has device class None, state class None unit State and suggested precision None thus indicating it has a numeric value; however, it has the non-numeric value: WorkingWeek (<class 'str'>)
2023-07-01 17:47:06.454 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved

By replacing unit_of_measurement: "State" with device_class: enum I have got rid of the error.

However, in the documentation (Sensor Entity | Home Assistant Developer Docs), it states

The sensor has a limited set of (non-numeric) states. The options property must be set to a list of possible states when using this device class.

How do I do that (set the options) and can that be used to convert the number received from MODBUS to the state more easily?

1 Like

Just delete the unit of measurement and don’t replace it with a device_class.

I did delete that and I added a device_class, not a state_class.

This change solves the error problem. I am just wondering what the right YAML would be to add the options to the sensor (as per docs) and if those could be used to do the translation.

Yeah sorry, I edited my post before you replied.

No, deleting the unit of measurement solved your problem.

Non numeric sensors can no longer have a unit of measurement.

That’s all you needed to do.

Yes, I get that and it’s reasonable (didn’t see it as a breaking change :frowning:).

What I wonder is, how to add the ‘options’. It says this should be a list so is the syntax

[ 'StayAtHome','WorkingWeek','Office','Custom']

Can I then use that List to do the translation and set the sensor value.

I also note that native_value is now a required property. (although this fails validation - might be my slightly out of date installation).

That’s not how the enum device_class works. You supply a list of valid states. There is no translation.

Hence: just delete the unit of measurement.

The legacy template sensor does not support the option list, and won’t as no new features are being added now that we have the new format.

The new format for template sensors does not support enum option lists either as far as I can see. Though you could open a feature request if there isn’t one already.

1 Like

Ah, yes. I have gone full circle here. I remember looking at the Template Sensor docs and wondering how I could define the sensors I had with the new format.

Looking at it again, it looks like the new syntax should simply be like this (there is an indentation error in this example I think);
image

template:
  - sensor:
    - name: "Komfovent Scheduler Mode"
      state: >
          {% set mapper =  {
              '0' : 'StayAtHome',
              '1' : 'WorkingWeek',
              '2' : 'Office',
              '3' : 'Custom'} %}
          {% set state =  states('sensor.komfovent_scheduler_num') %}
          {{ mapper[state] if state in mapper else 'Unknown' }}

That seems to work.

@tom_l

Almost final version (the device class works);

template:
  - sensor:
    - name: "Komfovent Scheduler Mode2"
      unique_id: komfovent_scheduler_mode2
      device_class: enum
      state: >
          {% set mapper =  {
              '0' : 'StayAtHome',
              '1' : 'WorkingWeek',
              '2' : 'Office',
              '3' : 'Custom'} %}
          {% set state =  states('sensor.komfovent_scheduler_num') %}
          {{ mapper[state] if state in mapper else 'Unknown' }}

What would be the best way to set the availability template rather than (or as well as) set the state to unknown?

If I am going to rewrite these, I might as well do it properly! :slight_smile:

@tom_l - could you confirm this is the correct solution and what I can do about an availability template? I’m just getting around to updating these :frowning:

Something like this should do it:

availability: "{{ states('sensor.komfovent_scheduler_num')|int(5) in [0,1,2,3] }}"

Or

availability: "{{ 0 <= states('sensor.komfovent_scheduler_num')|int(5) < 4 }}"
1 Like