[[Uebersicht|← Zurück zur Homepage]]
# HA-Automation: Akku Lade-/Entladesperre bei Tibber-Preisniveau
**Version:** 1.0
**Datum:** 30.06.2026, 13:43 UTC
**Status:** Codierungsanweisung erstellt, noch nicht implementiert
## Ziel
Automation für die drei Marstek Venus Akkus (MTV01, MTV02, MTV03), die abhängig vom
Tibber-Preisniveau (`sensor.daheim_aktuelles_preisniveau`) das Laden erzwingt und das
Entladen sperrt (bei günstigem Strom) bzw. dies wieder zurücknimmt (bei normalem/teurem Strom).
## Logik
**Trigger:** State-Trigger auf `sensor.daheim_aktuelles_preisniveau`
**Fall A — Zustand "günstig" oder "sehr günstig":**
- `switch.mtv01/02/03_battery_allow_discharge` → `false` (falls nicht bereits false)
- `switch.mtv01/02/03_battery_allow_charge` → `true` (falls nicht bereits true)
**Fall B — sonstiger Zustand (normal/teuer):**
- `switch.mtv01/02/03_battery_allow_discharge` → `true` (falls nicht bereits true)
- `switch.mtv01/02/03_battery_allow_charge` → `false` (falls nicht bereits false)
Jeder Switch wird nur geschaltet, wenn sein aktueller Zustand vom Zielzustand abweicht
(keine unnötigen Schreibzugriffe).
**Benachrichtigung:** Eine gesammelte `persistent_notification` pro Durchlauf, die alle
tatsächlich geänderten Switches auflistet. Wurde kein Switch geändert, entfällt die
Benachrichtigung.
## Codierungsanweisung für Claude Code
```
Erstelle eine Home Assistant Automation (YAML, automations.yaml-kompatibel) mit folgenden
Anforderungen:
Trigger:
- platform: state
entity_id: sensor.daheim_aktuelles_preisniveau
Condition: keine (Verzweigung über choose/if-then in der Action)
Action (Pseudocode):
1. Definiere Zielzustand je nach trigger.to_state.state:
- state in ["günstig", "sehr günstig"]:
target_discharge = "off" (false)
target_charge = "on" (true)
- sonst:
target_discharge = "on" (true)
target_charge = "off" (false)
2. Für jeden der 6 Switches:
- switch.mtv01_battery_allow_discharge
- switch.mtv02_battery_allow_discharge
- switch.mtv03_battery_allow_discharge
- switch.mtv01_battery_allow_charge
- switch.mtv02_battery_allow_charge
- switch.mtv03_battery_allow_charge
Prüfe aktuellen Zustand gegen Zielzustand (discharge-Switches gegen target_discharge,
charge-Switches gegen target_charge). Bei Abweichung: switch.turn_on/turn_off aufrufen
und den Switch-Friendly-Name + neuen Zustand in einer Variablen/Liste sammeln
(z.B. via repeat-Loop über eine input-Liste mit entity_id + target_state, um
Code-Duplikation zu vermeiden).
3. Nach Durchlauf aller 6 Switches: Wenn die Sammel-Liste nicht leer ist, eine einzelne
persistent_notification erstellen mit:
- Titel: "Akku-Sperre Tibber-Preisniveau"
- Inhalt: Aufzählung aller geänderten Switches mit altem → neuem Zustand,
plus aktuellem Preisniveau-Zustand
Ist die Liste leer, keine Notification erzeugen.
Empfohlene Umsetzung: nutze eine Template-/Repeat-Struktur (z.B. repeat.for_each über
eine Liste von Dicts {entity, target}) statt 6x identischen Code zu wiederholen, um
Wartbarkeit zu erhöhen. Variablen (variables:) für target_discharge/target_charge
am Anfang der Action setzen.
Automation-ID/Alias: "Akku Lade-Sperre bei Tibber-Preisniveau"
mode: single
```
## Offene Punkte
- Switch-Verhalten bei nicht erreichbarem Entity (unavailable/unknown): Entscheidung liegt
bei Claude Code.
- Reihenfolge Charge/Discharge beim Umschalten: Entscheidung liegt bei Claude Code.
## Fertiges YAML (v1.2)
```yaml
alias: "Akku Lade-Sperre bei Tibber-Preisniveau"
description: >
Sperrt/erlaubt Laden und Entladen der Marstek Akkus MTV01-03 abhängig vom
Tibber-Preisniveau (günstig/sehr günstig vs. normal/teuer).
mode: single
trigger:
- platform: state
entity_id: sensor.daheim_aktuelles_preisniveau
condition: []
variables:
guenstig: >
{{ trigger.to_state.state in ['günstig', 'sehr günstig'] }}
target_discharge: "{{ 'off' if guenstig else 'on' }}"
target_charge: "{{ 'on' if guenstig else 'off' }}"
switch_liste: >
{{ [
{'entity': 'switch.mtv01_battery_allow_discharge', 'target': target_discharge},
{'entity': 'switch.mtv02_battery_allow_discharge', 'target': target_discharge},
{'entity': 'switch.mtv03_battery_allow_discharge', 'target': target_discharge},
{'entity': 'switch.mtv01_battery_allow_charge', 'target': target_charge},
{'entity': 'switch.mtv02_battery_allow_charge', 'target': target_charge},
{'entity': 'switch.mtv03_battery_allow_charge', 'target': target_charge}
] }}
action:
- variables:
geaenderte: []
- repeat:
for_each: "{{ switch_liste }}"
sequence:
- variables:
entity: "{{ repeat.item.entity }}"
target: "{{ repeat.item.target }}"
aktuell: "{{ states(repeat.item.entity) }}"
- if:
- condition: template
value_template: "{{ aktuell not in ['unavailable', 'unknown'] and aktuell != target }}"
then:
- service: "switch.turn_{{ target }}"
target:
entity_id: "{{ entity }}"
- variables:
geaenderte: >
{{ geaenderte + [{
'name': state_attr(entity, 'friendly_name') or entity,
'alt': aktuell,
'neu': target
}] }}
- if:
- condition: template
value_template: "{{ geaenderte | length > 0 }}"
then:
- service: persistent_notification.create
data:
title: "Akku-Sperre Tibber-Preisniveau"
message: >
Preisniveau: {{ trigger.to_state.state }}
{% for s in geaenderte %}
- {{ s.name }}: {{ s.alt }} → {{ s.neu }}
{% endfor %}
```
**Entscheidung unavailable/unknown:** Switch wird übersprungen, nicht geschaltet.
**Entscheidung Reihenfolge:** Discharge-Switches zuerst, dann Charge-Switches (Liste oben).
## Verlauf
- v1.0 (30.06.2026, 13:43 UTC): Codierungsanweisung erstellt, Rückfragen zu Trigger,
Benachrichtigungsform und Sammel-/Einzelnachricht geklärt.
- v1.1 (30.06.2026, 13:48 UTC): Offene Punkte (unavailable-Verhalten, Reihenfolge
Charge/Discharge) an Claude Code zur Entscheidung übergeben.
- v1.2 (30.06.2026, 14:05 UTC): Fertiges YAML erstellt und in Note dokumentiert,
offene Punkte entschieden (unavailable → überspringen, Reihenfolge → Discharge
vor Charge).
---
[[Hinweise/Impressum|Impressum]] | [[Hinweise/Datenschutzerklärung|Datenschutz]]