Create virtual lambda sensor

Hi,

Currently I’m using this config and this is working very well.

    trigger_pin: GPIO14
    echo_pin: GPIO12
    name: "Zoutniveau waterontharder"
    id: "ontharder"
    update_interval: 2s
    timeout: 2.0m
    filters:
    - median:
        window_size: 15
    - lambda: return (0.51-x)*100;
    unit_of_measurement: "cm"

But I would like to create a new virtual sensor and make a math calculation on it. This is the exact math:
0 + ((35-0) / (51 - 5)) * (id(ontharder).state - 5)

But what ever I’m trying I cannot make it work. Everything results in “OFF” or “NaN M”

  - platform: template
    name: "Waterontharder in KG"
    lambda: |-
      return(0 + ((35-0) / (51 - 5)) * (id(ontharder).state - 5));

Some one who can give me a push to the right direction?

I think either:

- platform: template
    name: "Waterontharder in KG"
    lambda: |-
      return((35 / 46) * (id(ontharder)- 5));

or:

- platform: template
    name: "Waterontharder in KG"
    lambda: |-
      return((35 / 46) * (int(id(ontharder)) - 5));

If you want to simplify the math also.

The result is 0.0, whatever I’m trying. Even after replacing id(ontharder) with a fixed number.

I’f im trying to do this: return 2*2; the output is. 4.0 so it’s in the good direction :smiley:

I tried this and it seems to work:

- platform: template
    name: "Waterontharder in KG"
    lambda: |-
      return ((35 / 46) * (id(ontharder).state - 5));

You might need to add update_interval as without it it will only update every minute

Don’t know why, but my result is still 0.0:

esphome:
  name: esphome-web-0c14f8

esp8266:
  board: esp01_1m

# Enable logging
logger:
  level: VERBOSE

# Enable Home Assistant API
api:

ota:

web_server:
  port: 80

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-0C14F8"
    password: "f0SZDyGJNFc3"

captive_portal:
    
text_sensor:
  - platform: wifi_info
    ip_address:
      name: ESP IP Address
    ssid:
      name: ESP Connected SSID
  - platform: template
    name: Uptime Human Readable
    id: uptime_human
    icon: mdi:clock-start
sensor:
  - platform: uptime
    name: Uptime Sensor
    id: uptime_sensor
    update_interval: 60s
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? to_string(days) + "d " : "") +
                (hours ? to_string(hours) + "h " : "") +
                (minutes ? to_string(minutes) + "m " : "") +
                (to_string(seconds) + "s")
              ).c_str();
              
  - platform: ultrasonic
    trigger_pin: GPIO14
    echo_pin: GPIO12
    name: "Zoutniveau waterontharder"
    id: "ontharder"
    update_interval: 2s
    timeout: 2.0m
    filters:
    - median:
        window_size: 15
    - lambda: return (0.51-x)*100;
    unit_of_measurement: "cm"

  - platform: wifi_signal
    name: "WiFi Signal Sensor"
    update_interval: 60s

  - platform: template
    name: "Waterontharder in KG"
    lambda: |-
      return ((35 / 46) * (id(ontharder).state - 5));
    update_interval: 1s

What’s the value (state) of “Zoutniveau waterontharder”

Zoutniveau waterontharder 20.66 cm

Even this results into 0.0:

  - platform: template
    name: "test"
    lambda: |-
      return ((35/46)*(20-5));
    update_interval: 1s

Tried some more stuff and. this don’t work:

  - platform: template
    name: "test"
    lambda: |-
      return (35/46)*20;
    update_interval: 1s

But this results is 350:

  - platform: template
    name: "test"
    lambda: |-
      return (35/2)*20;
    update_interval: 1s

Looks like ESPHome don’t like it the first math part is below zero?

maybe so, this works for me:

return 0.76086956521739130434782608695652*(20-5);

If you just want to enter the two points of your linear equation so that you can adjust them, use the calibrate linear filter.

https://esphome.io/components/sensor/index.html#calibrate-linear

Yep,

Just. tried this:

  - platform: template
    name: "test"
    lambda: |-
      return 0.74468085106 * (id(ontharder).state - 5);
    update_interval: 1s

And that reports “11.7”

When I change 0.74468085106 into (35/46) it don’t work.

I will make a bug report at GitHub!

I want to have both values.

So use a template sensor that grabs your ultrasonic sensor state and applies the calibrate linear filter.

If that’s possible I will have a look into it. ESPHome is very new for me so I don’t have much experience with it.

Yes it is possible.

Thanks, will get this working before starting with the filter option :wink:

Why?

They do the same thing.

Because I’m already happy I’ve got this working :smiley: