Une pompe à chaleur est généralement la plus grosse charge unique d'une maison, et celle dont le coût est le plus difficile à deviner. Elle tourne quand la météo l'exige, et non quand vous le décidez ; avec un tarif jour/nuit, sa facture dépend donc d'heures que vous n'avez jamais choisies. La mesurer sur son propre circuit répond à la première question — combien coûte-t-elle réellement — et une fois que Home Assistant sait dans quelle zone tarifaire se trouve le hub, vous pouvez agir sur la seconde.
De quoi vous avez besoin :
- un hub RBgrid avec le circuit de la pompe à chaleur mesuré comme point distinct ;
- un plan tarifaire saisi sur le hub — si ce n'est pas encore fait, commencez par votre propre tarif selon l'heure ;
- le hub réglé sur votre fuseau horaire, avec son horloge synchronisée : chaque limite de zone de ce guide est calculée sur l'horloge du hub, et non sur la vôtre (quel fuseau horaire le hub doit-il utiliser) ;
- un broker MQTT, avec Home Assistant connecté au hub. Ce guide commence une fois cela opérationnel. Si ce n'est pas encore le cas, Un compteur de puissance pour Home Assistant le met en place pas à pas — le broker, le formulaire Settings → Home Assistant du hub et les premières entités — puis revenez ici.
Pour le câblage et le dimensionnement des pinces, l'installation triphasée décrite dans ce que coûtent la pompe à chaleur et le véhicule électrique couvre une pompe à chaleur de bout en bout.
Sécurité. Pour toute intervention à l'intérieur d'un tableau électrique, faites appel à un électricien qualifié.
1. Donnez à la pompe à chaleur son propre point
Dans Management → Points, liez le canal de la pompe à chaleur et réglez son Role sur Heating/cooling. Ce rôle indique à l'application qu'il s'agit d'une charge avec son propre programme : la carte de charge en veille, par exemple, retire les lignes de chauffage et de recharge VE de la base de la maison avant d'estimer ce qui fonctionne en permanence, car une pompe qui tourne à 03:00 n'est pas en veille.
Nommez le point avant qu'il n'atteigne jamais Home Assistant. Cela compte plus qu'il n'y paraît — voir §3.
Les pompes monophasées forment un seul point. Une pompe triphasée utilise une pince par conducteur, chacune sur le module Basic de cette phase, liée en trois points et regroupée ; le guide triphasé décrit la démarche.
2. Ce que vous montre l'application
Monitoring → Economics, avec la pompe à chaleur sélectionnée, donne son énergie et son coût pour une heure, aujourd'hui, hier, les 7 derniers jours, ce mois-ci, le mois dernier ou cette année. Le coût est celui que le hub a calculé au fur et à mesure de la consommation : toutes les 15 minutes, au prix de la zone en vigueur à ce moment-là, stocké avec l'enregistrement horaire. Rien n'est recalculé ensuite : si votre fournisseur modifie un tarif, ce que la pompe a coûté l'hiver dernier reste ce qu'il a coûté.
History dans la métrique Money la place à côté de vos autres circuits sur la même période, et Download CSV vous permet d'emporter les chiffres.
Pour le coût par zone : Economics propose cette répartition, mais lisez-la pour ce qu'elle est — un total cumulé depuis le dernier redémarrage du hub, qui ne suit pas le sélecteur de période. Elle répond à « comment se répartit la consommation en ce moment », non à « combien la pompe m'a coûté dans la zone de nuit en octobre ». Il n'existe pas de vue mensuelle du coût par zone ; pour un mois, utilisez le sélecteur de période et prenez le total.
Et avant de prendre le CSV pour le faire vous-même : les enregistrements stockés contiennent l'énergie et le coût par période, mais aucun champ de zone — la répartition ne vit que dans ce total cumulé. Donc la comparaison nuit-jour pour un mois n'est pas une vue qui vous manque : c'est un chiffre que le hub ne conserve pas.
3. Envoyez-le à Home Assistant
Une fois MQTT connecté, chaque point lié apparaît comme son propre appareil avec huit capteurs : courant, puissance, puissance réactive, facteur de puissance, et énergie entrante et sortante, en compteurs cumulés et journaliers. L'énergie entre directement dans le tableau de bord énergie sous Individual devices — sans utility_meter, sans capteur template. Utilisez le compteur cumulé Energy In, et non celui (Day) : les compteurs journaliers se remettent à zéro à minuit heure locale du hub, alors que les totaux cumulés ne peuvent jamais diminuer et survivent à un redémarrage ou à une mise à jour du firmware, dans la mémoire du hub. Une remise à zéro usine les efface, comme la suppression du point.
Deux choses qui vous feront gagner une soirée :
- L'identifiant d'entité est figé à la première découverte. Si vous renommez ensuite le point dans l'application, seul le nom affiché change : un point découvert d'abord sous « UI7 I2 » garde
sensor.rbgrid_ui7_i2_power. Vous pouvez renommer les entités dans Home Assistant, donc ce n'est pas définitif — c'est simplement un travail qu'on peut éviter. Nommez-le avant de connecter le broker, ou renommez les entités dans HA une seule fois. - Le rôle ne se transmet pas. Heating/cooling est un concept de l'application ; dans Home Assistant, l'appareil de la pompe à chaleur ressemble exactement à tous les autres points. Quoi que vous vouliez faire du rôle, faites-le côté RBgrid.
4. Rendez la zone tarifaire visible pour HA
Le hub publie sa zone tarifaire courante, mais pas comme entité découverte — la découverte couvre les mesures, pas le tarif. La zone se trouve dans la trame de télémétrie du hub, publiée toutes les trois secondes et non retenue. Un seul capteur MQTT la récupère. <MAC> représente les douze caractères hexadécimaux de l'adresse du hub en minuscules — les topics sont sensibles à la casse, et le préfixe rbgrid/ est fixe :
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>"]
Trois détails ici ne sont pas de la décoration.
Les modèles sont protégés, et ils doivent l'être. Les champs tarifaires sont absents de la trame tant qu'un plan n'existe pas sur le hub — et connecter le broker avant de saisir un tarif est un ordre de travail tout à fait normal. Un value_json.system.tariff.zone non protégé lève une erreur sur la clé absente, et Home Assistant n'enregistre rien : MQTT avale silencieusement les erreurs de template. Pire encore, le capteur réarme expire_after avant d'évaluer le template, si bien qu'un hub sans plan maintient le capteur en vie sur sa dernière valeur indéfiniment — une zone périmée qui a l'air parfaitement saine. La version protégée affiche unknown à la place, un état sur lequel votre automatisation peut refuser d'agir.
Le second capteur est le prix courant, et il est là pour une raison qui mérite d'être précisée. Le tableau de bord énergie de Home Assistant peut prendre une entité comme prix courant d'une source ; ainsi le buy_rate du hub donne à votre tableau de bord le bon chiffre pour la zone où vous vous trouvez à cet instant — c'est ainsi que le coût est calculé côté Home Assistant, avec votre propre tarif, pour tout ce que vous y avez déjà. RBgrid tient l'argent par circuit ; HA garde la vision de toute la maison qu'il a toujours eue.
plan_active est votre seul indicateur. Comme rien n'apparaît dans le journal, cet attribut est la seule façon de voir si le hub dispose réellement d'un tarif. À placer sur un tableau de bord si vous comptez vous appuyer sur tout cela.
default_entity_id fixe l'identifiant d'entité. Les entités MQTT tirent leur identifiant du nom de l'appareil plus le nom de l'entité ; sans lui, ce capteur atterrit dans sensor.rbgrid_system_tariff_zone et chaque automatisation ci-dessous surveille silencieusement le vide. (object_id remplissait le même rôle et est obsolète à partir de HA 2025.12.) Le préfixe ha_ de unique_id le tient à l'écart de l'espace de noms propre au firmware : si une future version découvre elle-même une entité de zone, les deux coexistent et vous supprimez ce bloc.
expire_after: 30 compte toujours : la trame n'est pas retenue, donc si le hub se tait, le capteur passe à indisponible plutôt que de conserver une zone qui n'est peut-être plus vraie.
Le topic de disponibilité fait aussi un vrai travail : le hub publie online en retained à chaque connexion, et enregistre un last will MQTT afin que le broker publie offline s'il tombe sans dire au revoir. Un Home Assistant qui redémarre apprend donc immédiatement l'état du hub au lieu d'attendre une trame. Et si votre broker redémarre et perd ses messages retenus, le hub republie tout son jeu de découverte à la reconnexion, de sorte que vos entités de point ne sont pas orphelines.
Un piège avant de construire dessus. time_src n'affiche sntp qu'une fois que le hub a atteint un serveur NTP. Une horloge réglée à la main depuis votre navigateur affiche toujours none, même si elle est juste — donc sur un hub sans accès Internet, la condition de la section suivante ne passe jamais et l'automatisation ne se déclenche jamais, silencieusement et pour toujours. Si time_src reste à none, c'est là qu'il faut chercher : la route du hub vers un serveur de temps, non l'automatisation.
Le capteur lit l'une de huit valeurs — NIGHT, MORNING_PEAK, DAY, EVENING_PEAK, LATE_EVENING, WEEKEND, HOLIDAY, CRITICAL_PEAK — écrites ainsi. Il s'agit du type de la zone active, non du nom que vous lui avez donné, donc deux zones de types différents au même prix se lisent quand même différemment. Sans plan tarifaire sur le hub, le champ n'est pas du tout présent dans la trame, et le capteur protégé affiche unknown avec plan_active: false.
Vous saurez que cela fonctionne quand Developer Tools → States affiche le nouveau capteur avec un nom de zone tel que NIGHT, avec plan_active: true, time_src: sntp et placeholder: false parmi ses attributs. S'il reste sur unknown, le topic ou le chemin du template est erroné pour votre hub : abonnez-vous à rbgrid/# dans n'importe quel client MQTT et comparez une vraie trame au template.
Les attributs sont là pour une raison, et elle est plus fine qu'il n'y paraît. Le hub calcule la zone à partir de sa propre horloge même quand celle-ci n'est pas encore synchronisée — après un démarrage sans SNTP, elle se situe autour de 1970 plus la durée de fonctionnement, donc la zone qu'il annonce, et le prix qu'il facture, peuvent être simplement faux. Il ne retient pas le champ en attendant. time_src est ce qui permet de le savoir, et la section suivante refuse d'agir tant qu'il n'affiche pas sntp.
⚠️ Après tout redémarrage, ressaisissez votre tarif avant de faire confiance à ces chiffres — ou de les laisser piloter quoi que ce soit. Sur la v1.1.4, un hub qui redémarre revient sur son plan intégré Test Day/Night jusqu'à ce que vous ouvriez Tariffs et appuyiez sur Save (le guide tarifaire donne le détail). Le piège pour cet article : tant que c'est le cas, la zone affiche toujours un
NIGHTtout à fait plausible ettime_srcaffiche toujourssntp, donc la vérification de la section suivante passe et votre automatisation pilote la pompe à chaleur d'après les limites du plan de test. Une coupure de courant à 02:00 est le cas à avoir en tête.
5. Automatisez — dans Home Assistant, sur la consigne
RBgrid mesure et signale. Il ne commute rien : aucun relais, aucun contacteur, aucune sortie d'aucune sorte. Tout ce qui suit s'exécute côté Home Assistant, sur une entité climate que vous possédez déjà.
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 garde du plan intégré est la troisième condition, et c'est celle que la plupart des gens n'auront pas pensée. Un hub qui redémarre en v1.1.4 revient sur son plan intégré Test Day/Night tant que vous n'avez pas ressaisi le vôtre — et tant que c'est le cas, la zone affiche une valeur plausible et l'horloge est signalée synchronisée, si bien que les contrôles évidents passent tous. Agir là-dessus piloterait votre pompe à chaleur d'après des prix de test.
Le hub le dit pourtant, si vous le demandez : tant que le plan intégré est actif, la télémétrie porte placeholder: true, et la clé n'est tout simplement plus là une fois votre propre plan enregistré. La condition est stricte à dessein — elle n'agit que sur un false explicite, jamais sur un attribut absent — si bien qu'un capteur qui ne peut pas vous le dire est traité comme un hub sur le plan de test.
La seconde automatisation ne fait qu'une chose : vous dire pourquoi tout s'est tu. Et comme l'automatisation de régulation se déclenche aussi sur cet attribut, dès que vous ressaisissez votre plan dans l'application, la consigne se met à jour immédiatement au lieu d'attendre la prochaine période de quinze minutes.
Pointez-la vers un thermostat d'ambiance, et vérifiez d'abord. climate.set_temperature suppose une entité dotée d'une consigne de température ambiante réglable en °C. Beaucoup d'intégrations de pompes à chaleur exposent autre chose : une température de départ ou d'eau, une courbe de compensation météo où une consigne ne fait rien, une entité à préréglages seuls sans température réglable — ou le ballon d'eau chaude. Régler 21 sur une entité de température de départ n'est pas une simple incitation ; sur un ballon ECS, c'est un ballon froid et un cycle antilégionelles que vous n'aviez pas voulu.
Ouvrez Developer Tools → States, trouvez votre entité climate et confirmez qu'elle possède un attribut temperature dans la plage attendue avant de laisser quoi que ce soit y écrire.
Associez-la à l'automatisation miroir sur la zone de jour, qui règle la température un ou deux degrés plus bas, ou climate.set_preset_mode: eco si votre appareil en possède un.
Vérifiez que NIGHT est bien votre zone bon marché. Le capteur indique le type de la zone, non le nom que vous lui avez donné, et c'est le type qui décide de ce qui se passe :
- Si votre plan comporte une zone Weekend, elle l'emporte sur Night les jours où elle s'applique, et
WEEKENDne figure pas dans la condition ci-dessus — donc dès que cette zone commence, l'automatisation cesse de décider quoi que ce soit. Elle ne revient pas à la consigne de jour : la consigne garde la dernière valeur reçue, donc si la nuit du vendredi a fixé la consigne de nuit, la maison maintient cette consigne jusqu'à la fin de la zone week-end. Que cela vous convienne dépend du prix de votre week-end, que le nom de la zone ne dit pas — voir plus bas. - Si votre tarif bon marché arrive en deux plages — une nuit bon marché et un milieu de journée bon marché, ce qui convient bien à une pompe à chaleur — la seconde arrive sous un autre type, comme
LATE_EVENING, et demande son propre déclencheur. Deux plages bon marché dans une même journée explique comment un tel plan se construit. - Sur un tarif à trois zones, « la zone de jour » peut être
DAY,MORNING_PEAKouEVENING_PEAK, et vous voudrez un déclencheur pour chacune.
Observez le capteur pendant un jour avant de faire confiance à une seule valeur to:.
Une zone week-end mérite une décision, non une valeur par défaut. WEEKEND est un type de zone ; il ne dit rien de ce que vous payez. Placez le capteur Tariff Buy Rate de la §4 sur un tableau de bord, regardez-le un samedi, puis ajoutez "WEEKEND" à la liste state: pour que l'automatisation agisse le week-end au lieu de se taire. Le choix suivant ne tient qu'à une ligne. Laissée telle quelle, le template target traite chaque zone qui n'est pas NIGHT comme la consigne de jour, donc un week-end à plein tarif reçoit la consigne de jour — ce qui est voulu. Ajoutez or is_state('sensor.rbgrid_tariff_zone', 'WEEKEND') à cette ligne, et un week-end bon marché reçoit la consigne de nuit :
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 }}"
Les deux formes ont été exécutées contre une zone WEEKEND réelle et font exactement cela ; les gardes time_src et placeholder ci-dessus ne sont pas modifiées et s'appliquent dans les deux cas. L'automatisation agit sur deux zones par défaut parce que le hub peut vous dire le type de la zone et son prix, mais pas laquelle votre foyer veut suivre.
Désactivez d'abord toute programmation déjà active sur cette entité. Si une automatisation horaire et celle-ci écrivent toutes deux la consigne, elles se battront, et celle qui a écrit en dernier l'emporte — ce qui n'est pas une propriété que vous voulez voir décider de votre chauffage.
Le hub recalcule la zone toutes les trois secondes et publie sur son propre minuteur de trois secondes, donc un changement de zone apparaît en six secondes au plus, souvent plus tôt, plus la latence propre de Home Assistant. C'est assez rapide pour une consigne ; ne construisez rien qui exige la limite à la seconde près.
Elle converge ; elle ne réagit pas. C'est la partie à comprendre avant de l'adapter. Une automatisation qui ne se déclenche que sur la transition vers une zone a une défaillance que vous ne remarquerez pas : si Home Assistant redémarre, ou si le broker a un raté, ou si le hub est muet au moment où 23:00 passe, la transition est manquée et la consigne n'est jamais rétablie. La pompe reste sur la consigne de jour — et rien dans la maison ne vous le signale, jusqu'à ce qu'il fasse froid.
Le déclencheur n'est donc pas « la zone de nuit a commencé », mais « quelque chose a changé, ou nous avons redémarré, ou quinze minutes se sont écoulées ». L'action calcule alors ce que la zone courante exige et ne l'envoie que si la pompe à chaleur n'y est pas déjà. C'est idempotent : la relancer après un redémarrage est correct plutôt qu'à supprimer, et une limite manquée se corrige au plus tard à la prochaine période de quinze minutes.
Ce qui assure la sécurité, ce sont les conditions, non le déclencheur : la zone doit être une valeur réelle (unknown et unavailable sont écartés), l'horloge du hub doit être synchronisée, et vous devez avoir confirmé le plan tarifaire. Si l'une de ces conditions échoue, rien n'est envoyé et la pompe à chaleur continue son propre programme.
Agissez sur la consigne ; ne coupez pas l'alimentation. Bloquer la pompe jusqu'au début de la zone bon marché est l'idée évidente et la mauvaise : les compresseurs ont besoin de leur propre cycle, il y a les dégivrages et les cycles antilégionelles.
L'entrée de signal réseau propre à l'appareil — SG Ready, dans la plus grande partie de l'Europe — peut la bloquer, y compris un verrouillage strict pouvant aller jusqu'à deux heures, et les contacts de délestage des fournisseurs sont courants sur les tarifs des pompes à chaleur. La différence est que le régulateur du fabricant garde la main sur la programmation du dégivrage et de l'antilégionelle pendant ce blocage, et sait quand passer outre. Une prise intelligente sur la ligne d'alimentation n'en gère aucune. Donc : la consigne, un préréglage ou un mode, par l'interface propre à l'appareil — jamais son alimentation.
Faites de « pas de données » l'état sûr — et sachez ce qu'il laisse derrière lui. Si le hub passe hors ligne, le capteur devient indisponible, les conditions échouent et rien n'est envoyé ; la pompe continue donc sous son propre programme. C'est le comportement juste pour l'appareil.
Soyez clair sur ce que ce n'est pas, toutefois : si l'automatisation de jour avait déjà abaissé votre consigne, rien ne la rétablit tant que le hub est absent. Le silence protège la machine, pas votre confort. C'est précisément pourquoi la conception de la régulation compte — dès que le hub revient, le prochain cycle remet la consigne là où la zone courante l'exige, sans que vous n'ayez rien à faire.
Faites-la tourner d'abord comme notification. Pendant un ou deux jours, remplacez l'action climate.set_temperature par
- action: persistent_notification.create
data:
title: "Tariff zone"
message: "Would set the heat pump to {{ target }} °C"
et observez les moments où elle se serait déclenchée. Cela ne coûte rien, et c'est ainsi que vous découvrez que votre limite de zone n'est pas là où vous la pensiez — ou que votre entité climate n'est pas celle que vous supposiez.
Si vous n'avez aucune entité climate dans Home Assistant, sautez complètement cette section. La mesure et la vue du coût par zone tiennent d'elles-mêmes, et une automatisation que vous ne pouvez pas piloter correctement vaut moins que pas d'automatisation du tout.
Ce que cela ne fait pas
- RBgrid ne commute jamais rien. Il n'a pas de sorties. Chaque action de ce guide est Home Assistant agissant sur votre propre équipement.
- Le coût par circuit reste dans l'application. Home Assistant reçoit l'énergie de la pompe à chaleur, non son coût.
- Pas de coût par zone par période. La répartition par zone est un total cumulé depuis le dernier redémarrage du hub.
- Le rôle n'est pas visible dans HA, donc une automatisation ne peut pas distinguer un point de chauffage d'un autre point.
- Un hub dont l'horloge n'est pas synchronisée annonce quand même une zone et facture quand même l'énergie, à partir de l'heure qu'il croit être. C'est pourquoi l'automatisation ci-dessus vérifie
time_src, et pourquoi les premiers chiffres après un démarrage à froid méritent un second regard. - RBgrid indique ce que l'énergie de la pompe coûte à vos tarifs. Il ne vérifie pas la facture de votre fournisseur et ne fait aucune promesse d'économies.