Die Energiewende findet im Heizungskeller statt – und in der Cloud. Auf herc.de dokumentiere ich oft meine technischen Projekte, aber dieses hier ist das Herzstück meines Smart Homes: Ein vollautomatisches Energiemanagementsystem (EMS), das entscheidet, wann die Batterie geladen, das Auto getankt oder das Haus geheizt wird.
In diesem Artikel zeige ich meine Konfiguration mit Home Assistant und dem genialen Add-on EMHASS.
Die Hardware
Bevor wir in den Code springen, hier das Setup:
- Wechselrichter/Speicher: FoxESS mit 5.7 kWh Batterie.
- Auto: VW ID.Buzz an einem go-eCharger.
- Wärme: Wärmepumpe (gesteuert über
climateEntitäten). - Gehirn: Home Assistant auf einem Raspberry Pi/NUC.
Warum EMHASS?
Die meisten PV-Steuerungen sind “reaktiv”: Wenn Sonne da ist, lade die Batterie. EMHASS (Energy Management for Home Assistant) hingegen ist “prädiktiv”. Es schaut in die Zukunft:
- Wie wird das Wetter? (Solcast)
- Was kostet der Strom? (Nordpool)
- Wie viel Energie braucht das Haus? (Machine Learning Forecast)
Daraus berechnet es einen Optimierungsplan für die nächsten 24-48 Stunden, um den maximalen Profit zu erzielen.
Die Konfiguration
Mein EMHASS-Config setzt auf die Strategie profit. Ich nutze mlforecaster für die Lastprognose des Hauses, da statische Profile oft ungenau sind.
Hier ein Auszug meiner config.json:
{
"costfun": "profit",
"battery_nominal_energy_capacity": 5700,
"battery_charge_power_max": 4500,
"load_forecast_method": "mlforecaster",
"number_of_deferrable_loads": 2,
"treat_deferrable_load_as_semi_cont": [true, true],
"set_battery_dynamic": false,
"set_use_battery": true
}
Ich habe zwei Deferrable Loads (verschiebbare Lasten) definiert:
- Warmwasser (Load 0)
- Heizung (Load 1)
Der “Secret Sauce”: Das dynamische Skript
Das Standard-EMHASS-Setup war mir nicht flexibel genug. Ich wollte die präzisen PV-Daten von Solcast (getrennt nach Süd/Nord-Dach) und ein dynamisches thermisches Modell für die Heizung nutzen.
Dafür habe ich ein komplexes Skript emhass_optimierung_dynamic gebaut. Es passiert folgendes:
- Es holt die Wetterdaten.
- Es kombiniert die Solcast-Prognosen von Süd- und Norddach.
- Es erstellt ein JSON-Objekt, das die thermischen Eigenschaften des Hauses on-the-fly an EMHASS übergibt.
Hier ein Blick in das Jinja2-Template des Scripts:
# scripts.yaml Auszug
emhass_optimierung_dynamic:
alias: "EMHASS Optimierung (Dynamischer Horizont)"
sequence:
- action: weather.get_forecasts
target:
entity_id: weather.openweathermap
data:
type: hourly
response_variable: weather_data
- action: shell_command.trigger_emhass_optim
data:
json_payload: >-
{%- set time_step_min = 30 -%}
{# ... (Logik zum Zusammenbau von Solcast Süd+Nord) ... #}
{
"prediction_horizon": {{ steps }},
"soc_init": {{ (states("sensor.foxess_inverter_battery_soc") | float(0) / 100.0) | round(4) }},
"pv_power_forecast": {{ raw_pv[:steps] | tojson }},
"load_cost_forecast": {{ raw_prices[:steps] | tojson }},
"def_load_config": [
{},
{
"thermal_config": {
"heating_rate": 2,
"cooling_constant": 0.03,
"overshoot_temperature": {{ (states("sensor.current_temperature_bad") | float(22) ) | round(2) + 2}},
"start_temperature": {{ (states("sensor.current_temperature_bad") | float(22) ) | round(2) }},
"desired_temperatures": {{ ns_temp.schedule[:steps] | tojson }}
}
}
]
}
Dieses Skript läuft alle 30 Minuten via Automation, sofern neue Daten von Nordpool oder Solcast vorliegen.
Die Umsetzung: Automatisierungen
Nachdem EMHASS gerechnet hat, müssen die Geräte geschaltet werden. EMHASS liefert dafür Sensoren wie sensor.p_deferrable0 (Warmwasser) oder sensor.p_deferrable1 (Heizung).
1. Heizung & Warmwasser
Meine Automation prüft, ob EMHASS > 0 Watt für die Last einplant. Wenn ja, wird die Wärmepumpe freigegeben.
# automations.yaml
- alias: 'EMHASS: Heizungsschalter (Load 1) Steuerung'
trigger:
- entity_id: sensor.p_deferrable1
trigger: state
action:
- if:
- condition: numeric_state
entity_id: sensor.p_deferrable1
above: 0
then:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.switch_heating_on
Besonders wichtig: Ich habe eine Mindestlaufzeit von einer Stunde implementiert, um das “Takten” der Wärmepumpe zu verhindern.
2. Smart Buffer für die Batterie
Eine Besonderheit ist meine FoxESS-Logik. Ich überlasse das Laden nicht allein dem Zufall. Wenn EMHASS vorhersagt, dass wir später viel PV-Strom haben (sensor.p_batt_forecast), aber aktuell wenig Sonne scheint, zwinge ich den Wechselrichter in den passenden Modus.
- alias: 'EMHASS: FoxESS Hybrid Charging (Smart Buffer)'
action:
- choose:
- conditions:
- condition: template
value_template: '{{ power_forecast_watts < 0 }}' # Batterie soll laden laut Plan
- condition: template
value_template: '{{ current_pv_watts > 300 }}' # Genug Sonne da
sequence:
- target:
entity_id: select.foxess_inverter_work_mode
data:
option: Self Use
Dadurch stelle ich sicher, dass die Batterie Platz für den günstigen Sonnenstrom lässt und nicht morgens sofort mit (teurerem) Netzstrom oder der ersten Morgensonne “vollgeknallt” wird, wenn Mittags ein Überschuss droht.
3. E-Auto (ID.Buzz)
Der ID.Buzz wird über den go-eCharger geladen. Hier nutze ich eine Kombination aus volkswagen_we_connect_id Integration zum Starten/Stoppen und MQTT, um die Phasen (1-phasig/3-phasig) am Charger umzuschalten, je nachdem wie viel Überschuss vorhanden ist.
Fazit
Durch die Kombination von Home Assistant und EMHASS ist aus einer “dummen” PV-Anlage ein intelligentes Kraftwerk geworden.
Die Vorteile:
- Kostenersparnis: Die Wärmepumpe läuft bevorzugt, wenn Strom günstig (dynamischer Tarif) oder Sonne da ist.
- Komfort: Das Haus ist warm, wenn wir es brauchen, dank des thermischen Modells im Skript.
- Automatisierung: Ich muss nicht mehr auf Wetter-Apps schauen – das Haus weiß es besser.
Wer tiefere Einblicke in den Code möchte: Die YAML-Dateien liegen auf meinem GitHub (Link einfügen, falls vorhanden).
Habt ihr Fragen zu meiner Config oder EMHASS? Schreibt es in die Kommentare!