I’m monitoring my oil-tank with a Watchman Sonic. I convert the cm of air into cm of oil which gives me an indication of how much gasoil I still have. I would like to convert that into liters.
I’ve been able to convert that (easily) using ksh (I’m still old-school…) so I can convert the cm of gasoil in liters. Is it possible to do this calculation in HA/Jinja? If not, is it possible to call my script with the cm of gasoil and get the liters?
It’s not possible with the native jinja because cos isn’t a math operation that is available in the HA jinja. You’d be better off creating a python script to handle this. But it may be simpler than that. When you talk about
What is the cm of air and the cm of gas refering to in reference to the equation? Is that the height? If so you could write a python script assuming that you are getting the information from a height sensor:
script: named calc_gas
import math
h = data.get('height') # units should be cm
try:
h = float(h) # convert h to a float.
except ValueError:
h = None
# hard coding this, but you could make it a variable like above.
L = 500 # cm
R = 100 # cm
if h != None:
# In cm
volume = L * (R**2 * math.acos((R - h) / R) - (R - h) * math.sqrt(2 * R * h - h**2))
# in liters, dividing by 1000.
volume /= 1000
else:
volume = None # volume will be invalid if we don't have a good entity id or height.
if volume != None:
hass.states.set('sensor.gas_tank', volume, {
'unit_of_measurement': 'Liters',
'friendly_name': 'Gas Left',
'icon': 'mdi:thermometer'})
Then call the script using an automation when your height sensor changes:
- alias: 'update gas amount'
trigger:
- platform: state
entity_id: sensor.gas_height
action:
- service: python_script.calc_gas
data_template:
height: "{{ trigger.to_state.state }}"
EDIT: had to fix the EQ. FYI you’d need to follow the script installation process:
Thanks for the quick response. Never played with Python-scripts so that’s another challenge.
Small type on the formula, a ( is missing: L * ((R**2 …
When I try to run the script from HASS I get following error:
2018-07-11 15:58:22 ERROR (Thread-2) [homeassistant.components.python_script.calc_gas.py] Error executing script: __import__ not found
Traceback (most recent call last):
File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/python_script.py", line 166, in execute
exec(compiled.code, restricted_globals, local)
File "calc_gas.py", line 1, in <module>
ImportError: __import__ not found
Yes. If you read the docs, Python Scripts (i.e., the HA component, not Python in general) are run in a sandboxed environment, and that environment does not let the script (among many other things) import modules. I think you’ll need to run the script from a Shell Command instead, which will make it slightly more complex.
Setup: rtl-sdr which sends a json to mosquitto_pub. just created an intermediary script that modifies the json, calculates the volume and adds it to the json. Now need to check if HASS picks that up. So I have both depth and volume sent so I should be set.
To do this without relying on external scripts/mqtt, you could create a piecewise-linear function and retrieve values from that function. The function looks slowly varying enough that even three linear periods would be enough to semi-accurately capture the curve. This would probably get you to a similar level of accuracy considering assumptions made, accuracy of the sensor itself, etc.
That’s how I receive the messages from mosquitto… That’s been working for quite some time now but I want to know the volume in stead of the level of oil. Test-script is running and now I have to wait for the sensor to send a signal (about 2-3 times an hour).
I have an ultra sonic distance sensor providing the distance from the top of the tank to the surface of the oil. That then converts it into a rudimentary %. Exactly like this…
It currently returns the diameter of the tank minus the distance measured, and I just use that as a rudimentary percentage full. So currently the distance measured is 62cm and the gauge is showing as 48% full (110-62).
So this formula cannot be done in HA within templates or a python script because we don’t have access to acos. We can estimate it and that is the best we can do.
So i found some forumla online that gives a rough estimation and that should be good enough:
cos-1(v) = (-0.69813170079773212 * v * v - 0.87266462599716477) * v + 1.5707963267948966
The estimation isn’t close at max or empty so you’ll have a ton of error near those values. Pretty much if you are within 10 cm of the top or bottom of your tank, the value will be wrong this is going to truncate that.
sensor:
- platform: template
sensors:
estimated_oil_volume:
name: Estimated Oil
unit_of_measurement: L
value_template: >
{%- set r = 55 %}
{%- set l = 150 %}
{%- set h = r*2 - states('sensor.oil_tank_level') | float %}
{%- macro acos(v) %}
{{ (-0.69813170079773212 * v * v - 0.87266462599716477) * v + 1.5707963267948966 }}
{%- endmacro %}
{%- set total = pi * r ** 2 * l %}
{%- set volume = l * ( r ** 2 * acos((r-h)/r) | float - (r - h)*sqrt(2 * r * h - h**2)) %}
{{ total }} {{ volume }}
{%- if volume > total %}
{{ total / 1000 }}
{%- elif volume < 0 %}
0
{%- else %}
{{ volume / 1000 }}
{%- endif %}
estimated_oil_level:
name: Estimated Oil Level
unit_of_measurement: %
value_template: >
{%- set r = 55 %}
{%- set l = 150 %}
{%- set total = (pi * r ** 2 * l) / 1000 %}
{%- set volume = states('sensor.estimated_oil_volume') | float %}
{{ volume / total }}