squishykid / solax

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

X1 Mini V34 not discovered + code version mismatch in pip package? #111

Open jefft4 opened 1 year ago

jefft4 commented 1 year ago

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:

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:

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?

jefft4 commented 1 year ago

@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.

kdehairy commented 1 year ago

This PR #110 is for speeding up the discovery process. It is indeed taking longer than necessary

squishykid commented 1 year ago

@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 commented 1 year ago

@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:///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];
*/

`