[solax] binding

Hi mate.
I coded most of the extraction of values with exception of combining two short values in one (the read 32bit parts).
Problem I see and I may need your help to track these down. Problem though is treating the values as signed/unsigned numbers is not so obvious without some bit mapper or calculator.
See this unit test file: openhab-addons/bundles/org.openhab.binding.solax/src/test/java/org/openhab/binding/solax/internal/local/TestEVChargerParser.java at ev-charger-support · theater/openhab-addons · GitHub

Problem I see is that the provided values on the other guy’s github does not match the values from your output. At least I see major discrepancies (even in the raw data) between the tree phases for external current and external power. They should be realtively the same as the 3 phases are usually distributed even or I’m not right? Maybe you have separate single-phase consumers on the separate phases?

Please let me know your thoughts. Meanwhile I will continue the work to produce as you mentioned something like an “alpha” so you can test out…

Cheers,
K.

@Vaclav_Provaznik I’ve uploaded the very first alpha release. You can find it from the link of the very first page of this post. There is a link “unofficial releases”.
Feel free to give it a try and let me know if it works for you…
If it doesn’t, probably I’ll need a highest trace level logs. :slight_smile:
I skipped the last 4 data values currently and added the most obvious ones. Also the ones that require 32 bit combinings of two short values are not working…

Cheers,
Konstantin

Hi Konstantin, thanks, I will give it a try probably tomorrow.

Maybe I don’t understand, but I believe that in case of integer the sign is the first bit, therefore for all numbers up to half of the possible unsigned integer value, the values are the same. Once you get to value bigger than half (i.e. the first bit is already 1) than the result of is the actual number minus the maximum value of the integer - minus 1… e.g. 1111 is 15 unsigned - 15 - 1 is -1. 1000 is 8 unsigned - 15 - 1 = -8. So so 11xxx11 is always -1.

Lets see how the values map and maybe there were some updates to the protocol. I will try to debug and compare with the app / modbus readings, but this may take some time on my side.

Three phases don’t need to be ballanced, the 3phase euipment creates ballanced load, but there may be different equipments drwaing pwoer only from one phase. Usually electricians try to “ballance” the house so that different lights/plugs/equpments are not only on different breakers/fuses, but also different phases.

I will try to see the combination on the two small 16 ints (bit rotation or some easy function?) as this can get tricky especially when the result is something completely different (float).

Hi Joerg,
I checked the issue with the channel.
it seems that in the 4.1.x (the stable branch) the documentation has not been updated.
In 4.2.0 everything is OK, so when 4.2.0 becomes official release, it will be fixed.

Cheers,
K.

Hi,
I think I (hopefully) managed to do the 32bit readings too so if you test it, pls use the alpha2 version. (or if it doesn’t work at all, try the alpha1)
I tried the binding on my system and it appears to be working but unfortunately I don’t have the device to test it thoroughly.

Cheers,
K.

Hi Konstantin, first observations:
Object is up and running.
Wrong password however leaves it is “'UNKNOWN” status and throws following error in log:

2024-06-26 17:04:57.460 [WARN ] [mmon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 2 path $
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:397) ~[?:?]
        at com.google.gson.Gson.fromJson(Gson.java:1227) ~[?:?]
        at com.google.gson.Gson.fromJson(Gson.java:1137) ~[?:?]
        at com.google.gson.Gson.fromJson(Gson.java:1047) ~[?:?]
        at com.google.gson.Gson.fromJson(Gson.java:982) ~[?:?]
        at org.openhab.binding.solax.internal.connectivity.rawdata.local.LocalConnectRawDataBean.fromJson(LocalConnectRawDataBean.java:125) ~[?:?]
        at org.openhab.binding.solax.internal.handlers.SolaxLocalAccessAbstractHandler.parseJson(SolaxLocalAccessAbstractHandler.java:59) ~[?:?]
        at org.openhab.binding.solax.internal.handlers.SolaxLocalAccessChargerHandler.updateFromData(SolaxLocalAccessChargerHandler.java:57) ~[?:?]
        at org.openhab.binding.solax.internal.handlers.AbstractSolaxHandler.retrieveData(AbstractSolaxHandler.java:89) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
        at java.lang.Thread.run(Thread.java:840) [?:?]
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 2 path $
        at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:393) ~[?:?]
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:386) ~[?:?]
        ... 14 more

However I can only see “raw_data” channel (when checking advanced box).
It seems it gets populated with the object.

Am I missing something?

What are the channel names so that I can try to add them manually?

Hi,
the exception comes from the serialization of the object. I don’t know how it could even populate the raw data as the exception should stop any further execution.
It seems that the response is something different than what you have provided to me because the handler is doing exactly the same de-serialization like the test that runs fine…

You mentioned a wrong password. What do you mean?

Have you tried to delete the charger and re-create it?

P.S. i.e. from what looks like the exception says that it receives a number on line1 instead of the start of object, i.e. { sign.

P.S.2 the channels can be found here: openhab-addons/bundles/org.openhab.binding.solax/src/main/resources/OH-INF/thing/localConnectEVCharger.xml at ev-charger-support · theater/openhab-addons · GitHub

Let me explain… When I made a mistake in password, there was no error message, just the object stayed in the “UNKNOWN” status and the error was thrown.

I understand that this is a result of the feedback object not being what is expected, actually it returns

0:code,message:"failed"}

But before realizing the mistake in password I did some restarts, remove, add, etc. as I did not thing of wrong password, but more of improper initialization.

I did try to remove / reinstall thing/binding, but on the things page it still shows only one channel.

This is how the “code” of the thing looks like:

UID: solax:local-connect-charger:f63e0a2dd1
label: xxxLocal Connect Charger
thingTypeUID: solax:local-connect-charger
configuration:
  refreshInterval: 60
  password: "xxxxxx"
  hostname: 192.168.xxx.xxx
channels:
  - id: raw-data
    channelTypeUID: solax:raw-data-type
    label: Raw Data
    description: The raw JSON data retrieved from the inverter's Wi-Fi module.
    configuration: {}

I will try tomorrow to do a bigger restart/refresh.

BTW: Version installed is 4.2.0.202406250806 (alpha2) but seems morning timestamp?

I got it… I’ll try to handle this error. About the channels there are a couple of options but I may need the logs… Do you see the following debug message: “Detected unsupported channels for the current inverter. Channels to be removed: {}”
Can you check if the channels for your charger are removed?

I turned on TRACE for the binding and indeed I’m getting

2024-06-26 18:27:57.127 [DEBUG] [lers.SolaxLocalAccessAbstractHandler] - Detected unsupported channels for the current inverter. Channels to be removed: [eq-single-session, eq-total, charger-output-power-phase1, charger-output-power-phase2, charger-output-power-phase3, charger-total-output-power, charger-current-phase1, charger-current-phase2, charger-current-phase3, charger-voltage-phase1, charger-voltage-phase2, charger-voltage-phase3, charger-external-current-phase1, charger-external-current-phase2, charger-external-current-phase3, charger-external-power-phase1, charger-external-power-phase2, charger-external-power-phase3, charger-external-total-power, charger-plug-temperature, charger-internal-temperature, charger-mode, charger-state, last-update-time]

Thanks! That’s on me. Forgot to add the proper channels to the supported channels list.
new release published - alpha3

Thanks a lot! First quick report, need more time and sun to test charging.

All channels in place.

Mapping probably wrong, following error log appear even before linking items:

2024-06-27 18:01:45.955 [WARN ] [lers.SolaxLocalAccessAbstractHandler] - Channel charger-total-output-power is marked as supported, but its value is out of the defined range. Value = -32768.0. This is unexpected behaviour. Please file a bug.
2024-06-27 18:02:19.465 [WARN ] [.core.thing.binding.BaseThingHandler] - Handler SolaxLocalAccessChargerHandler tried updating the thing status although the handler was already disposed.
2024-06-27 18:02:47.241 [WARN ] [lers.SolaxLocalAccessAbstractHandler] - Channel charger-total-output-power is marked as supported, but its value is out of the defined range. Value = -32768.0. This is unexpected behaviour. Please file a bug.

Some items seem to be reading well already, some seem to be off.

More details tmrw or over wknd.

I fixed the total power channel issue (hopefully). :slight_smile:
Was indeed a wrong mapping of the channel to the data bean.
if you see any other like this, just let me know.

Thanks, it seems to me that all “total” channels (showing null) (ie also Total Energy Charged).

Also there may be some issue with calculating the “signed” values, as Current on Phase 2 showed -300A, which is beyond all limits.

I will try to play later today and grab both “raw” data and results when charging.

Great. Any further input would be appreciated. I’ll be away for the weekend but hopefully I’ll be able to catch up on Monday. Also plenty of time to test and check for you I guess :slight_smile:

v4 installed.

Following error appeared in openhab.log

2024-06-28 10:01:00.696 [WARN ] [re.xml.osgi.XmlDocumentBundleTracker] - The XML document '/OH-INF/thing/localConnectInverter.xml' in module 'org.openhab.binding.solax' could not be parsed:
---- Debugging information ----
cause-exception     : com.ctc.wstx.exc.WstxLazyException
cause-message       : [com.ctc.wstx.exc.WstxLazyException] /openhab/userdata/cache/org.eclipse.osgi/315/1/bundleFile
class               : org.openhab.core.config.core.xml.util.NodeValue
required-type       : org.openhab.core.config.core.xml.util.NodeValue
converter-type      : org.openhab.core.config.core.xml.util.NodeValueConverter
path                : /thing-descriptions/thing-type/channels/channel[39]/description
line number         : 172
class[1]            : java.util.ArrayList
required-type[1]    : java.util.ArrayList
converter-type[1]   : com.thoughtworks.xstream.converters.collections.CollectionConverter
class[2]            : org.openhab.core.thing.xml.internal.ChannelXmlResult
required-type[2]    : org.openhab.core.thing.xml.internal.ChannelXmlResult
converter-type[2]   : org.openhab.core.thing.xml.internal.ChannelConverter
class[3]            : org.openhab.core.config.core.xml.util.NodeList
required-type[3]    : org.openhab.core.config.core.xml.util.NodeList
converter-type[3]   : org.openhab.core.config.core.xml.util.NodeListConverter
class[4]            : org.openhab.core.thing.xml.internal.ThingTypeXmlResult
required-type[4]    : org.openhab.core.thing.xml.internal.ThingTypeXmlResult
converter-type[4]   : org.openhab.core.thing.xml.internal.ThingTypeConverter
class[5]            : org.openhab.core.thing.xml.internal.ThingDescriptionList
required-type[5]    : org.openhab.core.thing.xml.internal.ThingDescriptionList
converter-type[5]   : org.openhab.core.thing.xml.internal.ThingDescriptionConverter
version             : 1.4.20
-------------------------------
com.thoughtworks.xstream.converters.ConversionException:
---- Debugging information ----
cause-exception     : com.ctc.wstx.exc.WstxLazyException
cause-message       : [com.ctc.wstx.exc.WstxLazyException] /openhab/userdata/cache/org.eclipse.osgi/315/1/bundleFile
class               : org.openhab.core.config.core.xml.util.NodeValue
required-type       : org.openhab.core.config.core.xml.util.NodeValue
converter-type      : org.openhab.core.config.core.xml.util.NodeValueConverter
path                : /thing-descriptions/thing-type/channels/channel[39]/description
line number         : 172
class[1]            : java.util.ArrayList
required-type[1]    : java.util.ArrayList
converter-type[1]   : com.thoughtworks.xstream.converters.collections.CollectionConverter
class[2]            : org.openhab.core.thing.xml.internal.ChannelXmlResult

Charging stats seem to be working:

Pasting log including “raw” data

2024-06-28 11:24:42.698 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Raw_Data' changed from NULL to {"SN":"SQEHLPBUGJ","ver":"3.004.11","type":1,"Data":[2,2,24161,24189,24179,995,992,1008,2420,2413,2448,7271,29,0,2098,0,103,35463,65457,26,65526,38,65426,0,49,0,2,15,0,0,0,0,0,5008,5006,5000,6173,7179,6150,5,0,0,0,0,0,0,0,0,1,100,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,1732,0,14115,7178,6150,0,1,1,1,0,0,120,586,174,0,50,0,0,1,1,0],"Information":[11.000,1,"C31103J2625066",1,1.13,1.01,0.00,0.00,0.00,1],"OCPPServer":"","OCPPChargerId":""}
2024-06-28 11:24:42.705 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_Output_Current_Phase_1' changed from 7.27 A to 9.95 A
2024-06-28 11:24:42.705 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_Output_Current_Phase_2' changed from 7.32 A to 9.92 A
2024-06-28 11:24:42.705 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_Output_Current_Phase_3' changed from 7.31 A to 10.08 A
2024-06-28 11:24:42.705 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_Voltage_Phase_1' changed from 241.83 V to 241.61 V
2024-06-28 11:24:42.705 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_Voltage_Phase_2' changed from 242.31 V to 241.89 V
2024-06-28 11:24:42.705 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_Voltage_Phase_3' changed from 242.08 V to 241.79 V
2024-06-28 11:24:42.706 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_Output_Power_Phase_1' changed from 1765 W to 2420 W
2024-06-28 11:24:42.706 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_Output_Power_Phase_2' changed from 1779 W to 2413 W
2024-06-28 11:24:42.706 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_Output_Power_Phase_3' changed from 1773 W to 2448 W
2024-06-28 11:24:42.706 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_Output_Total_Power' changed from 5318 W to 7271 W
2024-06-28 11:24:42.706 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_External_Current_Phase_3' changed from 0.8 A to -0.79 A
2024-06-28 11:24:42.706 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_External_Power_Phase_1' changed from 3 W to 26 W
2024-06-28 11:24:42.706 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_External_Power_Phase_2' changed from -156 W to -10 W
2024-06-28 11:24:42.707 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_External_Power_Phase_3' changed from 152 W to 38 W
2024-06-28 11:24:42.707 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Charger_External_Total_Power' changed from -130 W to -110 W

Seems to me that:
Total Energy Charged is not working (perhaps similar issue as with the Total Power Channel?)

External Power Phase 1-3 could be legitimate (positive numbers mean export, negative import)

External Current seems could be also ok, but seems to me thatn Phase 2 is not receiving updates and got stuck with some historical value off limits.

About the XML issue… it’s interesting as I haven’t even touched this file. Maybe it’s something temporary. please let me know if it appears also after a restart of the OH. (sometimes the resources do such issues).

Total Energy Charged is not working (perhaps similar issue as with the Total Power Channel?)

Most values seem OK to me but Totals as you say could be wrong (mostly because of the 2x16 to 32bit conversion). If you could give me a response and expected number for the merged value, I can try to see what I do wrong. (keep in mind I don’t use the calculation from the python script. Tried to use Java native conversions)

External Current seems could be also ok, but seems to me that Phase 2 is not receiving updates and got stuck with some historical value off limits.

Not sure if I understand that right. Is it changing in the response but is not changing in the channel? (it’s the 7th element, i.e. the data[6])

It seems to me that the data get updated in “raw” but the channel does not update.

2024-06-28 12:57:12.987 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Raw_Data' changed from {"SN":"SQEHLPBUGJ","ver":"3.004.11","type":1,"Data":[2,2,24094,24137,24098,1194,1183,1209,2896,2874,2931,8702,120,0,2189,0,101,35463,65456,30,65374,45,65373,0,49,0,2,15,0,0,0,0,0,5010,5008,5004,13880,7180,6150,5,0,0,0,0,0,0,0,0,1,100,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,7160,0,14115,7178,6150,0,1,1,1,0,0,121,583,209,0,50,0,0,1,1,0],"Information":[11.000,1,"C31103J2625066",1,1.13,1.01,0.00,0.00,0.00,1],"OCPPServer":"","OCPPChargerId":""} to {"SN":"SQEHLPBUGJ","ver":"3.004.11","type":1,"Data":[2,2,24103,24097,24106,1227,1199,1223,2976,2908,2967,8852,123,0,2192,0,105,35463,65451,247,65462,65363,65439,0,49,0,2,15,0,0,0,0,0,5004,5006,5000,14393,7180,6150,5,0,0,0,0,0,0,0,0,1,100,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,7281,0,14115,7178,6150,0,1,1,1,0,0,120,586,213,0,50,0,0,1,1,0],"Information":[11.000,1,"C31103J2625066",1,1.13,1.01,0.00,0.00,0.00,1],"OCPPServer":"","OCPPChargerId":""}
2024-06-28 12:59:14.283 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'xxx_Local_Connect_Charger_Raw_Data' changed from {"SN":"SQEHLPBUGJ","ver":"3.004.11","type":1,"Data":[2,2,24103,24097,24106,1227,1199,1223,2976,2908,2967,8852,123,0,2192,0,105,35463,65451,247,65462,65363,65439,0,49,0,2,15,0,0,0,0,0,5004,5006,5000,14393,7180,6150,5,0,0,0,0,0,0,0,0,1,100,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,7281,0,14115,7178,6150,0,1,1,1,0,0,120,586,213,0,50,0,0,1,1,0],"Information":[11.000,1,"C31103J2625066",1,1.13,1.01,0.00,0.00,0.00,1],"OCPPServer":"","OCPPChargerId":""} to {"SN":"SQEHLPBUGJ","ver":"3.004.11","type":1,"Data":[2,2,24206,24184,24205,581,583,587,1409,1415,1424,4249,125,0,2194,0,65435,35463,65461,65532,65493,2,61870,0,49,0,2,15,0,0,0,0,0,5008,5008,5002,14907,7180,6150,5,0,0,0,0,0,0,0,0,1,100,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,7403,0,14115,7178,6150,0,1,1,1,0,0,120,583,100,0,50,0,0,1,1,0],"Information":[11.000,1,"C31103J2625066",1,1.13,1.01,0.00,0.00,0.00,1],"OCPPServer":"","OCPPChargerId":""}

Total Charged Energy in this case should be somewhere close to 219.9kWh (seen in web GUI, may have some delay).

Will try to do some more tests/restarts/calculations over weekend, but it is already pretty good :wink:

oops… pardon. We’re talking about the external current. It’s indexes are 16, 17 and 18 (which is the 15th, 16th and 17th element).
So from one of your log dumps: 101,35463,65456, should be the values of the currents and
30,65374,45 should be the values of the power. They just don’t match looking at the numbers. The current should be proportional to the power but that’s what I got in the parser by the other guy in the DataEvCharger.txt

Hmm. There cen be a combination of several factors:

  • the meter readings are not continuous so in case of “jumps” there would be discrepancies
  • I would guess that the “suspicious” high numbers are actually “small negatives” (first bit sign)
  • there may be a “swap” between phases

Still it seems to me that all three numbers get updated in the raw. But it may be on my end, I would like to remove items/thins/binding, restart, start from scratch, restart twice and see… More time needed though :wink: