-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exact mapping from Solax Android application #108
Comments
As a primer, for my inverter X1 Hybrid G4 the correct and full mapping looks like this:
As you can see, current version of the library doesn't read |
Published all the documentation I was able to gather: https://github.com/nazar-pc/solax-local-api-docs New release of the app came out 3 days ago (0.4.4), but according to changelog nothing major happened there, so I didn't bother looking into it. |
Very much appreciated! I just got a set of X3 Hybrids up and running. Will be testing and integrating in about 2 weeks. |
BTW, what would be the right place to request more sensors in HA? I had to derive a bunch of things like load power, charge/discharge rate and remaining time, totals for stored/used battery power for energy management. I can provide templates and describe rationale, just want to make sure I post it in the correct place. |
Not an expert on this component but: In general sensors are created dynamically in HA. Line 85 in 5fdb6d1
Hope this is helpful. |
This library just extracts data. HA integration though should be free to add more sensors, which have derived values (for totals or change rate not provided by inverter itself it'll need access to older values for instance). |
You can create sensors either from data or from calculations. HA does not care. It's the integration that delivers the data and its classification. eg solax/solax/inverters/x3_hybrid_g4.py Line 53 in 5fdb6d1
But I am not the author of this integration. Just happen to watch it closely as I will need it soon. |
I understand that, my point is that it would be helpful if integration did provide some additional calculated sensors on top of raw values this library gets from the inverter. I just assumed you may be working on updating the library and integration afterwards, in which case I'd love to see some new sensors added. I might look into it myself, but I don't feel very comfortable working with Python. |
FYI There is also a bunch of modbus info out there that might come in handy: https://library.loxone.com/detail/solax-x3-hybrid-(neoom-kjubee)-917/overview |
Yeah, Solax even sent me docs for it. But it doesn't seem to provide any new information and it is much less convenient to work with than to issue an HTTP request. |
I'm currently working on including this new information in the next release of this library. |
@squishykid would you please add EV chargers as well, not just inverters? @nazar-pc Thanks a lot for extracting the mapping! ❤️ |
Yes, as long as UI allows to change settings (it does) it is certainly possible. The challenge is that API is kind of ugly and confusing, so changing critical parameters is potentially dangerous. Also limits configured in the app do not actually correspond to limits configured in the inverter itself (which leads to confusing errors), which is why I focused on reading data first rather than modifying. I'd love to see ability to change some setting like lowering charging current depending on some rules in Home Assistant for instance, but Python is not my strong side, so unless someone volunteers to do the hard work, I can try to extract up to date mappings (they are likely also model-dependent). |
FYI I have been digging into their private APIs last weekend since their public API was hard down. First of all, all the private API endpoints continued to work while the public API was down. I used Safari and Chrome to inspect the web interface, rather than the mobile App. Then used ARC to assemble the API calls to retrieve the data. You first need to login into the web App with a simple call:
if successful the response will include a token at the very end of the json document:
You need to use that token for all the realtime calls like this:
inverterSN is the serial number of the inverter independent of whatever communication module or its registration code. if successful the response will look like this:
Some of the values are incorrect like |
This is not the same as local access that this library is about. Also those "real time data" are not actually real time from what I saw, they are snapshots made every 5 minutes. So it is off-topic here (and please put the text under |
@fxstein good job on digging into it. As @nazar-pc points out though their cloud API is of low interest for us as it is slow and unreliable. |
Changing inverter settings uses a different login method and API. I have just started playing with that. The login is different as it also requires the installer password to change most settings.
in this case register 200 is the maximum charge level for the charger, setting it to 80% in this example. I have not had time to dig deeper into its login process or other settings, but Safari or Chrome developer shows you the details of every call when you hit the save button next to any setting. |
@nazar-pc changed the comment. My apologies for the length of it. I understand that their online APIs are too slow - painfully aware of that. But I figured it can help with mapping data. |
For reading I extracted close to 100% of data. I think updating something like charging mode and charge/discharge percentages is relatively safe, but I'll have to look closer into it if someone wants to tackle implementing it. If different inverters have different mappings though the danger is that you might be editing one setting, but accidentally changing another to arbitrary value. You can trip circuit breaker, put the whole house offline or do other kinds of fun things that we better avoid. Good thing is that it is all in the app. Bad thing is that application is poorly designed and code is minified with no documentation, so it is not exactly trivial to make sense of it. But certainly possible. Another fun exercise would be to run mobile UI on desktop, then it is even easier to inspect things comparing to just reading the code, but I'm not in the mood (should be not too difficult though). |
@fxstein I see. That's unfortunate. If only those LAN adapters worked the same as WiFi, providing local API or Modbus TCP. That would be much better than going WiFi... |
I added in support for Parallel Mode (Master Slave) a while back for the Modbus Integration. It's just untested, I don't see why it wouldn't work though.
If you can get some Modbus network traffic I can look into supporting that as well in the Modbus Integration. |
@wills106 Thank you! I did take a look at that but only had an ESP32 device with RS485 handy, so I played with your parallel protocol in ESPHome, but could never get any of the inverters to respond at all. I did get the occasional heartbeat message off the RS845 bus, so I knew I was on the correct settings. Currently 6000 miles away from the setup, hope to be back in person onsite in April. |
@wills106 The trouble is we would probably need a passive mode for this as the EV charger is connected to the same Modbus connector/cable on the Inverter as is used for the communication with the Modbus Smart meter. It is entirely possible there is no communication between EV charger and Inverter at all and the EV charger is just reading grid load from the Smart meter over Modbus... |
This might do the trick https://github.com/infradom/ha-addon-modbusspy |
There is a Modbus document available for the Charger. With your installation does the Charger rely solely on the Inverter for Import / Export values? |
On the charger there is only one RJ45 port and (same as on Inverters) you have to choose whether to use that port for CT Clamps or for the Modbus link. So I have both Inverter and Charger linked through common Modbus link that leads to the main grid meter.
I already noticed and added a comment there. Thanks! |
@squishykid do you have progress on this front? |
@nazar-pc I am working on this at the moment, but the refactor is difficult. It seems like some of the inverters have different mappings and I don't understand why. I.e. your mappings for inverter type 4 do not match https://github.com/squishykid/solax/blob/master/solax/inverters/x1_mini_v34.py. I am trying to figure out how to resolve this. Perhaps you could send me a copy of the decompiled android app? Perhaps this library can distinguish between different mappings based on whether the data parameter is required? Or perhaps it's based on whether the firmware version is >3? |
From what I read in the code, it doesn't check the firmware version. Attaching zip file with all the JS files contained in the from official Android application (version 0.4.3). One confusing thing I found was I'm fairly confident I mapped those correctly according to their source code, but I could have also made a mistake somewhere. UPD: Uploaded unmodified JS files (some were re-formatted and modified in the previous upload): |
@nazar-pc perhaps you can help me, the specific case I am trying to distinguish is between these two test cases. They both have the same inverter number in
How can the solax library determine which decoding to use when |
What does Also I see the link to a blog post with modified firmware, is there a chance that firmware is incompatible with official app and doesn't follow the rules? Also this is concerning, I have not seen any handling for solax/solax/inverters/x1_mini.py Line 12 in e17c930
I'll try to take a look at the latest version of the Android app (0.4.5 vs 0.4.3 that I looked at before) this weekend. |
@nazar-pc If you look at the |
I see, well, I'll have to dive back into JS then to figure it out, will try to find time this weekend |
I have looked at Android app 0.4.5 (latest as of right now, I was previous looking at and attached JS for 0.4.3), no meaningful changes to data handling there. Looks like #101 also used official app to decode the data. I have one user also stating that the data conversion must follow new format for X1 Boost in nazar-pc/solax-local-api-docs#1 (note that they are on v3 firmware already, also you can take a sample of their inverter data there). So far there is no consistency regarding versions or type there. As far as I can see in the code, those inverters should not be working properly with local WiFi connection. If they do I just don't see how. This is literally from application's sources: e.inverterType = i["Information"][1];
localStorage.setItem("inverterType", e.inverterType);
e.transportType = i["Information"][9];
e.inverterType >= 8 ? localStorage.setItem("transportType", 1) : localStorage.setItem("transportType", e.transportType);
1 == e.transportType || e.inverterType >= 8 ? e.getPub2(i["Data"]) : e.getPub1(i["Data"]);
localStorage.setItem("dongleModType", i["Information"][10]);
localStorage.setItem("dongleWorkMode", i["Information"][11]);
localStorage.setItem("sn", i["SN"] || i["sn"]); They write dumb redundant code, but it essentially boils down to this: inverterType >= 8 ? getPub2(Data) : getPub1(Data) There are no checks for other fields in there. Would be great to confirm with someone whether they can see proper data in their Android app with local WiFi connection. One thing I noticed (there are too few data points, but still) is that |
For anyone interested, I found a way to set the PowerLimit (which is usefull because I have dynamic tariffs which sometimes go negative in spring and summer). Value has is a number between 1 and 100. The trick to find what to send was using the app in local mode connected to the WiFi broadcasted from the inverter and capturing the packets with PCAPdroid. Below what I have in a NodeRed function what I send as an HTTP request to the local IP adress of the inverter:
|
Found an important bug in math today, fixed in nazar-pc/solax-local-api-docs#13 |
Solax Power in private conversation refused to disclose meaning of the parameters of the
ReadRealTimeData
endpoint, so I decided to go through the source code of the Android app (version 0.4.3) and extract everything I can from there, thankfully all the logic there is client-side in JS (though JS is minified, so it takes some effort).This will result in precise mapping the same exact way mobile app interprets data and will remove the need to guess values. With that information everything Android application supports will be also possible to support here in exactly the same way.
I'm only focusing on reading
ReadRealTimeData
values for now, but it would be possible to potentially replicate all the logic application supports if it is desirable (I'm a user of this library indirectly through Home Assistant, having ability to switch Work Mode, charge/discharge time and other things would be useful, but it would be a bit tricky to expose everything properly given how many inverter models they have and features are different for different inverters).Once I have basic version compiled, I'll open source it in GitHub repo and comment it here, this is just for tracking and discussion purposes for now.
cc @fxstein as you commented on home-assistant/home-assistant.io#25151
The text was updated successfully, but these errors were encountered: