# Boiler Auxiliary Heater Control A Home Assistant custom integration for intelligently controlling an auxiliary electric heating element inside a DHW (Domestic Hot Water) boiler. Designed for systems where a heat pump is the primary heat source and an electric resistance heater is the secondary element. The integration maximises PV self-consumption by diverting surplus solar energy to the boiler, while also supporting on-demand bath boost heating and fully configurable temperature presets. --- ## Features - **PV Excess Diversion** — monitors up to 3 CT clamps (single-phase or 3-phase) and activates the heater only when there is enough surplus export, using configurable start/stop delays to avoid rapid cycling - **Bath Boost** — one-tap hot water on demand; activates the heater and optionally runs the DHW circulation pump for a configurable duration, then automatically restores the previous state - **5 Temperature Presets** — Normal, Eco, Boost, Sleep, Away, each with individually adjustable target temperatures - **All-Modes Boost** — optional mode that lets the aux heater top up the boiler whenever the thermostat demands heat, regardless of PV availability - **Safety Interlocks** — hard cut-off temperature, HP aux heater interlock (disables aux heater while the heat pump's own electric element is running), and safe defaults for unavailable sensors - **Energy Tracking** — separate kWh counters for total, PV-sourced, and grid-sourced energy, compatible with HA's Energy Dashboard - **Decision Transparency** — a `Decision Reason` sensor tells you exactly why the heater is on or off at any moment - **Persistent State** — all settings and an active bath boost survive HA restarts - **Ready-to-Use Dashboard** — an importable Lovelace dashboard is included --- ## Requirements - Home Assistant 2024.1.0 or newer - A temperature sensor measuring the boiler water temperature (device class: `temperature`) - A switch entity controlling the heater relay - One or more power sensors measuring grid import/export at each phase (device class: `power`, **negative = export**) Optional: - A binary sensor indicating whether the heat pump's own auxiliary heater is active (for interlock) - A switch entity for a DHW circulation pump (enables the bath boost button) - A scheduler entity for the pump (its schedule is restored after bath boost) --- ## Installation ### Via HACS (recommended) 1. Open HACS in Home Assistant 2. Go to **Integrations** → click the three-dot menu → **Custom repositories** 3. Add this repository URL and select category **Integration** 4. Search for **Boiler Auxiliary Heater Control** and install 5. Restart Home Assistant ### Manual 1. Copy the `custom_components/boiler_aux_heater_3phase` folder into your HA `config/custom_components/` directory 2. Restart Home Assistant --- ## Configuration Navigate to **Settings → Devices & Services → Add Integration** and search for **Boiler Auxiliary Heater Control**. The setup wizard has three steps: ### Step 1 — Core Hardware | Field | Description | |-------|-------------| | Boiler temperature sensor | Sensor measuring the DHW tank temperature (must have device class `temperature`) | | Heater relay switch | The switch entity that controls the heating element | ### Step 2 — Solar Monitoring | Field | Description | |-------|-------------| | Number of phases | `1 Phase` or `3 Phases` | | Phase 1 CT power sensor | Grid power sensor for phase 1 (negative = exporting) | | Phase 2 CT power sensor | Phase 2 sensor (3-phase only, optional) | | Phase 3 CT power sensor | Phase 3 sensor (3-phase only, optional) | > **Important:** the CT sensors must report **negative values for export** and positive values for import. This is the convention used by most inverter integrations (Fronius, SolarEdge, Huawei, etc.). ### Step 3 — Optional Devices | Field | Description | |-------|-------------| | HP aux heater sensor | Binary sensor that is `on` when the heat pump's own electric element is active. If provided, the aux heater is disabled while this sensor is `on`. If the sensor becomes **unavailable**, the aux heater is disabled as a safety measure. | | Circulation pump switch | Switch controlling a DHW circulation pump. When provided, the **Bath Boost** button entities are created. | | Pump schedule entity | A scheduler entity whose schedule is re-applied after bath boost finishes. | After initial setup, all entity references can be changed via **Configure** on the integration card. --- ## Entities ### Climate | Entity | Description | |--------|-------------| | `climate.boiler_auxiliary_heater` | Main thermostat. Set HVAC mode (`heat`/`off`) and choose a preset. | **Presets:** Normal · Eco · Boost · Sleep · Away Selecting the **Boost** preset starts the bath boost timer. Selecting any other preset while boost is active cancels the boost. --- ### Switches (Configuration) | Entity | Default | Description | |--------|---------|-------------| | `switch…allow_aux_heater_usage` | ON | Master enable. Turn off to disable the aux heater entirely. | | `switch…pv_excess_mode` | ON | Enable PV excess diversion. | | `switch…boost_in_all_modes` | OFF | Allow the heater to run whenever the thermostat demands heat, regardless of PV. Uses the larger all-modes hysteresis to avoid short cycling. | | `switch…manual_override` | OFF | Force the relay ON, bypassing all logic. For testing or emergencies only. | --- ### Numbers (Configuration) **Temperatures** | Entity | Default | Range | Description | |--------|---------|-------|-------------| | `number…cut_off_temperature` | 60 °C | 40–85 | Hard safety limit. Heater is always off above this temperature. | | `number…temperature_hysteresis` | 4 °C | 1–15 | How far below the target temperature heating must be demanded before activating. Also used as PV shadow thermostat cold tolerance. | | `number…pv_target_temperature` | 55 °C | 40–70 | Target temperature for PV excess mode. Max is automatically capped at `cut_off_temp - 1`. | | `number…normal_preset_temperature` | 44 °C | 30–65 | Target for Normal preset. | | `number…eco_preset_temperature` | 40 °C | 30–60 | Target for Eco preset. | | `number…boost_preset_temperature` | 50 °C | 40–70 | Target for Boost preset. | | `number…sleep_preset_temperature` | 38 °C | 25–55 | Target for Sleep preset. | | `number…away_preset_temperature` | 35 °C | 20–50 | Target for Away preset. | **PV Excess Settings** | Entity | Default | Range | Description | |--------|---------|-------|-------------| | `number…heater_power_rating` | 4500 W | 1500–9000 | Rated wattage of the heating element. Used for PV surplus threshold and energy calculations. | | `number…pv_excess_buffer` | 100 W | 0–1000 | Additional margin required above heater power before PV mode activates. Prevents marginal activation. | | `number…pv_excess_start_delay` | 60 s | 1–300 | How long PV surplus must be sustained before activating. Prevents cloud transients from triggering the heater. | | `number…pv_excess_stop_delay` | 60 s | 1–300 | How long PV deficit must be sustained before deactivating. Allows short shading events without turning off. | **Bath Boost & All-Modes Settings** | Entity | Default | Range | Description | |--------|---------|-------|-------------| | `number…bath_boost_duration` | 30 min | 5–120 | How long bath boost runs. | | `number…all_modes_boost_hysteresis` | 10 °C | 3–20 | Temperature must be this far below target for all-modes boost to activate. Larger value → heater activates less often. | | `number…boost_recovery_offset` | 3 °C | 0–15 | All-modes boost turns off when temperature reaches `target - boost_recovery_offset`. | --- ### Binary Sensors (Status) | Entity | Description | |--------|-------------| | `binary_sensor…heater_decision` | `on` = heater relay should be on right now. | | `binary_sensor…pv_power_sufficient` | `on` = current PV export is enough to run the heater. | | `binary_sensor…running_on_pv` | `on` = heater is running and powered by PV surplus. | | `binary_sensor…running_on_grid` | `on` = heater is running on grid power (bath boost or all-modes boost). | | `binary_sensor…bath_boost_active` | `on` = bath boost timer is running. | --- ### Sensors (Status) | Entity | Description | |--------|-------------| | `sensor…heater_power` | Current total power consumption of the heater (W). | | `sensor…heater_pv_power` | Current power drawn from PV surplus (W). | | `sensor…heater_grid_power` | Current power drawn from the grid (W). | | `sensor…heater_energy` | Total energy consumed (kWh) — suitable for HA Energy Dashboard. | | `sensor…heater_pv_energy` | Energy consumed from PV (kWh). | | `sensor…heater_grid_energy` | Energy consumed from grid (kWh). | | `sensor…bath_boost_remaining` | Seconds remaining in the current bath boost (0 when inactive). | | `sensor…decision_reason` | Human-readable text explaining the current heater decision, e.g. *"PV excess heating"* or *"OFF: HP aux heater active"*. | | `sensor…pv_excess_state` | PV state machine state: `idle`, `waiting_to_start`, `active`, or `waiting_to_stop`. | --- ### Buttons (optional — only if circulation pump is configured) | Entity | Description | |--------|-------------| | `button…start_bath_boost` | Start the bath boost timer immediately. | | `button…cancel_bath_boost` | Cancel an active bath boost and restore previous state. | --- ## Services Both services are always available, regardless of whether a circulation pump is configured. ### `boiler_aux_heater_3phase.start_bath_boost` Starts the bath boost. Saves the current climate preset, activates the Boost preset, starts the countdown timer, and (if configured) turns on the circulation pump. ```yaml service: boiler_aux_heater_3phase.start_bath_boost ``` ### `boiler_aux_heater_3phase.stop_bath_boost` Cancels an active bath boost, restores the previous preset, and (if configured) turns off the circulation pump and re-applies the pump schedule. ```yaml service: boiler_aux_heater_3phase.stop_bath_boost ``` --- ## Events When a bath boost expires naturally (timer runs out), the integration fires: ``` event: boiler_aux_heater_3phase_boost_finished data: duration_minutes: 30 pre_boost_preset: "Normal" restored_preset: "Normal" ``` You can use this event in automations to notify occupants or take further action. --- ## How the PV Excess Logic Works ``` For each active CT phase: Turn-on threshold: CT_value < -(heater_power / phases + pv_buffer / phases) Stay-on threshold: CT_value <= 0 (any export at all) State machine: IDLE ──[all phases meet turn-on threshold]──► WAITING_TO_START WAITING_TO_START ──[pv_start_delay elapsed]──► ACTIVE WAITING_TO_START ──[PV drops]──► IDLE ACTIVE ──[any phase stops exporting]──► WAITING_TO_STOP WAITING_TO_STOP ──[pv_stop_delay elapsed]──► IDLE WAITING_TO_STOP ──[PV recovers]──► ACTIVE ``` While in `ACTIVE` or `WAITING_TO_STOP`, the PV shadow thermostat checks whether the boiler temperature is below `pv_target_temp`. This prevents unnecessarily overheating the tank on very sunny days. --- ## Dashboard A ready-to-use Lovelace dashboard is included in `custom_components/boiler_aux_heater_3phase/dashboard.yaml`. To import it: 1. Go to **Settings → Dashboards → Add Dashboard** 2. Or use the **Raw Configuration Editor** in an existing dashboard and paste the YAML The dashboard includes sections for: - Thermostat control with preset dropdown - Bath boost controls and timer - Mode switches - Preset temperature configuration - Safety and heater settings - PV excess settings - Live status (decision, PV state, power & energy) --- ## Automation Examples ### Notify when bath boost finishes ```yaml automation: - alias: "Notify bath boost done" trigger: - platform: event event_type: boiler_aux_heater_3phase_boost_finished action: - service: notify.mobile_app_my_phone data: message: "Hot water ready! Tank heated for {{ trigger.event.data.duration_minutes }} minutes." ``` ### Switch to Away preset when leaving home ```yaml automation: - alias: "Boiler away mode" trigger: - platform: state entity_id: person.resident to: not_home action: - service: climate.set_preset_mode target: entity_id: climate.boiler_auxiliary_heater data: preset_mode: Away ``` ### Start bath boost on a schedule ```yaml automation: - alias: "Morning bath boost" trigger: - platform: time at: "07:00:00" condition: - condition: state entity_id: binary_sensor.workday_sensor state: "on" action: - service: boiler_aux_heater_3phase.start_bath_boost ``` --- ## Troubleshooting **Heater never activates in PV mode** - Check `sensor…pv_excess_state` — if it stays `idle`, the CT sensors may not be reporting negative values when exporting. Confirm the sign convention of your inverter integration. - Check that `switch…pv_excess_mode` is on and `switch…allow_aux_heater_usage` is on. - Check `sensor…decision_reason` for the exact reason the heater is off. - Increase `pv_excess_buffer` to 0 temporarily to rule out threshold issues. **HP aux heater interlock keeps the heater off** - If the HP aux heater binary sensor reads `unavailable`, the integration disables the aux heater as a safety measure. Check the sensor entity or remove it from the configuration if not needed. **Bath boost buttons are missing** - The bath boost buttons are only created when a circulation pump switch is configured. Go to **Configure** on the integration card to add one. The `start_bath_boost` and `stop_bath_boost` services are always available regardless. **Energy counters reset after restart** - Energy sensors use `RestoreEntity` to persist their values. If values are lost, check that the HA recorder is running and that the entities are not excluded from recording. **PV mode activates but heater stays off** - Check `sensor…decision_reason`. Common causes: boiler temperature above `cut_off_temperature`, HVAC mode set to `off`, or `allow_aux_heater_usage` switch is off. --- ## License MIT License — see [LICENSE](LICENSE) for details.