squishykid / solax

🌞 Solax Inverter API Wrapper
MIT License
100 stars 57 forks source link

Q-Cells Q.VOLT HYB-G3-3P (Q.HOME+ ESS HYB-G3-3P) #85

Closed intimber2k closed 2 years ago

intimber2k commented 2 years ago

Hi,

We have a Q-Cells Q.HOME+ ESS HYB-G3-3P system with a Q-Cells Q.VOLT HYB-G3-3P inverter. I'm trying to get some realtime data out of it as the Q-Cells portal (https://qhome-ess-g3.q-cells.eu) only supports data updates from the inverter every 5 minutes.

At first I was looking at the Modbus connection which seems to work for a lot of users. But I thought that I already have a WLAN/LAN connection to it so I would like to go this way. Unfortunately there is no official API for the Q-Cells inverter. When I found this project I realized that there must be a way to get the needed realtime information from the inverter via network and an API.

My setup: the inverter is connected via the WLAN dongle to my home WiFi and gets an internal IP via DHCP (192.168.9.123). Opening a browser with this IP I get asked for username and password (admin/[WLAN serial number]) and get a WLAN settings page (DHCP,Static IP, System).

But using a browser there is no way to read the inverter information as browsers usually only use GET requests. But you can get the needed information with a POST request.

Example (Linux commandline): curl -X POST http://192.168.9.123 --data 'optType=ReadRealTimeData&pwd=[WiFiSerialNumber]'

Return: {"sn":"[WiFiSerialNumber]","ver":"3.003.02","type":14,"Data":[2403,2363,2398,119,118,120,2850,2787,2890,8527,6481,6978,90,42,5876,2962,5005,5004,5005,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,5775,0,0,0,0,42820,0,0,4268,0,0,1,49,2752,256,13610,3082,5640,100,0,51,0,0,0,0,0,0,0,0,0,0,0,0,0,19159,0,167,0,0,0,1722,0,2073,0,31,61,19816,0,197,0,0,0,11044,2,10147,0,1018,0,232,0,0,0,0,0,0,0,0,0,1,100,1,32,122,256,4672,3200,0,300,279,255,34,33,16,2132,778,14135,14135,14135,14135,0,0,3397,3332,15798,6,20564,12339,18497,12601,18741,12612,12856,20564,12339,18498,12866,18741,12356,13872,20564,12339,18498,12866,18741,12356,14128,20564,12339,18498,12866,18741,12356,13616,20564,12339,18498,12866,18740,12356,14640,4099,259,1281,259,0,42820,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Information":[15.000,14,"[InverterSerial]",8,1.23,0.00,1.23,1.08,0.00,1]}

So this basically proves that it is possible to get some information from the inverter via LAN.

Next issue is that I can't make the example code to work. I've changed the example code by adding my IP and also adding my personal password (WiFi serial number):

######## import solax import asyncio

async def work(): r = await solax.real_time_api('192.168.9.123','80','[WiFiSerialNumber]') return await r.get_data()

loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) data = loop.run_until_complete(work()) print(data) ########

Unfortunately this ends in an infinite loop. When I stop the code with Ctrl-C I see that "loop.run_until_complete(work())" was still waiting for "work()" to finish.

Any ideas?

Best Regards, Denis

VadimKraus commented 2 years ago
from solax.inverters.qvolt_hyb_g3_3p import QVOLTHYBG33P

import asyncio

async def work():
    return await (await QVOLTHYBG33P.make_request('IP',port=80,pwd='PASSWORD')).get_data()

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
data = loop.run_until_complete(work())
print(data)

What happens if you use the inverter directly?

gravemalte commented 2 years ago

Hey guys!

I was able to make it work. @VadimKraus your code was almost working thanks for the idea!

But a voluptuous.Schema change for the specific inverter was needed. https://github.com/squishykid/solax/blob/4c4bc83bf4ec1538f00621177e33cfc3fef428a7/solax/inverters/qvolt_hyb_g3_3p.py#L65-L69

The max=200 is wrong, a maximum of 300 is needed. I also incremented the min to 300 for the sake of equality. So the final change looks like the following:

 vol.Length(min=300, max=300) 

The request data code:

from solax.inverters.qvolt_hyb_g3_3p import QVOLTHYBG33P

async def work():
    return (await QVOLTHYBG33P.make_request('IP','80','PASSWORD'))

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
data = loop.run_until_complete(work())
print(data)

I hope this helps you @intimber2k

VadimKraus commented 2 years ago

Which version does your inverter report via the API? Because the current state definitely works on my

Q.VOLT HYB G3-P. Firmware: 2.034.06

I have the 9kW/h Batterie, maybe this also has an impact an the response?!

gravemalte commented 2 years ago

Q.VOLT HYB-G3-3P. Firmware: 3.003.02

I've got two 3.1kW/h batteries, which sums up to 6.2kW/h

intimber2k commented 2 years ago

Hi Malte, hi Vadim,

Now it works for me. My inverter has version '3.003.02'

Many thanks, Denis

VadimKraus commented 2 years ago

Ok so I guess another schema is needed for version 3...

MHBraun commented 1 year ago

Hi Malte, hi Vadim,

Now it works for me. My inverter has version '3.003.02'

Many thanks, Denis

How did you make it work? Using the code above I get

python "A:\QCellsInverterCall.py" Traceback (most recent call last): File "A:\QCellsInverterCall.py", line 197, in <module> data = loop.run_until_complete(work()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\Lib\asyncio\base_events.py", line 653, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "A:\QCellsInverterCall.py", line 192, in work return (await QVOLTHYBG33P.make_request('192.168.178.53','80','SXYSCAECDY')).get_data() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: Inverter.make_request() takes 1 positional argument but 3 were given