Marstek Energy Battery Binding [5.0.0.0;6.0.0.0)

Binding for Marstek energy storage systems (Venus C/D/E series).

more:

Monitor battery status, solar generation, grid power, energy meters, and system operating modes via local network API. Marstek devices communicate with third-party systems over a Local Area Network (LAN). Before using this binding, please ensure that the Marstek device is properly connected to your home network and the Open API feature has been enabled via the Marstek mobile app. Please note that different Marstek models may support only a subset of the commands.

Changelog

Version 0.1

  • initial release
  • programmed and tested with OH 5.0.2

Resources

Snapshot

Source

I have an error at startup:

2026-01-11 11:44:01.201 [ERROR] [Events.Framework                    ] - FrameworkEvent ERROR
org.osgi.framework.BundleException: Could not resolve module: org.openhab.addons.reactor.bundles [319]
  Unresolved requirement: Import-Package: com.google.errorprone.annotations; version="[2.38.0,3.0.0)"; resolution:="optional"
  Unresolved requirement: Import-Package: org.openhab.core.config.discovery; version="[5.0.0,6.0.0)"

	at org.eclipse.osgi.container.Module.start(Module.java:463) ~[org.eclipse.osgi-3.18.0.jar:?]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel$2.run(ModuleContainer.java:1847) ~[org.eclipse.osgi-3.18.0.jar:?]
	at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor$1$1.execute(EquinoxContainerAdaptor.java:136) ~[org.eclipse.osgi-3.18.0.jar:?]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1840) ~[org.eclipse.osgi-3.18.0.jar:?]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1783) ~[org.eclipse.osgi-3.18.0.jar:?]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1745) ~[org.eclipse.osgi-3.18.0.jar:?]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1667) ~[org.eclipse.osgi-3.18.0.jar:?]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1) ~[org.eclipse.osgi-3.18.0.jar:?]
	at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:234) [org.eclipse.osgi-3.18.0.jar:?]
	at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:345) [org.eclipse.osgi-3.18.0.jar:?]

…and when installing Add-on:

2026-01-11 11:58:54.475 [WARN ] [rketplace.MarketplaceBundleInstaller] - The marketplace bundle was successfully installed but doesn’t start: Could not resolve module: org.openhab.addons.reactor.bundles [320]
Unresolved requirement: Import-Package: com.google.errorprone.annotations; version=“[2.38.0,3.0.0)”; resolution:=“optional”
Unresolved requirement: Import-Package: org.openhab.core.config.discovery; version=“[5.0.0,6.0.0)

OpenHab-version: openHAB 4.3.5

This seems to be your issue, as you try to install an openHAB 5.2 SNAPSHOT version.

@acfischer42 You’d better add a version range to the title of this topic, so it will not appear in incompatible openHAB versions for installation.

Thanks for the nudge, done.

Hi, I would like Openhab to send a command to my Marstek Venus E to charge/discharge with a specific capacity. Unfortunately I cannot make this work. Any ideas?

Hi, this is not supported in the current version. I have a beta that needs a bit more testing. PM me if you want to test.

You’ll need to set timers with charging or discharging power set.

@Fdewaele here is the alpha version:

Readme with instructions: openhab-addons/bundles/org.openhab.binding.marstek/README.md at marstek · acfischer42/openhab-addons · GitHub

Please report testing results.

to install, you’ll need to remove the binding in Openhab and then copy this release to the addons folder of openhab. if not working check the permissions. Also a new thing needs to be created as the channels don’t get automatically updated.
One Information I am interested in especially is the frequency of updates you recieve from the battery. (Already with the current version). I am gettting only very sporadic data, but that might be linked to my wifi signal in that area.

Thanks

I am updating the Marstek every 10 seconds with the required energy demand using the PassiveActivate command. Unfortunately, in many cases there is no response, meaning the required energy demand is not updated. Is this related to the binding, or could it be a firmware issue on the Marstek side?

In my setup, the battery SOC and temperature are also not being updated by the binding.

Additionally, I would like to know whether the binding is using Modbus for communication.

2026-01-31 12:57:07.161 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2419 W, countdown=1200 s
2026-01-31 12:57:17.012 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 12:57:27.099 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2207 W, countdown=1200 s
2026-01-31 12:57:37.011 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 12:57:47.158 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1502 W, countdown=1200 s
2026-01-31 12:57:57.012 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 12:58:09.015 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 12:58:17.011 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 12:58:27.207 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1836 W, countdown=1200 s
2026-01-31 12:58:37.011 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 12:58:47.094 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2500 W, countdown=1200 s
2026-01-31 12:58:55.170 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2136 W, countdown=1200 s
2026-01-31 12:59:07.336 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2136 W, countdown=1200 s
2026-01-31 12:59:17.011 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 12:59:29.013 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 12:59:37.011 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 12:59:47.111 [WARN ] [ding.marstek.internal.marstekHandler] - Unexpected response when activating passive mode: {
	"id":	0,
	"src":	"VenusE 3.0-bc2a33601beb",
	"error":	{
		"code":	-32700,
		"message":	"Parse error",
		"data":	403
	}
}
2026-01-31 12:59:55.249 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1836 W, countdown=1200 s
2026-01-31 13:00:07.279 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1836 W, countdown=1200 s
2026-01-31 13:00:17.014 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:00:27.313 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1755 W, countdown=1200 s
2026-01-31 13:00:37.013 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:00:47.115 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2069 W, countdown=1200 s
2026-01-31 13:00:57.014 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:01:07.314 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1611 W, countdown=1200 s
2026-01-31 13:01:17.012 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:01:27.156 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1290 W, countdown=1200 s
2026-01-31 13:01:37.011 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:01:47.073 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2189 W, countdown=1200 s
2026-01-31 13:01:57.014 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:02:07.209 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1566 W, countdown=1200 s
2026-01-31 13:02:17.012 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:02:29.014 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:02:35.403 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2500 W, countdown=1200 s
2026-01-31 13:02:49.013 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:02:57.013 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:03:09.014 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:03:15.066 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1824 W, countdown=1200 s
2026-01-31 13:03:27.359 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1824 W, countdown=1200 s
2026-01-31 13:03:37.013 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:03:49.013 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:03:57.012 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:04:07.163 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2500 W, countdown=1200 s
2026-01-31 13:04:15.332 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2358 W, countdown=1200 s
2026-01-31 13:04:29.015 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:04:35.128 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2186 W, countdown=1200 s
2026-01-31 13:04:47.095 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2186 W, countdown=1200 s
2026-01-31 13:04:55.311 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2206 W, countdown=1200 s
2026-01-31 13:05:07.158 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2206 W, countdown=1200 s
2026-01-31 13:05:17.012 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:05:27.162 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1748 W, countdown=1200 s
2026-01-31 13:05:35.165 [WARN ] [ding.marstek.internal.marstekHandler] - Unexpected response when activating passive mode: {
	"id":	0,
	"src":	"VenusE 3.0-bc2a33601beb",
	"error":	{
		"code":	-32700,
		"message":	"Parse error",
		"data":	403
	}
}
2026-01-31 13:05:47.133 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2224 W, countdown=1200 s
2026-01-31 13:05:55.281 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1119 W, countdown=1200 s
2026-01-31 13:06:09.013 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:06:17.014 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:06:27.077 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-1578 W, countdown=1200 s
2026-01-31 13:06:37.013 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:06:47.129 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-2066 W, countdown=1200 s
2026-01-31 13:06:57.011 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:07:07.144 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-757 W, countdown=1200 s
2026-01-31 13:07:17.011 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:07:27.079 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-740 W, countdown=1200 s
2026-01-31 13:07:37.012 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode
2026-01-31 13:07:47.110 [INFO ] [ding.marstek.internal.marstekHandler] - Successfully activated passive mode with power=-986 W, countdown=1200 s
2026-01-31 13:07:57.011 [WARN ] [ding.marstek.internal.marstekHandler] - No response when activating passive mode

The binding is using the openAPI that Marstek publishes. This is not Modbus.
I also have seen very sporadic answers from the Battery. A friend of mine using direct API calls is reporting the same behaviour, so this might be firmware related. Are you on Wifi or on LAN?

I see some cases where 4 writes are working well in succession, and then again some where there is only one successful. the binding is sending the command, but not receiving a response, not sure how to explain this behaviour honestly. Do you see a difference when using a slower update rate? like 20 sec?

Are you trying to avoid using a P1 meter? It might be simpler to get one of those, as somehow the P1 meter connection seems to be working with the right refresh rates.

I will try using a slower update rate. However, if you want to optimize charging and discharging, a fast update rate is key.

I have connected a LAN cable to make sure that connectivity does not cause any issues.

I’m not sure whether using a P1 meter makes sense, since I want to implement much more intelligence than is possible when steering the Marstek using only P1 data.

I have raised a ticket with Marstek to see whether new firmware could resolve this issue.

I see update issues as well, just wanted to let you know I am working on it. :slight_smile:

updated binding: Release Marstek Binding v0.2.1 - BETA · acfischer42/openhab-addons · GitHub
this is now tested for 10 sec updates, I have not tested it with writing to the battery and the impact to performance. Activate trace logging (via CLI log:set trace org.openhab.binding.marstek) to see more details on the api calls.
The battery API seems to be needing some time. I had to add 1 sec delay between calls to reliaby get answers.
Happy testing and looking forward to more feedback. I am also interested in your advanced plans to control the battery.

You are using the “Marstek Device Open API(Rev 1.0)”?

like:

Yes

Thanks for doing this binding!
I am testing v0.2.1 BETA
I want to use the ModeSelect to switch between Auto and Manual.
I linked in item to the ModeSelect channell and calling in a rule:
items.getItem(“Marstek_Battery_Mode_Select”).sendCommand(“Manual”);
This change the value of the item but nothing at the battery.

Sending “Passive” did not change anything.
Sending “UPS” changed to “Manual” at the battery (also shown in the”Operating Mode”)

I assume I need to specify the scheduling settings for “Manual” as well (as I need to do this sending direct UDP commands) . How to do this in this binding? Ideally it should simply use the currenty configured on of the battery. Do I need to link items to all the relevant channels (e.g. which are they)?

You asked for use cases:
I want to do following: using hourly price info (e.g. aWATTar, Tibber,..) settting “Auto” for the 4 cheapest hours to load from PV (assuming these are also the sunniest ones) and for the 4 expensive hours to discharge (in Auto mode). At all other hours it should neither load nor discharge.

I hope you can find the needed info here. openhab-addons/bundles/org.openhab.binding.marstek/README.md at marstek · acfischer42/openhab-addons · GitHub

Please do comment if this does not work. Happy to get improvements.

You need to set the relevant items for the mode before activating.
I did not find a way to activate with the existing timers. There is also no way to read timers from the battery.

Please share a trace log if there are issues. Do you not see the mode change at all (if items are set) ?

Thanks.

items.getItem(“Marstek_Battery_Enabled”).sendCommand(OFF);
items.getItem(“Marstek_Battery_Weekdays”).sendCommand(“Daily”);
items.getItem(“Marstek_Battery_Start_Time”).sendCommand(“23:58”);
items.getItem(“Marstek_Battery_End_Time”).sendCommand(“23:59”);
items.getItem(“Marstek_Battery_Power”).sendCommand(-2000);
items.getItem(“Marstek_Battery_Activate_Manual_Mode”).sendCommand(ON);
items.getItem(“Marstek_Battery_Mode_Select”).sendCommand(“Manual”); //necessary?

The items are linked to the channels (timeperiod1…).
Above code does not even change the item states.
I activated logging in the CLI (trace org.openhab.binding.marstek)
In the log viewer I see entries for the reading from Marstek (e.g. .GetStatus .GetMode) but no .SetMode,…

items.getItem(“Marstek_Battery_Enabled”).sendCommand(OFF);
needs to be:

items.getItem(“Marstek_Battery_Enabled”).sendCommand(“OFF”);


Now the items are set but in the log this message:
”No enabled time periods found for manual mode”
This is deliberate and should not prevent sending the reuest to change the mode.
Using
items.getItem(“Marstek_Battery_Enabled”).sendCommand(“ON”);
then was successfull.

Wishes:

  1. Allow sending no timeperiod info for “mode=Manual”
    (eg. no params.config.manual_cfg in JSON)
    My direct UDP tests with Marstek Venus E V3 (firmware 147. ) were successfull with this.

  2. Allow sending disabled timeperiods (params.config.manual_cfg.enable=0)

  3. Merge Operating_Status, Mode_Select, Activate_Manual, Active_Passive.
    The needed logic behind should be in the binding code.

thanks