正在載入完整 README。 以下為已儲存的摘錄。
Lokale App für Solaranlagen mit Batteriespeicher, ganz ohne Cloud. OpenAmpere spricht direkt im Heimnetz mit dem Wechselrichter, speichert alle Daten lokal und zeigt sie im Browser an. Auf dem Smartphone lässt sich die Seite zum Home-Bildschirm hinzufügen und verhält sich dann wie eine App. Kein Konto, keine Cloud, keine Abhängigkeit von einem Hersteller-Server. Aus der Demo mit erfundenen Werten. Neu erzeugen mit scripts/screenshots.sh . Unabhängiges Community-Projekt. Hintergrund und rechtliche Hinweise stehen am Ende dieser Seite.檢視完整 README ↗
Deutsch: README.de.md
Website & Demo · FAQ · Source code · Questions · Roadmap · Report a bug · License · Third-party licenses · Security · Contributing · Code of Conduct · Governance
Local app for solar systems with battery storage, no cloud at all.
OpenAmpere talks to the inverter directly on your home network, stores all data locally and shows it in the browser. On a smartphone you can add the page to the home screen, and it then behaves like an app. No account, no cloud, no dependence on a manufacturer's server.
The app's user interface and the website are in German.
Independent community project. Background and legal notes are at the end of this page.
| Device | What OpenAmpere does | Confirmed on a real system? |
|---|---|---|
| FoxESS H3, newer firmware | Monitoring and control. Control is off by default. The new or old register map is detected automatically. | ✅ Monitoring and control confirmed |
| FoxESS H3, older firmware / H3 Smart / H3 Pro | Monitoring and control; with older firmware without the feed-in limit | Not yet confirmed |
| SAJ H2 / HS2 | Monitoring and control. Grid charging through a short charge time slot in the inverter, because SAJ has no remote control that ends by itself. | Monitoring confirmed on a "3P-X E2" (older "Ampere.StoragePro"), control not yet |
| Immersion heater, heat pump (SG-Ready) | Switching on solar surplus via Shelly relays or web addresses. | Not yet confirmed |
| Immersion heater my-PV AC ELWA-E, AC ELWA 2, AC THOR | Continuously variable according to solar surplus, optionally with cheap grid power. | Not yet confirmed |
| Wallbox | Via evcc: monitoring and operation in OpenAmpere, see docs/evcc.md. For many wallboxes evcc requires a paid sponsor token (list). | Not yet confirmed |
| Home Assistant | Dedicated integration: live data and control. Comes with the Home Assistant app, otherwise via HACS, see Installation. | – |
Not yet confirmed means: the support is based on documentation from the manufacturers or the community and is checked with tests and the simulator, but nobody has reported it from a real system yet. It may well work. If you have such a device, help with a device report: in the app, start the diagnostics under Mehr → Diagnose (More → Diagnostics; it only reads and changes nothing), tap Bericht kopieren (Copy report) and paste the report into the device report form. Remove IP addresses, passwords and API keys first. Every report helps to move a row to "confirmed".
The device type is detected automatically. Setup tries all known devices one after another, read-only: FoxESS at device address 247, SAJ at 1 and 2. So you don't need to know the device address or the manufacturer. The connection uses Modbus TCP, default port 502. New drivers are welcome, see src/openampere/drivers/registry.py.
Full list: docs/devices.md, with what is read and controlled per model and what exactly has been confirmed on real hardware.
OpenAmpere runs in one of two ways. Choose one of them: only one OpenAmpere may talk to the inverter.
| Way 1: standalone | Way 2: Home Assistant app | |
|---|---|---|
| Runs on | its own Linux computer with Docker | Home Assistant OS |
| Opens | in the browser, also as an app on the phone | in the sidebar of Home Assistant, and in the browser by IP address |
| Home Assistant | optional: install the integration via HACS | the app brings the integration along: no HACS |
| Updates | in OpenAmpere, at the push of a button or at night | through Home Assistant |
Requirements: a Linux computer on the same network as the inverter (Raspberry Pi with a 64-bit system, NAS, Proxmox …) and Modbus TCP enabled on the inverter. For the battery systems sold by EKD this is already the case; for other devices the installer can take care of it.
1. Install: run in a terminal on the computer:
curl -fsSL https://gr33ndev.github.io/OpenAmpere/install.sh | bash
Prefer to check the script before it runs? Download it with its helpers and SHA256SUMS from the latest release, compare the checksums and then start it. With the helpers next to it, install.sh uses those instead of downloading them:
mkdir openampere-install && cd openampere-install
for f in install.sh updater.sh tailscale.sh SHA256SUMS; do
curl -fsSLO "https://github.com/Gr33ndev/OpenAmpere/releases/latest/download/$f"
done
sha256sum -c SHA256SUMS && bash install.sh
The script installs Docker if needed and asks for the folder (default /opt/openampere), whether it should also set up evcc for a wallbox, and whether you want to use OpenAmpere on the go as well (Tailscale, see Remote access). When run again, the answers are kept. It detects the time zone and a free port by itself. At the end it shows the address of the app. What it does is in scripts/install.sh.
Updates: when a new version is available, the app shows a notice at the top; a tap on Aktualisieren (Update) is all it takes. Under Mehr → Über OpenAmpere (More → About OpenAmpere), updates can also be installed automatically at night. For this, the install script sets up a small helper container (scripts/updater.sh): it has access to Docker, but only reacts to a request file that the app writes into the data folder. It then pulls the new version, starts it and checks that it is running. If it doesn't start, the previous version is restored. The app itself gets no access to Docker. The app checks GitHub for new versions every 6 hours; this can be turned off. If you installed with the script before, run it once more so the helper is added.
2. Set up in the browser: open the displayed address, usually http://<server-ip>:8080, and set a password. A setup wizard searches for the inverter on the home network, or you enter its IP address. It tests the connection and saves it. Values can be viewed on the home network without a password. Changing settings, control commands and data backup require a login.
3. Optional: immersion heater or heat pump. No additional software is needed. Add it in the app under Mehr → Verbindung → Heizstab und weitere Geräte (More → Connection → Immersion heater and other devices).
4. Optional: wallbox. Most wallboxes are controlled by evcc, a separate open-source project. If you answered yes to "Wallbox" in the script, evcc is already running as a second container at http://<server-ip>:7070, and OpenAmpere knows its address. Then:
If evcc is already running elsewhere, enter its address under Mehr → Verbindung → Wallbox. Details are in docs/evcc.md.
A few wallboxes OpenAmpere controls directly, without evcc: so far the portable 11 kW wallbox sold as "dé" (Tuya Wi-Fi). Choose direkt (directly) under Mehr → Verbindung → Wallbox; you need the wallbox's local key from Tuya's developer platform. Step by step: docs/wallbox-direct.md.
Where to find what: under Geräte you operate the battery (backup power reserve, charge limits), wallbox and immersion heater, and set who gets solar power first. Under Mehr you'll find Meine Anlage (with the feed-in limit), Stromtarif (Electricity tariff), Verbindung, Steuerung und Protokoll (Control and log), Benachrichtigungen (Notifications), Zugriffsschutz (Access protection), Darstellung (Appearance), Daten & Sicherung and Diagnose (Diagnostics).
Forgot your password? Run this in a terminal on the server, then set a new password in the app:
cd /opt/openampere && sudo docker compose exec openampere openampere reset-password
If OpenAmpere is in a different folder (for a manual installation, the folder of the repository), replace /opt/openampere with that folder.
The same command is needed when the app says that the database was damaged and your previous password could not be taken over. Until then, nobody can set a new password in the app, so that nobody else in your home network can choose one first.
Problems during setup? See Troubleshooting. How to back up your data, move to a new computer or remove OpenAmpere again is described under Backup and restore, Moving to a new computer and Uninstalling.
Optional. The OpenAmpere integration brings power, energy (suitable for the Energy dashboard), state of charge and status live into Home Assistant, and if you allow it control of the battery, charging from the grid and the immersion heater. It connects to the running OpenAmpere; only OpenAmpere talks to the inverter.
The connection is encrypted, and each app gets its own revocable access. Only what is enabled in OpenAmpere can be controlled. Details: docs/homeassistant.md.
If you want to build it yourself or contribute to development, use the repository instead of the script:
git clone https://github.com/Gr33ndev/OpenAmpere.git openampere && cd openampere
mkdir -p data && sudo chown 1000:1000 data && sudo chmod 700 data
docker compose up -d --build
The app runs in the container as user 1000 and needs write access to data/; nobody else needs to read it (chmod 700, as the install script does). Besides the database, that folder contains secret.key, the key for the stored credentials. Without it, they have to be entered again in the app. evcc for a wallbox is available in docker-compose.yml as a commented-out service, see docs/evcc.md. So is Tailscale for access from anywhere; it needs the folder remote/ outside data/, created first as the comments in docker-compose.yml describe.
Release images are built by the release workflow of this repository and come with a signed build provenance attestation and an SBOM. With the GitHub CLI you can check that an image really was built here:
gh attestation verify oci://ghcr.io/gr33ndev/openampere:<version> --owner Gr33ndev \
--signer-workflow Gr33ndev/OpenAmpere/.github/workflows/release.yml --source-ref refs/tags/v<version>
--signer-workflow makes sure the image was built by the release workflow, not by another workflow of the repository, and --source-ref that this workflow ran for the version tag, not for a branch. <version> is written without the leading v, e.g. 0.10.0 (so --source-ref refs/tags/v0.10.0). In the image name, latest works as well; it is always the highest stable version, and --source-ref then names that version. Pre-releases and versions released later for an older line do not get latest. This works for releases after 0.9.0. The SBOM (the list of packages in the image) is shown by docker buildx imagetools inspect ghcr.io/gr33ndev/openampere:<version> --format '{{ json .SBOM }}'.
The image of the Home Assistant app is built and attested by the same workflow. It has no latest; its version is the one in ha-app/config.yaml:
gh attestation verify oci://ghcr.io/gr33ndev/openampere-ha-app:<version> --owner Gr33ndev \
--signer-workflow Gr33ndev/OpenAmpere/.github/workflows/release.yml --source-ref refs/tags/v<version>
Home Assistant itself does not check this when it installs or updates the app; run the command above if you want to be sure.
The update helper checks this automatically. Before it starts a new version (update button in the app or at night), it verifies the image with cosign against the release workflow of this repository; no account is needed. It does not start an older version than the one running, even a genuine one: older versions can have known flaws (existing installations get this protection by running the install script once more). If the check fails, the new version is not started and the previous one keeps running, with a message in the app. Installations from before 0.10.1 get this helper by running the install script once more. Only for emergencies, OPENAMPERE_VERIFY_IMAGES=nein in the updater service turns the check off.
install.sh, updater.sh and tailscale.sh are attached to every release together with SHA256SUMS. They come with a signed build provenance as well (openampere-<version>.intoto.jsonl); after downloading, gh attestation verify install.sh --repo Gr33ndev/OpenAmpere --signer-workflow Gr33ndev/OpenAmpere/.github/workflows/release.yml --source-ref refs/tags/v<version> checks that a script comes from the release workflow of this repository and from that version. The website serves the scripts of the latest release (with the same SHA256SUMS), so a change on main reaches new installations only with a release.
OpenAmpere is built for the home network. The safest way to reach it on the go is via a VPN.
Easiest with Tailscale: answer yes to the question „von unterwegs nutzen?“ (use on the go?) in the install script, then in the app tap Einrichten (Set up) under Mehr → Zugriff von unterwegs (More → Remote access) and sign in to Tailscale (free account, e.g. with Google, Apple or Microsoft). On your phone, sign in to the Tailscale app with the same account and open the address that OpenAmpere shows.
curl -fsSL https://gr33ndev.github.io/OpenAmpere/install.sh | OPENAMPERE_TAILSCALE=ja bash. With OPENAMPERE_TAILSCALE=nein it is removed again.127.0.0.1 is reachable from the tailnet as well, so share the tailnet only with your own devices or limit access to this machine in the Tailscale ACLs (the install script says so). As with the update helper, the app gets no access to Tailscale; it only drops a request (scripts/tailscale.sh). Sending log data to Tailscale is disabled, and Funnel (public access from the internet) is not used.https://openampere.<tailnet>.ts.net with a certificate from Tailscale (tailscale serve). This needs "HTTPS Certificates" enabled under DNS in the Tailscale admin console; if it is not, the app shows the link to enable it. Installations from before 0.13.0 get this by running the install script once more.Without a third party: the FRITZ!Box VPN (WireGuard) or your own WireGuard server. Then open the app via the server's IP address, just like at home.
Never expose it directly to the internet via port forwarding. Anyone who reaches the app that way can control the inverter as soon as the password is cracked or intercepted (no HTTPS).
Custom hostnames (e.g. a reverse proxy with your own domain on the home network) must be allowed: open OpenAmpere by its IP address and enter them under More → Access protection → Own addresses, or set server.allowed_hosts in data/config.yaml. The reverse proxy must pass on the host name and WebSocket connections (see Behind a reverse proxy). IP addresses, localhost, *.local, *.fritz.box, *.home.arpa and Tailscale names (*.ts.net) work without an entry. Do not use "*" in config.yaml (the app refuses it): it turns off the protection against DNS rebinding, so any website opened in a browser on your home network could read everything OpenAmpere shows without a login, including the live values, and set the password as long as none is set. Enter the names you need instead.
A reverse proxy (nginx, Caddy, Nginx Proxy Manager, Traefik …) has to pass on two things, otherwise the overview keeps saying "Verbinde …" (since #460 the app shows a hint and reads the values every few seconds instead) and saving settings fails with "Anfrage abgelehnt (fremde Herkunft)":
/api/live/ws).For nginx:
location / {
proxy_pass http://192.168.1.50:8080; # the address and port of OpenAmpere
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
In Nginx Proxy Manager switch on Websockets Support for the host. Caddy passes both by itself. Enter the domain under More → Access protection → Own addresses as described above. If it still does not work, the diagnostics report shows a log line "refused a request from origin …" with both host names.
For an automated installation, all values can additionally be preset via data/config.yaml (see config.example.yaml) or via OPENAMPERE_… environment variables. Environment variables take precedence and appear in the app as „fest eingestellt“ (fixed).
For Home Assistant OS (also Home Assistant Supervised). Home Assistant Container has no apps: use way 1 there.
https://github.com/Gr33ndev/OpenAmpere,
Add.Already running OpenAmpere with Docker? Download a backup there and stop it first, then restore the backup in the app: Moving from Docker. The full guide for the app is ha-app/DOCS.md (German: docs/homeassistant-app.de.md).
The app brings the OpenAmpere integration of its version along and installs it itself: no HACS needed. It brings power, energy (suitable for the Energy dashboard), state of charge and status live into Home Assistant, and if you allow it control of the battery, charging from the grid and the immersion heater.
Updates of the app update the integration as well. Control entities are available while control is switched on in OpenAmpere. Had the integration through HACS before? Remove it in HACS and restart the app; from then on the app keeps it up to date.
If another energy manager is also connected to the inverter (e.g. the previous Smartbox), the Modbus access is often shared via a Modbus TCP proxy. OpenAmpere handles this:
Important: the inverter only allows a few simultaneous Modbus connections. If another energy manager (e.g. a previous Smartbox) or another integration is also talking to it, connection drops can occur.
A previous Smartbox fetches its target settings from its manufacturer's cloud roughly every 100 seconds and writes them to the inverter. In doing so, it overwrites changes made by OpenAmpere, for example to the backup power reserve, operating mode or charging from the grid. OpenAmpere detects this, explains it in the app with the steps below and can send a notification „Einstellung überschrieben“ (Setting overwritten).
Remedies:
Whether a previous smartbox controls the system for your grid operator is not confirmed for any installation, but it is possible. Before disconnecting it, check:
If one answer is "yes" or you are unsure, ask your grid operator or your installer before disconnecting the box. Until then it is safer to only block its internet access (see above). This is not legal advice.
The commands in this and the following sections are for an installation with the script in the default folder /opt/openampere. If you chose a different folder, replace /opt/openampere with your folder.
Backup in the app: under Mehr → Daten & Sicherung (More → Data & backup), Datensicherung herunterladen (Download backup) downloads the complete database with all readings and settings as one file (openampere-backup-<date>.db). You need to be logged in for this. Passwords and API keys, for example for evcc, ntfy, the customer portal of the grid operator or the Ampere.IQ import, are not included. Keep the file in another place, for example on your computer or a USB stick.
Backing up everything: all data of OpenAmpere is in the folder data in the installation folder. Besides the database, it contains the file secret.key, the key for the stored passwords and API keys. If you back up this folder, you have everything. In a terminal on the server:
cd /opt/openampere
sudo docker compose stop openampere
sudo tar czf ~/openampere-sicherung.tar.gz data
sudo docker compose start openampere
The file openampere-sicherung.tar.gz is then in your home folder on the server. Copy it to another computer or a USB stick. If you set up evcc with the install script, its configuration is in the folder evcc next to it. Then write data evcc instead of data so that it is backed up as well.
Restore in the app: under More → Data & backup, choose the file from the app at Restore backup. You need to be logged in. OpenAmpere checks the file, keeps your password and the stored login details and then restarts. The previous database is kept as a copy in the data folder. Restored on another computer (without the secret.key of the old one), the local key of a wallbox OpenAmpere controls itself cannot be read: the wallbox keeps its settings and shows Local Key neu eintragen (Enter the local key again) under More → Connection → Wallbox and on the Devices page. Until you enter the key there, OpenAmpere neither reads nor controls it.
Devices with their own switch addresses (under More → Connection → Immersion heater and other devices): their addresses often hold the device's password and are in the backup only encrypted with the secret.key of the old computer. Restored on another computer, the device keeps its settings and shows Schaltadressen neu eintragen (Enter the switch addresses again) there and on the Devices page. Until you enter the addresses for switching on and off again, OpenAmpere does not switch the device, not even off. If it is running, switch it off yourself if needed.
Bring back the whole data folder: if you backed up the data folder as above, copy it back by hand. The file must be in your home folder on the server:
cd /opt/openampere
sudo docker compose stop openampere
sudo mv data data-alt
sudo tar xzf ~/openampere-sicherung.tar.gz
sudo docker compose start openampere
The previous data folder is kept as data-alt. Once everything runs again, you can delete it with sudo rm -r /opt/openampere/data-alt.
You take the whole installation folder with you. It contains the data folder data with secret.key and, if set up, evcc and Tailscale. This way your history, settings and stored passwords are kept.
cd /opt/openampere
sudo docker compose down
sudo tar czf ~/openampere-umzug.tar.gz -C /opt openampere
openampere-umzug.tar.gz to the new computer, for example with a USB stick or with scp ~/openampere-umzug.tar.gz <user>@<new-computer>:.sudo tar xzf ~/openampere-umzug.tar.gz -C /opt
curl -fsSL https://gr33ndev.github.io/OpenAmpere/install.sh | bash
Do not start OpenAmpere on the old computer again afterwards. Otherwise two programs talk to the inverter and disturb each other.
Before you start: settings that OpenAmpere changed on the inverter, such as the backup power reserve, charge limits, operating mode or feed-in limit, are stored by the inverter itself. They stay active after uninstalling, see Safety of control functions. If you want the earlier values back, set them again in the app first. Which values applied before is shown under Mehr → Steuerung und Protokoll (More → Control and log). If you use Laden aus dem Netz (Charging from the grid), switch it off first and wait a few minutes until OpenAmpere has released the inverter's remote control. Devices on a relay that OpenAmpere switched on stay on after uninstalling: set them to Aus (Off) on the Geräte (Devices) page first.
If you want to keep your data, download a backup first (see Backup and restore). Then, in a terminal on the server:
cd /opt/openampere
sudo docker compose down
cd /
sudo rm -r /opt/openampere
This stops OpenAmpere with all helpers and deletes the folder with all readings. Docker itself stays installed. If you used Tailscale, also remove the computer in the Tailscale admin console. In Home Assistant, remove the OpenAmpere integration.
The setup wizard already shows many hints under Gerät wird nicht gefunden? (Device not found?). If that does not help, here are the most common causes. If you need help, report a problem and attach a report from Mehr → Diagnose (More → Diagnostics).
What OpenAmpere is doing and which errors occur is shown in the server messages:
cd /opt/openampere && sudo docker compose logs --tail 100 openampere
With sudo docker compose logs -f openampere, new messages keep coming in; stop with Ctrl+C. Before you share messages publicly, remove IP addresses, serial numbers and other details about your system.
A device answers at this address but does not allow a Modbus connection. Usually Modbus TCP is not turned on or the port is wrong (usually 502; with a Modbus proxy, the port of the proxy). It can also be that another energy manager uses all connections, see below.
The device is reachable but does not answer as expected. Usually the device address is wrong. Normally OpenAmpere tries all known addresses by itself. If that does not work, enter the address in the setup wizard under Erweitert: Gerätetyp, Port, Geräteadresse (Advanced: device type, port, device address) or under Mehr → Verbindung (More → Connection):
If a Modbus proxy sits in between, the device address set in the proxy applies.
A FoxESS H3 (also sold as "Ampere.StoragePro E3") allows only very few Modbus TCP connections at a time. When all are taken, it accepts OpenAmpere's connection and closes it right away. Usually they are taken by another program that reads the inverter (Home Assistant or another smart home system with a Modbus setup of its own, a dashboard with its own collector such as Grafana, a script of your own or a second OpenAmpere installation) or by the previous IQ box. The network search then shows the device as "Modbus-Gerät, gerade belegt" (Modbus device, currently busy), because a busy device can also be a wallbox; the connection test and Mehr → Verbindung (More → Connection) show this message.
On an SAJ (the older "Ampere.StoragePro"; seen on a "3P-X E2") too, the previous IQ box keeps the connection busy all the time, and OpenAmpere cannot connect to the inverter. The message you see may be a different one. Disconnect the IQ box from the network as in step 2 below. OpenAmpere connects a few minutes later.
Go in this order:
Other options:
If the network search shows the inverter with its model and serial number and, at a second address, "Modbus-Gerät, gerade belegt" (Modbus device, currently busy), the second device is usually the wallbox on systems from EKD: the IQ box holds its connection as well while it has power. A wallbox that announces itself in the network is shown as "FoxESS-Wallbox".
The inverter allows only a few Modbus connections at the same time. If another energy manager is connected to the inverter, for example the previous Smartbox, all of them may be in use. Then the connection of OpenAmpere or of the other device keeps dropping. Fix: in the app under Mehr → Verbindung → Erweitert (More → Connection → Advanced), choose Pro Abfrage (Per poll) for Verbindung (Connection) and save. OpenAmpere then connects anew for every poll and releases the connection afterwards. More on this under Running behind a Modbus proxy.
On the batteries sold by EKD, Modbus TCP is already turned on. On other devices, the installer turns it on. If the installer no longer exists, ask another electrician or solar installer near you, or the manufacturer's customer service (FoxESS or SAJ) with the serial number of your device. Do not change anything in the inverter's service menu if you are not sure what the setting does.
OpenAmpere needs a 64-bit system. The command uname -m shows whether yours is one: aarch64 or x86_64 are fine, armv7l or armv6l mean 32 bit. On a Raspberry Pi 3, 4, 5 or Zero 2 W, write "Raspberry Pi OS (64-bit)" to the memory card with Raspberry Pi Imager and then install OpenAmpere again. This erases the memory card, so back up everything you want to keep first. Older models cannot run a 64-bit system.
The install script finds a free port between 8080 and 8099 by itself. If another program takes this port later, OpenAmpere does not start, and the server messages say "address already in use". Then give OpenAmpere another port: open /opt/openampere/docker-compose.yml, for example with sudo nano /opt/openampere/docker-compose.yml. For the service openampere, add a line such as OPENAMPERE_SERVER_PORT: "8081" under environment:, indented like TZ. If there already is such a line, only change the number. Then run the install script again. It takes over the new port and restarts OpenAmpere. You then open the app at the new address.
OpenAmpere includes a simulator for the FoxESS H3.
python -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/python -m openampere.simulator --port 5020 --speed 20
OPENAMPERE_INVERTER_HOST=127.0.0.1 OPENAMPERE_INVERTER_PORT=5020 OPENAMPERE_SERVER_PORT=8089 .venv/bin/python -m openampere
.venv/bin/python -m openampere.demo_data --db data/openampere.db --days 60
The last command is optional and generates demo history data.
Web app with live reload; it forwards the API to port 8089:
cd web && npm install && npm run dev
Tests:
.venv/bin/pytest
The Python dependencies are pinned in requirements.lock (Docker image, with hashes) and requirements-dev.lock (development, CI). Both are generated with uv from pyproject.toml:
scripts/deps.sh
This also generates the license list (THIRD_PARTY_LICENSES.md and the list in the app); everything belongs in the same commit. If something is missing, e.g. in Dependabot PRs, the dependencies.yml workflow regenerates the files and commits them to the same branch. Once a week it upgrades all Python dependencies to the latest allowed versions and opens a pull request for this from the deps/python-updates branch. CI on GitHub checks the tests, web build, Docker build and whether the license list is up to date.
Project site with demo: the landing page lives in site/; the demo is the regular web app, built with VITE_DEMO=1. It simulates a system in the browser (web/src/demo/) and sends nothing to a server. Build and view locally:
scripts/build-site.sh
python3 -m http.server 8090 -d _site
The pages.yml workflow publishes the site to GitHub Pages (once, under Settings → Pages, select "GitHub Actions" as the source). A version tag (v…) publishes the image for x86 and ARM under ghcr.io.
Everything that writes to the inverter is off by default. It is enabled in the app under Mehr → Steuerung und Protokoll (More → Control and log), with a safety confirmation:
Settings such as charge limits, operating mode or feed-in limit are stored by the inverter itself. They remain active even if OpenAmpere is not running or is uninstalled. To undo something, you have to change it again in the app (or have the installer do it).
The same applies to devices on a relay, such as a heat pump or an immersion heater without Modbus: a relay that OpenAmpere switched on stays on while OpenAmpere is stopped or uninstalled. Only adjustable devices are set to 0 W when OpenAmpere stops. Before stopping OpenAmpere, set such devices to Aus (Off) on the Geräte (Devices) page, see docs/devices.md.
Other apps such as Home Assistant can only control via their own access with the permission „Lesen + Steuern“ (Read + control), and only while control is enabled. They cannot change the main switch, test mode or the feed-in limit, and can change battery settings at most six times per hour.
The registers used for writing come from community documentation and have not yet been verified on every device variant. That is why OpenAmpere reads back every written value and reports deviations.
How OpenAmpere came about:
Why it works with EKD systems: OpenAmpere talks directly to the installed inverters. The battery systems sold by EKD as "Ampere.StoragePro E3" are based on the FoxESS H3 series, the older "Ampere.StoragePro" on SAJ H2/HS2. OpenAmpere works just the same with these devices from other sources.
No affiliation with EKD or the manufacturers: OpenAmpere is an independent, unofficial community project. It has no affiliation whatsoever with Energiekonzepte Deutschland GmbH, its insolvency administration, FoxESS, SAJ or Kiwigrid. It was neither commissioned, authorized nor supported by them.
No affiliation with Home Assistant: OpenAmpere, its Home Assistant integration and its Home Assistant app are not affiliated with Home Assistant, the Open Home Foundation or Nabu Casa. They only use the public interfaces of Home Assistant.
Trademarks: "AMPERE", "Ampere.IQ", "Ampere.StoragePro" and all other product and company names mentioned are trademarks or designations of their respective owners. All rights to them naturally remain with those owners. They are mentioned here solely to describe which devices OpenAmpere works with. The project name refers to the ampere, the physical unit.
No third-party code: OpenAmpere contains no code, graphics or text from the Ampere.IQ app. The cloud import exclusively uses the customer API that EKD documented for customers at developer.ekd-solar.de, with the personal key from the respective user's app.
Use at your own risk: OpenAmpere is a free community project without any warranty. It does not replace a qualified electrician. Control functions are switched off by default. Anyone who changes settings on the inverter, in particular the feed-in limit, is personally responsible for complying with the grid connection conditions. Unsuitable settings can put strain on the battery and jeopardize guarantee or warranty claims against the manufacturer, dealer or insolvency administrator. Note down the previous values before you change anything. The notes in the app are not legal advice.
Bug reports, device diagnostics and ideas are welcome – even without programming skills. First an issue, then the pull request; details in CONTRIBUTING.md.
MIT. Notes on the sources and trademarks used are in NOTICE, and the licenses of all bundled open-source components are in THIRD_PARTY_LICENSES.md. This file is generated with scripts/third_party_licenses.py. Please regenerate it when dependencies change.
/api/v1/customer/installation and /api/v1/installation/{id}/now/all/power respond like the previous cloud customer API. Existing tools only need to be pointed at the new address.