[solax] binding

Ok, first try was a complete failure. The inverter talks fine with Solax Cloud, however it doesn’t seem to be reachable locally at all (did a full portscan, turned out blank). They are gonna fix me a new one though, since this one was also too old to get me 10 seconds readings, so I guess we will have to wait for that :slight_smile:

Hi again.
Still waiting for my new lan module. While waiting I started actually reading into what the binding can do and I realize it doesn’t seem to do the thing I primarily thought I could use it for, and that’s changing the inverters settings, like affecting work mode or the forced charge period. Is this something that’s not available from the API? My plan was to force charge the battery from grid during cheap hours if the prognosis shows low income from the panels the next day…

Hi Daniel,
currently changes(commands) to the inverter are not possible.
If I find a documentation / similar code where it’s implemented, I guess we can add that to the binding. I’m not sure if the API even supports such a thing though…
If you come to any implementation, please let me know.

Cheers,
K.

1 Like

Hi Daniel, Konstantin & all.
I am actually doing what you are describing (and more), but not using the binding, but going through Modbus. I’m also using this binding as some readings get reset in Modbus (totals) so they are not usefull for long series, thay can be used for quicker data read and write.

The key use cases I have automated by now are:

  • Reading solar forecast for my location
  • Reading spot energy price (I sell/export surplus for spot) & EUR rate to convert
  • Early morning during “low energy price” I calculate energy needed until another “low price” window, tak into account expected gain, current battery status and some “margin for error” and if needed I charge the battery to a level that should cover until another “low price”, but not too much so that if sun is shining (or more than expected) I do not necessarily export because battery contains preloaded energy
  • I optimize export in the morning so that when there is a good forecast and algorhytm expects surplus (exports) I rather disable battery charging in the morning when export spot prices are higher and enable later, when the price drop
  • I completely block the export if the export price (spot-margin) is <0 so that I don’t get “penalized”
  • If no charging is needed I disable “night charging” and also reset “forced charging hours” as when they are set Solax does not live from battery despite “night charging is not enabled”

I based this on some other thread here, but had to get the current Modbus specification for X3 and update the definitions (things).

I have very ugly definitions and completely unelegant algorhitms, but they do the job. Can share if need be. Just its not relevant for this binding.

2 Likes

That hillarious! I just found your other thread describing this earlier today and was just about to make a reference to it here :joy:

Anyway, yep, I think I’m going for the Modbus approach as well. I’m waiting for my new lan module which according to my intel should support Modbus TCP. What would be really nice would be having this built into the Solax binding, but I guess that would mean quite a big work.

Yes, I believe both WiFi and LAN dongle have Modbus over IP in specifications. I believe the nature of this binding is very different (http api) so would probably not be ok to combine different transport layers into one binding as also some metrics overlap.
On the other hand it would probebly not be that difficult to build a “new binding on top of Modbus”, but what do I know. Combination of this binding and Modbus does the job for me, the only “downside” of the Modbus is that each each metric shows as single thing with single channel and so that the thing list is “cluttered” with many things “Modbus data”. If you need any help we cen move to the other thread and continue there where it belogs :slight_smile:

Just for the record: The pocket LAN v3 dongle does NOT have this function, it isn’t reachable locally over neither API nor Modbus. It needs to be version 4 of the module for that, which from what I understand is a quite new version.

That’s appreaciated! I’ll start a new thread (the one I found where you’d written about this is locked for some reason) and tag you! I guess it’s time to stop polluting this thread now :laughing:

Hi guys,
please refer the thread here, so anyone interested in the modbus integration does not have to search for that :slight_smile:
(I’m also interested for more functionality)

@Vaclav_Provaznik where do you get the forecast for the location and how do you consider it into your rules? Is it from some weather API?
I’m doing some “reactive” charging of my car trying to optimize the solar production to be maxed while maintaining battery and energy from the provider at minimum but I wonder if such a forecast may also be another parameter…

Thanks in advance,
K.

Yep: Solax Hybrid X1/X3 Inverter RealTime Data and control locally

Regarding the forecast, I installed the Solar Forecast PV binding yesterday, seems to do a very good job, more about it here: Solar Forecast PV

1 Like

Hi Konstantin,

same as @DanielMalmgren I’m using the Solar Forecast binding. I found SolCast more accurate, even though it only has 10 API calls for free / day. Strangely it seems that every refresh is using two calls for me so its basically 5 updates per day, but I use script to desdable the binding, so that I don’t waste them (kind of brute force). See the linked thread for detail.

It hase very convenient “Remaining Today” parameter which I use for calculations both early morning and during the time of peak price.

As said above my key lessons learned are:

  • Solax seems to honor “Forced Charge” window even when Night_Charging is disabled, so to prevent using grid in that window I also set it to 0:00-0:00 when disabling Night_Charging
  • Easiest way to “force export” during peak hours in the morning when battery is still empty is to switch to “FeedIn mode” (1). Don’t forget to set it back (timer and/or cron)
  • Setting export to 0 prevents exports during time with negative price (can adjust provider margin)
  • IMPORTANT: Export in modbus is in 10s of Watts, so for setting 14kW I need to set 1400
  • IMPORTANT: Dis/charging date/time in Modbus are 8bit (upper and lower from 16bits) for reading, but Modbus binding can’t write 8bits so you can only write byte. The guys in Solax planted a big trap as the Hour/Minute are reversed when Writing, so sometimes it kind of works (like 1:01 = 1:01), sometime is screws setting, but works (like 2:01 <>1.02 but is valid time) and sometimes it just forces error 4 (Modbus refused) (eg. 3:30 <> 30:03 but it is also invalid value).

Sorry to pick up this discussion.
Is there any chance to integrate the Solax Charger?
Curl command to get realtime local data: curl -d “?optType=ReadRealTimeData&pwd=PASSWORD” -X POST http://IP_ADDRESS
Description of the received data:

I’m pity not being a developer :frowning:

Hi Konstantin,

Thank you so much for the Solax binding and dedication.
I am trying to use the 4.1.1 OpenHab Solax binding for local connection to my X1 boost inverter, but keep getting the Thing with status offline and following message at the “Thing” configuration page:

“Parser for inverter of type X1_BOOST_AIR_MINI is not implemented.” - Looking at the code in the GitHub repository I found this inverter type (4) with that name, so this message was really not expected.

About the same time, when I curl to the wifi 3 pocket pen from the command line I get response from the inverter.
I was looking for the Raw channel you mention here, but could not find it, nor I believe it would even work, since OpenHab sees the Solax Thing as offline.

Could you please advise on my next actions for a better troubleshooting?

thank you!
Hugo

Hi,
as a first step I would propose that you move to the 4.2 milestone build. :slight_smile:
As far as I see the relevant changes are there. See here: Release openHAB 4.2 Milestone 1 · openhab/openhab-distro · GitHub

Cheers,
K.

P.S. Of course I would recommend using the very latest milestone build available (not M1) so you get the latest fixes too… :slight_smile:

Thank you very much! I will follow your suggestions and provide update on how it went.
I was considering to use curl requests and consuming them into OH, but I prefer using and if I can, helping towards this binding.

Cheers!
Hugo

Hi,
yes. You could also use the HTTP client binding and use the JSONPath transformation to retrieve the data but as there is out of the box binding, I guess it’s far less effort to use it.
That’s why I have created it. :slight_smile:

Cheers,
K.

For sure this way is far more convenient for me.
Updating to 4.2.0.M3 did the trick! and now I have OH talking to the inverter via LAN. Thanks!
Now it seems the “house consumption” channel is always reporting 0W. I am guessing this could have something to do with the inverter type’s (type 4 - x1 boost) mapping.
Over the next few days I will use the Raw channel and cross it with some mappings available for this inverter type. Could it be a matter of knowing what positions of “Data” vector/array this info should be grabbed from?

Yeah. Definitely.
If you find out about new channels or wrong ones let me know or create a PR for the changes.
I coded that based on parsers i have found on the internet and also there could be a mistake somewhere. That’s why i have created a unit test that checks against a real data dump but I’m not 100% sure about the values in the array positions.

Hi,
Checking raw data during night and during day, I suspect the relevant array positions are 48 (and probably 49). The following function (as stated here: solax/solax/utils.py at 4c4bc83bf4ec1538f00621177e33cfc3fef428a7 · squishykid/solax · GitHub) will report the real value.

def to_signed(val, *_args, **_kwargs):
    if val > 32767:
        val -= 65535
    return val

I have two doubts:

  1. which of these are the “to grid” and “house consumption” fields?
  • I will make further verifications and compare the raw against the values from cloud to have a better understanding of this.
  1. does OpenHAB Solax binding watch these array positions for the X1 Boost 3.6 Inverter (type 4)?
  • this will take me a bit more time to check the OH Solax binding code

Cheers,
Hugo

Good day!
Looking into the Solax binding code I found the following on Feed-in and Power usage.
I started with the inverter reported in OH: X1_BOOST_AIR_MINI

Feed-in:
in X3HybridG4InverterData.java - indexes 34 and 35, which differ from 48 and 49

    @Override
    public short getFeedInPower() {
        return (short) (getData(34) - getData(35));
    }

in X1HybridG4InverterData.java - index 32, which differs from 48 or 49

    @Override
    public short getFeedInPower() {
        return getData(32);
    }

Power Usage:
in X3HybridG4InverterData.java - index 47, which differs from 48 or 49

    @Override
    public short getPowerUsage() {
        return getData(47);
    }

In OH, I see no channel named as “Feed-in” or similar. Just “Power usage”.
It looks like the X1_BOOST_AIR_MINI inverter needs extension for dealing with its own feed-in and power usage indexes (48 and 49, not necessarily respective - I will investigate & reach a conclusion here soon.).

For reference, here is a real sample of my inverter’s raw data, obfuscating the SN and inverter id:

{"sn":"SR1A1AAAAA","ver":"3.009.03","type":4,"Data":[2367,14,289,2962,0,10,0,299,0,5001,2,988,0,6,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,24,0,212,0,0,0,0,0,0,65523,65535,362,0,15740,0,0,31,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":[3.680,4,"XB1111AA111111",8,2.29,0.00,1.45,0.00,0.00,1]} 

So I would like to kindly suggest the Solax binding to support this, perhaps as a new feature?
I would love to collaborate with this, but considering my fairly low knowledge level I would damage rather than benefit the binding… apologies here.

Hi,
you’re right…

 updateChannel(SolaxBindingConstants.CHANNEL_FEED_IN_POWER, inverterData.getFeedInPower(), Units.WATT,
                supportedChannels);

This means that on the FEED_IN_POWER channel we assign the value of the getFeedInPower() method (if it’s implemented in the respective parser).
If it’s not implemented but we have the data, we could add it relatively easy as a feature. :slight_smile:
Just make sure 48 (or 49… or both) index is the right one and let me know when you confirm it.

I just need to add the channel to the list of supported channels in the parser here:

and then I need to add the proper getter from the raw data array here:

Cheers,
K.