La tua pompa di calore su una linea dedicata: quanto costa, poi automazione in HA

  • Testato sul firmware v1.1.4
  • Intermedio

Scritto per il firmware v1.1.4. La release attuale è v1.2.1, quindi alcuni dettagli potrebbero differire.

Parte 3 di 3 · Ricette per Home Assistant

Una pompa di calore è di solito il carico singolo più grande di una casa, ed è quello il cui costo è più difficile da stimare. Funziona quando lo decide il meteo, non quando lo decide Lei, e con una tariffa giorno/notte la bolletta dipende da ore che Lei non ha scelto. Misurarla sul proprio circuito risponde alla prima domanda — quanto costa davvero — e una volta che Home Assistant sa in quale zona tariffaria si trova l'hub, si può fare qualcosa per la seconda.

Di cosa ha bisogno:

  • un hub RBgrid con il circuito della pompa di calore misurato come punto a sé;
  • una tariffa elettrica inserita nell'hub — se non l'ha ancora fatto, inizi con la Sua tariffa a fasce orarie;
  • l'hub impostato sul Suo fuso orario, con l'orologio sincronizzato: ogni confine di zona in questa guida viene calcolato in base all'orologio dell'hub, non al Suo (quale fuso orario usare per l'hub);
  • un broker MQTT, con Home Assistant collegato all'hub. Questa guida parte da quando tutto questo funziona. Se non funziona ancora, Un misuratore di potenza per Home Assistant lo configura passo dopo passo — il broker, il modulo Settings → Home Assistant dell'hub e le prime entità — poi torni qui.

Per il cablaggio e il dimensionamento delle pinze, la build trifase in cosa costano la pompa di calore e l'auto elettrica copre una pompa di calore dall'inizio alla fine.

Sicurezza. Per qualsiasi lavoro all'interno di un quadro elettrico, si rivolga a un elettricista qualificato.

1. Dia alla pompa di calore il suo punto

In Management → Points, associ il canale della pompa di calore e imposti il suo Role su Heating/cooling. Il ruolo indica all'app che questo è un carico con una pianificazione propria: la scheda del carico in standby, per esempio, toglie le linee di riscaldamento e di ricarica dell'auto elettrica dalla base della casa prima di stimare cosa resta sempre acceso, perché una pompa che funziona alle 03:00 non è in standby.

Dia un nome al punto prima che arrivi a Home Assistant. Conta più di quanto sembri — vedi §3.

Le pompe monofase sono un solo punto. Una pompa trifase è una pinza per conduttore, ognuna sul modulo Basic di quella fase, associata come tre punti e raggruppata; la guida trifase ne illustra i passaggi.

2. Cosa Le mostra l'app

Monitoring → Economics, con la pompa di calore selezionata, ne mostra energia e costo per un'ora, oggi, ieri, gli ultimi 7 giorni, questo mese, il mese scorso o quest'anno. Il costo è quello che l'hub ha calcolato mentre l'energia veniva consumata: ogni 15 minuti, al prezzo della zona in vigore in quel momento, memorizzato insieme al record orario. Nulla viene ricalcolato dopo, quindi quando il fornitore cambia una tariffa, quanto la pompa è costata lo scorso inverno resta quello che è stato.

History nella metrica Money la mette accanto agli altri circuiti sullo stesso periodo, e Download CSV le permette di portare via i numeri.

Sul costo per zona: Economics ha questa suddivisione, ma la legga per quello che è — un totale progressivo dall'ultimo riavvio dell'hub, che non segue il selettore del periodo. Risponde a "com'è la suddivisione in questo momento", non a "quanto mi è costata la pompa nella zona notturna a ottobre". Non esiste una vista mensile del costo per zona; per un mese, usi il selettore del periodo e prenda il totale.

E prima di prendere il CSV per farlo da sola: i record memorizzati contengono energia e denaro per periodo ma nessun campo di zona — la suddivisione vive solo nel totale progressivo. Quindi il confronto notte-giorno per un mese non è una vista che Le manca: è un dato che l'hub non conserva.

3. Lo invii a Home Assistant

Con MQTT collegato, ogni punto associato compare come dispositivo proprio con otto sensori: corrente, potenza, potenza reattiva, fattore di potenza, ed energia in entrata e in uscita sia come contatore complessivo sia come contatore giornaliero. L'energia entra direttamente nella dashboard Energia sotto Individual devices — senza utility_meter, senza sensore template. Usi il contatore complessivo Energy In, non quello (Day): i contatori giornalieri si azzerano a mezzanotte locale dell'hub, mentre i totali complessivi non diminuiscono mai e sopravvivono a un riavvio o a un aggiornamento del firmware nella memoria dell'hub. Un ripristino di fabbrica li cancella, come li cancella eliminare il punto.

Due cose che Le faranno risparmiare una serata:

  • L'id dell'entità viene fissato alla prima scoperta. Se rinomina il punto nell'app in seguito, cambia solo il nome visualizzato: un punto scoperto la prima volta come "UI7 I2" mantiene sensor.rbgrid_ui7_i2_power. Le entità si possono rinominare in Home Assistant, quindi non è definitivo — è solo lavoro che può evitare. Lo dia un nome prima di collegare il broker, oppure rinomini le entità in HA una volta.
  • Il ruolo non viene trasferito. Heating/cooling è un concetto dell'app; in Home Assistant il dispositivo della pompa di calore appare esattamente come ogni altro punto. Qualunque cosa voglia fare con il ruolo, la faccia dal lato RBgrid.

4. Renda la zona tariffaria visibile a HA

L'hub pubblica la sua zona tariffaria corrente, ma non come entità scoperta — la discovery copre le misure, non la tariffa. La zona vive nel frame di telemetria dell'hub, pubblicato ogni tre secondi e non retained, cioè non trattenuto. Un solo sensore MQTT la legge. <MAC> sono i dodici caratteri esadecimali dell'hub in minuscolo — i topic sono sensibili alle maiuscole, e il prefisso rbgrid/ è fisso:

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>"]

Tre dettagli qui dentro non sono decorazione.

I template sono protetti, e devono esserlo. I campi della tariffa sono assenti dal frame finché non esiste un piano sull'hub — e collegare il broker prima di inserire una tariffa è un ordine di lavoro del tutto normale. Un value_json.system.tariff.zone non protetto genera errore sulla chiave mancante, e Home Assistant non registra nulla: MQTT ingoia in silenzio gli errori dei template. Peggio, il sensore riarma expire_after prima di valutare il template, quindi un hub senza piano tiene in vita il sensore sull'ultimo valore a tempo indeterminato — una zona vecchia che sembra perfettamente sana. La versione protetta riporta invece unknown, uno stato che la Sua automazione può rifiutare di usare.

Il secondo sensore è il prezzo corrente, e c'è per una ragione che vale la pena spiegare. Il dashboard Energia di Home Assistant può prendere un'entità come prezzo corrente per una sorgente, quindi il buy_rate dell'hub dà alla dashboard il numero giusto per la zona in cui si trova adesso — ed è così che il costo viene calcolato dal lato di Home Assistant, con la Sua tariffa, per tutto ciò che ha già lì. RBgrid tiene il denaro per circuito; HA tiene il quadro dell'intera casa che ha sempre avuto.

plan_active è il Suo unico indicatore. Poiché nel log non compare nulla, quell'attributo è il modo per vedere se l'hub ha davvero una tariffa. Vale la pena metterlo su una dashboard se intende basarsi su qualcosa di tutto questo.

default_entity_id fissa l'id dell'entità. Le entità MQTT prendono il loro id dal nome del dispositivo più il nome dell'entità, quindi senza di esso questo sensore finirebbe in sensor.rbgrid_system_tariff_zone e ogni automazione qui sotto osserverebbe silenziosamente il nulla. (object_id faceva lo stesso lavoro ed è deprecato da HA 2025.12 in poi.) Il prefisso ha_ su unique_id lo tiene distinto dallo spazio dei nomi del firmware, così se una versione futura scoprirà da sola un'entità di zona, le due coesistono e Lei elimina questo blocco.

expire_after: 30 conta ancora: il frame non è trattenuto, quindi se l'hub si zittisce il sensore diventa unavailable invece di tenere una zona che potrebbe non essere più vera.

Anche il topic di disponibilità fa un lavoro reale: l'hub pubblica online trattenuto a ogni connessione e registra un last will MQTT, così il broker pubblica offline se cade senza salutare. Un Home Assistant che si riavvia apprende quindi subito lo stato dell'hub invece di aspettare un frame. E se il broker si riavvia e perde i messaggi trattenuti, l'hub ripubblica l'intero set di discovery alla riconnessione, così i Suoi punti non restano orfani.

Una trappola prima di costruirci sopra. time_src legge sntp solo dopo che l'hub ha raggiunto un server NTP. Un orologio impostato a mano dal browser riporta ancora none, anche se è corretto — quindi su un hub senza accesso a internet la condizione della sezione successiva non passa mai e l'automazione non scatta mai, in silenzio e per sempre. Se time_src resta none, è questo che va verificato: la strada dell'hub verso un server dell'ora, non l'automazione.

Il sensore legge uno di otto valori — NIGHT, MORNING_PEAK, DAY, EVENING_PEAK, LATE_EVENING, WEEKEND, HOLIDAY, CRITICAL_PEAK — con questa grafia. È il tipo della zona attiva, non il nome che le ha dato, quindi due zone di tipo diverso allo stesso prezzo risultano comunque diverse. Senza un piano tariffario sull'hub il campo non è affatto nel frame, e il sensore protetto legge unknown con plan_active: false.

Funziona quando Developer Tools → States mostra il nuovo sensore con il nome di una zona, per esempio NIGHT, con plan_active: true, time_src: sntp e placeholder: false tra gli attributi. Se resta su unknown, il topic o il percorso del template è sbagliato per il Suo hub: si iscriva a rbgrid/# con un qualsiasi client MQTT e confronti un frame reale con il template.

Gli attributi ci sono per una ragione, e più acuta di quanto sembri. L'hub calcola la zona dal proprio orologio anche quando quell'orologio non è ancora sincronizzato — dopo un avvio senza SNTP si colloca vicino al 1970 più il tempo di funzionamento, quindi la zona che riporta, e il prezzo che applica, possono essere semplicemente sbagliati. Non trattiene il campo mentre aspetta. time_src è ciò che lo dice, e la sezione successiva rifiuta di agire finché non legge sntp.

⚠️ Dopo ogni riavvio, salvi di nuovo la Sua tariffa prima di fidarsi di questi valori — o di lasciarli guidare qualcosa. Nella v1.1.4 un hub che si riavvia torna sul piano segnaposto integrato Test Day/Night finché non apre Tariffs e preme Save (la guida alle tariffe ne spiega i dettagli). Il problema per questo articolo: finché è così, la zona continua a leggere un plausibilissimo NIGHT e time_src continua a leggere sntp, quindi il controllo della sezione successiva passa e l'automazione pilota la pompa di calore sui confini del piano di prova. Immagini un'interruzione di corrente alle 02:00.

5. Automatizzi — in Home Assistant, sul setpoint

RBgrid misura e riferisce. Non commuta nulla: nessun relè, nessun contattore, nessuna uscita di alcun tipo. Tutto ciò che segue gira dal lato di Home Assistant, su un'entità climate che ha già.

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 guardia del segnaposto è la terza condizione, ed è quella a cui pensa meno gente. Un hub che si riavvia nella v1.1.4 torna sul piano integrato Test Day/Night finché non salva di nuovo il Suo — e finché è così la zona continua a leggersi in modo plausibile e l'orologio risulta ancora sincronizzato, quindi i controlli ovvi passano tutti. Agire su di esso significherebbe guidare la pompa di calore con i prezzi di prova.

L'hub però lo dice, se lo si chiede: finché è attivo il piano integrato, la telemetria riporta placeholder: true, e la chiave semplicemente non c'è più una volta salvato il piano personale. La condizione è rigorosa apposta — agisce solo su un false esplicito, mai su un attributo mancante — così un sensore che non sa dirlo viene trattato come un hub che sta sul piano di prova.

La seconda automazione serve solo a dirle perché tutto è diventato silenzioso. E poiché l'automazione di riconciliazione scatta anche su quell'attributo, nel momento in cui salva di nuovo il piano nell'app il setpoint si riallinea subito invece di aspettare il prossimo intervallo di quindici minuti.

Lo punti a un termostato da ambiente, e lo verifichi prima. climate.set_temperature presuppone un'entità con un target di temperatura ambiente impostabile in °C. Molte integrazioni per pompe di calore espongono altro: una temperatura di mandata o dell'acqua, una curva di compensazione climatica dove un target non fa nulla, un'entità solo a preset senza temperatura impostabile — oppure il serbatoio dell'acqua calda sanitaria (ACS). Impostare 21 su un'entità di temperatura di mandata non è una piccola spinta; su un serbatoio ACS è un cilindro freddo e un ciclo anti-legionella che non aveva previsto.

Apra Developer Tools → States, trovi la Sua entità climate e verifichi che abbia un attributo temperature nell'intervallo che si aspetta prima di lasciare che qualcosa vi scriva.

Lo abbini all'automazione speculare sulla zona diurna, che imposta la temperatura uno o due gradi più bassa, oppure climate.set_preset_mode: eco se la Sua unità ne ha uno.

Verifichi che NIGHT sia davvero la Sua zona economica. Il sensore riporta il tipo della zona, non il nome che le ha dato, e il tipo decide cosa succede:

  • Se il Suo piano ha una zona Weekend, essa prevale sulla notte nei giorni in cui è attiva, e WEEKEND non compare nella condizione qui sopra — quindi dal momento in cui quella zona inizia, l'automazione non decide più nulla. Non ripiega sul target diurno: il setpoint mantiene l'ultimo valore ricevuto, quindi se venerdì notte ha impostato il target notturno, la casa mantiene quel target fino alla fine della zona weekend. Se questo le vada bene è una questione che riguarda il prezzo nel weekend, che il nome della zona non dice — vedi sotto.
  • Se la Sua tariffa economica arriva in due finestre — una notte economica e un mezzogiorno economico, cosa che si adatta bene a una pompa di calore — la seconda compare come un tipo diverso, per esempio LATE_EVENING, e richiede un proprio trigger. Due finestre economiche in un giorno spiega come si costruisce un piano del genere.
  • Con una tariffa a tre zone, "la zona diurna" può essere DAY, MORNING_PEAK o EVENING_PEAK, e Le servirà un trigger per ciascuna.

Osservi il sensore per un giorno prima di fidarsi di un singolo valore to:.

Una zona weekend merita una decisione, non un default. WEEKEND è un tipo di zona; non dice nulla su quanto si paga. Metta il sensore Tariff Buy Rate del §4 su una dashboard, lo guardi di sabato, e poi aggiunga "WEEKEND" alla lista state: così l'automazione agisce nel weekend invece di restare muta. Da lì in poi è una sola riga. Lasciata così, il template target tratta ogni zona diversa da NIGHT come target diurno, quindi un weekend a prezzo pieno riceve il setpoint diurno — che è ciò che si vuole. Aggiunga or is_state('sensor.rbgrid_tariff_zone', 'WEEKEND') a quella riga e un weekend economico riceve quello notturno:

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 }}"

Entrambe le forme sono state eseguite su una zona WEEKEND attiva e fanno esattamente questo; le guardie time_src e placeholder qui sopra non cambiano e si applicano comunque in entrambi i casi. L'automazione agisce su due zone per default perché l'hub può dire il tipo della zona e il suo prezzo, ma non quale delle due voglia la Sua famiglia.

Prima spenga qualunque programma temporizzato che usa già su questa entità. Se un'automazione a orario e questa scrivono entrambe il setpoint, litigheranno, e vince chi ha scritto per ultimo — il che non è una proprietà che vuole far decidere al riscaldamento.

L'hub ricalcola la zona ogni tre secondi e pubblica sul proprio timer da tre secondi, quindi un cambio di zona si vede in al massimo circa sei secondi, di solito prima, più la latenza di Home Assistant. Abbastanza veloce per un setpoint; non costruisca nulla che richieda il confine al secondo.

Converge; non reagisce. È la parte da capire prima di adattarla. Un'automazione che scatta solo alla transizione verso una zona ha un guasto che non noterà: se Home Assistant si sta riavviando, o il broker ha un blip, o l'hub è silenzioso quando passano le 23:00, la transizione viene persa e il setpoint non viene mai ripristinato. La pompa resta sul target diurno — e nulla in casa lo segnala, finché non fa freddo.

Quindi il trigger non è "la zona notturna è iniziata", ma "qualcosa è cambiato, o siamo ripartiti, o sono passati quindici minuti". L'azione allora calcola cosa richiede la zona corrente e la invia solo se la pompa di calore non è già lì. È idempotente, quindi rieseguirla dopo un riavvio è corretto e non va soppresso, e un confine perso si ripara al più tardi al prossimo intervallo di quindici minuti.

Ciò che rende sicuro il sistema sono le condizioni, non il trigger: la zona deve avere un valore reale (unknown e unavailable cadono), l'orologio dell'hub deve essere sincronizzato, e deve aver confermato il piano tariffario. Se una di queste fallisce, non viene inviato nulla e la pompa di calore continua col proprio programma.

Spinga il setpoint; non blocchi l'alimentazione. Tenere ferma la pompa finché non inizia la zona economica è l'idea più ovvia e quella sbagliata: i compressori hanno bisogno dei propri cicli, dei cicli di sbrinamento e dei cicli anti-legionella.

L'ingresso di segnale di rete dell'unità — SG Ready, nella maggior parte d'Europa — può bloccarla, anche con un blocco rigido fino a due ore, e i contatti di blocco delle utility sono normali nelle tariffe per pompe di calore. La differenza è che il controllore del costruttore continua a gestire sbrinamento e programmazione anti-legionella mentre è bloccato, e sa quando fare un'eccezione. Una presa intelligente sulla linea di alimentazione non gestisce nulla di tutto questo. Quindi: il setpoint, un preset o una modalità, attraverso l'interfaccia dell'unità stessa — mai la sua alimentazione.

Renda lo "stato senza dati" lo stato sicuro — e sappia cosa lascia dietro di sé. Se l'hub va offline il sensore diventa unavailable, le condizioni falliscono e non viene inviato nulla, quindi la pompa di calore va avanti con il proprio programma. Per l'apparecchio è il comportamento giusto.

Sia chiaro su ciò che non fa, però: se l'automazione diurna aveva già abbassato il Suo setpoint, nulla lo ripristina finché l'hub è assente. Il silenzio protegge la macchina, non il Suo comfort. Proprio per questo il disegno di riconciliazione conta — appena l'hub torna, il tick successivo porta il setpoint dove la zona corrente dice che deve stare, senza che Lei faccia nulla.

Lo esegua prima come notifica. Per un giorno o due, sostituisca l'azione climate.set_temperature con

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

e osservi quando sarebbe scattata. Non costa nulla, ed è il modo per scoprire che il confine della Sua zona non è dove pensava — o che la Sua entità climate non è quella che dava per scontata.

Se non ha un'entità climate in Home Assistant, salti interamente questa sezione. La misura e il quadro del costo per zona reggono da soli, e un'automazione che non si sa guidare bene è peggio di nessuna.

Cosa non fa

  • RBgrid non commuta mai nulla. Non ha uscite. Ogni azione di questa guida è Home Assistant che agisce sulla Sua apparecchiatura.
  • Il costo per circuito resta nell'app. Home Assistant riceve l'energia della pompa di calore, non il suo costo.
  • Nessun costo per zona per periodo. La suddivisione per zona è un totale progressivo dall'ultimo riavvio dell'hub.
  • Il ruolo non è visibile in HA, quindi un'automazione non può distinguere un punto di riscaldamento da qualsiasi altro.
  • Un hub il cui orologio non si è sincronizzato riporta comunque una zona e continua a valorizzare l'energia, in base a qualunque ora creda sia. Per questo l'automazione sopra controlla time_src, e per questo i primi valori dopo un avvio a freddo meritano un secondo sguardo.
  • RBgrid mostra quanto è costata l'energia della pompa alle Sue tariffe. Non verifica la fattura del fornitore e non fa alcuna affermazione su quanto risparmierà.

Avanti