• 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 Deye micro-inverter via Modbus using Python script

Lasgo

New Member
Joined
Jun 10, 2025
Messages
4
Location
Belgium
Hi all,

I have a Deye SUN-M80G4-EU-Q0 micro-inverter.
It is connected (only) to a battery, so I need to control the power that it injects into the grid. Otherwise the inverter just dumps the entire battery power to the grid until the battery is empty.

I managed to write a (test) Python script that uses the Deye Cloud OpenAPI.
That way, I can set the MAX_SOLAR_POWER parameter, to define the max power into the grid.
That basically works, but the OpenAPI commands go over the Deye servers.
I fear that sooner or later, Deye will put some limitations on that, concerning the maximum rate of API calls that users make. Although for the moment, they do not do that yet.

So, I am looking for a way to control the Deye inverter 'locally'. So, not passing via the Deye servers.
The obvious way seems to be to use the Modbus protocol.

I've been trying to write a Python script to make a Modbus connection and communication with my Deye, but I can't get it to work.

Apparantly, a client connection is made, but when I try to access a register, the inverter does not respond. The connection always times out.

These are the main parameters that I use:
Code:
modbus_host      = "192.168.0.187"
modbus_port      = 8899    
slave_id         = 1

I haven't tried connecting to "10.10.100.254", because my controller (that runs Python) needs to also connect to the internet.

This script does not work:
Python:
from pyModbusTCP.client import ModbusClient

modbus_host      = "192.168.0.187"
modbus_port      = 8899  
slave_id         = 1       
register_address = 40       
register_count   = 1      

client = ModbusClient(host=modbus_host, port=modbus_port, unit_id=slave_id, timeout=30.00, auto_open=False)
print(client.open())
print(client)

try:
    if client.open():
        print("Successfully connected to the Modbus server!")
    else:
        print("Failed to connect to the Modbus server. Check IP, Port, Firewall.")
      
except Exception as e:
    print(f"An error occurred during connection: {e}")
  
if client.is_open:
    print("Client connection is currently open.")
else:
    print("Client connection is not open.") 
  
response_registers = client.read_input_registers(0, 1)
#response_registers = client.read_holding_registers(0, 1)

if response_registers is not None:
    print(f"Server responded successfully. Value: {response_registers[0]}")
else:
    print("Failed to read from server or no response.")
    print(f"Last error: {client.last_error_as_txt}")
  
client.close()
exit()
The strange thing is that using AT-commands using this tool works fine!
So, I also have been trying to use AT-commands via a Python script, and it also does not work ...

Does anybody have any suggestions of things to try?
 
Method 1 - Modbus via TCP.
I have not yet got this to work. I have tried (always with Python code) via my WLAN IP (192.168. 0.xxx). I have not succeeded yet. I suspect (but I would have to verify this) that the inverter can only be controlled in AP mode (i.e. via its local IP 10.10.100.254) with Modbus commands. Nice to make one-off settings, but less to control it continuously because the controller cannot be connected to the internet at the same time.

Method 2 - Adjust Modbus registers via AT commands.
This is a method that (in my opinion) is not openly published by Deye, but that users have figured out themselves. AT commands are a way to change settings in devices. Traditionally often used for modems and such.
I found this tool (deye-logger-at-cmd) and that led me to this method. With that tool (downloadable and run out-of-the-box) you can do many interesting things (e.g. read SSID, read passwords), and therefore also read and write Modbus registers.
And ... all this via your WLAN IP (192.168. 0.xxx). Completely local (not via servers), and you can still access the internet at the same time.
That tool is written in Golang. I am studying that code to convert the code that is useful to me to Python. I think it will work.
 
Hey @Lasgo . In last day I was also looking at this series of Deye microinverter and I had the same question as you : how I can control (in real time if possible) the power output from the microinverter.
The best resource of information I could find until now is this github repo : https://github.com/Hypfer/deye-microinverter-cloud-free
Hi,
Yes, I know that link.
What seems most promising to me, at this moment, is the system I mentioned in my post above as 'Method 2'. That is to read/write Modbus registers using the AT+ commands. You can already experiment with it, using the 'deye-logger-at-cmd' tool.
I am looking at converting that to python code. I am just a bit short of time for now.
One difficulty also is that the Modbus registers are not the same for every Deye inverter. The micro inverters are different from the hybrid inverters ... I am sometimes hesitating to try a Modbus register, fearing that I will damage my inverter.
Although just reading a register should never harm the inverter.
 
Hi Lasgo.
Unfortunately I don't have an microinverter to test, I'm still in documenting phase.
Related with AT commands, just reading will do no harm, that's 100% safe.
What I would like to know, but is not easy to find : how that registers are stored. If it's an EEPROM and let's assume that will change the output power every 10 seconds , I have around 100.000 (more if it's a high quality EEPROM) writes until the EEPROM will fail.
That's an important aspect to take in consideration.
 
I have thought
Hi Lasgo.
Unfortunately I don't have an microinverter to test, I'm still in documenting phase.
Related with AT commands, just reading will do no harm, that's 100% safe.
What I would like to know, but is not easy to find : how that registers are stored. If it's an EEPROM and let's assume that will change the output power every 10 seconds , I have around 100.000 (more if it's a high quality EEPROM) writes until the EEPROM will fail.
That's an important aspect to take in consideration.
I have thought about the EEPROM too. But 100 000 write cycles for the lifetime of an EEPROM is rather conservative. Most can handle 1 000 000 cycles before dying.
But also keep in mind that a micro-inverter like Deye SUN-M80G4-EU-Q0 does not respond superfast to a change in setting of Active Power. If you change power setting, it will 'ramp up' (or down) to the new setting. Do not expect a fast regulation loop to work well.
So, it might not make sense to try to capture every spike in consumed power and adjust the inverter power.
Once every minute should do ...
 

diy solar

diy solar
Back
Top