Use of entity values in compensation

What is compensation?

Thanks for the quick reply Tom.

But is it possible to create a linear compensation based on 2 points in a template?

Or otherwise would it be possible to reload the configuration without restarting HA?

Regards

I use the compansation integration to calibrate my PH sensor.

compensation:
  ph_calibrated_waarde:
    unique_id: ph_calibrated_waarde
    source: sensor.esp_aquarium_ph_controller
    unit_of_measurement: pH
    data_points:
      - [2.846, 4] #PH4
      - [2.32, 6.9] #PH7

I have a work around to automate the calibration of these values but that is including restarting HA.
So i hoped it would be possible to enter a entity value:

compensation:
  ph_calibrated_waarde:
    unique_id: ph_calibrated_waarde
    source: sensor.esp_aquarium_ph_controller
    unit_of_measurement: pH
    data_points:
      - [{{ states("sensor.esp_aquarium_ph4_voltage") }}, 4] #PH4
      - [{{ states("sensor.esp_aquarium_ph7_voltage") }}, 6.9] #PH7
1 Like

As I said you can’t use templates in the configuration options.

Here are some template sensor examples of implementing linear equations, unfortunately in the legacy template format:

https://community.home-assistant.io/t/light-color-to-match-battery-voltage/327494/3

https://community.home-assistant.io/t/soil-moisture-sensor-calibration/170582/2?u=tom_l

The coefficients of the linear equation y = mx + c can be worked out from two given points. In your case these points are a combination of fixed values and your sensors.

Ok clear.

If I adjust the “compensation” file is there a way to reload the changes without restarting home assistant?

It has a unique id option so it should allow reloading instead of restarting.

However I still think the template sensor would be a better way to go as then there is no need to reload. Do you actually have the ph7 and ph4 sensors?

If not you can load the voltages into input_numbers after you take the readings in the buffer solutions.

I’ll write an example template sensor for you tomorrow if you like. I’m on my mobile right now.

Thanks Tom, i have one sensor with 2 measurements indeed for ph4 and ph7 buffer solutions. I don’t have a clue in how to build it in a template. So if you can write an template that is able to replace the compensation i can pick it up from there. I have already a script to addthe measurements in input_numbers, at this momnet i use those to overwrite the yaml file from shell.

Thanks for the effort.

Try this:

configuration.yaml

template:
  - sensor:
      - name: Calibrated pH
        unique_id: ph_calibrated_waarde
        device_class: ph
        state_class: measurement # only include this line if you want long term statistics
        state: >
          {% set y4 = 4 %}
          {% set y7 = 6.9 %}
          {% set x4 = states('input_number.esp_aquarium_ph4_voltage')|float(0) %}
          {% set x7 = states('input_number.esp_aquarium_ph7_voltage')|float(0) %}
          {% set m = (y7 - y4) / (x7 - x4) %} {# calculate slope of line #}
          {% set c = y4 - m * x4 %} {# calculate y intercept of line #}
          {% set x = states('sensor.esp_aquarium_ph_controller')|float(0) %} {# get uncalibrated value #}
          {{ [0, m * x + c, 14]|sort(1)|round(1) }} {# calculate calibrated value, limit to a range of 0 to 14 and round to 1 decimal place #}
        availability: >
          {{ has_value('input_number.esp_aquarium_ph4_voltage') and
             has_value('input_number.esp_aquarium_ph7_voltage') and
             has_value('sensor.esp_aquarium_ph_controller') }}

This template is a lot more verbose than it needs to be, just for clarity.

All you have to do is set the input numbers to the correct voltages and this will return the calibrated value. It will be limited to a range of 0.0 to 14.0.

The output will only be available if all input numbers and your pH sensor have numeric values.

I can probably incorporate these values directly in the template if you show the sensor entity id and attributes. This would mean you could remove the script and input numbers.

Hi Tom,

I have tried the template but getting the following error:

Logger: homeassistant.config
Source: config.py:978
First occurred: 18:44:51 (2 occurrences)
Last logged: 18:44:53

Invalid config for [template]: required key not provided @ data['sensor'][0]['state']. Got None. (See /config/packages/aquarium/aquarium_ph_calibration.yaml, line 1).

Any suggestion?

If I remove the “-” before state and available the entity is available but without any value.

Oops. Yeah it should be this:

template:
  - sensor:
      - name: Calibrated pH
        unique_id: ph_calibrated_waarde
        device_class: ph
        state_class: measurement # only include this line if you want long term statistics
        state: >
          {% set y4 = 4 %}
          {% set y7 = 6.9 %}
          {% set x4 = states('input_number.esp_aquarium_ph4_voltage')|float(0) %}
          {% set x7 = states('input_number.esp_aquarium_ph7_voltage')|float(0) %}
          {% set m = (y7 - y4) / (x7 - x4) %} {# calculate slope of line #}
          {% set c = y4 - m * x4 %} {# calculate y intercept of line #}
          {% set x = states('sensor.esp_aquarium_ph_controller')|float(0) %} {# get uncalibrated value #}
          {{ [0, m * x + c, 14]|sort(1)|round(1) }} {# calculate calibrated value, limit to a range of 0 to 14 and round to 1 decimal place #}
        availability: >
          {{ has_value('input_number.esp_aquarium_ph4_voltage') and
             has_value('input_number.esp_aquarium_ph7_voltage') and
             has_value('sensor.esp_aquarium_ph_controller') }}

Put this in the template editor and see what it returns at each stage:

          {% set y4 = 4 %}
          {% set y7 = 6.9 %}
          {% set x4 = states('input_number.esp_aquarium_ph4_voltage')|float(0) %}
x4        {{ x4 }}
          {% set x7 = states('input_number.esp_aquarium_ph7_voltage')|float(0) %}
x7        {{ x7 }}
          {% set m = (y7 - y4) / (x7 - x4) %} {# calculate slope of line #}
m         {{ m }}
          {% set c = y4 - m * x4 %} {# calculate y intercept of line #}
c         {{ c }}
          {% set x = states('sensor.esp_aquarium_ph_controller')|float(0) %} {# get uncalibrated value #}
x         {{ x }}
          {{ [0, m * x + c, 14]|sort(1)|round(1) }} {# calculate calibrated value, limit to a range of 0 to 14 and round to 1 decimal place #}

Also if this is the first time you have used a template sensor you will need to restart home assistant, rather than reloading templates.

Hi Tom,

I get the following error in the template editor:

ValueError: Template error: round got invalid input '[14, 5.1905263157894765, 0]' when rendering template '{% set y4 = 4 %}
  {% set y7 = 6.9 %}
  {% set x4 = states('input_number.aquarium_ph4_v')|float(0) %}
x4  {{ x4 }}
  {% set x7 = states('input_number.aquarium_ph7_v')|float(0) %}
x7  {{ x7 }}
{% set m = (y7 - y4) / (x7 - x4) %} {# calculate slope of line #}
m   {{ m }}
    {% set c = y4 - m * x4 %} {# calculate y intercept of line #}
c         {{ c }}
          {% set x = states('sensor.esp_aquarium_ph_controller')|float(0) %} {# get uncalibrated value #}
x         {{ x }}
          {{ [0, m * x + c, 14]|sort(1)|round(1) }}' but no default was specified

If i remove the “round(1)” i get this:

x4  3.067
  
x7  2.592
 
m   -6.105263157894736
     
c         22.724842105263157
           
x         2.875
          [14, 5.172210526315791, 0]

Ah. I see the problem. The final template should be:

 {{ ([0, m * x + c, 14]|sort)[1]|round(1) }}
1 Like

Hi Tom,

Thank you so much for all the support, it is working perfectly.
It was a good learning curve for me on templating :smiley:

Regards

1 Like

Hi Tom, Can i ask you support once more. I thought i found out how the templates worked but ashame i didn’t :stuck_out_tongue:

I created the next formula and it is working in the template editor:

But when i add it in the template:

template:
  - sensor:
    - name: Aquarium Sensor CO2 Calibrated
      unique_id: aq_sensor_co2_calibrated
      state_class: measurement
      state: >
        {% set KH = states('input_number.aquarium_helper_kh')|float(0) %}
        {% set PH = states('sensor.aquarium_sensor_ph_calibrated')|float(0) %}
        {{ ([ (( 44 / 2.8) * KH * 10**(6.28 - PH))|round(2)]) }}
      availability: >
        {{ has_value('input_number.aquarium_helper_kh') and
           has_value('sensor.aquarium_sensor_ph_calibrated') }}     

It keep showing the status not available.

Any ideas or suggestions.

Thank you in advance.

Regards,
Micha

PS: yes the value is way off because the PH sensor is not connected but still generating values.

Found the issue.

1 Like

What was it?

The issue was that i kept the brackets in :sweat_smile: