EMHASS is the brain of the system: every 15 minutes it calculates when the battery should charge, discharge or rest, and when the hot water may heat up. But it does not control anything itself. This page describes how I use EMHASS with a Deye inverter: how EMHASS gets its data, and how a translation layer of my own (the translator) takes the plan to the Deye.
What EMHASS is and why I chose it is explained in What is EMHASS, and why I use it. Want to start yourself? Follow Installing EMHASS in Home Assistant. This page is about how it is set up in my house.
How Home Assistant reads and controls the Deye
The Deye inverter is not connected to Home Assistant through the cloud, but locally: with the Sunsynk add-on over RS485 (Modbus), via a dedicated USB-to-RS485 adapter. That way Home Assistant reads the battery level and the power, and writes the settings the translator chooses. Why I deliberately leave the cloud alone is explained in Why I control my Dyness Stack 100 locally over Modbus. If a second integration shares the same adapter, you get Errno 11: exclusively lock port.
The configuration
EMHASS (Energy Management for Home Assistant) runs as an add-on and receives a payload every 15 minutes: a package with prices, the solar forecast, the expected load and the current battery level. The configuration itself is almost standard. The interesting choices are in the payload.
| Setting | Value |
|---|---|
| Time step | 15 minutes |
| Battery | 30,720 Wh, 11 kW charge and discharge, 93 % efficiency per direction |
| Window | 20–95 %, target at the end of the horizon 25 % |
| Cost function | profit |
| Deferrable loads | 1 (hot water) |
| Solver timeout | 180 s |
Prices from Tibber, aligned to the current quarter
Tibber provides 96 quarter-hour prices for today and, after 13:00, for tomorrow as well. The payload filters on the current quarter and fills the missing hours with the same quarter index from the last known day.
A classic mistake: filtering on now() instead of the start of the quarter. That put every price one quarter too early.
A 36-hour horizon
With a fixed 24-hour horizon, EMHASS plans an export every evening: whatever is left in the battery at the end of the horizon is worthless in its eyes. As soon as the horizon runs until the next evening, that behaviour disappears and it keeps the battery charged for the morning peak.
I now send 144 steps. 192 turned out to be too heavy for the solver and hit the 180 s timeout. Start with 96 and increase step by step while you watch the calculation time in the log. The full story is in The EMHASS horizon: from 24 to 36 hours.
An export planned 18 hours or more ahead is therefore not a problem. It is rarely carried out: later runs know tomorrow’s prices and hold on to the energy.
Note: the built-in
naiveload forecast only works correctly at exactly 96 steps. With a longer horizon, EMHASS pastes the last N measurements onto the future, and shifts the consumption pattern by exactly the number of extra steps. So send your ownload_power_forecastalong.
A custom load forecast from a buffer
A trigger-based template sensor stores the average base load every 15 minutes: the house without the car, and without the part of the heat pump that EMHASS controls itself. The buffer keeps 49 hours of values in an attribute.
From that, the payload builds the value from 24 hours earlier for every future quarter, or from 48 hours earlier if the 24-hour value still lies in the future. As long as the buffer is not full, or if more than four quarters are missing, everything falls back to 96 steps and EMHASS’s own forecast.
Known limitation: around the switch to winter time, “24 hours earlier” is off by one hour for one day.
The base load has to be clean. What EMHASS learns as consumption determines what it plans. That is why the car is filtered out, and so is the part of the heat pump that EMHASS controls itself. If that goes wrong, EMHASS plans for a house that does not exist. See EMHASS thought my house used 6 kW at night.
Hot water as a deferrable load
A deferrable load is a consumer that EMHASS may shift in time. The 300-litre tank is a buffer; it needs no building model. EMHASS gets one hour at 2.8 kW per day, in blocks of at least 30 minutes and at most three starts.
The payload sends the remaining hours: one hour minus what has already run today, and zero once the tank is warm enough. Without that, the block kept sliding along all day. During the block an automation sets the boiler target to 52 °C, outside it to 45 °C. If the plan is older than 45 minutes, the target stays at 45 °C.
No run without a real SoC
After a Home Assistant restart, the inverter entities only become available after a few minutes. The payload then fell back to a state of charge (SoC) of 50 %, and EMHASS planned from a made-up value. The optimisation now only runs when the SoC is a number greater than zero.
The translator: from EMHASS plan to Deye inverter
The Deye is controlled through six time-of-use blocks, a charge current, a discharge current, an export limit and the choice between Zero Export and Allow Export. EMHASS delivers a power in watts. The translator sits in between and follows a fixed set of rules:
- Every 5 minutes, no sensor triggers, with 3 seconds between writes and dead bands of 2 A, 2 % and 250 W.
- Fresh plan: follow it. Stale plan: safe mode. If the plan is older than 45 minutes: Zero Export, no grid charging, and the battery covers the house down to its floor.
- Export only when EMHASS plans it, with a limit of planned power + 300 W. Solar surplus may always go out. Why: the Deye once exported itself empty.
- No discharging into the car. When the car is charging, the battery may only cover the house; the rest of the car’s power comes from the grid.
- SoC target in steps of 5 %. At 1 % precision the target wobbled every 10 minutes, costing six writes each time.
- Charge current limited to the grid headroom next to a charging car: grid connection minus car minus the house without the car.
- Balancing on Sunday: once a week to 100 %, grid charging only below a price limit, then hold for an hour.
- Floor and ceiling identical in three places: the EMHASS config, the helpers in HA and the translator’s ceiling.
What is not a fault
- Grid import around +20 W. The Deye regulates towards that value, measured by an Eastron SDM630-M grid meter at the main connection. Peaks of ±2 kW for a few seconds are the response to appliances switching.
- The battery supplies about 3 A while the car charges. That is the house, not the car.
- Three steps in the logbook for every Deye write (new, old, new): an optimistic update, the read-back poll and the confirmation.
- “Export solar now, charge the battery later.” EMHASS sometimes plans that when exporting now pays more. The Deye always charges the battery from solar first, so this part of the plan is not carried out.
What I would do differently
- A translator with a safe mode from day one, instead of sending EMHASS output straight to the inverter.
- Export off by default, and only on when the plan asks for it.
- A custom load forecast first, a longer horizon only after that.
- For every setting with a SoC limit, write down straight away in which three other places it lives.
Frequently asked questions about EMHASS and Deye
Can EMHASS control a Deye inverter directly?
No. EMHASS only delivers a plan: a planned battery power in watts per quarter hour. The Deye wants time blocks, charge and discharge currents and an export mode. Something has to translate in between. In my setup that is the translator: a Home Assistant automation that runs every 5 minutes.
What do you need to use EMHASS with a Deye?
A Deye that Home Assistant can read and configure locally, in my case through the Sunsynk add-on over RS485. Plus quarter-hour prices (mine come from Tibber), a solar forecast, a clean base load and a real battery level. Without those four, EMHASS plans on assumptions.
What does the Deye do if EMHASS fails?
Then the plan goes stale. After 45 minutes the translator puts the Deye in a safe mode: Zero Export, no grid charging, and the battery covers the house down to its floor. The house does not notice; you only miss the optimisation.
The incidents behind these lessons are on Lessons from practice (in Dutch for now).
This page contains an affiliate link. As an Amazon Associate I earn from qualifying purchases. The price stays the same for you.
These values apply to one installation. Check them against your own documentation; leave work on 230/400 V to a qualified electrician. Status: October 2026.

