8000 Add Marstek Venus battery by Chris8er · Pull Request #21487 · evcc-io/evcc · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add Marstek Venus battery #21487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
May 30, 2025
Merged

Add Marstek Venus battery #21487

merged 24 commits into from
May 30, 2025

Conversation

Chris8er
Copy link
Contributor
@Chris8er Chris8er commented May 28, 2025

This PR adds support for the Marstek Venus battery storage system via Modbus TCP.

Changes:

Testing:

  • Tested with Marstek Venus firmware version V151 and PUSR USR-DR134 Modbus TCP gateway.
  • Verified functionality with real hardware (power, SOC, battery modes).

Chris8er added 2 commits May 28, 2025 08:46
Introduce `MarstekVenus` implementation for battery system monitoring and control, including CurrentPower, SoC, and battery mode management. Also, add a template definition for configuration with Modbus TCP parameters.
Copy link
Contributor
@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Chris8er - I've reviewed your changes and they look great!

Here's what I looked at during the review
  • 🟡 General issues: 3 issues found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

8000
@Chris8er
Copy link
Contributor Author

Hinweis: ich habe kaum Erfahrungen in GO, wollte aber gerne den Marstek Venus integriert haben. Lokal läuft es. Habe ich noch etwas vergessen? Schaut bitte mal drüber und sagt Bescheid, wenn noch etwas zu tun ist.

Die Steuerung des Venus erfordert mehrere Modbus Befehle: Steuerung aktivieren, Modus setzen. Danach Steuerung deaktivieren um wieder in den "normal" mode zu kommen.

Chris8er added 5 commits May 28, 2025 09:10
Replaced hardcoded Modbus control values with named constants for better readability and maintainability. Updated associated logic and comments to ensure consistent use of the new constants. Also added `"skiptest"` to the EVCC requirements in the YAML definition.
Replaced WriteMultipleRegisters calls with WriteSingleRegister to simplify register writing logic. This enhances code readability and reduces unnecessary complexity in setting battery modes. Logging improvements were also added to provide clearer status updates.
… holding the battery in place. Explicitly noted the intentional decision not to disable RS485 to prevent the battery from reverting to Normal mode.
@andig
Copy link
Member
andig commented May 28, 2025

Thank you for this PR. Afaikt by a quick look, there‘s nothing special that would require a Go module here. Could this be implemented purely using templates?

@andig andig marked this pull request as draft May 28, 2025 10:00
@andig andig added the devices Specific device support label May 28, 2025
@Chris8er
Copy link
Contributor Author
Chris8er commented May 28, 2025

Thank you for this PR. Afaikt by a quick look, there‘s nothing special that would require a Go module here. Could this be implemented purely using templates?

@andig
Ich bin mit den Templates nicht wirklich vertraut. Sehe ich das richtig, dass sie Generatoren für Konfigurationsabschnitte sind?
Kann man darüber für die Steuerung mehrere Modbus Befehle nacheinander senden (über das Modbus Plguin)? Das ist nötig für die aktive Steuerung.

Ich hatte das Ganze schon mal nur über die Config laufen. Allerdings musste ich für die Steuerung dann einen Umweg über IO Broker Script über HTTP Plugin in EVCC gehen.

Um genau zu sein: ich wüsste nicht wie ich die Logik in SetBatteryMode in einem Template abbilden könnte.

@andig
Copy link
Member
andig commented May 28, 2025

Kann man darüber für die Steuerung mehrere Modbus Befehle nacheinander senden

Ja, dafür gibts das sequence Plugin.

Removed the Go-based Marstek Venus meter implementation, replacing it with an enhanced YAML-based custom configuration template. The new template simplifies configuration, adds battery-mode handling, and improves flexibility with support for additional parameters and mappings.
@Chris8er
Copy link
Contributor Author

Kann man darüber für die Steuerung mehrere Modbus Befehle nacheinander senden

Ja, dafür gibts das sequence Plugin.

Ah das kannte ich noch nicht. Habs angepasst und lokal getestet. Noch was zu tun?

Chris8er added 3 commits May 28, 2025 15:58
    Updated the scale value from 1 to 0.01 in the Marstek Venus YAML template. This correction ensures accurate decoding of the total charging energy value from Modbus data.
@Chris8er Chris8er marked this pull request as ready for review May 28, 2025 14:18
Copy link
Contributor
@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Chris8er - I've reviewed your changes - here's some feedback:

  • Consider pulling the hard‐coded control codes (e.g. 21930, 21947) and the fixed 2500 W charge power into named parameters or constants to improve readability and configurability.
  • The template defines an energy measurement at register 33000, but the PR description and code only mention power, SOC, and mode—please confirm the implementation supports energy or remove it from the template.
  • Factor out the repeated RS485 Enable/Disable sequence into a shared step or helper to reduce duplication across the three battery modes.
Here's what I looked at during the review
  • 🟢 General issues: all looks good
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@Chris8er
Copy link
Contributor Author

Hey @Chris8er - I've reviewed your changes - here's some feedback:

  • Consider pulling the hard‐coded control codes (e.g. 21930, 21947) and the fixed 2500 W charge power into named parameters or constants to improve readability and configurability.
  • The template defines an energy measurement at register 33000, but the PR description and code only mention power, SOC, and mode—please confirm the implementation supports energy or remove it from the template.
  • Factor out the repeated RS485 Enable/Disable sequence into a shared step or helper to reduce duplication across the three battery modes.

Here's what I looked at during the review
Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

  • Hm ich glaube die register und values konfigurierbar zu machen ist keine gute Idee.
  • Habe die Description angepasst.
  • Ich wüsste nicht wie ich shared steps anlegen kann. Ich glaube das kann man aber auch so lassen.

Introduced `charge_power` and `work_mode_normal` parameters to allow customization of charge power and work mode settings. Updated Modbus write operations to use these parameters dynamically instead of hardcoded values. Improved flexibility for different deployment scenarios.
Chris8er and others added 3 commits May 28, 2025 17:29
Co-authored-by: andig <cpuidle@gmail.com>
Co-authored-by: andig <cpuidle@gmail.com>
Corrected an erroneous space in the variable reference `{{ . maxchargepower }}` to `{{ .maxchargepower }}`. This ensures proper rendering and functionality in the template.
@andig
Copy link
Member
andig commented May 28, 2025

Do we need all these timeouts and delays? If not, please remove. Go version didn't have them?

The `timeout` and `delay` parameters were removed from multiple modbus register definitions in the `marstek-venus.yaml` file. These parameters were either unnecessary or handled elsewhere, simplifying the configuration. This change helps reduce potential configuration errors and improves maintainability.
@Husches88
Copy link

The LilyGo is connected to the RS485 port on the Marstek Venus E and provides all the necessary data in Home Assistant (i think with MQTT). However, EVCC cannot use it.

@andig
Copy link
Member
andig commented Jun 1, 2025

If LilyGo is a Modbus converter you can use it. If not... not. You can still create a "custom" meter to integrate data over MQTT.

@Tunestwo
Copy link
Tunestwo commented Jun 1, 2025

If I read it correct i first need a modbuss that i can use over wifi? The setup in evcc asks for the ipadress, of the marstek or the modbuss?

@DanielGlaas
Copy link

If I read it correct i first need a modbuss that i can use over wifi? The setup in evcc asks for the ipadress, of the marstek or the modbuss?

The same question do I also have.
The readme https://docs.evcc.io/docs/devices/meters#marstek-venus-battery-storage does not tell something about an additional device that is needed. This should be improved.

The first stats that a device called "PUSR USR-DR134 Modbus TCP gateway" shall be used. However, this is not a unique name/brand to order.

@Chris8er
Copy link
Contributor Author
Chris8er commented Jun 4, 2025

The evcc documentation specifies that the Marstek Venus battery storage connects via RS485, which can be interfaced using various methods like a TCP Ethernet gateway, TCP WiFi gateway, or a USB-to-RS485 adapter, depending on your setup. The PUSR USR-DR134 Modbus TCP gateway is mentioned as an example (got mine from Amazon), but any compatible RS485-to-TCP gateway should work. However, since evcc supports multiple hardware configurations, I think the docs likely avoid being overly prescriptive to allow flexibility.

@DanielGlaas
Copy link

Well, I agreed that the docs mentions RS485 and that - if you are familiar with this - it is clear that an additional device is needed.

However, all other devices I integrated in my setup worked directly with using their local IP address for the host parameter. So the point, that this is not the case for the Marstek Venus was quite surprisingly for me, not having being familiar with the meaning of the term RS485.

@heithomas
Copy link

@Chris8er I have an Marstek Venus E und just received an "PUSR Din Rail “Lipstick” RS485 zu Ethernet Server für serielle Geräte Modbus Gateway Modbus RTU nach Modbus TCP Rich Protocols USR-DR134". I would assume that matches the Hardware you used. I now recognized, that the ModBus Connector cable delivered by Marstek is not compatible with the connector on the lipstick, so I assume I have to remove the connector from the Marstek cable and insert the cables directly in the connector of the Lipstick. From the number of cables it should work, but I'm unsure about the order, because I did not found any documentation from the Marstek ModBus Connector. There are just 5 cables (from left to right: red, black, black, red, yellow) and I don't know how to connect.
The PUSR Modbus connector has a description which says from left to right: DCS5-24V + - (assume the first 2 are power connectors), RX A- TX B - GND.
Any suggestion?

@Chris8er
Copy link
Contributor Author
Chris8er commented Jun 5, 2025

I'm not part of the evcc team and can't speak for them. Your issue is hardware-specific and beyond evcc's scope, as it only requires RS485 for the Marstek Venus E. The rest is your responsibility. Modbus isn't as straightforward as web APIs, so some technical knowledge is needed, and since it's not plug-and-play, proceed carefully to avoid issues.

Having faced the same challenge connecting the PUSR USR-DR134, I can share a tip. Refer to this post for wiring details (the image shows the connector from the back not front). I cut the white connector from the Marstek cable and wired it directly to the PUSR. Since Marstek's cable colors may vary across batches, use a multimeter to verify the pin connections before wiring.

In my case it was:

Yellow -> A
Red -> B

Black -> Data GND
Middle black -> +5DC
Red -> GND

Use this information carefully and at your own risk.

F438

@DanielGlaas
Copy link

@Chris8er: Your last reply was very helpful!

I now managed to include my Marstek Venus E into evcc with this device: https://www.amazon.de/dp/B09PD5ZD56/

@DanielGlaas
Copy link

I have an additional question.

I interprete the code in line 60 (https://github.com/evcc-io/evcc/pull/21487/files#diff-061f0ffca5472bbfa10184a4f4fe0c29ce3bf98874a73f77c1e3a8fe25fd96d5R60) such that evcc is able to control the charging value of the Marstek battery. A variable names batterymode is mentioned, but I don't know what to do to enable/use it.
batterymode appears in the docs only at one place, which is not helpful for me: https://docs.evcc.io/docs/devices/meters#manuell

@heithomas
Copy link

@DanielGlaas I'm pretty confident, that this is only the setting for the work mode, this does not control the charging in a narrow sense, only work mode: Work mode für Normal-Modus. 0 manuell, 1 Eigenverbrauch, 2 AI-Optimierung. This can be set in the configuration of the battery
From explanation somewhere above I do understand, that evcc only controls the charging of the CAR dependent of the status and the setting of the battery, but the battery itself works independent and just tries to balance charge/discharge to keep the accumulated power (of all phases) value at 0 (if setting of Venus is = 1 Eigenverbrauch and connected with a meter) until it's fully charged/discharged

@beebee
Copy link
beebee commented Jun 6, 2025

I have an additional question.

I interprete the code in line 60 (https://github.com/evcc-io/evcc/pull/21487/files#diff-061f0ffca5472bbfa10184a4f4fe0c29ce3bf98874a73f77c1e3a8fe25fd96d5R60) such that evcc is able to control the charging value of the Marstek battery. A variable names batterymode is mentioned, but I don't know what to do to enable/use it. batterymode appears in the docs only at one place, which is not helpful for me: https://docs.evcc.io/docs/devices/meters#manuell

the batterymode definitions enable how evcc can use the active battery control on the device: https://docs.evcc.io/en/docs/features/battery#active-battery-control

For some you might need to enable experimental mode in the UI config. So it should be possible to grid load the device on cheap prices with by evcc via UI menu for HomeBattery/Grid Charging Tab also. (batterymode 3 / "Charge")

@DanielGlaas
Copy link

@DanielGlaas I'm pretty confident, that this is only the setting for the work mode, this does not control the charging in a narrow sense,

Well, in the code for case 3, there are three subsequent modbus write commands:

  • RS485 Control Mode = Enabled
  • Force Charge/Discharge = Charge
  • Forcible Charge Power

For me, this looks the battery charging is controlled by evcc.

@DanielGlaas
Copy link

I have an additional question.
I interprete the code in line 60 (https://github.com/evcc-io/evcc/pull/21487/files#diff-061f0ffca5472bbfa10184a4f4fe0c29ce3bf98874a73f77c1e3a8fe25fd96d5R60) such that evcc is able to control the charging value of the Marstek battery. A variable names batterymode is mentioned, but I don't know what to do to enable/use it. batterymode appears in the docs only at one place, which is not helpful for me: https://docs.evcc.io/docs/devices/meters#manuell

the batterymode definitions enable how evcc can use the active battery control on the device: https://docs.evcc.io/en/docs/features/battery#active-battery-control

For some you might need to enable experimental mode in the UI config. So it should be possible to grid load the device on cheap prices with by evcc via UI menu for HomeBattery/Grid Charging Tab also. (batterymode 3 / "Charge")

@beebee Thanks for the link to the docs. But it does not explain the three modes of batterymode.

To be honest, it still is not clear to me what I have to do.

@Chris8er
Copy link
Contributor Author
Chris8er commented Jun 7, 2025

Clicking "Battery" in the EVCC menu allows you to configure your battery to charge from the grid (scheduled). This disables discharging and charges the battery at the specified power level (config). The code is used for that.

The "work_mode_normal" option in the Venus EVCC settings determines the mode that Venus returns to after being locked by EVCC vehicle fast charge.

@tjahebro1
Copy link
tjahebro1 commented Jun 9, 2025

@DanielGlaas : How did you setup the Elfin Device?

When implementing the Code in the evcc.yaml with the dedicated adresses it computes error message as it seems, that it cannot access the tcp-server:

21:12:17.703778489 +0200 CEST m=+1481.251765055 !! 3013ms read failed: read tcp 192.168.188.80:40902->192.168.188.114:502: i/o timeout

in the evcc.yaml:

  • name: my_battery
    type: template
    template: marstek-venus
    usage: battery
    modbus: rs485tcpip
    id: 1
    host: 192.168.188.114 # Hostname
    port: 502 # Port

in general the communication is working with modbus in homeassistant... :-?

@DanielGlaas
Copy link

Clicking "Battery" in the EVCC menu allows you to configure your battery to charge from the grid (scheduled). This disables discharging and charges the battery at the specified power level (config). The code is used for that.

The "work_mode_normal" option in the Venus EVCC settings determines the mode that Venus returns to after being locked by EVCC vehicle fast charge.

@Chris8er Thank you for the additional details.

To sum up, the setup of the Marstek with a shelly meter is necessary, such that it can autonomously decide without evcc when to charge/discharge.
Charging/Discharging can not be completely controlled by evcc, which was my initial expectation/hope.

@DanielGlaas
Copy link

@DanielGlaas : How did you setup the Elfin Device?

When implementing the Code in the evcc.yaml with the dedicated adresses it computes error message as it seems, that it cannot access the tcp-server:

21:12:17.703778489 +0200 CEST m=+1481.251765055 !! 3013ms read failed: read tcp 192.168.188.80:40902->192.168.188.114:502: i/o timeout

in the evcc.yaml:

  • name: my_battery
    type: template
    template: marstek-venus
    usage: battery
    modbus: rs485tcpip
    id: 1
    host: 192.168.188.114 # Hostname
    port: 502 # Port

in general the communication is working with modbus in homeassistant... :-?

@tjahebro1
Is homeassitant also communicating via the Elfin device?
If yes, I only see a possible error in the evcc.yaml device and there only in the parameters host and port.

Maybe you compare these parameters with those in homeassistant.

@Chris8er
Copy link
Contributor Author
Chris8er commented Jun 10, 2025

Clicking "Battery" in the EVCC menu allows you to configure your battery to charge from the grid (scheduled). This disables discharging and charges the battery at the specified power level (config). The code is used for that.
The "work_mode_normal" option in the Venus EVCC settings determines the mode that Venus returns to after being locked by EVCC vehicle fast charge.

@Chris8er Thank you for the additional details.

To sum up, the setup of the Marstek with a shelly meter is necessary, such that it can autonomously decide without evcc when to charge/discharge. Charging/Discharging can not be completely controlled by evcc, which was my initial expectation/hope.

Yes, you need a meter compatible with Venus to effectively manage battery adaptation to your grid consumption. The cycles in EVCC might be too slow for this purpose anyways. Have you installed a meter? If so, you could potentially use it with Unimeter. I'm using it with my SMA Home Manager 2 in combination with the Venus.

@tjahebro1
Copy link
tjahebro1 commented Jun 10, 2025

@DanielGlaas : How did you setup the Elfin Device?
When implementing the Code in the evcc.yaml with the dedicated adresses it computes error message as it seems, that it cannot access the tcp-server:

21:12:17.703778489 +0200 CEST m=+1481.251765055 !! 3013ms read failed: read tcp 192.168.188.80:40902->192.168.188.114:502: i/o timeout

in the evcc.yaml:

  • name: my_battery
    type: template
    template: marstek-venus
    usage: battery
    modbus: rs485tcpip
    id: 1
    host: 192.168.188.114 # Hostname
    port: 502 # Port

in general the communication is working with modbus in homeassistant... :-?

@tjahebro1 Is homeassitant also communicating via the Elfin device? If yes, I only see a possible error in the evcc.yaml device and there only in the parameters host and port.

Maybe you compare these parameters with those in homeassistant.

solved:

  • name: my_battery
    type: template
    template: marstek-venus
    usage: battery
    modbus: tcpip
    id: 1
    host: 192.168.188.114 # Hostname
    port: 502 # Port

it did not work with "rs485tcpip" in my config using the elfin modbus to wifi adapter. changed now to "tcpip". now it seems to work.

@Tunestwo
Copy link

Its working! thanks allot, only thing is. small thing is that EVCC does not see my battery charging as self-consumption.
Schermafbeelding 2025-06-12 194350

@Chris8er
Copy link
Contributor Author
Chris8er commented Jun 12, 2025

This should be an configuration (assignment) issue. Nothing to do with the Venus integration itself.

@Tunestwo
Copy link

This should be an configuration (assignment) issue. Nothing to du with the Venus integration itself.

Hmm okey… going to look for a fix, not happend to anyone before?

@njoerd114
Copy link

Hi, first of all, thanks @Chris8er for the initial integration. I'm wondering if it's possible to have dynamic charging values - currently, it's set to a fixed value from the config. I couldn't find any information in the docs, unfortunately, but I would like to be able to control the charging power, just like when charging the car: Charge the battery if there's enough solar power and/or charge at max power if prices are cheap/co2 is low.

@Chris8er
Copy link
Contributor Author
Chris8er commented Jun 13, 2025

EVCC does not directly support dynamic grid consumption control, as it primarily integrates batteries to adjust EV charging power. As mentioned, EVCC's cycle concept is too slow for real-time grid management. It mainly handles the scenarios "stop charging during fast EV charging," "prevent battery discharge while charging an EV," and "charge at (config setting) power when prices are low." For broader control, use Venus with a compatible meter.

@njoerd114
Copy link

For anybody who's using the ha integration through lilygo - you can integrate with the HA REST API like this:

power: # current power
  source: http
  uri: http://YOURHOMEASSISTANT/api/states/sensor.esp_akku_marstek_ac_power
  auth:
    type: bearer
    token: YOURLONGLIVEDACCESSTOKEN
  jq: '.state | tostring'

soc: # state of charge in % (for battery)
  source: http
  uri: http://YOURHOMEASSISTANT/api/states/sensor.esp_akku_marstek_battery_state_of_charge
  auth:
    type: bearer
    token: YOURLONGLIVEDACCESSTOKEN
  jq: '.state | tostring'

I'm going to add controls later...

@joernbeutel
Copy link

Maybe someone knows the answer: I have tried to incorporate the Venus connected to Lilygo to evcc. It doesn't work for me. According to tweakers, however, it works. Anybody who succeded can push me round the corner? I have tried with yaml as well as with the GUI.
Screenshot 2025-06-13 120613
Screenshot 2025-06-13 120512

@njoerd114
Copy link

@joernbeutel it doesn't work that way round - you either use the lilygo for a modbus tcp interface + create a modbus tcp proxy with evcc or you connect it to homeassistant using esphome (or whatever home automation you're using) and talk to the esphome API (or Homeassistant, as mentioned above)

@joernbeutel
Copy link

@njoerd114 Ah, THANK YOU!! okay. Either - or. I have it in homeassistant using esphome. Now it is clear that some got it working. Prob. not using esphome...
As you probably already guessed by me not having a clue of what you indicated in your example I guess I have to find out how to create a rest API in evcc, right? Then I could use yor script snipes...?

@joernbeutel
Copy link

I treid to find out using chatgpt. Was advised to put it under meters like this
`

but obviously is wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
devices Specific device support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants
0