Skip to content

Instantly share code, notes, and snippets.

@dsiebel
Last active December 30, 2025 12:31
Show Gist options
  • Select an option

  • Save dsiebel/b76cab682c13ce59e3e54240deddd286 to your computer and use it in GitHub Desktop.

Select an option

Save dsiebel/b76cab682c13ce59e3e54240deddd286 to your computer and use it in GitHub Desktop.
Solar Power Zero Grid Export - Home Assistant Automation

Solar Power Zero Frid Export - Home Assistant Automation

Prerequisites

Description

  • run on every change to the current total power (grid) consumption or production
  • alternatively: trigger every 9s
  • only if the delta is <> 10W
  • calculate interver target power to achieve 0W grid consumption
  • use min power setting when the battery minimum level is reached

Global Variables

Variable Description
battery_level_entity_id Entity for the current battery level, i.e. "Average Battery Level" from the SunLit REST HACS integration
batter_level_min_entity_id input_number helper id to configure minimum battery level to stop the power output
grid_current_power Current total grid consumption. Negative means export, positive mean consumption
inverter_control_entity_id Inverter entity to set desired power output
inverter_rated_power Inverter rated power (maximum output you want to allow), e.g. 800W
inverter_min_power_entity_id input_number helper id to configure the inverter's min power setting. E.g. 30W for APSystems EZ1-M. Used once min battery level is reached.
inverter_min_power Value from above entity
step Step size in which to increase / decrease power output

Action Variables

Variable Description
battery_level_min Minimum battery level configured. Stops power output once reached.
battery_level_current Current Battery level from battery_level_entity_id
inverter_current_power Currently set inverter power output from inverter_control_entity_id
inverter_current_power_stepped inverter_current_power normalized to the next step, e.g. 34 => 40
grid_current_power_stepped grid_current_power normalized to the next step, e.g. 123 => 130, -44 => -40
target_power Calculated desired output power to set on the inverter
target_power_clamped target_power contraint to min and max values of the inverter
log_message some debug output
inverter_control_number_set_value_action internal purposes only

Helpers

Helpers used in this automation.
Either create them in your Home Assistant instance, or use hard-coded values in their place.

Name Description
input_number.solar_battery_level_min Minimum battery level at which the automation stops
input_number.solar_inverter_rated_power Rated Power output of your inverter. Used to clamp the calculated target power output
input_number.solar_inverter_output_min Minmum target output power. Used once minimum battery level is reached. The automation can not turn off your inverter!
input_select.solar_power_feed_strategy List of available strategies. Automation checks for value zero grid export
alias: "solar_power_feed_zero_export"
triggers:
# Trigger when power consumption changes
- trigger: "state"
entity_id: "sensor.energy_power_current"
# set `to` to `null`, otherwise the automation will trigger
# for both `from` and `to` states, as well as attribute changes
to: null
# Trigger every 9 seconds
# - trigger: "time_pattern"
# seconds: "/9"
variables:
# Battery
battery_level_entity_id: "sensor.home_solar_system_average_battery_level"
battery_level_min_entity_id: "input_number.solar_battery_level_min"
# Current grid power (positive = importing, negative = exporting)
grid_current_power: >
{{ states("sensor.energy_power_current") | int(0) }}
# Inverter number entity controlling output power
inverter_control_entity_id: "number.solar_max_output"
# Inverter max rated output power
inverter_rated_power: >
{{ states("input_number.solar_inverter_rated_power") }}
# Inverter min output power setting
inverter_min_power_entity_id: input_number.solar_inverter_output_min
inverter_min_power: >
{{ states(inverter_min_power_entity_id) }}
# Step size for power calculations
step: 10
conditions:
# Don't run if grid consumption/production is within acceptable parameters
- condition: "template"
value_template: >
{{ not (-(step) < grid_current_power < step) }}
# Don't run if strategy isn't active
- condition: "state"
entity_id: "input_select.solar_power_feed_strategy"
state: "zero grid export"
# Don't run if the grid connection is interrupted
- condition: "state"
entity_id: "switch.0xa4c13833f21e39cf"
state: "on"
actions:
- variables:
# Minimum battery level
battery_level_min: >
{{ states(battery_level_min_entity_id) | int(0) }}
battery_level_current: >
{{ (states(battery_level_entity_id) | int(0)) }}
# Current output power set on the inverter
inverter_current_power: >
{{ states(inverter_control_entity_id) | round(0) }}
# Normalize to steps
inverter_current_power_stepped: >
{{ (inverter_current_power // step) * step }}
# Calculated target power setting (in steps of `step`)
grid_current_power_stepped: >
{{ ((grid_current_power // step) + 1) * step }}
# New target output power value for inverter
target_power: >
{{ (inverter_current_power_stepped + grid_current_power_stepped) }}
# New Target output power, clamped for min and max values
target_power_clamped: >
{{ [([target_power, inverter_rated_power] | min), inverter_min_power] | max }}
# Debug logging message
log_message: >
{{
"Grid:" ~ grid_current_power ~ "W | " ~
"Grid (stepped):" ~ grid_current_power_stepped ~ "W | " ~
"Inverter current:" ~ inverter_current_power ~ "W | " ~
"Inverter current (stepped):" ~ inverter_current_power_stepped ~ "W | " ~
"Inverter rated:" ~ inverter_rated_power ~ "W | " ~
"Target:" ~ target_power ~ "W | " ~
"Target (clamped):" ~ target_power_clamped ~ "W"
}}
# Switch action based on inverter_controller_entity type
inverter_control_number_set_value_action: >
{% if inverter_control_entity_id.startswith("input_number.") %}
input_number.set_value
{% else %}
number.set_value
{% endif %}
- action: "system_log.write"
data:
level: "info"
message: "Zero Power Feed: {{ now().strftime('%H:%M:%S') }} | {{ log_message }}"
- if:
# Don't set calculated target power when battery is low
- condition: "template"
value_template: >
{{ battery_level_current >= battery_level_min }}
then:
- action: "{{ inverter_control_number_set_value_action }}"
target:
entity_id: "{{ inverter_control_entity_id }}"
data:
value: "{{ target_power_clamped }}"
else:
# Instead, set inverter min power when battery is low
- action: "{{ inverter_control_number_set_value_action }}"
target:
entity_id: "{{ inverter_control_entity_id }}"
data:
value: "{{ inverter_min_power }}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment