Skip to content

Instantly share code, notes, and snippets.

@linux4life798
Last active August 8, 2025 20:50
Show Gist options
  • Select an option

  • Save linux4life798/417a932a54503c9747d3a3a40219ac46 to your computer and use it in GitHub Desktop.

Select an option

Save linux4life798/417a932a54503c9747d3a3a40219ac46 to your computer and use it in GitHub Desktop.
Home Assistant dew point blueprint template
blueprint:
name: Dew Point (Template Sensor)
description: >
Create a dew point sensor from temperature and relative humidity using
precise psychrometric formulas. Defaults to Buck (1981, ice/water split);
Magnus–Tetens (Alduchov & Eskridge, 1996) available as an alternative.
domain: template
source_url: https://gist.github.com/linux4life798/417a932a54503c9747d3a3a40219ac46
input:
temperature_entity:
name: Temperature sensor
description: Entity with ambient temperature (°C or °F).
selector:
entity:
domain: sensor
device_class: temperature
humidity_entity:
name: Relative humidity sensor
description: Entity with RH in percent (0–100).
selector:
entity:
domain: sensor
device_class: humidity
output_unit:
name: Output unit
default: "°C"
selector:
select:
options: ["°C", "°F"]
formula:
name: Formula
description: Choose Buck (1981) for higher fidelity; Magnus as a familiar alternative.
default: buck
selector:
select:
options:
- label: Buck (1981) — piecewise over ice/water
value: buck
- label: Magnus–Tetens (Alduchov & Eskridge, 1996)
value: magnus
precision:
name: Decimal places
default: 1
selector:
number:
min: 0
max: 3
step: 1
mode: box
name:
name: Sensor name
default: Dew Point
variables:
t_entity: !input temperature_entity
rh_entity: !input humidity_entity
out_unit: !input output_unit
method: !input formula
prec: !input precision
sensor_name: !input name
sensor:
- name: "{{ sensor_name }}"
unique_id: >
dew_point_{{ now().timestamp() | string | hash('md5') }}
device_class: temperature
state_class: measurement
unit_of_measurement: "{{ out_unit }}"
availability: >
{% set t = states(t_entity) %}
{% set h = states(rh_entity) %}
{{
t is not none and h is not none and
t|float(default=None) is not none and
h|float(default=None) is not none and
(0 <= h|float(0) <= 100)
}}
state: >
{# --- Read inputs & determine units --- #}
{% set t_val = states(t_entity) | float(0) %}
{% set t_unit = state_attr(t_entity, 'unit_of_measurement') %}
{% set rh = (states(rh_entity) | float(0)) %}
{# clamp RH to avoid log(0) and out-of-range issues #}
{% set rhc = [ [rh, 0.1] | max, 100.0 ] | min %}
{# Convert to Celsius for computation #}
{% if t_unit in ['°F', 'F', 'Fahrenheit'] %}
{% set t_c = (t_val - 32.0) * 5/9 %}
{% else %}
{% set t_c = t_val %}
{% endif %}
{# === Buck (1981) ===
Over water (t >= 0°C):
e_s = 6.1121 * exp((18.678 - T/234.5) * (T/(257.14 + T)))
Over ice (t < 0°C):
e_s = 6.1115 * exp((23.036 - T/333.7) * (T/(279.82 + T)))
e = RH/100 * e_s
Inversion uses matching constants.
#}
{% if method == 'buck' %}
{% if t_c >= 0 %}
{% set es = 6.1121 * e**((18.678 - t_c/234.5) * (t_c/(257.14 + t_c))) %}
{% set e_act = (rhc / 100.0) * es %}
{% set ln_ratio = log(e_act / 6.1121) %}
{% set td_c = (257.14 * ln_ratio) / (18.678 - ln_ratio) %}
{% else %}
{% set es = 6.1115 * e**((23.036 - t_c/333.7) * (t_c/(279.82 + t_c))) %}
{% set e_act = (rhc / 100.0) * es %}
{% set ln_ratio = log(e_act / 6.1115) %}
{% set td_c = (279.82 * ln_ratio) / (23.036 - ln_ratio) %}
{% endif %}
{% else %}
{# === Magnus–Tetens (Alduchov & Eskridge, 1996) ===
gamma = ln(RH/100) + (a*T)/(b+T); Td = (b*gamma)/(a - gamma)
Using a=17.625, b=243.04 °C (common modern pair).
#}
{% set a = 17.625 %}
{% set b = 243.04 %}
{% set gamma = (log(rhc/100.0) + (a * t_c) / (b + t_c)) %}
{% set td_c = (b * gamma) / (a - gamma) %}
{% endif %}
{# Output conversion & rounding #}
{% if out_unit in ['°F','F','Fahrenheit'] %}
{% set td_out = (td_c * 9/5 + 32) %}
{% else %}
{% set td_out = td_c %}
{% endif %}
{{ td_out | round(prec) }}
attributes:
formula: "{{ 'Buck (1981, ice/water split)' if method == 'buck' else 'Magnus–Tetens (Alduchov & Eskridge, 1996)' }}"
temperature_entity: "{{ t_entity }}"
humidity_entity: "{{ rh_entity }}"
input_temperature_unit: "{{ state_attr(t_entity, 'unit_of_measurement') }}"
rh_clamped: "{{ ([ [states(rh_entity)|float(0), 0.1 ] | max, 100.0 ] | min) | round(2) }}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment