Skip to content

Instantly share code, notes, and snippets.

@devTechi
Last active May 8, 2026 07:06
Show Gist options
  • Select an option

  • Save devTechi/8d5420049e4da60a6ea906adc5db8022 to your computer and use it in GitHub Desktop.

Select an option

Save devTechi/8d5420049e4da60a6ea906adc5db8022 to your computer and use it in GitHub Desktop.
Zendure Charge/Discharge Blueprint for Home Assistant
blueprint:
name: "Zendure Charge/Discharge"
description: >
Intelligently discharges the Zendure battery overnight. Discharge power is
recalculated every 30 minutes: available energy ÷ remaining hours, capped
at current house consumption (no grid feed-in). Accounts for min/max SoC
limits. During the day, automatically switches to the configured daytime
operation mode.
domain: automation
input:
operation_entity:
name: Zendure Operation Mode
selector:
entity:
domain: select
filter:
- integration: zendure_ha
manual_power_entity:
name: Zendure Manual Power
selector:
entity:
domain: number
device_class: power
filter:
- integration: zendure_ha
soc_entity:
name: Zendure Electric Level (SoC %)
selector:
entity:
domain: sensor
device_class: battery
filter:
- integration: zendure_ha
soc_min_entity:
name: Zendure Minimum SoC
selector:
entity:
domain: number
device_class: battery
filter:
- integration: zendure_ha
soc_max_entity:
name: Zendure Maximum SoC
selector:
entity:
domain: number
device_class: battery
filter:
- integration: zendure_ha
consumption_entity:
name: House Consumption Sensor (W)
selector:
entity:
domain: sensor
device_class: power
capacity_wh:
name: Akkukapazität (Wh)
default: 1920
selector:
number:
min: 100
max: 10000
unit_of_measurement: Wh
start_time:
name: Entladen ab
default: "23:00:00"
selector:
time:
end_time:
name: Entladen bis (= Tagesmodus ab)
default: "08:00:00"
selector:
time:
daytime_operation:
name: Betriebsmodus tagsüber
default: smart
selector:
select:
options:
- label: "Smart Matching (lädt & entlädt, Ziel 0W)"
value: smart
- label: "Nur laden (Solar + Netz)"
value: smart_charging
- label: "Nur Solar speichern"
value: store_solar
variables:
start_time: !input start_time
end_time: !input end_time
capacity_wh: !input capacity_wh
soc_entity: !input soc_entity
soc_min_entity: !input soc_min_entity
soc_max_entity: !input soc_max_entity
consumption_entity: !input consumption_entity
triggers:
- trigger: time
at: !input start_time
- trigger: time
at: !input end_time
- trigger: time_pattern
minutes: "/30"
actions:
- choose:
- conditions:
- condition: template
value_template: >
{% set sh = start_time[:5] %}
{% set eh = end_time[:5] %}
{% set t = now().strftime('%H:%M') %}
{{ t >= sh or t < eh }}
sequence:
- target:
entity_id: !input operation_entity
data:
option: manual
action: select.select_option
- target:
entity_id: !input manual_power_entity
data:
value: >
{% set soc = states(soc_entity) | float(50) %}
{% set soc_min = states(soc_min_entity) | float(10) %}
{% set soc_max = states(soc_max_entity) | float(100) %}
{% set verbrauch = states(consumption_entity) | float(0) %}
{% set available_wh = capacity_wh * ([soc - soc_min, 0] | max) / 100 %}
{% set eh = end_time[:2] | int %}
{% set now_min = now().hour * 60 + now().minute %}
{% set end_min = eh * 60 %}
{% set remaining_min = (end_min - now_min) if now_min < end_min else (24 * 60 - now_min + end_min) %}
{% set remaining_h = [remaining_min / 60, 0.5] | max %}
{% set ideal_power = (available_wh / remaining_h) | round | int %}
{{ [ideal_power, verbrauch] | min | int }}
action: number.set_value
default:
- target:
entity_id: !input operation_entity
data:
option: !input daytime_operation
action: select.select_option
mode: single
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment