Tu bomba de calor en su propia línea: cuánto cuesta y luego automatízala en HA

  • Probado con el firmware v1.1.4
  • Intermedio

Redactado para el firmware v1.1.4.. La versión actual es v1.2.1, así que algunos detalles pueden ser distintos.

Parte 3 de 3 · Recetas de Home Assistant

Una bomba de calor suele ser la carga individual más grande de una casa, y la de coste más difícil de estimar. Funciona cuando lo dice el tiempo, no cuando lo decide usted, y con una tarifa de día y de noche eso significa que su factura depende de horas que usted no eligió. Medirla en su propio circuito responde a la primera pregunta —cuánto cuesta realmente— y, una vez que Home Assistant sabe en qué zona tarifaria está el hub, puede hacer algo con la segunda.

Lo que necesita:

  • un hub RBgrid con el circuito de la bomba de calor medido como punto propio;
  • un plan tarifario introducido en el hub; si aún no lo ha hecho, empiece con su propia tarifa de uso horario;
  • el hub configurado con su zona horaria y con el reloj sincronizado: todos los límites de zona de esta guía se resuelven según el reloj del hub, no el suyo (qué zona horaria debe usar el hub);
  • un broker MQTT, con Home Assistant conectado al hub. Esta guía empieza cuando eso ya funciona. Si todavía no funciona, Un medidor de potencia para Home Assistant lo configura paso a paso —el broker, el formulario Settings → Home Assistant del hub y las primeras entidades— y después vuelva aquí.

Para el cableado y el dimensionado de las pinzas, la construcción trifásica de lo que cuestan la bomba de calor y el VE cubre una bomba de calor de principio a fin.

Seguridad. Para cualquier trabajo dentro de un cuadro eléctrico, llame a un electricista cualificado.

1. Dé a la bomba de calor su propio punto

En Management → Points, asocie el canal de la bomba de calor y ponga su Role en Heating/cooling. El rol es lo que indica a la aplicación que se trata de una carga con horario propio: la tarjeta de carga en espera, por ejemplo, quita las líneas de calefacción y de carga de VE de la línea base de la casa antes de estimar lo que está siempre encendido, porque una bomba que funciona a las 03:00 no es consumo en espera.

Ponga nombre al punto antes de que llegue a Home Assistant. Esto importa más de lo que parece; véase §3.

Las bombas monofásicas son un solo punto. Una bomba trifásica es una pinza por conductor, cada una en el módulo Basic de esa fase, asociadas como tres puntos y agrupadas; la guía trifásica lo explica paso a paso.

2. Lo que muestra la aplicación

Monitoring → Economics, con la bomba de calor seleccionada, muestra su energía y su coste por hora, hoy, ayer, los últimos 7 días, este mes, el mes pasado o este año. El coste es el que calculó el hub a medida que se usaba la energía: cada 15 minutos, al precio de la zona vigente en ese momento, guardado junto con el registro horario. Nada se recalcula después, de modo que cuando su proveedor cambia una tarifa, lo que la bomba costó el invierno pasado sigue siendo lo que costó.

History en la métrica Money la sitúa junto a sus otros circuitos durante el mismo periodo, y Download CSV le lleva los números consigo.

Sobre el coste por zona: Economics tiene esa división, pero léala por lo que es: un total acumulado desde el último reinicio del hub, que no sigue al selector de periodo. Responde a «cómo va el reparto ahora mismo», no a «cuánto me costó la bomba en la zona nocturna en octubre». No existe una vista mensual del coste por zona; para un mes, use el selector de periodo y tome el total.

Y antes de recurrir al CSV para hacerlo usted: los registros guardados contienen energía y dinero por periodo, pero ningún campo de zona; el reparto vive solo en ese total acumulado. Así que la comparación entre noche y día de un mes no es una vista que le falte: es una cifra que el hub no conserva.

3. Envíelo a Home Assistant

Con MQTT conectado, cada punto asociado aparece como su propio dispositivo con ocho sensores: corriente, potencia, potencia reactiva, factor de potencia, y energía entrante y saliente, tanto acumulada de por vida como de día. La energía entra en el Energy dashboard bajo Individual devices directamente, sin utility_meter ni sensor de plantilla. Use el contador de por vida Energy In, no el (Day): los contadores diarios se reinician a la medianoche local del hub, mientras que los totales de por vida nunca disminuyen y sobreviven a un reinicio o a una actualización de firmware en la memoria del propio hub. Un restablecimiento de fábrica los borra, y también los borra eliminar el punto.

Dos cosas que le ahorrarán una tarde:

  • El id de entidad se fija en el primer descubrimiento. Si renombra el punto después en la aplicación, solo cambia el nombre visible: un punto descubierto primero como «UI7 I2» conserva sensor.rbgrid_ui7_i2_power. Puede renombrar las entidades en Home Assistant, así que no es permanente; es solo trabajo que puede evitar. Póngale nombre antes de conectar el broker, o renombre las entidades en HA una vez.
  • El rol no se transmite. Heating/cooling es un concepto de la aplicación; en Home Assistant el dispositivo de la bomba de calor se ve exactamente igual que cualquier otro punto. Lo que quiera hacer con el rol, hágalo del lado de RBgrid.

4. Haga visible la zona tarifaria para HA

El hub publica su zona tarifaria actual, pero no como entidad descubierta: el descubrimiento cubre las mediciones, no la tarifa. La zona vive en la trama de telemetría del hub, que se publica cada tres segundos y no se retiene. Un sensor MQTT la recoge. <MAC> son los doce caracteres hexadecimales del hub en minúsculas —los temas distinguen mayúsculas de minúsculas, y el prefijo rbgrid/ es fijo:

yaml
mqtt:
  sensor:
    - name: "Tariff Zone"
      unique_id: ha_rbgrid_<MAC>_tariff_zone
      default_entity_id: sensor.rbgrid_tariff_zone
      state_topic: "rbgrid/<MAC>/telemetry"
      value_template: >-
        {% set t = value_json.get('system', {}).get('tariff') or {} %}
        {{ t.zone if t.zone is defined else None }}
      expire_after: 30
      availability:
        - topic: "rbgrid/<MAC>/status"
          payload_available: "online"
          payload_not_available: "offline"
      json_attributes_topic: "rbgrid/<MAC>/telemetry"
      json_attributes_template: >-
        {% set t = value_json.get('system', {}).get('tariff') or {} %}
        {{ {'plan_active': t.zone is defined,
            'time_src': value_json.get('time_src'),
            'buy_rate': t.get('buy_rate'), 'sell_rate': t.get('sell_rate'),
            'currency': t.get('currency'),
            'placeholder': t.get('placeholder', false)} | tojson }}
      device:
        identifiers: ["<MAC>"]
    - name: "Tariff Buy Rate"
      unique_id: ha_rbgrid_<MAC>_tariff_buy_rate
      default_entity_id: sensor.rbgrid_tariff_buy_rate
      state_topic: "rbgrid/<MAC>/telemetry"
      value_template: >-
        {% set t = value_json.get('system', {}).get('tariff') or {} %}
        {{ t.buy_rate if t.buy_rate is defined else None }}
      unit_of_measurement: "EUR/kWh"
      expire_after: 30
      availability:
        - topic: "rbgrid/<MAC>/status"
          payload_available: "online"
          payload_not_available: "offline"
      device:
        identifiers: ["<MAC>"]

Tres detalles de ahí no son decorativos.

Las plantillas tienen protección, y deben tenerla. Los campos de tarifa no aparecen en la trama hasta que existe un plan en el hub, y conectar el broker antes de introducir una tarifa es un orden de trabajo perfectamente normal. Una value_json.system.tariff.zone sin protección falla por la clave ausente, y Home Assistant no registra nada: MQTT traga los errores de plantilla en silencio. Peor aún, el sensor vuelve a armar expire_after antes de evaluar la plantilla, de modo que un hub sin plan mantiene vivo el sensor con su último valor indefinidamente: una zona obsoleta que parece perfectamente sana. La versión protegida informa unknown, un estado que su automatización puede negarse a usar.

El segundo sensor es el precio actual, y está ahí por una razón que vale la pena explicar. El Energy dashboard de Home Assistant puede tomar una entidad como precio actual de una fuente, así que el buy_rate del hub da a su panel el número correcto para la zona en la que está ahora mismo. Así es como, en el lado de Home Assistant, se calcula el coste con su propia tarifa, para lo que ya tenga allí. RBgrid conserva el dinero por circuito; HA conserva la imagen de la casa completa que siempre ha tenido.

plan_active es su único indicador. Como no aparece nada en el registro, ese atributo es la manera de ver si el hub tiene realmente una tarifa. Merece la pena ponerlo en un panel si piensa confiar en cualquiera de esto.

default_entity_id fija el id de entidad. Las entidades MQTT toman su id del nombre del dispositivo más el nombre de la entidad, así que sin él este sensor acabaría en sensor.rbgrid_system_tariff_zone y todas las automatizaciones de abajo vigilarían en silencio nada. (object_id hacía el mismo trabajo y está obsoleto desde HA 2025.12 en adelante.) El prefijo ha_ en unique_id lo mantiene aparte del espacio de nombres del firmware, de modo que si una versión futura descubre una entidad de zona por sí misma, las dos coexisten y usted elimina este bloque.

expire_after: 30 sigue importando: la trama no se retiene, así que si el hub se queda en silencio, el sensor pasa a unavailable en lugar de mantener una zona que quizá ya no sea cierta.

El tema de disponibilidad también hace trabajo real: el hub publica online retenido en cada conexión, y registra un last will de MQTT para que el broker publique offline si se cae sin despedirse. Un Home Assistant que se reinicia, por tanto, conoce el estado del hub de inmediato en lugar de esperar a una trama. Y si su broker se reinicia y pierde sus mensajes retenidos, el hub vuelve a publicar todo su conjunto de descubrimiento al reconectar, así que sus entidades de punto no quedan huérfanas.

Una trampa antes de construir sobre esto. time_src lee sntp solo después de que el hub haya llegado a un servidor NTP. Un reloj que usted ajustó a mano desde su navegador sigue informando none, aunque sea correcto; así que en un hub sin acceso a internet, la condición de la sección siguiente nunca se cumple y la automatización nunca se dispara, en silencio y para siempre. Si time_src permanece en none, eso es lo que hay que investigar: la ruta del hub hacia un servidor horario, no la automatización.

El sensor lee uno de ocho valores —NIGHT, MORNING_PEAK, DAY, EVENING_PEAK, LATE_EVENING, WEEKEND, HOLIDAY, CRITICAL_PEAK— con esa grafía. Es el tipo de la zona activa, no el nombre que usted le dio, así que dos zonas de tipos distintos al mismo precio siguen leyéndose de forma diferente. Sin plan tarifario en el hub, el campo no aparece en la trama en absoluto, y el sensor protegido lee unknown con plan_active: false.

Sabrá que funciona cuando Developer Tools → States muestre el nuevo sensor con un nombre de zona como NIGHT, con plan_active: true, time_src: sntp y placeholder: false entre sus atributos. Si se queda en unknown, el tema o la ruta de la plantilla no son correctos para su hub: suscríbase a rbgrid/# en cualquier cliente MQTT y compare una trama real con la plantilla.

Los atributos vienen por una razón, y es más afilada de lo que parece. El hub calcula la zona a partir de su propio reloj incluso cuando ese reloj aún no está sincronizado: tras un arranque sin SNTP se queda cerca de 1970 más el tiempo de actividad, así que la zona que informa, y el precio que cobra, pueden ser simplemente erróneos. No retiene el campo mientras espera. time_src es la forma de saberlo, y la sección siguiente se niega a actuar hasta que lea sntp.

⚠️ Tras cualquier reinicio, vuelva a guardar su tarifa antes de fiarse de estas cifras o de dejar que impulsen algo. En v1.1.4, un hub que se reinicia vuelve con su plan provisional integrado Test Day/Night hasta que abra Tariffs y pulse Save (the tariff guide tiene el detalle). El problema para este artículo: mientras eso sea cierto, la zona sigue leyendo un NIGHT perfectamente plausible y time_src sigue leyendo sntp, así que la comprobación de la sección siguiente pasa y su automatización maneja la bomba de calor según los límites del plan de prueba. Piense en un corte de luz a las 02:00.

5. Automatice: en Home Assistant, sobre la consigna

RBgrid mide e informa. No conmuta nada: ni relé, ni contactor, ni salida de ningún tipo. Todo lo que sigue se ejecuta en el lado de Home Assistant, contra una entidad de climatización que ya tenga.

yaml
automation:
  - alias: "Heat pump: follow tariff zone (reconcile)"
    mode: single
    max_exceeded: silent
    triggers:
      - trigger: state
        entity_id: sensor.rbgrid_tariff_zone
        to: ~
      - trigger: state
        entity_id: sensor.rbgrid_tariff_zone
        attribute: placeholder
      - trigger: homeassistant
        event: start
      - trigger: time_pattern
        minutes: "/15"
    conditions:
      - condition: state
        entity_id: sensor.rbgrid_tariff_zone
        state: ["NIGHT", "DAY"]
      - condition: template
        value_template: "{{ state_attr('sensor.rbgrid_tariff_zone', 'time_src') == 'sntp' }}"
      - condition: template
        value_template: "{{ state_attr('sensor.rbgrid_tariff_zone', 'placeholder') is sameas false }}"
    actions:
      - variables:
          target: "{{ 21 if is_state('sensor.rbgrid_tariff_zone', 'NIGHT') else 19 }}"
      - condition: template
        value_template: "{{ (state_attr('climate.heat_pump', 'temperature') | float(0)) != (target | float) }}"
      - action: climate.set_temperature
        target: { entity_id: climate.heat_pump }
        data: { temperature: "{{ target }}" }
  - alias: "RBGrid: placeholder tariff plan active"
    mode: single
    triggers:
      - trigger: state
        entity_id: sensor.rbgrid_tariff_zone
        attribute: placeholder
        to: true
    actions:
      - action: persistent_notification.create
        data:
          notification_id: rbgrid_placeholder_plan
          title: "RBGrid: placeholder tariff plan"
          message: >-
            The hub is running the built-in Test Day/Night plan. Re-save your tariff
            plan in the RBgrid app; zone automations stay paused until then.

La protección de plan provisional es la tercera condición, y es la que menos gente pensará. Un hub que se reinicia en v1.1.4 vuelve con su plan integrado Test Day/Night hasta que vuelva a guardar el suyo; y mientras eso sea cierto, la zona sigue leyendo de forma plausible y el reloj sigue indicando sincronización, así que las comprobaciones obvias pasan todas. Actuar sobre ello haría funcionar su bomba de calor con precios de prueba.

El hub lo dice, sin embargo, si se lo pregunta: mientras el plan integrado esté activo, la telemetría lleva placeholder: true, y la clave simplemente no está presente una vez guardado su propio plan. La condición es estricta a propósito: actúa solo con un false explícito, nunca con un atributo ausente, así que un sensor que no puede informarle se trata igual que un hub que está con el plan de prueba.

La segunda automatización no hace más que indicarle por qué todo se ha quedado en silencio. Y como la automatización de reconciliación también se dispara con ese atributo, en el momento en que vuelva a guardar su plan en la aplicación la consigna se pone al día de inmediato, en lugar de esperar al siguiente intervalo de quince minutos.

Apúntela a un termostato de habitación, y compruébelo primero. climate.set_temperature supone una entidad con una consigna de temperatura ambiente ajustable en °C. Muchas integraciones de bomba de calor exponen otra cosa: una temperatura de impulsión o de agua, una curva de compensación climática donde una consigna no hace nada, una entidad solo de preajustes sin temperatura ajustable, o el depósito de agua caliente. Poner 21 en una entidad de temperatura de impulsión no es un ajuste suave; en un depósito de ACS es un cilindro frío y un ciclo de legionela que usted no pretendía.

Abra Developer Tools → States, localice su entidad de climatización y confirme que tiene un atributo temperature en el rango que espera antes de dejar que algo escriba en ella.

Acompáñela con la automatización espejo para la zona diurna, que ajuste la temperatura uno o dos grados más baja, o climate.set_preset_mode: eco si su unidad lo tiene.

Compruebe que NIGHT es realmente su zona barata. El sensor informa del tipo de zona, no del nombre que usted le dio, y el tipo decide lo que ocurre:

  • Si su plan tiene una zona de Weekend, prevalece sobre la nocturna los días en que se aplica, y WEEKEND no está en la condición de arriba; así que desde el momento en que esa zona empieza, la automatización deja de decidir nada. No vuelve al objetivo diurno: la consigna conserva lo último que se le dio, así que si la noche del viernes fijó el objetivo nocturno, la casa mantiene ese objetivo hasta que termine la zona de fin de semana. Si eso le conviene es una cuestión sobre su precio de fin de semana, que el nombre de la zona no responde; véase abajo.
  • Si su tarifa barata llega en dos franjas —una noche barata y un mediodía barato, lo que encaja bien con una bomba de calor—, la segunda aparece como un tipo distinto, como LATE_EVENING, y necesita su propio disparador. Dos franjas baratas en un día explica cómo se construye un plan así.
  • En una tarifa de tres zonas, «la zona diurna» puede ser DAY, MORNING_PEAK o EVENING_PEAK, y querrá un disparador para cada una.

Observe el sensor durante un día antes de fiarse de un solo valor to:.

Una zona de fin de semana merece una decisión, no un valor por defecto. WEEKEND es un tipo de zona; no dice nada sobre lo que paga. Ponga el sensor Tariff Buy Rate del §4 en un panel, mírelo un sábado y luego añada "WEEKEND" a la lista state: para que la automatización actúe en fin de semana en lugar de quedarse en silencio durante él. Hasta dónde llegar desde ahí es una línea. Tal como está, la plantilla target trata cada zona que no sea NIGHT como objetivo diurno, así que un fin de semana a precio completo recibe la consigna diurna, que es lo que usted quiere. Añada or is_state('sensor.rbgrid_tariff_zone', 'WEEKEND') a esa línea y un fin de semana barato recibirá la consigna nocturna en su lugar:

yaml
conditions:
      - condition: state
        entity_id: sensor.rbgrid_tariff_zone
        state: ["NIGHT", "DAY", "WEEKEND"]            # add WEEKEND here → the automation also acts at weekends
    actions:
      - variables:
          # a full-price weekend: leave this line exactly as it is in the automation above — WEEKEND then gets 19
          # a cheap weekend: add the second is_state(), as below — WEEKEND then gets 21
          target: "{{ 21 if is_state('sensor.rbgrid_tariff_zone', 'NIGHT') or is_state('sensor.rbgrid_tariff_zone', 'WEEKEND') else 19 }}"

Ambas formas se ejecutaron contra una zona WEEKEND real y hacen exactamente eso; las protecciones de time_src y placeholder de arriba no cambian y siguen aplicándose en cualquier caso. La automatización actúa sobre dos zonas por defecto porque el hub puede decirle el tipo de zona y su precio, pero no cuál de ellas quiere su hogar como referencia.

Desactive antes cualquier programación que ya ejecute sobre esta entidad. Si una automatización basada en la hora y esta escriben ambas la consigna, pelearán, y gana la que escribió por último: no es una propiedad que quiera que decida su calefacción.

El hub vuelve a resolver la zona cada tres segundos y publica con su propio temporizador de tres segundos, así que un cambio de zona aparece en unos seis segundos como máximo, normalmente antes, más la latencia propia de Home Assistant. Es lo bastante rápido para una consigna; no construya nada que necesite el límite exacto al segundo.

Converge; no reacciona. Esta es la parte que conviene entender antes de adaptarla. Una automatización que solo se dispara en la transición a una zona tiene un fallo que no notará: si Home Assistant se está reiniciando, o el broker falla un instante, o el hub está callado cuando pasan las 23:00, la transición se pierde y la consigna nunca se restaura. La bomba se queda con el objetivo diurno, y nada en la casa se lo indica, hasta que hace frío.

Así que el disparador no es «empezó la zona nocturna», sino «algo ha cambiado, o hemos reiniciado, o han pasado quince minutos». La acción entonces calcula lo que exige la zona actual y la envía solo si la bomba de calor no está ya en ese valor. Es idempotente: ejecutarla tras un reinicio es correcto y no hay que suprimirlo, y un límite perdido se corrige solo en el siguiente intervalo de quince minutos como máximo.

Lo que la mantiene segura son las condiciones, no el disparador: la zona debe ser un valor real (unknown y unavailable quedan descartados), el reloj del hub debe estar sincronizado y usted debe haber confirmado el plan tarifario. Si falla cualquiera de ellas, no se envía nada y la bomba de calor sigue con su propio programa.

Ajuste la consigna; no corte el suministro. Retener la bomba apagada hasta que empiece la zona barata es la idea obvia y la equivocada: los compresores necesitan sus propios ciclos, los desescarches y los ciclos antilegionela.

La entrada de señal de red propia de la unidad —SG Ready, en la mayor parte de Europa— sí puede bloquearla, incluido un bloqueo duro de hasta dos horas, y los contactos de bloqueo de la compañía son habituales en las tarifas de bomba de calor. La diferencia es que el controlador del fabricante sigue gestionando el desescarche y la programación antilegionela mientras está bloqueada, y sabe cuándo anular. Un enchufe inteligente en la línea de alimentación no gestiona nada de eso. Así que: la consigna, un preajuste o un modo, a través de la propia interfaz de la unidad; nunca su suministro.

Haga que «sin datos» sea el estado seguro, y sepa qué deja tras de sí. Si el hub se desconecta, el sensor pasa a unavailable, las condiciones fallan y no se envía nada, así que la bomba de calor sigue con su propio programa. Ese es el comportamiento correcto para el aparato.

Pero tenga claro lo que no es: si la automatización diurna ya había bajado su consigna, nada la restaura mientras el hub esté ausente. El silencio protege la máquina, no su confort. Por eso el diseño de reconciliación importa tanto: cuando el hub vuelve, el siguiente ciclo sitúa la consigna donde la zona actual indica que debe estar, sin que usted haga nada.

Ejecútela primero como notificación. Durante un día o dos, sustituya la acción climate.set_temperature por

yaml
- action: persistent_notification.create
        data:
          title: "Tariff zone"
          message: "Would set the heat pump to {{ target }} °C"

y observe cuándo se habría disparado. No cuesta nada, y así descubrirá si su límite de zona no está donde creía, o si su entidad de climatización no es la que suponía.

Si no tiene ninguna entidad de climatización en Home Assistant, omita esta sección por completo. La medición y el cuadro de coste por zona se sostienen por sí solos, y una automatización que no puede manejar bien es peor que ninguna.

Lo que esto no hace

  • RBgrid nunca conmuta nada. No tiene salidas. Cada acción de esta guía es Home Assistant actuando sobre su propio equipo.
  • El coste por circuito se queda en la aplicación. Home Assistant recibe la energía de la bomba de calor, no su coste.
  • Sin coste por zona por periodo. El reparto por zona es un total acumulado desde el último reinicio del hub.
  • El rol no es visible en HA, así que una automatización no puede distinguir un punto de calefacción de cualquier otro.
  • Un hub cuyo reloj no se ha sincronizado sigue informando una zona y sigue poniendo precio a la energía, según la hora que crea que es. Por eso la automatización de arriba comprueba time_src, y por eso las primeras cifras tras un arranque merecen una segunda mirada.
  • RBgrid muestra cuánto cuesta la energía de la bomba a sus tarifas. No comprueba la factura de su proveedor y no afirma nada sobre lo que ahorrará.

Siguiente