squishykid / solax

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

Data mapping for X1-FIT G4 #97

Open rwg0 opened 1 year ago

rwg0 commented 1 year ago

Since I've found so much useful info in this repo, it's only fair that I share back what I've discovered. My previous X1-AC is now replaced by the X1-FIT I should have had to begin with, and (of course) the data mapping is different :)

As usual, you can fetch the data using

curl -s -X POST http://solax --data 'optType=ReadRealTimeData&pwd=<SERIALNO>'

The data mappings I have worked out for this inverter are

AC power from battery : Index 2 (16 bit signed) AC power export to grid : Index 32 (16 bit signed, positive export) Battery charge percent : Index 18 Battery temperature (C) : Index 17 Grid voltage (V) : Index 0 ( 0.1) Grid Frequency (Hz) : Index 3 ( 0.01) Power to battery DC (W) : Index 16 (16 bit signed) Battery power remaining (kWh) : Index 23 (0.1) Lowest cell temperature (C) : Index 46 (16 bit signed, 0.1) Highest cell temperature (C) : Index 45 (16 bit signed, 0.1) Lowest cell Voltage (V) : Index 115 (0.001) Highest cell Voltage (V): Index 114 (0.001) BMS Max discharge current (A): Index 44 (0.1) BMD Max charge current (A) : Index 43 (0.1) EPS Power (W) : Index 28 EPS Voltage (V) : Index 29 (0.1)

I found in the end that the best way to work out the data mapping was to take a combination of data indices for similar model and also looking at the values that you can obtain from modbus over TCP (which is documented and seems less random - see https://secondlifestorage.com/index.php?attachments/hybrid-x1-x3-g3-modbustcp-rtu-v3-21-english-pdf.24841/) . You can use a tool like 'Modbus Poll' (30 day free trial) to connect to your inverter on port 502 and read the 'input' registers.

cheers,

Robin

wills106 commented 1 year ago

Just so you know RetroFit Inverters with serials starting 'PRI' are based on Gen4 Hybrids so you are best finding Gen4 documents compared to the Gen3.

adambogocz commented 1 year ago

Hi @rwg0, what is the type code of your inverter?

rwg0 commented 1 year ago

15 maybe? Presumably in the data below somewhere even if that isn't right.

cheers, Robin

$ curl -s -X POST http://solax --data 'optType=ReadRealTimeData&pwd=WIFISERIALNO' {"sn":"WIFISERIALNO","ver":"3.003.02","type":15,"Data":[2442,48,64335,5011,0,0,0,0,0,0,2,1267,0,0,24170,540,1321,19,58,1399,0,1999,0,64,100,0,23,3788,0,0,0,0,0,0,29953,0,34956,2,64335,30,256,2628,1800,100,350,165,108,34,34,105,1,1,2043,0,0,0,1203,0,65389,65535,0,0,0,0,0,0,0,0,0,0,2538,0,61859,65535,2220,0,63316,65535,3,0,645,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,1,7216,5131,5644,1106,520,8995,9252,0,0,0,0,1,2420,49,1185,3364,3351,50333,22,21302,14389,18753,12593,16689,12355,13876,21302,14389,18753,12593,16689,12355,13876,21302,14389,18754,12598,16691,12611,13106,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2305,260,1026,3,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,0,0,0,0,0,1,0,0,0,0,0,0],"Information":[3.680,15,"INVERTERSERIALNO",8,1.26,0.00,1.23,1.04,0.00,1]}

adambogocz commented 1 year ago

OK, that's basically the same as X1-Hybrid-G4, data mapping wise and that is implemented and missing EPS values. Which are

EPS Power (W) : Index 28 EPS Voltage (V) : Index 29 (0.1) EPS Current (A) : Index 30 (0.1)

Have you tried to run the discovery manually? It takes some time now since timeout per try is 5sec and it is trying 2 methods per known inverter. My X3-HYBRID-G4 takes about 2-3 minutes before gets connected.

rwg0 commented 1 year ago

I must admit that I have my own hand-crafted code to read the data, and only posted the info here as this seemed the best place to find data mappings on Solax inverters, so it made sense to post additional info in the same place.

Anyway, I had a go with the sample code and the library, but it times out after 5 minutes.

$ time python testsolax.py 
Traceback (most recent call last):
  File "testsolax.py", line 10, in <module>
    data = loop.run_until_complete(work())
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "testsolax.py", line 5, in work
    r = await solax.real_time_api('solax',80,'XXXXXXXXXX')
  File "/home/robin/.local/lib/python3.8/site-packages/solax/__init__.py", line 36, in real_time_api
    i = await discover(ip_address, port, pwd)
  File "/home/robin/.local/lib/python3.8/site-packages/solax/discovery.py", line 39, in discover
    await i.get_data()
  File "/home/robin/.local/lib/python3.8/site-packages/solax/inverter.py", line 51, in get_data
    data = await self.make_request(self.host, self.port, self.pwd)
  File "/home/robin/.local/lib/python3.8/site-packages/solax/inverter.py", line 151, in make_request
    async with session.post(url, headers=headers) as req:
  File "/home/robin/.local/lib/python3.8/site-packages/aiohttp/client.py", line 1141, in __aenter__
    self._resp = await self._coro
  File "/home/robin/.local/lib/python3.8/site-packages/aiohttp/client.py", line 560, in _request
    await resp.start(conn)
  File "/home/robin/.local/lib/python3.8/site-packages/aiohttp/client_reqrep.py", line 914, in start
    self._continue = None
  File "/home/robin/.local/lib/python3.8/site-packages/aiohttp/helpers.py", line 720, in __exit__
    raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError

real    5m1.254s
user    0m0.140s
sys 0m0.034s

My testsolax.py

import solax
import asyncio

async def work():
    r = await solax.real_time_api('solax',80, 'XXXXXXXXXX')
    return await r.get_data()

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

tried the IP address as well as the hostname - same thing.

cheers,

Robin