TinyC program for Tasmota · your meter in the language your battery understandsTinyC-Programm für Tasmota · dein Zähler in der Sprache, die dein Akku versteht
A home battery needs to know how much power your house is using right now, so it can feed in just that much (zero feed-in). Most batteries can not read your electricity meter themselves. But almost all of them can work with one of a few well-known energy meters. This program makes your reading head pretend to be one of these meters.
| EcoTracker | The simplest one. The battery asks the device over the network and gets the values back. |
|---|---|
| Shelly Pro 3EM | The meter most batteries know. Our first choice if you are not sure. |
| Shelly Pro EM50 | The Shelly with one channel. Works like the Pro 3EM, but with one power value instead of three phases. |
| Shelly EM Gen3 | The newest Shelly generation. Also sends current, voltage, power factor and frequency per phase. |
Works with batteries from Marstek, Jackery, Growatt (NOAH), Hoymiles and others. For Marstek there is a third option that also coordinates several batteries: the CT002 emulator.
You need: an ESP32, my Tasmota image with TinyC, and a reading head. How to set up the meter is explained on the SML help page.
Ein Stromspeicher muss wissen, wie viel Strom dein Haus gerade braucht, damit er genau so viel einspeisen kann (Nulleinspeisung). Die meisten Akkus können deinen Stromzähler nicht selbst auslesen. Fast alle können aber mit einem von ein paar bekannten Energiezählern zusammenarbeiten. Dieses Programm lässt deinen Lesekopf so tun, als wäre er einer dieser Zähler.
| EcoTracker | Der einfachste. Der Akku fragt das Gerät übers Netzwerk und bekommt die Werte zurück. |
|---|---|
| Shelly Pro 3EM | Der Zähler, den die meisten Akkus kennen. Die erste Wahl, wenn du unsicher bist. |
| Shelly Pro EM50 | Der Shelly mit einem Kanal. Funktioniert wie der Pro 3EM, aber mit einem Leistungswert statt drei Phasen. |
| Shelly EM Gen3 | Die neueste Shelly-Generation. Schickt zusätzlich Strom, Spannung, Leistungsfaktor und Frequenz je Phase. |
Funktioniert mit Akkus von Marstek, Jackery, Growatt (NOAH), Hoymiles und anderen. Für Marstek gibt es eine dritte Möglichkeit, die zusätzlich mehrere Akkus aufeinander abstimmt: den CT002-Emulator.
Du brauchst: einen ESP32, mein Tasmota-Image mit TinyC und einen Lesekopf. Wie du den Zähler einrichtest, steht auf der SML-Hilfeseite.
These reports come from users who still used my older emulator scripts. The TinyC program speaks the same language and does it better, so a battery from this list should also work here. Please tell me about your experience with the TinyC program on GitHub or in the forum.
✅ works · ❌ does not work · – not tested
| Battery | EcoTracker | Shelly | Note |
|---|---|---|---|
| Marstek Jupiter C Plus | ✅ | ✅ | with Regulator tweak |
| Marstek Venus A | ✅ | ✅ | Forum |
| Marstek Venus E V2 / V3 | ✅ | ✅ | Forum; problems reported with 3.0 |
| Marstek B2500 | ✅ | ✅ | UDP port 2220 (depends on firmware); three in parallel |
| Hoymiles MS-A2 | ✅ | ❌ | EcoTracker, Shelly apparently not |
| Hoymiles HiBattery 1920 AC | ✅ | – | Discussion |
| Growatt NOAH 2000 | – | ✅ | Forum |
| Solakon ONE | – | ✅ | UDP port 1010 |
| Indevolt SF2000 | ✅ | – | |
| Ecoflow Stream AC Pro | ✅ | – | |
| Minjet | – | ✅ | Blog comments |
| Jackery Homepower 2000 Ultra | – | ❌ | Shelly impossible; EcoTracker can be tried with the TinyC test |
Several batteries on one emulator also work: 3 Marstek (2× B2500, 1× Venus A) in parallel. For several Marstek batteries the CT002 emulator is the better choice.
Battery and reading head need good Wi-Fi. A Marstek Jupiter C Plus with poor reception found the emulator and lost it again right away. Some batteries also have problems when they and the reading head are connected to different access points or repeaters.
If the battery has problems or the web page feels slow, switch on Power saving off (at the top of the settings page, below the language).
Diese Rückmeldungen kommen von Nutzern, die noch meine älteren Emulator-Scripte benutzt haben. Das TinyC-Programm spricht dieselbe Sprache und macht es besser. Ein Akku aus dieser Liste sollte also auch hier laufen. Erzähl mir gerne von deinen Erfahrungen mit dem TinyC-Programm auf GitHub oder im Forum.
✅ läuft · ❌ läuft nicht · – nicht getestet
| Akku | EcoTracker | Shelly | Hinweis |
|---|---|---|---|
| Marstek Jupiter C Plus | ✅ | ✅ | mit Regleroptimierung |
| Marstek Venus A | ✅ | ✅ | Forum |
| Marstek Venus E V2 / V3 | ✅ | ✅ | Forum; mit 3.0 wurden Probleme gemeldet |
| Marstek B2500 | ✅ | ✅ | UDP-Port 2220 (je nach Firmware); auch 3 parallel |
| Hoymiles MS-A2 | ✅ | ❌ | EcoTracker, Shelly wohl nicht |
| Hoymiles HiBattery 1920 AC | ✅ | – | Diskussion |
| Growatt NOAH 2000 | – | ✅ | Forum |
| Solakon ONE | – | ✅ | UDP-Port 1010 |
| Indevolt SF2000 | ✅ | – | |
| Ecoflow Stream AC Pro | ✅ | – | |
| Minjet | – | ✅ | Blog-Kommentare |
| Jackery Homepower 2000 Ultra | – | ❌ | Shelly unmöglich; EcoTracker kann mit dem TinyC-Test probiert werden |
Mehrere Akkus an einem Emulator gehen auch: 3 Marstek (2× B2500, 1× Venus A) parallel. Für mehrere Marstek-Akkus ist der CT002-Emulator die bessere Wahl.
Akku und Lesekopf brauchen gutes WLAN. Ein Marstek Jupiter C Plus mit schlechtem Empfang fand den Emulator und verlor ihn gleich wieder. Manche Akkus haben auch Probleme, wenn sie und der Lesekopf an verschiedenen Access Points oder Repeatern hängen.
Hat der Akku Probleme oder fühlt sich die Webseite langsam an, schalte Energiesparmodus aus ein (oben auf der Einstellungsseite, unter der Sprache).
Only in slot 0. Tasmota sends the web addresses the battery asks for to slot 0 only.
Use only one emulator per network for the same battery. Two meters answering at the same time confuse a battery more than none.
Nur in Slot 0. Tasmota leitet die Webadressen, nach denen der Akku fragt, nur an Slot 0 weiter.
Nimm für denselben Akku nur einen Emulator im Netz. Zwei Zähler, die gleichzeitig antworten, verwirren einen Akku mehr als gar keiner.
| Mode | EcoTracker, Shelly Pro 3EM, Pro EM50 or EM Gen3. Only takes effect after restarting the program. |
|---|---|
| UDP port | Only for the Pro 3EM: 1010 is the normal Shelly port. A Marstek B2500 expects 2220. If your battery does not find the meter, try this first. For the Pro EM50 (always 2223), the EM Gen3 (always 2222) and the EcoTracker (no UDP) the field is greyed out. |
Which mode does your battery want? If the manual names a supported meter, take that one. Otherwise start with Shelly Pro 3EM, most batteries know it.
The Pro EM50 mode is the newest and the least tested. If you own a real EM50 and can compare, please let me know.
The EM Gen3 mode follows a script that is already in use and works with the Marstek app. Voltage (230 V), power factor (1) and frequency (50 Hz) are fixed values, because an electricity meter does not deliver them. The current is calculated from the power.
| Modus | EcoTracker, Shelly Pro 3EM, Pro EM50 oder EM Gen3. Wirkt erst nach einem Neustart des Programms. |
|---|---|
| UDP-Port | Nur beim Pro 3EM: 1010 ist der normale Shelly-Port. Ein Marstek B2500 erwartet 2220. Findet dein Akku den Zähler nicht, probier das als Erstes. Beim Pro EM50 (immer 2223), beim EM Gen3 (immer 2222) und beim EcoTracker (kein UDP) ist das Feld ausgegraut. |
Welchen Modus will dein Akku? Steht im Handbuch ein unterstützter Zähler, nimm den. Sonst fang mit Shelly Pro 3EM an, den kennen die meisten Akkus.
Der Pro-EM50-Modus ist der neueste und am wenigsten getestete. Hast du einen echten EM50 zum Vergleichen, melde dich gerne.
Der EM-Gen3-Modus folgt einem Script, das schon im Einsatz ist und mit der Marstek-App funktioniert. Spannung (230 V), Leistungsfaktor (1) und Frequenz (50 Hz) sind feste Werte, weil ein Stromzähler sie nicht liefert. Der Strom wird aus der Leistung berechnet.
| Offset [W] | The value the battery aims for, instead of exactly 0 W. A positive value (e.g. 20) means you always buy a few watts, so you do not feed in by accident. A negative value works the other way round. |
|---|---|
| Regulator tweak | Helps a battery that swings up and down. The battery then approaches the target carefully from above and corrects quickly when it goes too far. If your battery already regulates calmly, leave it OFF. |
| Update rate [s] | How often the value is calculated again. 1 s is fine. A slower rate makes everything calmer, but the battery reacts later. |
| Force sending | Only in Shelly mode. Sends the value again and again, even if the battery does not ask. Some batteries regulate better this way, most do not need it. |
The To battery row on the main page shows what the battery really gets, with offset and tweak. Compare it with the power to see what your settings do.
This value is also called PwrSP. With PwrAvg / PwrSP (MQTT) switched on (see Telemetry), it is sent every 5 seconds as stat/<topic>/script/PwrSP. In MQTT Explorer or Home Assistant you find it under stat → <topic> → script. /pwr always delivers it too: {…,"PwrAvg":-217,"PwrSP":-180}.
3 phases is set under Meter on the main settings page. Switched on, the battery also gets the power of each phase. The total is always the value of your meter, and that is what the battery regulates on.
Automatic: the program registers the offset with Home Assistant by itself (MQTT discovery). It appears as a number field on the Tasmota device, you do not have to set anything up. This needs MQTT discovery in Home Assistant (on by default) and Tasmota's standard FullTopic.
You can also change the offset with the command PVEmuOffset <W>. PVEmuOffset without a value shows the current one. Over MQTT: cmnd/<topic>/PVEmuOffset, over HTTP: /cm?cmnd=PVEmuOffset%20-50. The current value is also in tele/<topic>/SENSOR as "PVEmu":{…,"Offset":-50}. Lowest value −200 W.
A value set this way is only kept until the next restart. So an automation can change it as often as it likes without wearing out the flash memory. After a restart, the value saved on the page applies again. The field on the page shows the saved value, the value currently in use is shown right next to it. To keep a value, enter it in the field and press Save.
Without discovery you can create the field yourself in configuration.yaml (replace <topic> with the MQTT topic of your device):
mqtt:
number:
- name: "PV Offset"
unique_id: pv_offset
command_topic: "cmnd/<topic>/PVEmuOffset"
state_topic: "tele/<topic>/SENSOR"
value_template: >-
{% if value_json.PVEmu is defined %}{{ value_json.PVEmu.Offset }}
{% else %}{{ states('number.pv_offset') }}{% endif %}
optimistic: true
min: -200
max: 2000
step: 5
mode: box
unit_of_measurement: "W"
Without MQTT, the same over HTTP:
rest_command:
pv_offset:
url: "http://<ip>/cm?cmnd=PVEmuOffset%20{{ offset }}"
Then call rest_command.pv_offset with offset: -50. Example of an automation that sets a bigger margin at night:
automation:
- alias: "Offset 50 W at night"
triggers:
- trigger: time
at: "22:00:00"
actions:
- action: number.set_value
target:
entity_id: number.pv_offset
data:
value: 50
| Offset [W] | Der Wert, auf den der Akku regelt, statt genau 0 W. Ein positiver Wert (z.B. 20) heißt: Du kaufst immer ein paar Watt und speist nicht aus Versehen ein. Ein negativer Wert wirkt andersherum. |
|---|---|
| Regleroptimierung | Hilft einem Akku, der hoch und runter schwingt. Der Akku nähert sich dann vorsichtig von oben an und korrigiert schnell, wenn er zu weit geht. Regelt dein Akku schon ruhig, lass sie AUS. |
| Update-Rate [s] | Wie oft der Wert neu berechnet wird. 1 s ist gut. Langsamer macht alles ruhiger, aber der Akku reagiert später. |
| Senden erzwingen | Nur im Shelly-Modus. Schickt den Wert immer wieder, auch wenn der Akku nicht fragt. Manche Akkus regeln so besser, die meisten brauchen das nicht. |
Die Zeile An den Akku auf der Hauptseite zeigt, was der Akku wirklich bekommt, mit Offset und Regleroptimierung. Vergleich sie mit der Leistung, dann siehst du, was deine Einstellungen bewirken.
Dieser Wert heißt auch PwrSP. Ist PwrAvg / PwrSP (MQTT) eingeschaltet (siehe Telemetrie), wird er alle 5 Sekunden als stat/<topic>/script/PwrSP gesendet. Im MQTT Explorer oder in Home Assistant findest du ihn unter stat → <topic> → script. /pwr liefert ihn auch immer mit: {…,"PwrAvg":-217,"PwrSP":-180}.
3 Phasen stellst du auf der Haupt-Einstellungsseite unter Zähler ein. Eingeschaltet bekommt der Akku zusätzlich die Leistung jeder Phase. Die Summe ist immer der Wert deines Zählers, und darauf regelt der Akku.
Automatisch: Das Programm meldet den Offset selbst bei Home Assistant an (MQTT-Discovery). Er erscheint als Zahlenfeld am Tasmota-Gerät, du musst nichts einrichten. Dafür muss in Home Assistant die MQTT-Discovery an sein (ist sie standardmäßig) und Tasmota das Standard-FullTopic nutzen.
Du kannst den Offset auch mit dem Befehl PVEmuOffset <W> ändern. PVEmuOffset ohne Wert zeigt den aktuellen an. Per MQTT: cmnd/<topic>/PVEmuOffset, per HTTP: /cm?cmnd=PVEmuOffset%20-50. Der aktuelle Wert steht außerdem in tele/<topic>/SENSOR als "PVEmu":{…,"Offset":-50}. Kleinster Wert −200 W.
Ein so gesetzter Wert gilt nur bis zum nächsten Neustart. Eine Automation darf ihn also beliebig oft ändern, ohne den Flash-Speicher abzunutzen. Nach einem Neustart gilt wieder der auf der Seite gespeicherte Wert. Das Feld auf der Seite zeigt den gespeicherten Wert, rechts daneben steht der gerade benutzte. Soll ein Wert bleiben, trag ihn ins Feld ein und drücke Speichern.
Ohne Discovery kannst du das Feld selbst in der configuration.yaml anlegen (<topic> durch das MQTT-Topic deines Geräts ersetzen):
mqtt:
number:
- name: "PV Offset"
unique_id: pv_offset
command_topic: "cmnd/<topic>/PVEmuOffset"
state_topic: "tele/<topic>/SENSOR"
value_template: >-
{% if value_json.PVEmu is defined %}{{ value_json.PVEmu.Offset }}
{% else %}{{ states('number.pv_offset') }}{% endif %}
optimistic: true
min: -200
max: 2000
step: 5
mode: box
unit_of_measurement: "W"
Ohne MQTT dasselbe per HTTP:
rest_command:
pv_offset:
url: "http://<ip>/cm?cmnd=PVEmuOffset%20{{ offset }}"
Dann rest_command.pv_offset mit offset: -50 aufrufen. Beispiel für eine Automation, die nachts einen größeren Abstand einstellt:
automation:
- alias: "Offset 50 W at night"
triggers:
- trigger: time
at: "22:00:00"
actions:
- action: number.set_value
target:
entity_id: number.pv_offset
data:
value: 50
These are the addresses the battery asks. You can open them in your browser to see what the battery sees.
/v1/json | EcoTracker. Power, smoothed power, power per phase and both energy counters in Wh. |
|---|---|
/rpc/EM.GetStatus | Shelly. Power per phase and total. |
/rpc/Shelly.GetStatus | Shelly. The same plus the energy counters. |
/rpc/EM1.GetStatus | Pro EM50 and EM Gen3. The power of the one channel. |
/rpc/EMData.GetStatus | EM Gen3. Only the energy counters. |
| UDP 1010 / 2220 / 2223 / 2222 | Shelly. The same questions over UDP. 2223 is the Pro EM50, 2222 the EM Gen3. |
{"power":-440,"powerAvg":-217,"agePower":1000,
"powerPhase1":-440,"powerPhase2":0,"powerPhase3":0,
"energyCounterIn":26714950,"energyCounterOut":659775}
Without 3 phases the whole power is on phase 1. That is all a normal meter value gives, and it is exactly what a battery regulating on the total needs.
In the network the device shows up as ecotracker-<mac>, shellypro3em-<mac>, shellyproem50-<mac> or shellyemg3-<mac>, with the MAC address of your ESP.
Das sind die Adressen, die der Akku abfragt. Du kannst sie im Browser öffnen und siehst, was der Akku sieht.
/v1/json | EcoTracker. Leistung, geglättete Leistung, Leistung je Phase und beide Energiezähler in Wh. |
|---|---|
/rpc/EM.GetStatus | Shelly. Leistung je Phase und Summe. |
/rpc/Shelly.GetStatus | Shelly. Dasselbe plus die Energiezähler. |
/rpc/EM1.GetStatus | Pro EM50 und EM Gen3. Die Leistung des einen Kanals. |
/rpc/EMData.GetStatus | EM Gen3. Nur die Energiezähler. |
| UDP 1010 / 2220 / 2223 / 2222 | Shelly. Dieselben Fragen über UDP. 2223 ist der Pro EM50, 2222 der EM Gen3. |
{"power":-440,"powerAvg":-217,"agePower":1000,
"powerPhase1":-440,"powerPhase2":0,"powerPhase3":0,
"energyCounterIn":26714950,"energyCounterOut":659775}
Ohne 3 Phasen liegt die ganze Leistung auf Phase 1. Mehr gibt ein normaler Zählerwert nicht her, und genau das braucht ein Akku, der auf die Summe regelt.
Im Netzwerk meldet sich das Gerät als ecotracker-<mac>, shellypro3em-<mac>, shellyproem50-<mac> oder shellyemg3-<mac>, mit der MAC-Adresse deines ESP.
You can check whether the emulator answers without a battery. Shelly-EcoTracker Tester.ps1 is a small Windows program that asks the same questions as a battery. Right-click it and choose Run with PowerShell.
Enter the IP of your device at the top, then choose:
| Device | Sets the right port: Pro 3EM 1010, Pro 3EM with Marstek B2500 2220, Pro EM50 2223, EM Gen3 2222. The EcoTracker is asked over HTTP. |
|---|---|
| Method | The question to ask. The list fits the chosen device. |
The switch at the very top decides whether the question goes out over UDP or HTTP.
Two more useful functions:
If the tool gets an answer, the emulator works. That does not mean the battery accepts it. If the tool gets values but the app still finds nothing, the problem is the search in the network or the port, not the values.
Ob der Emulator antwortet, kannst du auch ohne Akku prüfen. Shelly-EcoTracker Tester.ps1 ist ein kleines Windows-Programm, das dieselben Fragen stellt wie ein Akku. Rechtsklick darauf und Mit PowerShell ausführen wählen.
Oben die IP deines Geräts eintragen, dann wählen:
| Gerät | Setzt den richtigen Port: Pro 3EM 1010, Pro 3EM mit Marstek B2500 2220, Pro EM50 2223, EM Gen3 2222. Der EcoTracker wird über HTTP gefragt. |
|---|---|
| Methode | Die Frage, die gestellt wird. Die Liste passt zum gewählten Gerät. |
Der Schalter ganz oben entscheidet, ob die Frage über UDP oder HTTP rausgeht.
Zwei weitere nützliche Funktionen:
Bekommt das Testprogramm eine Antwort, funktioniert der Emulator. Das heißt aber nicht, dass der Akku sie annimmt. Kommen im Testprogramm Werte und die App findet trotzdem nichts, liegt es an der Suche im Netzwerk oder am Port, nicht an den Werten.
| Battery finds nothing | Wrong mode or wrong UDP port. In Pro 3EM mode try 2220. Battery and reading head must be in the same network. Guest networks and separate subnets usually do not work. |
|---|---|
| Found, but 0 W | No meter values. Check your meter on the SML help page. |
| Battery swings up and down | Switch on Regulator tweak, or set a slower update rate. An offset of 20–50 W also calms things down. |
| Still feeds into the grid | Raise the offset. The battery always reacts a little later than the meter, the offset makes up for that. |
| Worked, then stopped | Restart the program. After the Wi-Fi reconnects, the device is sometimes no longer found under its meter name. |
| Akku findet nichts | Falscher Modus oder falscher UDP-Port. Im Pro-3EM-Modus 2220 probieren. Akku und Lesekopf müssen im selben Netzwerk sein. Gastnetze und getrennte Teilnetze gehen meistens nicht. |
|---|---|
| Gefunden, aber 0 W | Keine Zählerwerte. Prüfe deinen Zähler mit der SML-Hilfeseite. |
| Akku schwingt hoch und runter | Regleroptimierung einschalten oder eine langsamere Update-Rate einstellen. Ein Offset von 20–50 W beruhigt auch. |
| Speist trotzdem ein | Offset erhöhen. Der Akku reagiert immer etwas später als der Zähler, der Offset gleicht das aus. |
| Ging, geht jetzt nicht mehr | Programm neu starten. Nach einem WLAN-Neuaufbau wird das Gerät manchmal nicht mehr unter seinem Zählernamen gefunden. |