Anticipación meteorológica para suelo radiante con Home Assistant


El suelo radiante tiene un problema inherente: reacciona tarde. Cuando el termostato detecta que hace frío y pide calor, el agua caliente tiene que calentar la solera, que a su vez tiene que calentar el aire de la habitación. Ese proceso puede tardar entre 2 y 4 horas dependiendo del grosor de la solera y de si el suelo está en frío o ya templado.

La consecuencia práctica es que si esperas a que baje la temperatura para encender la calefacción, ya llevas horas de retraso. La solución es anticiparse: saber que va a hacer frío antes de que haga frío, y arrancar el sistema con suficiente antelación.

Vamos a intentar explicarlo y cómo implementar en Home Assistant usando la predicción meteorológica de Met.no, que ya viene integrada de serie.

La idea

La integración de Met.no en Home Assistant incluye un forecast horario con hasta 90 horas de predicción. En lugar de reaccionar a la temperatura actual exterior, podemos mirar qué temperatura va a hacer en N horas y actuar en consecuencia.

El parámetro N es lo que llamamos inercia térmica del suelo: el tiempo que tarda el sistema en llegar a temperatura desde que arranca. Es algo que hay que medir empíricamente en cada instalación, pero un punto de partida razonable son 2 horas.

El sensor de temperatura anticipada

El primer componente es un sensor template que consulta el forecast de Met.no y devuelve la temperatura prevista dentro de N horas:

template:
  - sensor:
      - name: "temp_exterior_anticipada"
        unique_id: clima_temp_exterior_anticipada
        unit_of_measurement: "°C"
        device_class: temperature
        icon: mdi:weather-partly-cloudy
        state: >
          {% set horas = states('input_number.inercia_suelo_horas') | int(2) %}
          {% set forecast = state_attr('weather.casa', 'forecast') %}
          {% if forecast is none or forecast | length == 0 %}
            {{ state_attr('weather.casa', 'temperature') | float(0) }}
          {% else %}
            {% set objetivo = (now() + timedelta(hours=horas)) .isoformat() %}
            {% set ns = namespace(temp=none) %}
            {% for f in forecast %}
              {% if ns.temp is none and f.datetime > objetivo %}
                {% set ns.temp = f.temperature %}
              {% endif %}
            {% endfor %}
            {{ ns.temp if ns.temp is not none
               else state_attr('weather.casa', 'temperature') | float(0) }}
          {% endif %}

Cambia weather.casa por el nombre de tu entidad de Met.no. El sensor recorre el forecast hasta encontrar la primera entrada futura que supera el horizonte temporal que has configurado, y devuelve esa temperatura.

Si el forecast no está disponible (por ejemplo, justo tras reiniciar HA), cae de vuelta a la temperatura actual exterior.

El helper de inercia térmica

El número de horas de anticipación es configurable desde el dashboard, no está hardcodeado:

input_number:
  inercia_suelo_horas:
    name: "Inercia térmica suelo (h)"
    min: 0.5
    max: 6.0
    step: 0.5
    initial: 2.0
    unit_of_measurement: h
    icon: mdi:clock-fast

  anticipacion_umbral_temp:
    name: "Umbral anticipación exterior (°C)"
    min: 0
    max: 15
    step: 0.5
    initial: 8.0
    unit_of_measurement: "°C"
    icon: mdi:thermometer-low

anticipacion_umbral_temp es la temperatura exterior por debajo de la cual el sistema decide arrancar en modo anticipación. Con 8°C como punto de partida, si la predicción indica que en 2 horas va a bajar de 8°C, el sistema actúa ahora.

La automatización

Con el sensor listo, la automatización es sencilla:

automation:
  - id: clima_anticipacion_meteo
    alias: "Clima · Anticipación meteorológica suelo radiante"
    description: >
      Activa preset comfort de forma anticipada cuando la temperatura
      exterior prevista cae del umbral configurado.
    mode: single
    trigger:
      - platform: time_pattern
        minutes: "/30"
    condition:
      - condition: template
        value_template: >
          {{ states('input_select.modo_casa') in ['Invierno', 'Confort'] }}
      - condition: template
        value_template: >
          {{ states('sensor.temp_exterior_anticipada') | float(20) <
             states('input_number.anticipacion_umbral_temp') | float(8) }}
      - condition: template
        value_template: >
          {{ state_attr('climate.aerotermia_salon', 'preset_mode') != 'comfort' }}
      - condition: not
        conditions:
          - condition: state
            entity: climate.aerotermia_salon
            state: "off"
    action:
      - service: climate.set_preset_mode
        target:
          entity_id: climate.aerotermia_salon
        data:
          preset_mode: "comfort"
      - service: notify.moviles_de_la_granja
        data:
          title: "&#x2744;&#xfe0f; Anticipación climática activa"
          message: >
            Temperatura prevista en
            {{ states('input_number.inercia_suelo_horas') }}h:
            {{ states('sensor.temp_exterior_anticipada') }}°C.
            Aerotermia en modo confort por anticipación.

La automatización se evalúa cada 30 minutos. Si las condiciones se cumplen, sube el preset de la aerotermia a comfort (temperatura más alta) para que el suelo llegue a temperatura antes de que realmente haga falta.

Visualización: la clave para calibrar

La parte más interesante es poder ver en una gráfica la temperatura exterior real junto con la anticipada. Si están bien alineadas, significa que Met.no predice con precisión y que el parámetro de inercia es correcto.

- type: history-graph
  title: Exterior y referencia
  hours_to_show: 24
  entities:
    - entity: sensor.aerotermia1_displayedoutsidetemp
      name: Exterior (sonda)
    - entity: sensor.temperatura_internet
      name: Exterior (internet)
    - entity: sensor.temp_exterior_anticipada
      name: Exterior anticipada
    - entity: sensor.aerotermia1_z1roomtemp
      name: Salón (referencia)

Lo que verás en la gráfica es que la curva «anticipada» se desplaza N horas hacia la izquierda respecto a la curva real. Si tu suelo tarda 2 horas en responder y configuras inercia_suelo_horas = 2, las dos curvas deberían solaparse visualmente en el historial — lo que ves en «anticipada» ahora es lo que tendrás como «real» en 2 horas.

grafica_temperaturas sobre Aerotermia
grafica_circuito_hidraulico sobre Aerotermia
grafica_termostatos sobre Aerotermia

Cómo calibrar la inercia térmica

El proceso de calibración es empírico y requiere unos días de observación:

  1. Arranca con 2 horas — es un buen punto de partida para soleras estándar de 5-8 cm.
  2. Observa la temperatura interior en las horas que siguen a una bajada brusca exterior. Si el salón empieza a enfriarse antes de que el suelo responda, aumenta el valor.
  3. Ajusta en pasos de 0,5 horas hasta que el sistema empiece a calentar justo a tiempo.
  4. Considera la estación: en otoño el suelo está más frío de base y tarda más. En primavera responde más rápido.

Una señal clara de que el parámetro está bien ajustado es que nunca notes que el suelo llega tarde — la casa siempre está a temperatura cuando la necesitas, sin haber arrancado el sistema antes de lo necesario.

Parámetros de configuración avanzada

El sistema completo expone todos sus parámetros como helpers de HA, accesibles desde el dashboard sin tocar YAML. Esto es importante para poder ajustar el comportamiento en el día a día sin necesidad de editar configuración.

Histéresis de demanda

input_number:
  clima_histeresis:
    name: "Histéresis demanda zonas"
    min: 0.1
    max: 1.0
    step: 0.1
    initial: 0.3
    unit_of_measurement: "°C"

La histéresis evita el efecto de flapping: que una válvula se abra y cierre repetidamente cuando la temperatura oscila justo alrededor del setpoint. Con 0,3°C, la válvula se abre cuando la temperatura baja 0,3°C por debajo del setpoint y se cierra cuando lo supera. Este parámetro solo aplica a las zonas sin termostato Beca — las que tienen Beca usan directamente el relay_state del propio termostato, que ya incorpora su propia histéresis interna.

Throttle de válvulas: cooldown y ventana de corrección

Las válvulas de suelo radiante son actuadores lentos. Abrirlas y cerrarlas repetidamente en poco tiempo es ineficiente y potencialmente dañino. El sistema implementa un throttle con dos parámetros:

input_number:
  valvula_cooldown_min:
    name: "Cooldown válvulas (min)"
    min: 1
    max: 30
    step: 1
    initial: 10
    unit_of_measurement: min

  valvula_correccion_seg:
    name: "Ventana corrección rápida (seg)"
    min: 5
    max: 60
    step: 5
    initial: 15
    unit_of_measurement: s

La lógica: después de actuar sobre una válvula, el sistema bloquea nuevos cambios durante el cooldown (10 minutos por defecto). Sin embargo, si han pasado menos de 15 segundos desde el último cambio, sí se permite actuar de nuevo — es la ventana de corrección para revertir un cambio accidental sin esperar 10 minutos.

El throttle se implementa con timestamps Unix en input_number en lugar de input_datetime, que resulta más robusto en los templates de HA:

template:
  - sensor:
      - name: "valvula_puede_actuar_03"
        state: >
          {% set ts = states('input_number.ts_suelo_03') | float(0) %}
          {% if ts == 0 %}true
          {% else %}
            {% set seg = now().timestamp() - ts %}
            {% set corr = states('input_number.valvula_correccion_seg') | float(15) %}
            {% set cool = states('input_number.valvula_cooldown_min') | float(10) * 60 %}
            {{ (seg < corr or seg > cool) | string | lower }}
          {% endif %}

Consignas para zonas sin termostato

Las zonas sin termostato Beca (baños y salón/cocina) usan sensores de temperatura a pilas y un setpoint configurable:

input_number:
  consigna_banyo_pasillo:
    name: "Consigna baño pasillo"
    min: 15
    max: 26
    step: 0.5
    initial: 21.0
    unit_of_measurement: "°C"

  consigna_salon:
    name: "Consigna salón / cocina / comedor"
    min: 15
    max: 26
    step: 0.5
    initial: 21.0
    unit_of_measurement: "°C"

El salón, cocina y comedor comparten sensor y consigna porque son un espacio abierto — climatizarlos de forma independiente no tiene sentido hidráulico.

A tener en cuenta

Suelo refrescante en verano: la misma lógica se puede invertir para el modo refrigeración. En lugar de anticipar bajadas de temperatura, anticipa subidas. El umbral y la inercia son diferentes (el suelo tarda menos en refrescar porque trabaja con menor diferencial térmico), así que conviene tener parámetros separados para cada temporada.

Días nublados vs días de sol: la temperatura exterior es una proxy imperfecta. Un día nublado de 10°C y un día soleado de 10°C tienen demandas de calefacción muy diferentes por la ganancia solar. En una instalación más avanzada se puede añadir un sensor de luminosidad para corregir este factor — pero eso es material para otro post.

Integración con presencia: si la casa va a estar vacía durante el día, no tiene sentido anticipar. El sistema de anticipación debería desactivarse en modo «Ausente» y reactivarse con suficiente antelación antes de volver a casa.

Todo el código de este post forma parte de un paquete más amplio de control climático multi-zona. El sensor de temperatura anticipada y los helpers son independientes y se pueden usar solos sin el resto del sistema.

Si tienes suelo radiante con aerotermia y usas Home Assistant, este tipo de anticipación es probablemente la mejora de confort más grande que puedes implementar con relativamente poco esfuerzo. El coste computacional es mínimo — es una consulta al forecast que ya tienes disponible — y los beneficios en confort y eficiencia energética son significativos.

panel_control sobre Aerotermia
panel_zonas sobre Aerotermia
configuracion_avanzada sobre Aerotermia

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *


El periodo de verificación de reCAPTCHA ha caducado. Por favor, recarga la página.