Automating Solar Energy in Home Assistant: Dynamic Surplus Charging

Contents
Maximizing the self-consumption rate of a residential photovoltaic (PV) installation requires real-time synchronization between solar power generation, household base loads, and high-capacity electrical consumers. When excess solar energy is fed back into the public grid at low feed-in tariffs, financial efficiency drops significantly. Implementing a dynamic surplus charging architecture within Home Assistant—leveraging Modbus or MQTT telemetry from hybrid inverters, smart energy meters, and battery storage units—allows high-demand consumers (such as battery banks, EV chargers, and heat pump boilers) to modulate their power draw dynamically based on real-time solar surplus.
1. Architectural Principles of Real-Time Surplus Calculation
Dynamic surplus management relies on calculating the net available power at the grid interconnection point before triggering or modulating load devices. The system architecture is built on three foundational metrics:
- Grid Export Power (
sensor.grid_export_power): Real-time wattage measured by a bidirectional smart meter at the main electrical intake. A positive export value indicates surplus solar energy leaving the household. - Dynamic Surplus Thresholds: High-demand appliances must only activate when export power exceeds a defined hysteresis threshold (e.g., > 1,500 W for at least 300 seconds) to prevent short-cycling caused by passing clouds.
- Priority-Based Load Modulation: Available surplus must be allocated hierarchically: first to home battery storage (via hybrid inverter charging limits), second to variable-rate EV charging, and third to thermal storage or resistive heating elements.
2. Step-by-Step Template Sensor Configuration
To provide a clean, noise-filtered signal for Home Assistant automations, a dedicated template sensor must be configured within configuration.yaml to calculate the exact net surplus wattage:
- Define the Template Sensor: Create a modern template sensor entity named
sensor.solar_surplus_powerthat evaluates grid export power and sets negative values (grid import) strictly to zero. - Apply Hysteresis Smoothing: Implement a low-pass filter or moving average using the Home Assistant Filter integration to eliminate rapid wattage spikes caused by momentary appliance activation.
- Verify Unit Consistency: Ensure all power metrics are standardized to Watts (W) and include explicit
device_class: powerandstate_class: measurementdefinitions for Riemann sum integration compatibility.
Production-Ready YAML Template Sensor
template:
- sensor:
- name: "Solar Surplus Power"
unique_id: "solar_surplus_power_dynamic"
unit_of_measurement: "W"
device_class: "power"
state_class: "measurement"
state: >
{% set export_power = states('sensor.grid_meter_export_power') | float(0) %}
{% set import_power = states('sensor.grid_meter_import_power') | float(0) %}
{% if export_power > import_power %}
{{ (export_power - import_power) | round(0) }}
{% else %}
0
{% endif %}
availability: >
{{ has_value('sensor.grid_meter_export_power') and has_value('sensor.grid_meter_import_power') }}
3. Step-by-Step Automation for Dynamic Battery & Appliance Stepping
With a reliable surplus sensor operational, an automation must be deployed to modulate charging current or trigger smart switches without causing grid oscillation:
- Trigger Definition: Configure a Numeric State trigger observing
sensor.solar_surplus_powerexceeding 1,500 W for a continuous duration of 5 minutes. - Condition Evaluation: Add conditions requiring household battery State of Charge (SoC) to be below 95% and the EV charger to be plugged in.
- Action Execution (Dynamic Amp Tuning): Execute a service call to adjust battery charging power or increment EV charging current (e.g., from 6A up to 16A per phase) dynamically matching the available surplus delta.
- Graceful Deactivation: Build a secondary shut-off automation that ramps down or pauses charging when grid import exceeds 300 W for more than 120 seconds.
Production-Ready Automation YAML (Surplus Activation)
alias: "Solar Surplus: Dynamic Load Engagement"
description: "Engages surplus charging when export power is stable above threshold."
trigger:
- platform: numeric_state
entity_id: sensor.solar_surplus_power
above: 1500
for:
minutes: 5
condition:
- condition: numeric_state
entity_id: sensor.battery_state_of_charge
below: 95
action:
- service: number.set_value
target:
entity_id: number.inverter_max_charge_current
data:
value: >
{% set surplus = states('sensor.solar_surplus_power') | float(0) %}
{% set voltage = 50.0 %}
{{ [ ((surplus * 0.9) / voltage) | round(0), 40 ] | min }}
mode: single
4. Summary & Architectural Value
What this tutorial achieves: The deployment of a deterministic, hysteresis-protected solar surplus management system in Home Assistant using custom template sensors and automated power modulation scripts.
Resulting value: Photovoltaic self-consumption rates are maximized, frequently exceeding 80% to 90%. Dependency on grid power imports during peak evening tariff periods is drastically minimized by prioritizing home battery charging and heavy household appliances during peak midday irradiance. Furthermore, hysteresis timers prevent mechanical relay wear and electrical grid oscillation caused by fluctuating cloud cover.
Questions and answers
Does the automation keep adjusting the charging current as the surplus changes?
No. A numeric_state trigger fires when the value crosses the threshold and stays above it for five minutes; as long as it stays above, it does not fire again. The action therefore sets the charging current once and holds it until the surplus falls below 1,500 W and rises again, however the sun moves in the meantime.
Continuous tracking needs a second trigger, such as a time_pattern every minute, and a condition that checks whether regulation should happen at all.
The calculation matters more than the interval. The meter is at the grid connection, so the measured surplus is what remains after charging already under way. The new set point must therefore include the charging power reported by the inverter plus the measured surplus, rather than the surplus alone. Otherwise, the control reacts to the battery’s own consumption and makes the current swing up and down.
Is a surplus of 1,500 W enough as the switch-on threshold for an EV charger?
For single-phase charging, just about. The minimum charging current of 6 A corresponds to about 1,380 W at 230 V; after switching on, around 120 W of surplus remain, and the shut-off condition of 300 W import is not met.
A three-phase charger, by contrast, draws about 4.1 kW at 6 A per phase. With a surplus just above the threshold, it imports about 2.6 kW from the grid after switching on, the shut-off automation pauses charging after 120 seconds, the surplus returns, and five minutes later the whole cycle starts again. For three-phase charging the switch-on threshold therefore belongs above 4.1 kW plus a reserve, or the charger runs on a single phase while the surplus is small.
What do the 50 volts and the factor of 0.9 in the action stand for?
The action converts watts into amperes because the inverter expects a charging current, and the 50 V stands for a low-voltage battery of the 48-volt class. The factor of 0.9 leaves ten percent of the surplus unused so that charging does not slide into grid import, and the 40 A limit caps the charging power at 2 kW. For a high-voltage battery, its actual voltage belongs in the formula instead of the 50; otherwise the current comes out several times too high.