solax
solax copied to clipboard
X1 Mini V34 not discovered + code version mismatch in pip package?
I couldn't get the HA SolaX integration to load reliably, so tried some tests by calling the solax functions directly from Python using the test code from the front page of this repo.
I have two inverters for it to discover:
- X1 Hybrid G4 - solax_real_time_api(IP, pwd="pwd") eventually returns valid data (it's the last inverter in the list, hence the long wait I guess - though it's 5+ minutes which is VERY long for 12 or so HTTP requests)
- X1 Mini 2.0 - hangs for a very long time and eventually says it failed to connect to any inverter type.
Both are accessed using their local SSIDs via nginx reverse proxies presenting them on port 80. The proxy logs show the expected mixture of POSTs with query strings and POSTs with form data as the code tries to discover different inverter types. Both my inverters expect form data.
I remove all the other inverters from the list in discovery.py, leaving just X1miniV34, it still times out without finding my inverter. I've checked the API response with curl and it shows "type": 4, which is the discovery test for the X1miniV34 type. Counting the entries in the proxy logs, it looks like the X1miniV34 discovery tries both query string and form data POSTs, so it should work.
Looking at the full requirements in x1_mini_v34.py:
- type is integer 4
- sn is a string of 10 characters
- ver is a string, "3.003.02"
- Data is present and all numeric, an array of about 100 items (I may have lost count! ;-) )
- Information is present, an array of 10 items [num,num,str,num...num]
All of that looks like it fits the requirements.
What else should I check to find out why it's not discovering the X1miniV34?
Additional note: I just spotted that inverter.py in my installation is very different from the version in the git repo. pip says that the version of solax is 0.3.0, though. That would mean that the code I'm running might not be doing what I think based on reading the code in github. Why would the file differ if the version is correct?
@jaykijay - is your PR https://github.com/squishykid/solax/pull/89 possibly helpful to this problem? It looks like you set it up for 69, 100, or 200 Data elements; mine returns 100 (I thought more, but mis-counted). I see that the code in the master branch allows only 69 or 200. I added the line to allow 100 elements, but mine still fails to detect.
This PR #110 is for speeding up the discovery process. It is indeed taking longer than necessary
@jefft4 if you follow the instructions here, we can look at adding your inverter. We require a direct copy of the data returned from the inverter. https://github.com/squishykid/solax/wiki/Adding-Support-for-Your-Inverter
@jefft4 if you follow the instructions here, we can look at adding your inverter. We require a direct copy of the data returned from the inverter. https://github.com/squishykid/solax/wiki/Adding-Support-for-Your-Inverter
It's http://<LAN_IP>/optType=ReadRealTimeData&pwd=SVBH99XXXX
Response (inverter & dongle serial numbers changed for privacy):
{"sn":"SVBH99XXXX","ver":"3.003.02","type":4,"Data":[2496,52,1325,1495,0,93,0,1390,0,5003,2,10418,0,49,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,49,0,2889,0,0,0,0,0,0,0,0,0,0,0,0,0,48,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,0,0,0,0,0,0,0,0,0],"Information":[2.000,4,"XM3A20I0000000",8,2.22,0.00,1.38,0.00,0.00,1]}
I have it working in a Node Red flow - I had to resort to that as I need to aggregate two inverters to get a system view.
This is the part of my NR code that identifies the key data elements, in case it helps: ` res.payload.wifiSerial = msg.payload.sn; res.payload.wifiVersion = msg.payload.ver; res.payload.inverterType = msg.payload.type; res.payload.ACVoltage = msg.payload.Data[0] / 10; res.payload.ACCurrent = msg.payload.Data[1] / 10; res.payload.ACPower = msg.payload.Data[2]; if (res.payload.ACPower > 32767) { // have seen this -ve (e.g. 65534), though that should be impossible res.payload.ACPower = 0; } res.payload.VDC1 = msg.payload.Data[3] / 10; res.payload.VDC2 = msg.payload.Data[4] / 10; res.payload.IDC1 = msg.payload.Data[5] / 10; res.payload.IDC2 = msg.payload.Data[6] / 10; res.payload.powerDC1 = msg.payload.Data[7]; res.payload.powerDC2 = msg.payload.Data[8]; res.payload.ACFreqcy = msg.payload.Data[9] / 100; res.payload.runMode = msg.payload.Data[10]; res.payload.yieldToday = msg.payload.Data[13] / 10; // total yield in 11,12; we don't need that
// feedInPower (grid): 32 bits signed; -ve is import, +ve is export
res.payload.feedInPower = msg.payload.Data[49] * 2**16 + msg.payload.Data[48];
if (res.payload.feedInPower > 2**15) { // -ve value
res.payload.feedInPower = res.payload.feedInPower - 2 ** 32;
}
// these may be signed fields(?), but are kWh generated/used, which should never be -ve, so we don't try to handle it
res.payload.feedInEnergy = (msg.payload.Data[51] * 2**16 + msg.payload.Data[50]) / 100;
res.payload.consumeEnergy = (msg.payload.Data[53] * 2**16 + msg.payload.Data[52]) / 100;
/*
res.payload.inverterSerial = msg.Payload.Information[2];
res.payload.dspVersion = msg.Payload.Information[4];
res.payload.armVersion = msg.Payload.Information[6];
*/
`