Local Openhab/Solax X1 Integration

There are instructions on how to feed data from the Solax X1 solar inverter into Openhab via the vendor’s cloud service. For those interested in keeping communication local, here’s how to do it.

  1. Set up a local MQTT/Mosquitto server
  2. Make sure that the MQTT server listens at port 2901. (For Mosquitto add the line “listener 2901” to mosquitto.conf)
  3. Redirect all DNS queries for mqtt001.solaxcloud.com and mqtt002.solaxcloud.com to your local MQTT server IP.
  4. Install the MQTT binding in Openhab and configure it like this in your things-file:

    Bridge mqtt:broker:brokerhome [ host="", secure=false ]{
    Thing topic solax {
    Channels:
    Type string : inverter “State [%s]” [stateTopic=“loc/xxxxxx”]
    }
    }

    “xxxxx” should be replaced with the serial number of your LAN stick. (I guess it should work in the same/similar way with a WLAN stick.)

These are my items:

Group gSolarPower
String inverter_state “[JSONPATH($.Data):%s]” {channel=“mqtt:topic:brokerhome:solax:inverter”}
Number:ElectricCurrent iPV_Current1 “PV1 Current [%.1f A]” (gInitializeZero,gSolarPower)
Number:ElectricCurrent iPV_Current2 “PV2 Current [%.1f A]” (gInitializeZero)
Number:ElectricPotential iPV_Voltage1 “PV1 Voltage [%.1f V]” (gInitializeZero,gSolarPower)
Number:ElectricPotential iPV_Voltage2 “PV2 Voltage [%.1f V]” (gInitializeZero)
Number:ElectricCurrent iPV_Grid_A “Grid Output Current [%.1f A]” (gInitializeZero,gSolarPower)
Number:ElectricPotential iPV_Grid_V “Grid Voltage [%.1f V]” (gInitializeZero,gSolarPower)
Number:Power iPV_Grid_W “Grid Power [%.1f W]” (gInitializeZero,gSolarPower)
Number:Temperature iPV_inverter_temp “Inverter Temperature [%.0f °C]” (gInitializeZero,gSolarPower)
Number:Energy iPV_kWh_daily “Inverter Yield - Today [%.1f kWh]” (gInitializeZero,gSolarPower)
Number:Energy iPV_kWh_total “Inverter Yield - Total [%.1f kWh]” (gInitializeZero,gSolarPower)
Number:Frequency iPV_gridFrequency “Grid Frequency [%.2f Hz]” (gInitializeZero,gSolarPower)
Number iPV_inverter_status “Status [%.0f]” (gInitializeZero,gSolarPower)

And here is a rule that is triggered on every update to parse the MQTT-data from the inverter:

rule “parse solar inverter data on update”
when
Item inverter_state changed
then
val state_json = transform(“JSONPATH”, “$.Data”, inverter_state.state.toString)
val state_data = state_json.replace(’[’, ‘’).replace(’]’, ‘’)
val state_tmp = state_data.split(’,’)

iPV_Current1.postUpdate(Float::parseFloat(state_tmp.get(0)))
iPV_Current2.postUpdate(Float::parseFloat(state_tmp.get(1)))
iPV_Voltage1.postUpdate(Float::parseFloat(state_tmp.get(2)))
iPV_Voltage2.postUpdate(Float::parseFloat(state_tmp.get(3)))
iPV_Grid_A.postUpdate(Float::parseFloat(state_tmp.get(4)))
iPV_Grid_V.postUpdate(Float::parseFloat(state_tmp.get(5)))
iPV_Grid_W.postUpdate(Float::parseFloat(state_tmp.get(6)))
iPV_inverter_temp.postUpdate(Float::parseFloat(state_tmp.get(7)))
iPV_kWh_daily.postUpdate(Float::parseFloat(state_tmp.get(8)))
iPV_kWh_total.postUpdate(Float::parseFloat(state_tmp.get(9)))
iPV_gridFrequency.postUpdate(Float::parseFloat(state_tmp.get(50)))
iPV_inverter_status.postUpdate(Float::parseFloat(state_tmp.get(68)))
end

And here are my sources for this setup:

This approach is working fine for me, except for some hiccups where data is not delivered to my Mosquitto instance. I guess it’s some issue with DNS resolution - will update this post once I know more.

UPDATE
The hiccups in data delivery were indeed caused by DNS issues in my internal network, where the real address of the Solax cloud service was delivered instead of the local MQTT server.

Also I managed to find out the meaning of some status values delivered by the inverter. Here is my solaxstatus.map

0=unknown
1=Grid sync
2=Normal
3=Lost grid
NULL=NULL
-=NA
=NA

In the .items file the iPV_inverter_status needs to become a String.
String iPV_inverter_status “Status [%s]” (gInitializeZero,gSolarPower)

Finally, the last line in the parsing rule needs to be replaced with the following:
iPV_inverter_status.postUpdate(transform(“MAP”, “solaxstatus.map”, state_tmp.get(68).toString.replace(’ ‘,’’)))

I have WLAN Wifi Packet 2.0 firmware 2.034.06 and mqtt messages don’t looks like JSON, here is example:
loc/tsp/XXXXXXXXXX $$�XXXXXXXXXXYYYYYYYYYYYYYY�m � Z LLOS
� y�������2.034.06|ff�5

XXXXXXXXXX - Wifi serial number
YYYYYYYYYYYYYY - inverter serial number

Does LAN module sends nice formatted mqtt messages?

Hi,

i use a Raspberry Pi as “Wifi/LAN Bridge”. It is connected to the Wifi of the Solax S1 and is running a Docker-webserver serving the Values via LAN. OpenHAB connects to the Website running on the Pi via LAN interface.

See GitHub - BoBiene/SolaxHttpServer and Docker Hub

Sorry for the delay, didn’t check in for a while.

Yes, my LAN module sends proper MQTT messages and the decoding has never been an issue for me. Where/how did you get the above results?