• Have you tried out dark mode?! Scroll to the bottom of any page to find a sun or moon icon to turn dark mode on or off!

diy solar

diy solar

Controlling Solis S5 Hybrid via Modbus

lukjasin

New Member
Joined
May 7, 2025
Messages
3
Location
Poland/Belgium
Hey all,

I’m trying to control a Solis S5 Hybrid inverter in installation (grid+PV+battery setup) via Modbus, using Node-RED running on a Victron Cerbo GX.
The idea is to have an external algorithm decide when to connect/disconnect from the grid, set charge/discharge limits, etc. The algorithm works great with Victron devices, but there is a problem with controlling the Solis inverter.

I found register 43132 – Remote Control: Grid Adjustment, which looks like it should allow grid control (ON/OFF), but I can’t seem to get it to work.
Has anyone successfully used this register (or others) to actively control a Solis inverter? Or maybe found a better approach?

Any tips or experiences would be super appreciated!
 
there is a problem with controlling the Solis inverter.
Welcome!

The Solis is very controllable via Modbus RTU and/or CANBus. What exactly do you want to do?

Myself, @peufeu, @rpdom and @Solar Guppy all control our Solis inverters over Modbus.

Check out this thread and also @peufeu's excellent Grugbus project on Github.

 
The idea is to have an external algorithm decide when to connect/disconnect from the grid,

So far, I haven't found a way to do this.

It's possible to turn the inverter on/off via modbus. Since I have two, I use that to turn one off at night to avoid having double the idle power consumption. When it is off, it's off, so it won't charge batteries from PV.

set charge/discharge limits, etc.

There are registers for that, but you need to explain exactly what you want to do.

I found register 43132 – Remote Control: Grid Adjustment, which looks like it should allow grid control (ON/OFF), but I can’t seem to get it to work.
It's for controlling power input/output on the grid port.
 
The idea is to have an external algorithm decide when to connect/disconnect from the grid, set charge/discharge limits, etc. The algorithm works great with Victron devices, but there is a problem with controlling the Solis inverter.

You could update the active grid profile and change the HZ value so its out of spec to disconnect and change back to connect ( 43038, 43040 )

Battery Discharge / Charge current is ( 43117, 43118 ) which I used to override the inverter logic for charging to utilize my own algorithm.

 
Thanks a lot for the replies!

What I’m trying to achieve is dynamic control of the grid setpoint — meaning I want to tell the inverter how much power to take from or send to grid at a time. This is based on an external algorithm predictions that uses weather forecasts, energy prices, and household consumption history to optimize energy flow.
This works beautifully with Victron systems, simply set the grid power setpoint and the system adjusts battery and PV output accordingly to match the target. Like on the picture below.

Zrzut ekranu 2025-05-8 o 16.57.57.png

With the Solis S5 Hybrid inverter I’m still unsure whether such grid control is possible. If not, I’d at least like to control the battery charge/discharge.

I followed the link SeaGal posted, and here’s what I’ve tested so far:
- Setting register 43135 to 1 I can control the battery charging via register 43136. That works.
- Setting register 43135 to 2 I don’t observe any actual discharging. How to set the value for battery discharge power?
- Writing values to 43130 or 43131 doesn’t seem to have any effect.

There is still some PV production and I don't know if I can force the battery to discharge and redirect the current from the battery together with the PV to the grid.
Also, is there a way to write those values just to RAM, without saving to flash every time? Just trying to avoid killing the inverter’s internal memory by writing too often.
 
I followed the link SeaGal posted, and here’s what I’ve tested so far:
- Setting register 43135 to 1 I can control the battery charging via register 43136. That works.
- Setting register 43135 to 2 I don’t observe any actual discharging. How to set the value for battery discharge power?
- Writing values to 43130 or 43131 doesn’t seem to have any effect.
Yeah I tested the "remote control battery force charge/discharge" registers and they work (with latest firmware). The "Remote control grid blah blah", never could do anything with them.

Simplest is to use MITM (Man In The Middle) between the inverter and the meter.

In normal use the inverter will attempt to keep the meter reading at setpoint = zero.

So I have a python script and 2 RS485 interfaces. On one interface, it reads the meter periodically and stores the received data. On the other RS485, it acts as modbus server and pretends to be a meter that the inverter then reads.

If the fake meter reports the reading of the real meter + offset, then the inverter will adjust its grid power so that meter+offset=0, which means your setpoint becomes -offset.

This does not set inverter grid power directly, it alters the setpoint for import/export at the point the meter is installed. So the result will dpeend on where the meter is. If it is on the inverter's grid port, then it will set inverter grid power directly (I'm not using the words "output power" because it goes both directions).

This will work with any inverter of any brand that uses a RS485 meter since they all work the same.

On Solis you need to "set meter placement grid" ("load" doesn't work) and if you don't set it to zero export but something else, it will export more if the battery is full. So it's simpler to set it to zero export.

I use it to share power between the 2 Solis inverters, which aren't intended to work together to do so. It works fine.

Code is on my github, Seagal posted the link above.

If you also want to talk to the inverter on Modbus to query battery SOC and other stuff, then you need another RS485 interface. Can't be the same because you can only have one master per modbus bus, and the inverter is master on the meter port and slave on the COM port. Also modbus is damn slow so I ended up not sharing the bus and I'm using 4 dual port interfaces on a USB hub on a Pi 🤣 (2 inverters, 2 fake meters, 3 real meters, 1 EVSE).
 
What I’m trying to achieve is dynamic control of the grid setpoint — meaning I want to tell the inverter how much power to take from or send to grid at a time. This is based on an external algorithm predictions that uses weather forecasts, energy prices, and household consumption history to optimize energy flow.
I'm trying to get my head around having a "setpoint" for the grid. It seems to me like you're trying to push the toothpaste back into the tube? If you are not producing enough PV or have enough battery SOC to export you won't be able to export the amount you have "set".

Similarly, if you are producing more power than the house is consuming and your battery is full - i.e. exactly as you have the in the diagram above then you will simply export what you have as excess power = no need to set a "setpoint".

Sorry if I'm missing something :unsure:
 
I think he wants to do some energy trading and make money, so in/outflow has to be controlled according to spot price
 
Yeah I tested the "remote control battery force charge/discharge" registers and they work (with latest firmware). The "Remote control grid blah blah", never could do anything with them.
Solis was updated with new firmware about two weeks ago, so I’ll make sure to re-test the remote control battery force charge/discharge registers. Maybe I missed something.
I tested register 43132 Remote Control Grid Adjustment too, and just like you said, I couldn’t get it to do anything either, completely unresponsive.

Simplest is to use MITM (Man In The Middle) between the inverter and the meter.
Thanks for the detailed explanation. Your MITM approach is a really clever way to take control. Tricking the inverter with fake meter data is just brilliant 👏

Code is on my github, Seagal posted the link above.
I already started looking through your scripts and it’s really inspiring stuff.

I think he wants to do some energy trading and make money, so in/outflow has to be controlled according to spot price
Something like that, but maybe not make money but avoid costs ;)


Similarly, if you are producing more power than the house is consuming and your battery is full - i.e. exactly as you have the in the diagram above then you will simply export what you have as excess power = no need to set a "setpoint".
You’re right. In a typical setup, the inverter just reacts automatically: if there’s more solar than needed, it sends the extra to the grid, if there’s not enough, it takes power from the grid. But this kind of setup doesn’t consider things like electricity prices or what we’re planning to do.

Take the example from the image I posted earlier: there’s ongoing solar production, the house is using very little power and the battery is already full. So the extra energy gets pushed to the grid. If electricity prices are negative at that moment, exporting that energy doesn’t make money, it actually costs money.
The algorithm can predict when situations like this are likely to happen, and prepares in advance by freeing up space in the battery, so that the extra energy can be stored instead of exported.
 
In case you wonder about the code's peculiar structure: it's due mainly to two constraints.

First, while most of the code can be updated and reloaded without restarting the program, some changes do require restarting.

Second, when restarting the fake meter modbus server, the inverter will detect the unresponsive meter and go into safe mode, log an error, and take a while to return to normal mode. I wanted to avoid this.

So I split it into several parts to be able to restart or reload the one I'm working with without restarting the whole thing, and especially the fake meter server. These parts talk to each other via MQTT, and they publish a lot of data on MQTT and can be controlled via MQTT.

There are a bunch of python programs launched at startup on the Pi, in files pv_****.py

Each of these does some setup, then loads a module of the same name in pv/ which contains the actual code. So pv_controller.py (this one contains the fake meter and other things) loads pv/controller.py. Then it monitors the timestamp of pv/reload.py. If this timestamp changes (for example via unix command touch) then all modules marked as reloadable are reloaded at runtime. When this occurs, the old version of the code is told to exit, the new one is loaded, and executed. Live reloading of python code is a bit touchy subject because if you keep objects referencing the old version of the code around then they will still use the old code version, so the cleanup is critical.

This makes it a bit complex and hard to get into, but it works fine.
 
Take the example from the image I posted earlier: there’s ongoing solar production, the house is using very little power and the battery is already full. So the extra energy gets pushed to the grid. If electricity prices are negative at that moment, exporting that energy doesn’t make money, it actually costs money.
The algorithm can predict when situations like this are likely to happen, and prepares in advance by freeing up space in the battery, so that the extra energy can be stored instead of exported.
The problem there is that even if you set a forced discharge to grid of, say 2500W, the energy will still come from PV first, with battery second. So if you are generating 2000W, only 500W will come from battery. I'm sure there must be a way to limit production from PV, but I haven't found one other than turning the panels off.

I like overnight negative prices where I can charge batteries and put large loads on, during the day when there is plenty of sun I have to balance that with the 15p/kWh I'm getting for export. At those times I do limit the battery output to 1A, so any extra comes from grid.
 
I'm sure there must be a way to limit production from PV, but I haven't found one other than turning the panels off.

One can command the mppt's on Solis to be in constant voltage mode and then set the tracking target at the VOC voltage would stop harvesting from mppt(s)

Register 43248: Target voltage for mppt tracking. used when inverter is in constant voltage mode, for example set to 3900 for 390.0 Volts
Register 43249: Value 2A is disabled constant voltage mode , AA is constant voltage enabled for the special settings register ( bit 7 )
 
Thanks for the detailed explanation. Your MITM approach is a really clever way to take control. Tricking the inverter with fake meter data is just brilliant
(y) Although I don't use that part of @peufeu's code, I'd say the abstraction of Solis and the Acrel/Estron power meter Modbus registers is brilliant. I run a modified version of his Grugbus code to extract data from my Solis Inverters :)
 

diy solar

diy solar
Back
Top