elli-2-modbus 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- elli_2_modbus-0.1.0/.github/workflows/ci.yml +15 -0
- elli_2_modbus-0.1.0/.github/workflows/publish.yml +19 -0
- elli_2_modbus-0.1.0/.gitignore +8 -0
- elli_2_modbus-0.1.0/LICENSE +21 -0
- elli_2_modbus-0.1.0/PKG-INFO +108 -0
- elli_2_modbus-0.1.0/README.de.md +85 -0
- elli_2_modbus-0.1.0/README.md +85 -0
- elli_2_modbus-0.1.0/docs/enable-modbus.de.md +62 -0
- elli_2_modbus-0.1.0/docs/enable-modbus.md +62 -0
- elli_2_modbus-0.1.0/docs/registers.md +41 -0
- elli_2_modbus-0.1.0/pyproject.toml +45 -0
- elli_2_modbus-0.1.0/src/elli2modbus/__init__.py +24 -0
- elli_2_modbus-0.1.0/src/elli2modbus/__main__.py +3 -0
- elli_2_modbus-0.1.0/src/elli2modbus/charger.py +165 -0
- elli_2_modbus-0.1.0/src/elli2modbus/cli.py +146 -0
- elli_2_modbus-0.1.0/src/elli2modbus/client.py +156 -0
- elli_2_modbus-0.1.0/src/elli2modbus/py.typed +0 -0
- elli_2_modbus-0.1.0/src/elli2modbus/registers.py +78 -0
- elli_2_modbus-0.1.0/src/elli2modbus/simulator.py +124 -0
- elli_2_modbus-0.1.0/tests/test_elli2modbus.py +188 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
jobs:
|
|
4
|
+
test:
|
|
5
|
+
runs-on: ubuntu-latest
|
|
6
|
+
strategy:
|
|
7
|
+
matrix:
|
|
8
|
+
python: ["3.10", "3.11", "3.12", "3.13"]
|
|
9
|
+
steps:
|
|
10
|
+
- uses: actions/checkout@v4
|
|
11
|
+
- uses: actions/setup-python@v5
|
|
12
|
+
with:
|
|
13
|
+
python-version: ${{ matrix.python }}
|
|
14
|
+
- run: pip install -e ".[test]"
|
|
15
|
+
- run: pytest
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Publishes to PyPI when a GitHub release is published.
|
|
2
|
+
# One-time setup on pypi.org: add a "trusted publisher" for this repo and workflow.
|
|
3
|
+
name: Publish
|
|
4
|
+
on:
|
|
5
|
+
release:
|
|
6
|
+
types: [published]
|
|
7
|
+
jobs:
|
|
8
|
+
pypi:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
environment: pypi
|
|
11
|
+
permissions:
|
|
12
|
+
id-token: write
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.13"
|
|
18
|
+
- run: pip install build && python -m build
|
|
19
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Frane Bandov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: elli-2-modbus
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local Modbus TCP control of Elli Charger 2 wallboxes (VW ID. Charger 2, Škoda, CUPRA)
|
|
5
|
+
Project-URL: Homepage, https://github.com/frane/elli-2-modbus
|
|
6
|
+
Project-URL: Issues, https://github.com/frane/elli-2-modbus/issues
|
|
7
|
+
Author: Frane Bandov
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: elli,ev-charger,home-assistant,modbus,volkswagen,wallbox
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Framework :: AsyncIO
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: Home Automation
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Provides-Extra: test
|
|
20
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'test'
|
|
21
|
+
Requires-Dist: pytest>=8; extra == 'test'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# elli-2-modbus
|
|
25
|
+
|
|
26
|
+
**English** | [Deutsch](README.de.md)
|
|
27
|
+
|
|
28
|
+
Python library and CLI for local control of **Elli Charger 2** wallboxes over **Modbus TCP**. No cloud, no EEBUS, and no dependencies.
|
|
29
|
+
|
|
30
|
+
The Home Assistant integration built on it is [ha-elli-2-modbus](https://github.com/frane/ha-elli-2-modbus).
|
|
31
|
+
|
|
32
|
+
## Supported wallboxes
|
|
33
|
+
|
|
34
|
+
Second-generation Elli wallboxes with firmware **R03.004.045.121-elli or newer** (the version that added the Modbus server):
|
|
35
|
+
|
|
36
|
+
- Elli Charger Connect 2, Pro 2, Pro 2 Eichrecht
|
|
37
|
+
- Volkswagen ID. Charger Connect 2 / Pro 2
|
|
38
|
+
- Škoda Charger Connect 2 / Pro 2
|
|
39
|
+
- CUPRA Charger 2 / Pro 2
|
|
40
|
+
|
|
41
|
+
Modbus runs alongside the Elli backend, so the Elli app, OCPP and firmware updates keep working.
|
|
42
|
+
|
|
43
|
+
## Enable Modbus on the wallbox
|
|
44
|
+
|
|
45
|
+
Short version (detailed guide: [docs/enable-modbus.md](docs/enable-modbus.md)):
|
|
46
|
+
|
|
47
|
+
1. Open the charger configuration in a browser at `https://<IP or hostname>`. Alternatively, connect to the wallbox hotspot and open `https://10.0.2.1`. Accept the certificate warning (**Advanced** → continue).
|
|
48
|
+
2. Log in as **Service User** with the service user password from the access data card.
|
|
49
|
+
3. **Software update**: the firmware must be **R03.004.045.121 or newer**.
|
|
50
|
+
4. **Connections → Modbus server**: switch it **on**. Port 502, unit ID 1.
|
|
51
|
+
5. Give the wallbox a fixed IP address (a DHCP reservation in your router).
|
|
52
|
+
6. If something else controls the current, set **Charging management → Charging settings → PV surplus charging** to **off**.
|
|
53
|
+
7. Test: `elli-2-modbus status <ip>`
|
|
54
|
+
|
|
55
|
+
The interface is also available in German, with the same steps: *Verbindungen → Modbus-Server*, *Ladeverwaltung → Ladeeinstellungen*.
|
|
56
|
+
|
|
57
|
+
## CLI
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install elli-2-modbus
|
|
61
|
+
|
|
62
|
+
elli-2-modbus status 192.168.1.50 # read everything
|
|
63
|
+
elli-2-modbus status 192.168.1.50 --json
|
|
64
|
+
elli-2-modbus set-current 192.168.1.50 10 # allow charging with up to 10 A
|
|
65
|
+
elli-2-modbus stop 192.168.1.50 # block charging
|
|
66
|
+
elli-2-modbus set-failsafe 192.168.1.50 0 # what happens when Modbus traffic stops
|
|
67
|
+
elli-2-modbus set-watchdog 192.168.1.50 30
|
|
68
|
+
elli-2-modbus simulate --port 5020 # simulated wallbox for testing
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Without installing, from the repo: `PYTHONPATH=src python3 -m elli2modbus status <ip>`
|
|
72
|
+
|
|
73
|
+
## Library
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from elli2modbus import ElliCharger
|
|
77
|
+
|
|
78
|
+
async with ElliCharger("192.168.1.50") as charger:
|
|
79
|
+
info = await charger.read_info() # layout version, min/max current
|
|
80
|
+
status = await charger.read_status() # state, currents, voltages, power, energy, limits
|
|
81
|
+
if status.vehicle_connected:
|
|
82
|
+
await charger.set_current(10) # 0.1 A resolution
|
|
83
|
+
await charger.stop()
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The library raises three errors: `ModbusConnectionError` when the wallbox cannot be reached, `ModbusExceptionResponse` when it rejects the request, and `ValueError` when a value is out of range.
|
|
87
|
+
|
|
88
|
+
## Things to know
|
|
89
|
+
|
|
90
|
+
- **Watchdog:** if the wallbox sees no Modbus traffic for the watchdog time (default 15 s), it falls back to the failsafe current. Poll faster than that, and set the failsafe current deliberately: 0 stops charging, 6 A or more keeps charging.
|
|
91
|
+
- **Maximum 16 A** over Modbus for now, including the 22 kW variants. Elli has announced 32 A for a future firmware.
|
|
92
|
+
- **No phase switching** over Modbus.
|
|
93
|
+
- Register 261 can report **less than you wrote**, because the wallbox's internal limits take priority. `status.current_limit` shows the limit that is actually in effect.
|
|
94
|
+
- Power is reported as apparent power (VA).
|
|
95
|
+
|
|
96
|
+
Register reference: [docs/registers.md](docs/registers.md).
|
|
97
|
+
|
|
98
|
+
## Development
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
python3 -m venv .venv && . .venv/bin/activate
|
|
102
|
+
pip install -e ".[test]"
|
|
103
|
+
pytest
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The simulator only implements registers from Elli's register list. Undocumented ones (for example Heidelberg's 13, 258, 259) return Modbus exception 2, like the real device.
|
|
107
|
+
|
|
108
|
+
*Not affiliated with Elli or Volkswagen Group Charging GmbH.*
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# elli-2-modbus
|
|
2
|
+
|
|
3
|
+
[English](README.md) | **Deutsch**
|
|
4
|
+
|
|
5
|
+
Python-Bibliothek und Kommandozeilen-Tool, um **Elli Charger 2** Wallboxen lokal über **Modbus TCP** zu steuern. Ohne Cloud, ohne EEBUS und ohne Abhängigkeiten.
|
|
6
|
+
|
|
7
|
+
Die Home-Assistant-Integration dazu ist [ha-elli-2-modbus](https://github.com/frane/ha-elli-2-modbus).
|
|
8
|
+
|
|
9
|
+
## Unterstützte Wallboxen
|
|
10
|
+
|
|
11
|
+
Elli-Wallboxen der zweiten Generation mit Firmware **R03.004.045.121-elli oder neuer** (seitdem gibt es den Modbus-Server):
|
|
12
|
+
|
|
13
|
+
- Elli Charger Connect 2, Pro 2, Pro 2 Eichrecht
|
|
14
|
+
- Volkswagen ID. Charger Connect 2 / Pro 2
|
|
15
|
+
- Škoda Charger Connect 2 / Pro 2
|
|
16
|
+
- CUPRA Charger 2 / Pro 2
|
|
17
|
+
|
|
18
|
+
Modbus läuft parallel zum Elli-Backend. Elli-App, OCPP und Firmware-Updates funktionieren also weiter.
|
|
19
|
+
|
|
20
|
+
## Modbus an der Wallbox aktivieren
|
|
21
|
+
|
|
22
|
+
Kurzfassung (ausführlich: [docs/enable-modbus.de.md](docs/enable-modbus.de.md)):
|
|
23
|
+
|
|
24
|
+
1. Wallbox-Konfiguration im Browser öffnen: `https://<IP oder Hostname>`, oder mit dem Hotspot der Wallbox verbinden und `https://10.0.2.1` öffnen. Die Zertifikatswarnung bestätigen (**Erweitert** → fortfahren).
|
|
25
|
+
2. Als **Service User** mit dem Service-User-Passwort von der Zugangsdatenkarte anmelden.
|
|
26
|
+
3. **Software-Update**: Die Firmware muss **R03.004.045.121 oder neuer** sein.
|
|
27
|
+
4. **Verbindungen → Modbus-Server**: **einschalten**. Port 502, Modbus-ID 1.
|
|
28
|
+
5. Der Wallbox eine feste IP geben (DHCP-Reservierung im Router).
|
|
29
|
+
6. Wenn ein anderes System den Strom regelt: **Ladeverwaltung → Ladeeinstellungen → PV-Überschuss-Laden** auf **PV-Laden aus** stellen.
|
|
30
|
+
7. Testen: `elli-2-modbus status <ip>`
|
|
31
|
+
|
|
32
|
+
Auf Englisch heißen die Menüs *Connections → Modbus server* und *Charging management → Charging settings*.
|
|
33
|
+
|
|
34
|
+
## Kommandozeile
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install elli-2-modbus
|
|
38
|
+
|
|
39
|
+
elli-2-modbus status 192.168.1.50 # alles auslesen
|
|
40
|
+
elli-2-modbus status 192.168.1.50 --json
|
|
41
|
+
elli-2-modbus set-current 192.168.1.50 10 # Laden mit bis zu 10 A freigeben
|
|
42
|
+
elli-2-modbus stop 192.168.1.50 # Laden sperren
|
|
43
|
+
elli-2-modbus set-failsafe 192.168.1.50 0 # Verhalten, wenn der Modbus-Verkehr ausbleibt
|
|
44
|
+
elli-2-modbus set-watchdog 192.168.1.50 30
|
|
45
|
+
elli-2-modbus simulate --port 5020 # simulierte Wallbox zum Testen
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Ohne Installation, direkt aus dem Repo: `PYTHONPATH=src python3 -m elli2modbus status <ip>`
|
|
49
|
+
|
|
50
|
+
## Bibliothek
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from elli2modbus import ElliCharger
|
|
54
|
+
|
|
55
|
+
async with ElliCharger("192.168.1.50") as charger:
|
|
56
|
+
info = await charger.read_info() # Layout-Version, min./max. Strom
|
|
57
|
+
status = await charger.read_status() # Status, Ströme, Spannungen, Leistung, Energie, Grenzen
|
|
58
|
+
if status.vehicle_connected:
|
|
59
|
+
await charger.set_current(10) # Auflösung 0,1 A
|
|
60
|
+
await charger.stop()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Die Bibliothek wirft drei Fehler: `ModbusConnectionError`, wenn die Wallbox nicht erreichbar ist, `ModbusExceptionResponse`, wenn sie die Anfrage ablehnt, und `ValueError`, wenn ein Wert außerhalb des Bereichs liegt.
|
|
64
|
+
|
|
65
|
+
## Gut zu wissen
|
|
66
|
+
|
|
67
|
+
- **Watchdog:** Sieht die Wallbox länger als die Watchdog-Zeit (Standard 15 s) keinen Modbus-Verkehr, fällt sie auf den Failsafe-Strom zurück. Deshalb häufiger abfragen und den Failsafe-Strom bewusst setzen: 0 stoppt das Laden, ab 6 A lädt sie weiter.
|
|
68
|
+
- **Maximal 16 A** per Modbus, auch bei den 22-kW-Varianten. Elli hat 32 A für eine künftige Firmware angekündigt.
|
|
69
|
+
- **Keine Phasenumschaltung** per Modbus.
|
|
70
|
+
- Register 261 kann **weniger zurückmelden als geschrieben**, weil die internen Grenzen der Wallbox Vorrang haben. `status.current_limit` zeigt die Grenze, die tatsächlich gilt.
|
|
71
|
+
- Die Leistung wird als Scheinleistung (VA) gemeldet.
|
|
72
|
+
|
|
73
|
+
Register-Referenz: [docs/registers.md](docs/registers.md).
|
|
74
|
+
|
|
75
|
+
## Entwicklung
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
python3 -m venv .venv && . .venv/bin/activate
|
|
79
|
+
pip install -e ".[test]"
|
|
80
|
+
pytest
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Der Simulator kennt nur die Register aus Ellis Registerliste. Nicht dokumentierte Register (z. B. 13, 258 und 259 von Heidelberg) beantwortet er wie das echte Gerät mit Modbus-Exception 2.
|
|
84
|
+
|
|
85
|
+
*Kein offizielles Projekt von Elli oder der Volkswagen Group Charging GmbH.*
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# elli-2-modbus
|
|
2
|
+
|
|
3
|
+
**English** | [Deutsch](README.de.md)
|
|
4
|
+
|
|
5
|
+
Python library and CLI for local control of **Elli Charger 2** wallboxes over **Modbus TCP**. No cloud, no EEBUS, and no dependencies.
|
|
6
|
+
|
|
7
|
+
The Home Assistant integration built on it is [ha-elli-2-modbus](https://github.com/frane/ha-elli-2-modbus).
|
|
8
|
+
|
|
9
|
+
## Supported wallboxes
|
|
10
|
+
|
|
11
|
+
Second-generation Elli wallboxes with firmware **R03.004.045.121-elli or newer** (the version that added the Modbus server):
|
|
12
|
+
|
|
13
|
+
- Elli Charger Connect 2, Pro 2, Pro 2 Eichrecht
|
|
14
|
+
- Volkswagen ID. Charger Connect 2 / Pro 2
|
|
15
|
+
- Škoda Charger Connect 2 / Pro 2
|
|
16
|
+
- CUPRA Charger 2 / Pro 2
|
|
17
|
+
|
|
18
|
+
Modbus runs alongside the Elli backend, so the Elli app, OCPP and firmware updates keep working.
|
|
19
|
+
|
|
20
|
+
## Enable Modbus on the wallbox
|
|
21
|
+
|
|
22
|
+
Short version (detailed guide: [docs/enable-modbus.md](docs/enable-modbus.md)):
|
|
23
|
+
|
|
24
|
+
1. Open the charger configuration in a browser at `https://<IP or hostname>`. Alternatively, connect to the wallbox hotspot and open `https://10.0.2.1`. Accept the certificate warning (**Advanced** → continue).
|
|
25
|
+
2. Log in as **Service User** with the service user password from the access data card.
|
|
26
|
+
3. **Software update**: the firmware must be **R03.004.045.121 or newer**.
|
|
27
|
+
4. **Connections → Modbus server**: switch it **on**. Port 502, unit ID 1.
|
|
28
|
+
5. Give the wallbox a fixed IP address (a DHCP reservation in your router).
|
|
29
|
+
6. If something else controls the current, set **Charging management → Charging settings → PV surplus charging** to **off**.
|
|
30
|
+
7. Test: `elli-2-modbus status <ip>`
|
|
31
|
+
|
|
32
|
+
The interface is also available in German, with the same steps: *Verbindungen → Modbus-Server*, *Ladeverwaltung → Ladeeinstellungen*.
|
|
33
|
+
|
|
34
|
+
## CLI
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install elli-2-modbus
|
|
38
|
+
|
|
39
|
+
elli-2-modbus status 192.168.1.50 # read everything
|
|
40
|
+
elli-2-modbus status 192.168.1.50 --json
|
|
41
|
+
elli-2-modbus set-current 192.168.1.50 10 # allow charging with up to 10 A
|
|
42
|
+
elli-2-modbus stop 192.168.1.50 # block charging
|
|
43
|
+
elli-2-modbus set-failsafe 192.168.1.50 0 # what happens when Modbus traffic stops
|
|
44
|
+
elli-2-modbus set-watchdog 192.168.1.50 30
|
|
45
|
+
elli-2-modbus simulate --port 5020 # simulated wallbox for testing
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Without installing, from the repo: `PYTHONPATH=src python3 -m elli2modbus status <ip>`
|
|
49
|
+
|
|
50
|
+
## Library
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from elli2modbus import ElliCharger
|
|
54
|
+
|
|
55
|
+
async with ElliCharger("192.168.1.50") as charger:
|
|
56
|
+
info = await charger.read_info() # layout version, min/max current
|
|
57
|
+
status = await charger.read_status() # state, currents, voltages, power, energy, limits
|
|
58
|
+
if status.vehicle_connected:
|
|
59
|
+
await charger.set_current(10) # 0.1 A resolution
|
|
60
|
+
await charger.stop()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The library raises three errors: `ModbusConnectionError` when the wallbox cannot be reached, `ModbusExceptionResponse` when it rejects the request, and `ValueError` when a value is out of range.
|
|
64
|
+
|
|
65
|
+
## Things to know
|
|
66
|
+
|
|
67
|
+
- **Watchdog:** if the wallbox sees no Modbus traffic for the watchdog time (default 15 s), it falls back to the failsafe current. Poll faster than that, and set the failsafe current deliberately: 0 stops charging, 6 A or more keeps charging.
|
|
68
|
+
- **Maximum 16 A** over Modbus for now, including the 22 kW variants. Elli has announced 32 A for a future firmware.
|
|
69
|
+
- **No phase switching** over Modbus.
|
|
70
|
+
- Register 261 can report **less than you wrote**, because the wallbox's internal limits take priority. `status.current_limit` shows the limit that is actually in effect.
|
|
71
|
+
- Power is reported as apparent power (VA).
|
|
72
|
+
|
|
73
|
+
Register reference: [docs/registers.md](docs/registers.md).
|
|
74
|
+
|
|
75
|
+
## Development
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
python3 -m venv .venv && . .venv/bin/activate
|
|
79
|
+
pip install -e ".[test]"
|
|
80
|
+
pytest
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The simulator only implements registers from Elli's register list. Undocumented ones (for example Heidelberg's 13, 258, 259) return Modbus exception 2, like the real device.
|
|
84
|
+
|
|
85
|
+
*Not affiliated with Elli or Volkswagen Group Charging GmbH.*
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Modbus TCP an der Elli Charger 2 aktivieren
|
|
2
|
+
|
|
3
|
+
[English](enable-modbus.md) | **Deutsch**
|
|
4
|
+
|
|
5
|
+
Gilt für Elli Charger Connect 2 / Pro 2 / Pro 2 Eichrecht, VW ID. Charger 2, Škoda Charger 2 und CUPRA Charger 2. Die Weboberfläche der Wallbox gibt es auf Deutsch und Englisch (sie richtet sich nach der Browsersprache). Menünamen stehen unten auf Deutsch, die englische Bezeichnung in Klammern.
|
|
6
|
+
|
|
7
|
+
Du brauchst die **Zugangsdatenkarte**, die bei der Wallbox lag. Darauf stehen WLAN-Name und -Passwort, der Hostname und das **Passwort für den Service User**.
|
|
8
|
+
|
|
9
|
+
## 1. Wallbox-Konfiguration öffnen
|
|
10
|
+
|
|
11
|
+
**Variante A: über das Heimnetz** (Wallbox per LAN oder WLAN verbunden)
|
|
12
|
+
|
|
13
|
+
- Im Browser im selben Netz `https://<Hostname>` (von der Karte) oder `https://<IP der Wallbox>` öffnen. Die IP findest du in der Geräteliste deines Routers.
|
|
14
|
+
|
|
15
|
+
**Variante B: über den Hotspot der Wallbox**
|
|
16
|
+
|
|
17
|
+
- Mit dem WLAN der Wallbox verbinden (SSID und Passwort von der Karte) oder den QR-Code auf der Karte scannen.
|
|
18
|
+
- `https://10.0.2.1` öffnen.
|
|
19
|
+
|
|
20
|
+
Der Browser warnt vor einer unsicheren Verbindung, weil die Wallbox ein selbst signiertes Zertifikat nutzt. Auf **Erweitert** (*Advanced*) klicken und fortfahren.
|
|
21
|
+
|
|
22
|
+
## 2. Als Service User anmelden
|
|
23
|
+
|
|
24
|
+
Rolle **Service User** wählen und das Service-User-Passwort von der Karte eingeben. Der Standard User darf keine Systemeinstellungen ändern.
|
|
25
|
+
|
|
26
|
+
## 3. Firmware prüfen
|
|
27
|
+
|
|
28
|
+
Unter **Software-Update** (*Software update*) steht die installierte Version. Modbus braucht **R03.004.045.121-elli oder neuer**. Ist sie älter, zuerst aktualisieren (Elli-App oder *Software-Update*).
|
|
29
|
+
|
|
30
|
+
## 4. Modbus-Server einschalten
|
|
31
|
+
|
|
32
|
+
**Verbindungen → Modbus-Server** (*Connections → Modbus server*) → **Modbus-Server** einschalten.
|
|
33
|
+
|
|
34
|
+
| Einstellung | Wert |
|
|
35
|
+
|---|---|
|
|
36
|
+
| Port | 502 |
|
|
37
|
+
| Modbus-ID (Unit ID) | 1 |
|
|
38
|
+
|
|
39
|
+
## 5. Feste IP-Adresse vergeben
|
|
40
|
+
|
|
41
|
+
Die IP der Wallbox im Router reservieren (DHCP-Reservierung) oder unter **Verbindungen → Ethernet** (*Connections → Ethernet*) eine statische Adresse eintragen und DHCP ausschalten. Der Client muss im selben lokalen Netz sein; über LTE funktioniert es nicht.
|
|
42
|
+
|
|
43
|
+
## 6. Eigenes PV-Überschussladen der Wallbox ausschalten
|
|
44
|
+
|
|
45
|
+
Wenn ein anderes System den Strom regelt, soll die Wallbox nicht gleichzeitig selbst regeln:
|
|
46
|
+
|
|
47
|
+
**Ladeverwaltung → Ladeeinstellungen → PV-Überschuss-Laden → PV-Laden aus** (*Charging management → Charging settings → PV surplus charging → off*).
|
|
48
|
+
|
|
49
|
+
## 7. Testen
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install elli-2-modbus
|
|
53
|
+
elli-2-modbus status <IP der Wallbox>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Du solltest Ladestatus, Spannungen und Stromgrenze sehen. Bei `cannot connect`: Ist der Modbus-Server an, die IP richtig, und sind beide Geräte im selben Netz?
|
|
57
|
+
|
|
58
|
+
## Gut zu wissen
|
|
59
|
+
|
|
60
|
+
- Modbus läuft **zusätzlich** zum Elli-Backend. Elli-App, OCPP und Firmware-Updates funktionieren weiter.
|
|
61
|
+
- **Watchdog:** Sobald einmal Modbus-Verkehr stattgefunden hat, erwartet die Wallbox regelmäßigen Verkehr (Standard alle 15 s). Bleibt er aus, schaltet sie auf den **Failsafe-Strom**. Den bewusst setzen: `elli-2-modbus set-failsafe <ip> 0` stoppt das Laden, `6` lädt langsam weiter.
|
|
62
|
+
- **Autorisierung:** Modbus setzt die Stromgrenze. Ob ein Ladevorgang zusätzlich RFID oder App-Freigabe braucht, hängt von den Wallbox-Einstellungen ab. Für vollautomatisches Laden in der Elli-App *Sofortladen* (Laden ohne Authentifizierung) aktivieren.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Enabling Modbus TCP on an Elli Charger 2
|
|
2
|
+
|
|
3
|
+
**English** | [Deutsch](enable-modbus.de.md)
|
|
4
|
+
|
|
5
|
+
Applies to Elli Charger Connect 2 / Pro 2 / Pro 2 Eichrecht, VW ID. Charger 2, Škoda Charger 2 and CUPRA Charger 2. The wallbox web interface is available in English and German (it follows the browser language). Menu names below are English, with the German label in brackets.
|
|
6
|
+
|
|
7
|
+
You need the **card with the access data** that came with the wallbox: Wi-Fi SSID and password, hostname, and the **service user password**.
|
|
8
|
+
|
|
9
|
+
## 1. Open the charger configuration
|
|
10
|
+
|
|
11
|
+
**Option A: through your home network** (the wallbox is connected by LAN or Wi-Fi)
|
|
12
|
+
|
|
13
|
+
- In a browser on the same network, open `https://<hostname>` (hostname from the card) or `https://<IP of the wallbox>` (from your router's device list).
|
|
14
|
+
|
|
15
|
+
**Option B: through the wallbox hotspot**
|
|
16
|
+
|
|
17
|
+
- Connect to the wallbox Wi-Fi (SSID and password from the card), or scan the QR code on the card.
|
|
18
|
+
- Open `https://10.0.2.1`.
|
|
19
|
+
|
|
20
|
+
The browser warns about an insecure connection, because the wallbox uses a self-signed certificate. Click **Advanced** (*Erweitert*) and continue.
|
|
21
|
+
|
|
22
|
+
## 2. Log in as Service User
|
|
23
|
+
|
|
24
|
+
Choose the role **Service User** and enter the service user password from the card. The Standard User cannot change system settings.
|
|
25
|
+
|
|
26
|
+
## 3. Check the firmware
|
|
27
|
+
|
|
28
|
+
**Software update** (*Software-Update*) shows the installed version. Modbus needs **R03.004.045.121-elli or newer**. If the version is older, update first (Elli app or *Software update*).
|
|
29
|
+
|
|
30
|
+
## 4. Turn on the Modbus server
|
|
31
|
+
|
|
32
|
+
**Connections → Modbus server** (*Verbindungen → Modbus-Server*) → switch **Modbus server** on.
|
|
33
|
+
|
|
34
|
+
| Setting | Value |
|
|
35
|
+
|---|---|
|
|
36
|
+
| Port | 502 |
|
|
37
|
+
| Unit ID (Modbus ID) | 1 |
|
|
38
|
+
|
|
39
|
+
## 5. Give the wallbox a fixed IP address
|
|
40
|
+
|
|
41
|
+
Reserve the wallbox's IP in your router (DHCP reservation), or set a static address under **Connections → Ethernet** (*Verbindungen → Ethernet*) with DHCP turned off. The client must be on the same local network; this does not work over LTE.
|
|
42
|
+
|
|
43
|
+
## 6. Turn off the wallbox's own PV surplus charging
|
|
44
|
+
|
|
45
|
+
When something else controls the current, the wallbox should not regulate on its own at the same time:
|
|
46
|
+
|
|
47
|
+
**Charging management → Charging settings → PV surplus charging → off** (*Ladeverwaltung → Ladeeinstellungen → PV-Überschuss-Laden → PV-Laden aus*).
|
|
48
|
+
|
|
49
|
+
## 7. Test
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install elli-2-modbus
|
|
53
|
+
elli-2-modbus status <IP of the wallbox>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
You should see the charging state, voltages and the current limit. If you get `cannot connect`, check that the Modbus server is on, the IP is correct and both devices are on the same network.
|
|
57
|
+
|
|
58
|
+
## Good to know
|
|
59
|
+
|
|
60
|
+
- Modbus runs **in addition** to the Elli backend. The Elli app, OCPP and firmware updates keep working.
|
|
61
|
+
- **Watchdog:** once Modbus traffic has started, the wallbox expects regular traffic (default every 15 s). If traffic stops, it switches to the **failsafe current**. Set it deliberately: `elli-2-modbus set-failsafe <ip> 0` stops charging, `6` keeps charging slowly.
|
|
62
|
+
- **Authorization:** Modbus sets the current limit. Whether a session also needs RFID or app authorization depends on the wallbox settings. For fully automatic charging, enable instant charging (charging without authentication) in the Elli app.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Elli Charger 2 Modbus registers
|
|
2
|
+
|
|
3
|
+
Source: Elli "Modbus Register" list v1.0 (15 Oct 2025), valid from firmware R03.004.045.121-elli. Download: <https://www.elli.eco/de/downloads-charger2> → *Modbus Registerliste [EN]*.
|
|
4
|
+
|
|
5
|
+
Elli states that the layout follows the "Ghost" platform implementation from eSystems, which is the Heidelberg/Amperfied layout. In Elli's PDF, footnote numbers are printed directly after the addresses (e.g. `2613` = register 261, footnote 3).
|
|
6
|
+
|
|
7
|
+
Modbus TCP, port 502, unit ID 1. Big-endian, 16-bit registers.
|
|
8
|
+
|
|
9
|
+
## Input registers (FC 0x04)
|
|
10
|
+
|
|
11
|
+
| Reg | Content | Unit / encoding |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| 4 | Register layout version | 0x0100 = 1.0.0 |
|
|
14
|
+
| 5 | Charging state | 2=A1, 3=A2, 4=B1, 5=B2, 6=C1, 7=C2, 8=derating, 9=E, 10=F, 11=ERR |
|
|
15
|
+
| 6, 7, 8 | Current L1, L2, L3 rms | 0.1 A |
|
|
16
|
+
| 9 | PCB temperature | int16, 0.1 °C |
|
|
17
|
+
| 10, 11, 12 | Voltage L1, L2, L3 rms | V |
|
|
18
|
+
| 14 | Power L1+L2+L3 | VA |
|
|
19
|
+
| 15 / 16 | Energy since power-on, high / low word | VAh (high × 65536 + low) |
|
|
20
|
+
| 17 / 18 | Energy since installation, high / low word | VAh |
|
|
21
|
+
| 100 | Hardware max current | A (currently 0..16)¹ |
|
|
22
|
+
| 101 | Hardware min current | A¹ |
|
|
23
|
+
|
|
24
|
+
Register 13 (Heidelberg: external lock) is **not** documented by Elli and is never read.
|
|
25
|
+
|
|
26
|
+
## Holding registers (FC 0x03 read / 0x06 write)
|
|
27
|
+
|
|
28
|
+
| Reg | Content | Unit / range | Default |
|
|
29
|
+
|---|---|---|---|
|
|
30
|
+
| 257 | Modbus master watchdog timeout² | ms, 0 = off | 15000 |
|
|
31
|
+
| 261 | Maximal current command³ | 0.1 A: 0 or 60..160 | |
|
|
32
|
+
| 262 | Failsafe current (on loss of Modbus communication)⁴ | 0.1 A: 0 or 60..160 | |
|
|
33
|
+
|
|
34
|
+
Heidelberg registers 258 (standby) and 259 (remote lock) are **not** documented by Elli.
|
|
35
|
+
|
|
36
|
+
## Footnotes (Elli)
|
|
37
|
+
|
|
38
|
+
1. To correctly support the 22 kW variants, the value ranges will be extended to [0..32] in a future release.
|
|
39
|
+
2. The timer only starts after an initial interaction between client and server (read or write).
|
|
40
|
+
3. Unlike the Amperfied reference implementation, the "MaximalCurrentCommand" value can be further reduced by additional internal limit functions. Writing register 261 sets an active limit; internal automatic limits or other external EMS controls can reduce it further. A read of register 261 always shows the currently valid limit. The maximum will be raised to 32 A for the 22 kW variant.
|
|
41
|
+
4. The value 0 for the error state is not supported. Later, maximum values of 32 A (= 320) will be supported here as well, for the 22 kW variant.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "elli-2-modbus"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Local Modbus TCP control of Elli Charger 2 wallboxes (VW ID. Charger 2, Škoda, CUPRA)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [{ name = "Frane Bandov" }]
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
|
+
dependencies = []
|
|
15
|
+
keywords = ["elli", "wallbox", "ev-charger", "modbus", "home-assistant", "volkswagen"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Framework :: AsyncIO",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Topic :: Home Automation",
|
|
23
|
+
"Typing :: Typed",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/frane/elli-2-modbus"
|
|
28
|
+
Issues = "https://github.com/frane/elli-2-modbus/issues"
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
elli-2-modbus = "elli2modbus.cli:main"
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
test = ["pytest>=8", "pytest-asyncio>=0.23"]
|
|
35
|
+
|
|
36
|
+
[tool.hatch.build.targets.wheel]
|
|
37
|
+
packages = ["src/elli2modbus"]
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
asyncio_mode = "auto"
|
|
41
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
42
|
+
testpaths = ["tests"]
|
|
43
|
+
|
|
44
|
+
[tool.ruff]
|
|
45
|
+
line-length = 100
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Local Modbus TCP control of Elli Charger 2 wallboxes."""
|
|
2
|
+
|
|
3
|
+
from .charger import ChargerInfo, ChargerStatus, ElliCharger
|
|
4
|
+
from .client import (
|
|
5
|
+
ModbusConnectionError,
|
|
6
|
+
ModbusError,
|
|
7
|
+
ModbusExceptionResponse,
|
|
8
|
+
ModbusTcpClient,
|
|
9
|
+
)
|
|
10
|
+
from .registers import ChargingState
|
|
11
|
+
|
|
12
|
+
__version__ = "0.1.0"
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"ChargerInfo",
|
|
16
|
+
"ChargerStatus",
|
|
17
|
+
"ChargingState",
|
|
18
|
+
"ElliCharger",
|
|
19
|
+
"ModbusConnectionError",
|
|
20
|
+
"ModbusError",
|
|
21
|
+
"ModbusExceptionResponse",
|
|
22
|
+
"ModbusTcpClient",
|
|
23
|
+
"__version__",
|
|
24
|
+
]
|