EMHASS: a linear programming energy scheduler for Home Assistant
emhass: Energy Management for Home Assistant, is a Python module designed to optimize your home energy interfacing with Home Assistant.
At a glance
- What is it?
- EMHASS is a Python module that turns a Home Assistant household into a linear programming problem, solving for an optimized daily schedule of devices given electricity prices, solar generation and battery storage. It ships on PyPI and Conda, runs as a container, and is versioned with a Docker add-on, but the model only knows about the appliances you configure.
- Who is it for?
- Adopt EMHASS if you run Home Assistant, have a controllable load, a solar array or a battery, and you have real price and forecast data to feed the optimiser, and if you are prepared to declare each device as a controllable appliance.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A household modelled as a linear program
EMHASS stands for Energy Management for Home Assistant, and it is a Python module rather than a Home Assistant integration in the usual sense. The description in the repository is precise: it is an optimization tool designed for residential households that uses a linear programming approach to optimize energy usage.
The inputs are the things that actually determine what a home should do over a day: electricity prices, power generation from solar panels, and energy storage from batteries. The output is an optimized daily schedule for the household's devices.
The interesting choice is the method. A linear program has a specific structure, a set of decision variables, a set of constraints and an objective, and it is solved to optimality. That means the schedule EMHASS produces is not a heuristic that happens to look reasonable. It is the optimum of the problem you configured, subject to the constraints you configured, and the quality of the result is therefore bounded by the quality of your model rather than by the search.
The project describes itself as highly configurable and easy to integrate with Home Assistant and other smart home systems, and it names the case of a household with only a controllable load as a valid target, not just one with solar and storage. The repository topics back this up with energy, home-automation, linear-programming, management, model-predictive-control and optimization, which tells you the family of techniques involved: forecasting, then control, on a rolling horizon.
What the dependency list reveals about the internals
The package manifest is the best available description of the internals, and it is a long one.
The numerical stack is numpy with scipy above it, plus pandas for data handling. Solar forecasting comes from pvlib. The optimiser itself is cvxpy, which means the modelling is done in a modelling language rather than by hand-writing a solver call, and highspy is present as a solver backend. That combination is what lets the model express constraints directly in the code that builds the problem.
The forecasting and storage side uses h5py and tables, which are the HDF5 libraries, so historic and forecast data can be held in columnar files rather than in a database. skforecast is included for the time series forecasting of loads and generation, pytz for time zones, and protobuf for message serialisation.
The serving side is interesting for anyone planning to run this as a service. Both gunicorn and uvicorn are dependencies, along with waitress, quart, aiohttp, websockets, jinja2 and orjson. The presence of a synchronous web server and an async one together suggests both a request-response interface and a push channel. On the storage side for results, influxdb appears, which points at time series persistence of optimisation output.
The package declares itself as requiring Python 3.10 to 3.12, is an operating system independent library, and is classified as a production stable library for developers.
Distribution through PyPI, Conda and a container image
EMHASS is distributed in three ways, and the badges at the top of the repository point at each: PyPI, the davidusb Conda channel, and a GitHub Actions workflow that publishes a Docker image on release.
The container route is the one to look at if you are running Home Assistant on a host rather than inside Home Assistant OS. The Dockerfile is built on the Home Assistant base images, with the target architecture and OS version passed as build arguments, and it supports armhf, amd64, armv7 and aarch64 with a Debian base by default. The image installs uv and then the Python version the project pins, so the interpreter matches the project rather than the base image.
The build has to install a fair number of system libraries, and the reason is visible in the comments: libgfortran5 and the openblas packages for numpy, and a full set of HDF5 development packages for h5py and tables, with a symlink step to fix up the HDF5 include paths afterwards. The image also creates the data and share directories the application expects and runs as a non-root user.
The documented test invocation mounts a config file and a secrets file into the container, and publishes a port so the web interface is reachable:
## docker build -t emhass .
## OR docker build --build-arg TARGETARCH=amd64 -t emhass .
## docker run --rm -it -p 5000:5000 --name emhass-container -v ./config.json:/share/config.json -v ./secrets_emhass.yaml:/app/secrets_emhass.yaml emhassNote the two mounted files. The configuration and the secrets are volumes, not baked into the image, which is the right shape for a service that has to hold credentials for your inverter, your battery and your price provider.
Configuration files, secrets and a data directory
The repository layout is organised around configuration rather than around a package, and the file names are the clearest guide to what the thing expects.
At the top level there is options.json, secrets_emhass(example).yaml, a data/ directory, a scripts/ directory, a deploy_docker.mk makefile and a gunicorn.conf.py. The example secrets file is the important one. It shows that credentials are supplied as a YAML file with a name that ends in (example), which is the conventional way to ship a secret template without shipping the secret, and the Docker run command mounts a file of that name at /app/secrets_emhass.yaml.
The data directory is where the time series live, and the HDF5 dependencies in the manifest are the reason: historic and forecast data is stored in columnar files that h5py and tables read, and skforecast works over them. This matters for sizing. A year of hourly load, price and generation data is small, but it accumulates, and a deployment that never prunes the directory will grow without a mechanism in the project to stop it.
The docs directory holds the guides the repository points to, with a quick start, an installation methods page, a usage guide and a page on Home Assistant automations, plus a development page. The separate install methods documentation matters here, because EMHASS is not only a library you import, it is also something you can run as a service and then drive from Home Assistant automations, and the automations guide is where that division of labour is described.
The Docker add-on and the community around it
EMHASS is not limited to running next to Home Assistant. The repository links a separate EMHASS Add-on repository, and the badges show a Home Assistant community thread alongside it, so the project has a user community rather than being a solo script.
The distinction between the three deployment shapes is the practical thing to understand before adopting it. As a Python module inside Home Assistant, EMHASS is called from automations and the schedule is applied by the automation layer. As a separate service on the network, EMHASS runs its own web server, exposed on a port, and Home Assistant calls into it, which is what the Docker instructions set up. As an add-on, Home Assistant supervises the process.
These have different operational consequences. The in-module approach keeps everything in one process and one configuration, but ties the optimisation to the Home Assistant event loop and its restart behaviour. The separate service decouples them, so a long solve does not block Home Assistant, and so the service can be restarted independently, at the cost of a network hop and a second place to configure.
The maintenance picture supports taking this seriously as a long-term dependency. The recent releases are v0.18.4 from 2026-09-27, v0.18.5 from 2026-10-09 and v0.18.6 from 2026-10-16, a cadence of one or two releases a month. The last push to the repository was on 2026-10-17, the repository is not archived, and the licence is MIT with copyright running from 2021 to 2026.
The model only knows the appliances you declared
The largest limitation is not a bug but a consequence of the approach. An optimiser is only as good as the description of the system it is given. EMHASS schedules the devices you configured as controllable appliances, with their power consumption and their constraints. Anything you did not declare is invisible to it, and it will happily produce a schedule that looks optimal and moves the cost of your unmodelled loads somewhere you did not intend.
That is a common and instructive failure mode in home energy optimisation. A realistic home has a heat pump, a water heater, an electric vehicle charger, a washing machine and a handful of always-on electronics, and the difference between a good schedule and an expensive one is often in the one appliance you left out. The documentation for the configuration is therefore the part to read most carefully, and the community forum is where people compare the models that others built.
The second limitation is the data. The forecasts depend on pvlib for solar, on skforecast for loads, and on whatever source you point the price component at. A forecast of solar generation for a site with trees, chimneys or a future roof extension is wrong in a way no solver can fix, and a price feed that does not reflect your actual tariff makes the optimisation precise about the wrong thing. The third is that the result is only as good as the execution. EMHASS computes a schedule; something still has to switch the devices at the right times, and if Home Assistant is down or a device is unresponsive, the plan and the reality diverge with nothing in the model to record it.
What to use instead, and when each one fits
There are two credible alternatives, and they solve different problems.
The first is writing the schedule by hand in Home Assistant automations, with a helper sensor for the current electricity price. For a single controllable load, a cheap tariff and no battery, this is often the right answer. A few lines of automation do the job, they are easy to read two years later, and they have none of the dependencies that come with an optimisation stack. The cost is that you are optimising one rule at a time, and you are doing the arithmetic in your head.
The second is a commercial energy management system, or a utility or inverter vendor controller. The difference in approach is that those are usually sold around a single device, a specific inverter, or a specific tariff, with the optimisation tuned to that hardware and the vendor responsible for it. EMHASS is vendor neutral and open, it works with whatever Home Assistant already talks to, and it will optimise a mix of solar, storage and loads together, but that also means you own the configuration and the correctness of the model.
There is a third path worth naming, which is the optimisation frameworks themselves. cvxpy and highspy are in the dependency list, so a user who wants a different objective function, a different appliance model or a stochastic formulation writes their own model rather than fighting the configuration. That is the honest dividing line: EMHASS for the case where the default model already matches your home, and the raw stack for the case where it does not.
Editorial conclusion
Adopt EMHASS if you run Home Assistant, have a controllable load, a solar array or a battery, and you have real price and forecast data to feed the optimiser, and if you are prepared to declare each device as a controllable appliance. Do not adopt it as a general Home Assistant add-on that saves money without configuration, since the schedule only covers the devices the model knows about, and do not adopt it if you have no price signal, because the optimisation then has nothing to optimise against. Before you run it, check the Python version constraint, since the package requires Python 3.10 to 3.12, and confirm that your inverter, battery and price provider match the forecasting and control assumptions in your configuration rather than assuming the defaults match your hardware.
Frequently asked questions
What is EMHASS?
EMHASS, Energy Management for Home Assistant, is a Python module that optimizes home energy use with a linear programming approach, taking electricity prices, solar generation and battery storage into account to produce a daily device schedule. It is released on PyPI and Conda, and the licence is MIT.
How do I install EMHASS?
The project documents several installation methods, including PyPI, the davidusb Conda channel and a Docker image built on the Home Assistant base images. The container run command mounts a config file and a secrets file as volumes and publishes a port so the web interface is reachable, and a separate add-on repository provides a supervised Home Assistant option.
Which Python versions does EMHASS support?
The package metadata requires Python 3.10 to 3.12 and marks the project as operating system independent. The container image installs the pinned interpreter with uv rather than using the base image's Python, so the runtime matches the project.
What does EMHASS need from my Home Assistant setup?
It needs the devices you want scheduled to be described as controllable appliances in the configuration, together with price, forecast and storage data. Since the optimizer only acts on the model it is given, appliances you do not declare are not part of the schedule, and the documentation on installation methods and usage is the place to check what your setup supports.
Is EMHASS still being developed?
The repository is not archived and the last push was on 2026-10-17. Recent releases include v0.18.4 on 2026-09-27, v0.18.5 on 2026-10-09 and v0.18.6 on 2026-10-16, and the package metadata classifies it as a production stable library.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/davidusb-geek-emhass)Was this useful?