# EMHASS Energy Management — Deye + NordPool Setup Energy Management for Home Assistant (EMHASS) configured for: - **Deye SUN-12K-SG04LP3-EU** hybrid inverter - **32 kWh LiFePO4 battery** - **NordPool LV** spot prices - Self-consumption optimization with price arbitrage --- ## System Overview ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Deye Inverter │ │ Home Assistant │ │ NordPool │ │ (MQTT → HA) │─────▶│ Sensors │◀─────│ Spot Prices │ │ │ │ │ │ (LV zone) │ └─────────────────┘ └────────┬────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ │ EMHASS │ │ (add-on) │ │ │ │ • Day-ahead │ │ optimization │ │ • Battery │ │ scheduling │ │ • Price │ │ arbitrage │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Forecast Sensors │ │ • p_pv_forecast │ │ • p_load_forecast │ │ • p_grid_forecast│ │ • soc_batt_forecast│ └─────────────────┘ ``` --- ## Daily Workflow ### 1. NordPool Price Publication (~14:30 EET/EEST) NordPool publishes next-day spot prices for the LV zone. The `sensor.nordpool_kwh_lv_eur_3_10_021` sensor receives: - `today` — 96 values (15-min resolution) for current day - `tomorrow` — 96 values for next day (once published, typically by 14:30) - `tomorrow_valid` — becomes `true` when prices are available ### 2. EMHASS Automation (14:30 daily) ```yaml trigger: 14:30 ↓ wait: tomorrow_valid == true (timeout 60min) ↓ build: 48-value price list (30-min resolution) = NordPool 15-min prices resampled to 30-min steps (prices already include distribution + VAT — no offset added) read: battery_soc_init = sensor.deye_inverter_mqtt_battery_soc / 100 ↓ POST: /action/dayahead-optim with price list + battery_soc_init ↓ wait: 15 seconds ↓ POST: /action/publish-data ↓ result: Forecast sensors updated with tomorrow's plan ``` ### 3. What EMHASS Optimizes With `costfun: profit` and `set_nodischarge_to_grid: true`: - **Discharge battery** to cover load during expensive hours (sell to yourself) - **Charge battery** from grid during cheap hours (price arbitrage) - **Never export** to grid (`maximum_power_to_grid: 0`) - Maintain SOC between 10%–100%, target 60% end-of-day --- ## Configuration Files ### EMHASS Config (`/addon_configs/5b918bf2_emhass/config.json`) ```json { "hass_url": "http://192.168.66.113:8123", "long_lived_token": "", "costfun": "profit", "optimization_time_step": 30, "historic_days_to_retrieve": 10, "sensor_power_photovoltaics": "sensor.deye_inverter_mqtt_dc_total_power", "sensor_power_load_no_var_loads": "sensor.deye_inverter_mqtt_total_load_power", "maximum_power_from_grid": 16090, "maximum_power_to_grid": 0, "load_cost_forecast_method": "list", "set_use_battery": true, "battery_nominal_energy_capacity": 32000, "battery_charge_power_max": 11000, "battery_discharge_power_max": 11000, "battery_charge_efficiency": 0.96, "battery_discharge_efficiency": 0.96, "battery_minimum_state_of_charge": 0.1, "battery_maximum_state_of_charge": 1.0, "battery_target_state_of_charge": 0.6, "number_of_deferrable_loads": 0 } ``` ### HA Configuration (`/config/configuration.yaml`) ```yaml rest_command: emhass_dayahead_optim: url: http://192.168.66.113:5000/action/dayahead-optim method: POST content_type: application/json body: "{{ body }}" emhass_publish_data: url: http://192.168.66.113:5000/action/publish-data method: POST content_type: application/json ``` ### Automation (`/config/automations.yaml`) Located at the end of automations.yaml — see the file for the full Jinja2 template that: 1. Reads `sensor.nordpool_kwh_lv_eur_3_10_021` `tomorrow` attribute 2. Resamples from 96 values (15-min) to 48 values (30-min) 3. Reads real battery SOC and converts to fraction (`battery_soc_init`) 4. Passes both to EMHASS via `load_cost_forecast` + `battery_soc_init` parameters Note: NordPool prices already include distribution + VAT — no fixed offset is added. --- ## Key Sensors | Role | Entity ID | Notes | |------|-----------|-------| | PV Power | `sensor.deye_inverter_mqtt_dc_total_power` | DC total from strings | | Load Power | `sensor.deye_inverter_mqtt_total_load_power` | House consumption | | Grid Power | `sensor.deye_inverter_mqtt_total_grid_power` | +import / -export | | Battery SOC | `sensor.deye_inverter_mqtt_battery_soc` | % | | Battery Power | `sensor.deye_inverter_mqtt_battery_power` | +discharge / -charge | | NordPool | `sensor.nordpool_kwh_lv_eur_3_10_021` | Spot price EUR/kWh | | PV Forecast | `sensor.p_pv_forecast` | EMHASS output | | Load Forecast | `sensor.p_load_forecast` | EMHASS output | | Grid Forecast | `sensor.p_grid_forecast` | EMHASS output | | SOC Forecast | `sensor.soc_batt_forecast` | EMHASS output — planned end-of-day SOC (always = target 60%) | --- ## Sign Conventions | Sensor | Positive | Negative | |--------|----------|----------| | `battery_power` | Discharging to load | Charging from PV/grid | | `total_grid_power` | Importing from grid | Exporting to grid | | `inverter_l*_power` | Export to grid | Import from grid | --- ## Comparison: Forecast vs Reality ### Template Sensors Created | Sensor | Description | |--------|-------------| | `sensor.battery_soc_forecast_error` | Actual SOC - Forecast SOC (%) | | `sensor.current_hour_price` | Current hour's electricity price (€/kWh) | ### Monitoring Dashboard Add the dashboard card from `dashboard_card.yaml`: 1. Go to **Dashboard** → **Edit** → **Add Card** → **Manual** 2. Paste the YAML content ### Checking Performance **Daily comparison questions:** 1. Did battery charge during cheap hours (00:00–05:00, 12:00–14:00)? 2. Did battery discharge during peak hours (19:00–22:00)? 3. Is `sensor.battery_soc_forecast_error` within ±5%? **If error > 10%:** - Check if Deye inverter is overriding EMHASS decisions - Consider adding enforcement automation (see below) ### History Graph Compare actual vs forecast over time: ```yaml type: history-graph entities: - entity: sensor.deye_inverter_mqtt_battery_soc name: Actual SOC - entity: sensor.soc_batt_forecast name: Forecast SOC hours_to_show: 48 ``` --- ## Adding EV Charging (OpenEVSE) When the EV charger is integrated: 1. **Create a sensor** for EV power (or use OpenEVSE integration): ```yaml # In configuration.yaml sensor: - platform: template sensors: ev_charger_power: friendly_name: "EV Charger Power" value_template: "{{ states('sensor.openevse_current_power') | float(0) * 230 }}" unit_of_measurement: "W" ``` 2. **Create a template sensor** that subtracts EV from total load: ```yaml - platform: template sensors: load_power_no_var_loads: friendly_name: "Load Power (no EV)" value_template: "{{ states('sensor.deye_inverter_mqtt_total_load_power') | float - states('sensor.ev_charger_power') | float(0) }}" unit_of_measurement: "W" ``` 3. **Update EMHASS config**: ```json "sensor_power_load_no_var_loads": "sensor.load_power_no_var_loads", "number_of_deferrable_loads": 1, "nominal_power_of_deferrable_loads": [7400], "operating_hours_of_each_deferrable_load": [6] ``` 4. **Restart EMHASS** --- ## Troubleshooting ### EMHASS logs show "config.json does not exist" The config file must be at: ``` /addon_configs/5b918bf2_emhass/config.json ``` Not at `/homeassistant/config.json` or `/config/config.json`. ### "Shape of passed values is (X, 1), indices imply (48, 1)" Load sensor has insufficient history. EMHASS needs ≥48 data points (24h at 30-min resolution). Either: - Wait for more history to accumulate - Switch to `sensor.deye_inverter_mqtt_total_load_power` (has months of history) ### Check EMHASS status via SSH ```bash ssh root@192.168.66.113 ha addons logs 5b918bf2_emhass | tail -30 ha addons restart 5b918bf2_emhass ``` ### Verify NordPool prices are being passed ```bash curl -s -X POST http://192.168.66.113:5000/action/dayahead-optim \ -H "Content-Type: application/json" \ -d '{"load_cost_forecast": [0.20, 0.19, ...]}' ``` Check logs for: `Passed runtime parameters: {'load_cost_forecast': [...]}` --- ## Files in This Repository | File | Purpose | |------|---------| | `config.json` | EMHASS configuration (deploy to HA) | | `config_emhass.yaml` | Human-readable reference (same config) | | `migration_log.md` | Migration notes from Domoticz | | `README.md` | This file | --- ## References - [EMHASS Documentation](https://emhass.readthedocs.io/) - [EMHASS GitHub](https://github.com/davidusb-geek/emhass) - [Deye Inverter MQTT Integration](https://github.com/kbialek/deye-inverter-mqtt) - [NordPool Integration](https://www.home-assistant.io/integrations/nordpool/)