Create a template sensor.
value_template: "{{ 100*(e**((17.625 *TD)/(243.04+TD))/e**((17.625* T)/(243.04+T))) }}"
Replace TD and T with your sensors.
e.g. for TD, it could be something like this states('sensor.outside_dew_pt') | float
Create a template sensor.
value_template: "{{ 100*(e**((17.625 *TD)/(243.04+TD))/e**((17.625* T)/(243.04+T))) }}"
Replace TD and T with your sensors.
e.g. for TD, it could be something like this states('sensor.outside_dew_pt') | float
That’s amazing, thank you so much for taking the time to do that for me!
So I’m getting an error, but I don’t really understand what the issue is:
[homeassistant.components.sensor.template] Template sensor humidity_true_inside has no entity ids configured to track nor were we able to extract the entities to track from the value template(s). This entity will only be able to be updated manually.
The sensor values are:
sensor.bedroom_temperature
20.0
unit_of_measurement: °C friendly_name: Bedroom Temperature
And:
Sensor.pws_dewpoint_c
-4
attribution: Data provided by the WUnderground weather service date: Last Updated on February 7, 7:40 PM EST unit_of_measurement: °C friendly_name: Dewpoint icon: mdi:water
You need to explicitly tell the sensor template which entities to monitor.
Post the code you have for the template sensor and I’ll be able to help.
"{{ 100*(e**((17.625 *('sensor.pws_dewpoint_c')|float)/(243.04+('sensor.pws_dewpoint_c')|float))/e**((17.625*('sensor.bedroom_temperature')|float)/(243.04+('sensor.bedroom_temperature')|float))) }}"
Thank you!
Try this:
- platform: template
sensors:
humidity_true_inside:
friendly_name: True Inside Humidity
entity_id:
- sensor.pws_dewpoint_c
- sensor.bedroom_temperature
value_template: "{{ 100 * (e**((17.625 * states('sensor.pws_dewpoint_c')|float)/(243.04 + states(‘sensor.pws_dewpoint_c’)|float))/e**((17.625 * states('sensor.bedroom_temperature')|float)/(243.04+ states('sensor.bedroom_temperature')|float))) }}"
The defined entity ids tell HA what to monitor to update the template.
You also missed the “states” part of states(‘sensor.pws_dewpoint_c’) in your template. Same for the bedroom temp sensor (fixed above).
So this is now giving a value, but it is constantly 100.
I need to check our the math
I once started doing this for absolute humidity by using the python_script component. Even though you may have your answer, an alternative approach might be interesting for comparison.
Here’s the script (it’s just logging everything):
# Compute the absolute humidity in g/m³
# Param rh - relative humidity in %
# Param t - temperature in °C
def ah(rh, t):
mw = 18.016 # kg/kmol (Molecularweight of vapor)
rs = 8314.3 # J/(kmol*K) (Universal Gasconstant)
svp = 6.112 * math.exp((17.67*t)/(243.5+t)) # Compute saturated water vapor pressure in hPa
vp = rh/100. * svp # Compute actual water vapor pressure in hPa
return 10**5 * mw/rs * vp/(t + 273.15)
humidity_entity = data.get('humidity_entity')
humidity_attribute = data.get('humidity_attribute')
temperature_entity = data.get('temperature_entity')
temperature_attribute = data.get('temperature_attribute')
if humidity_entity is not None and temperature_entity is not None:
if humidity_attribute is not None:
logger.warning("Humidity attr: {}".format(humidity_attribute))
humidity = float(hass.states.get(humidity_entity).attributes[humidity_attribute])
else:
humidity = float(hass.states.get(humidity_entity).state)
if temperature_attribute is not None:
logger.warning("Temperature attr: {}".format(temperature_attribute))
temperature = float(hass.states.get(temperature_entity).attributes[temperature_attribute])
else:
temperature = float(hass.states.get(temperature_entity).state)
logger.warning("Humidity: {}".format(humidity))
logger.warning("Temperature: {}".format(temperature))
absolute_humidity = ah(humidity, temperature)
logger.warning("Absolute Humidity: {}".format(absolute_humidity))
#hass.bus.fire(name, { "wow": "from a Python script!" })
else:
logger.error("Missing entities in service data.")
To use this you would you would call the service with data like this:
{
"humidity_entity":"sensor.myhumiditysensor",
"temperature_entity":"climate.mythermostat",
"temperature_attribute":"current_temperature"
}
So it’s using existing entities, just like the template approach. In my example I used a climate entity for the temperature where the current temperature is exposed via an attribute. But it could also be a sensor like I do it for the humidity.
That’s an interesting approach. Did this actually work? I’m just getting a value of 100, which when I do the math means that there are no values for either sensor, but this doesn’t make a whole load of sense as the sensors actually have values.
Where do you put the Python script? And where do you call the service? In HA?
Use the developer tools template editor to play with your equation.
What was your source of the equation?
If you can post that I can check the formula for order of operations problems.
Tom, I put the calculation in a spreadsheet and it returns the correct values! Therefore I think there is an issue with my sensor values…
Excel and HA may have a different order of operations.
What happens when you put your sensors in the template editor?
I’m still getting 100. I’ll post more tomorrow
It does generate a value. I am however not too involved in that topic to judge if the result makes any sense. It’s what I implemented based on my Google research.
Follow the python_script instructions. Once you have placed the script at the correct location etc., you shoul see the script as a service in the service overview panel of HA. There you can feed it with JSON just like I have posted above. The result will be logged. Just below the line that does the final log there’s a commented out line I took from a template that would generate an event. But you probably could also modify an entity. I don’t know about that. So that’s the part you have to figure out, as it depends on you how you want this to work.
I tried to prettify the Jinja2 code + using even more accurate constants.
(huge thanks for @danielperna84, for rhTdFromWetBulb.pdf and for this book)
Here is my solution:
- platform: template
sensors:
o1balcony_ah:
friendly_name: 'Outside: Abs. humidity'
entity_id:
- sensor.o1balcony_xiamul_t
- sensor.o1balcony_xiamul_h
device_class: humidity
unit_of_measurement: 'g/m³'
availability_template: >
{{ not is_state('sensor.o1balcony_xiamul_t', 'unavailable') and not is_state('sensor.o1balcony_xiamul_h', 'unavailable') }}
value_template: >
{%- set t = states('sensor.o1balcony_xiamul_t') | float %}
{%- set rh = states('sensor.o1balcony_xiamul_h') | float %}
{%- set mw = 18.016 %} {#- kg/kmol (Molecularweight of vapor) #}
{%- set rs = 8314.3 %} {#- J/(kmol*K) (Universal Gasconstant) #}
{%- set svp = 6.112 * (e ** ((17.67 * t) / (243.5 + t))) %} {#- Compute saturated water vapor pressure in hPa #}
{%- set vp = rh / 100.0 * svp %} {#- Compute actual water vapor pressure in hPa #}
{{ (10 ** 5 * mw / rs * vp / (t + 273.15)) | round(1) }}
And a follow-up in the new template form:
- sensor:
- name: o1balcony_ah
unique_id: d698a9fe-6c31-4351-a821-704ba488cddb
device_class: humidity
icon: 'mdi:water'
unit_of_measurement: 'g/m³'
availability: >
{{ not is_state('sensor.o1balcony_xiamul_t', 'unavailable') and not is_state('sensor.o1balcony_xiamul_h', 'unavailable') }}
state: >
{%- set t = states('sensor.o1balcony_xiamul_t') | float %}
{%- set rh = states('sensor.o1balcony_xiamul_h') | float %}
{%- set mw = 18.016 %} {#- kg/kmol (Molecularweight of vapor) #}
{%- set rs = 8314.3 %} {#- J/(kmol*K) (Universal Gasconstant) #}
{%- set svp = 6.112 * (e ** ((17.67 * t) / (243.5 + t))) %} {#- Compute saturated water vapor pressure in hPa #}
{%- set vp = rh / 100.0 * svp %} {#- Compute actual water vapor pressure in hPa #}
{{ (10 ** 5 * mw / rs * vp / (t + 273.15)) | round(1) }}
Thanks for this, everyone!
I appreciate this is a very old thread, but here is the same calculation as a macro (which I keep in /custom_temlates/humidity.jinja
):
{% macro ah(temp,rel_humid) %}
{% set t = temp |float %} {# Temp [°C] #}
{% set rh = rel_humid |float %} {# Rel. humidity [%] #}
{% set tk = t + 273.15 %} {# Temp [°K] #}
{% set mw = 18.016 %} {# Molecularweight of vapor [kg/kmol] #}
{% set rs = 8314.3 %} {# Universal Gas constant [J/(kmol*K)] #}
{% set svp = 6.112*e**(17.67*t/(t+243.5)) %} {# Saturated water vapor pressure [hPa] #}
{% set vp = rh / 100.0 * svp %} {# Actual water vapor pressure [hPa] #}
{{ (10**5 *mw/rs *vp/tk) |round(1) }} {# Abs. humidity [g/m³] #}
{% endmacro -%}
I added tk
to make the final calculation easier to read.
Below is the reverse calculation (RH from AH). It’s a different method so, if you recalculate the RH from AH, there is a small (~0.5%) error to the RH you started with.
{% macro rh(temp,abs_humid) %}
{% set t = temp |float %} {# Temp [°C] #}
{% set ah = abs_humid |float %} {# Abs. humidity [%] #}
{% set tk = t + 273.15 %} {# Temp [°K] #}
{% set svp = 6.112*e**(17.67*t/(t+243.5)) %} {# Saturated water vapor pressure, [hPa] #}
{{ (ah*tk / (svp*2.1764))|round(1) }} {# Rel. humidity, [g/m³] #}
{% endmacro -%}
Hi not John.
Thanks for linking this thread from your WTH comment. I have a question less about the math and more on the process.
After saving this .jinja
file in /custom_templates/
, how do you reference the macro in your normal workflow? Is it as simple as just typing {{ ah(23,60) }}
anywhere a template is accepted (e.g. template sensor, automation, markdown card)?
No worries and sort of.
You have to call on the template first so HA knows you are going to use it and then call the function itself. You can do this (as a test) in developer tools > templates but, for real, do it in a template sensor using sensors ilo fixed numbers (you could use fixed numbers if you needed to).
Here is one of mine as an example…
template:
- sensor:
- name: Utility abs humidity
unit_of_measurement: "g/m³"
state: >
{% from 'humidity.jinja' import ah %}
{{ ah(states('sensor.utility_temp'),states('sensor.utility_rel_humidity')) }}
Brilliant. Thanks!