Distributed Energy Optimizer for Home Automation
Project description
HEMM — Distributed Energy Optimizer for Home Automation
Beta. The manifest schema is stable (existing manifests validate unchanged); the constraint vocabulary may still gain types and the solver interface may refine before 1.0. Contributions and code reviews are welcome.
Home Assistant users: see ha-hemm for the HA integration. This repository is the core Python library — no HA dependency, standalone testable.
HEMM optimizes energy consumption across heterogeneous home devices (PV, battery, heat pump, EV charger, hot water) using declarative device manifests and MILP optimization. Each device declares its constraints, cost function, and actions in a JSON manifest; the solver compiles every manifest down to a handful of physics primitives and produces 24-hour power plans in 15-minute slots. Adding a new device type is a manifest, not a code change.
Developer Quick Start
uv venv
uv pip install -e ".[dev]"
make test # unit tests
make ci # lint + type check + test
hemm --help
hemm schema # list manifest types
hemm validate <manifest.json>
hemm sim run <scenario.yaml>
hemm sim compare <scenario_a.yaml> <scenario_b.yaml>
Development Setup
HEMM is developed alongside ha-hemm, the Home Assistant integration. Both repos live under one parent directory:
~/dev/hemm/
├── hemm/ # this repo (core library, PyPI package)
└── ha-hemm/ # HA custom component
The integration uses an editable install of the core during development:
cd ha-hemm
uv pip install -e ../hemm
Architecture
- Declarative manifests — devices describe themselves via a versioned JSON schema (constraints, cost functions, efficiency maps, actuator contracts with expected-outcome verification).
- Primitive component model — every manifest compiles (
to_components()) to a small, fixed set of physics primitives: source, sink, storage, converter, node. The solvers build from these primitives, never from device types, so teaching HEMM a new device means writing a manifest that composes existing primitives — not editing a solver. Apool_pump, for example, plans correctly with zero lines changed in either solver file. - Control classes — each manifest declares
control_class(planned / reactive / passive). Planned devices get full 15-min scheduling; reactive devices follow second-by-second setpoints; passive devices are monitored but never actuated. - Reason annotation — every plan slot carries a
reasonfield (pv_surplus,cheap_grid,constraint,idle,manual,safety_default) explaining why the solver chose that power level. - Two backends, one contract — a central MILP (Pyomo + HiGHS; the default, provably optimal) and a distributed price-iteration backend. Both read the same manifests and build from the same primitives, so device knowledge lives in the manifest layer rather than in either solver — the second backend adds little to maintain. On the standard scenarios the distributed backend now tracks the optimal plan within ~1.2% average cost and converges on all of them; the MILP stays the default because it is exact. See solver-decision for the A/B gate.
- Forecast adapters — pluggable sources for PV and price forecasts (Solcast, Forecast.Solar, template fallback).
- Simulation harness — run scenarios against historical data, compare solver backends, generate Markdown reports.
- No vendor knowledge in core — device quirks belong in HA automations, not here.
Testing
The test suite has 350+ tests across three levels:
- Unit tests cover manifest schema, constraint vocabulary, solver correctness, and forecast adapters. Run with
make testin under 60 seconds. - Slow tests (
-m slow) run multi-day simulations and A/B comparisons between solver backends. - Onboarding scenario tests (
tests/test_onboarding_examples.py) verify that the canonical worked examples in the ha-hemm onboarding guide solve correctly on every commit. If these tests pass, the guide is accurate.
CI runs on Python 3.12 and 3.13 on every push.
Contributing
Issues, pull requests, and code reviews are welcome. The project is in early-access beta — feedback on the manifest schema and constraint vocabulary is particularly useful because those are the interfaces that future manifest types and the HA integration depend on.
See CONTRIBUTING.md for workflow details.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hemm-2026.7.1.tar.gz.
File metadata
- Download URL: hemm-2026.7.1.tar.gz
- Upload date:
- Size: 264.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
700ecf518086a9fa2197227b5494397b6adee6dfff9fb3143a09381e8ee8eeab
|
|
| MD5 |
f2da6f6f626611592be708cd4a22842a
|
|
| BLAKE2b-256 |
f7ce6fa158b4846bd248c21964be299f64b2fbaf08efe452f65522fabaad46f7
|
Provenance
The following attestation bundles were made for hemm-2026.7.1.tar.gz:
Publisher:
release.yml on hemm-ems/hemm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hemm-2026.7.1.tar.gz -
Subject digest:
700ecf518086a9fa2197227b5494397b6adee6dfff9fb3143a09381e8ee8eeab - Sigstore transparency entry: 2144276331
- Sigstore integration time:
-
Permalink:
hemm-ems/hemm@e690b01d20361d59fbcf6ce0032fc2249aae19d0 -
Branch / Tag:
refs/tags/v2026.7.1 - Owner: https://github.com/hemm-ems
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e690b01d20361d59fbcf6ce0032fc2249aae19d0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file hemm-2026.7.1-py3-none-any.whl.
File metadata
- Download URL: hemm-2026.7.1-py3-none-any.whl
- Upload date:
- Size: 63.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d341996945f2c0403ecf99472cf390dc07e24c3fa5632fd5dd618e1b00dca85e
|
|
| MD5 |
864ed10a19d746c144729bab0c534a72
|
|
| BLAKE2b-256 |
62cd745a5ba969faa66d4516f16aa96773bb8383b55befae9f9b21a7d2cde1c5
|
Provenance
The following attestation bundles were made for hemm-2026.7.1-py3-none-any.whl:
Publisher:
release.yml on hemm-ems/hemm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hemm-2026.7.1-py3-none-any.whl -
Subject digest:
d341996945f2c0403ecf99472cf390dc07e24c3fa5632fd5dd618e1b00dca85e - Sigstore transparency entry: 2144276528
- Sigstore integration time:
-
Permalink:
hemm-ems/hemm@e690b01d20361d59fbcf6ce0032fc2249aae19d0 -
Branch / Tag:
refs/tags/v2026.7.1 - Owner: https://github.com/hemm-ems
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e690b01d20361d59fbcf6ce0032fc2249aae19d0 -
Trigger Event:
push
-
Statement type: