Help with a template sensor that sets a number based on values between two numbers

I’m trying to determine the speed of my ceiling fan by monitoring the power usage. I’ve got three different values so I’m trying to make a template sensor that gives me either a 1, 2 or 3 based on a true/false between two values. Ive tested the code below and it works but I don’t know how to turn that into a {%- if is_state('sensor... statement.

"{{ (states.sensor.bedroom_fan_shelly_power.state | float > 4 ) and (states.sensor.bedroom_fan_shelly_power.state | float < 5 ) }}'

I want to do something like this but of course, I have the syntax completely wrong.

    value_template: >-
     {%- if is_state("sensor.bedroom_fan_shelly_power", ">4") and ("sensor.bedroom_fan_shelly_power", "<5")%}
       1
     {%- elif is_state("sensor.bedroom_fan_shelly_power", ">6") and ("sensor.bedroom_fan_shelly_power", "<7")%}
       2
     {%- elif is_state("sensor.bedroom_fan_shelly_power", ">8") and ("sensor.bedroom_fan_shelly_power", "<9")%}
       3
     {%- else -%}
        Off
     {%- endif %}
1 Like

Making some progress but only reports ‘1’ despite the value changing to between the other numbers.

    value_template: >-
     {% if states('sensor.bedroom_fan_shelly_power') | float >3 and ('sensor.bedroom_fan_shelly_power') | float <5.5 %}
       1
     {%- elif is_state('sensor.bedroom_fan_shelly_power') | float >6 and ('sensor.bedroom_fan_shelly_power') | float <8 %}
       2
     {%- elif is_state('sensor.bedroom_fan_shelly_power') | float >8 and ('sensor.bedroom_fan_shelly_power') | float <10 %}
       3
     {%- else -%}
        Off
     {%- endif %}

You are missing states() in the second part of your templates. And is_state is in a few places where states should be used. Try:

    value_template: >-
     {% if states('sensor.bedroom_fan_shelly_power') | float > 3 and states('sensor.bedroom_fan_shelly_power') | float < 5.5 %}
       1
     {% elif states('sensor.bedroom_fan_shelly_power') | float > 6 and states('sensor.bedroom_fan_shelly_power') | float < 8 %}
       2
     {% elif states('sensor.bedroom_fan_shelly_power') | float > 8 and states('sensor.bedroom_fan_shelly_power') | float < 10 %}
       3
     {% else %}
       Off
     {%- endif %}

You can make it a bit more human readable by doing this:

    value_template: >-
     {% set fan_power = states('sensor.bedroom_fan_shelly_power') | float %}

     {% if fan_power > 3 and fan_power < 5.5 %}
       1
     {% elif fan_power > 6 and fan_power < 8 %}
       2
     {% elif fan_power > 8 and fan_power < 10 %}
       3
     {% else %}
       Off
     {% endif %}

Simplifying further:

    value_template: >-
     {% set fan_power = states('sensor.bedroom_fan_shelly_power') | float %}

     {% if 3 < fan_power < 5.5 %}
       1
     {% elif 6 < fan_power < 8 %}
       2
     {% elif 8 < fan_power < 10 %}
       3
     {% else %}
       Off
     {% endif %}

This would be a safer set of values (no chance of 5.6 or 10.1 being reported as ‘Off’):

    value_template: >-
     {% set fan_power = states('sensor.bedroom_fan_shelly_power') | float %}

     {% if 3 < fan_power < 6 %}
       1
     {% elif 6 <= fan_power < 8 %}
       2
     {% elif fan_power >= 8 %}
       3
     {% else %}
       Off
     {% endif %}
8 Likes

Whoa! Yet again, mind blown. Wish I had the ability to figure all that out. Last one works a treat thank you. I just have to figure out why when I use the scripts defined in the fan template I get a different setting than if I use the direct broadlink switches for the three fan speeds.

The broadlink fan speed switches give me +/- 1 watt consumption levels increasing as the fan speed does (obviously) but for some strange reason, the speed script in the fan template yields intermittent results.

Seems the code I used to define speed was not correct. I have the following now and it’s working flawlessly.

  master_fan_set_speed:
    alias: Master Fan Set Speed
    sequence:
    - service: input_select.select_option
      data_template:
        entity_id: input_select.master_fan_set_speed
        option: '{{speed}}'
    - service: script.turn_on
      data_template:
        entity_id: >-
          {% if speed | string == "1"  %}
            script.bedroom_fan_1
          {% elif speed | string == "2" %}
            script.bedroom_fan_2
          {% elif speed | string == "3" %}
            script.bedroom_fan_3
          {% endif %}

This is where service templates are useful (scripts are services).

service_template: >
  {% if speed | string == "1"  %}
    script.bedroom_fan_1
  {% elif speed | string == "2" %}
    script.bedroom_fan_2
  {% elif speed | string == "3" %}
    script.bedroom_fan_3
  {% endif %}
service_template: "script.bedroom_fan_{{speed | string}}"

For the value_template, if you don’t mind the fan_power being like this:

< 3 is off
>= 3 and < 6 is 1
>= 6 and < 9 is 2
>= 9 is 3

then you can achieve it using arithmetic:

    value_template: >-
     {% set fan_power = ((states('sensor.bedroom_fan_shelly_power') | float) // 3) | int %}
     {{ fan_power if fan_power > 0 else 'off' }}
2 Likes