Here is tutorial to complete control and read data from Solax Inverter X1/X3 (maybe others, but data can be wrong). It is connected directly to lan by RJ45 cable (No wifi required). Labels are in czech, but I hope, you can easily translate it.
Don´t change settings frequently, because EEPROM of Solax has limited number of writings (I think 1 million) so 7 changes a day should be ok, do not use more.
There is a lot more settings and data for your Solax available via modbus, but I didn’t put that here because you could damage the inverter.
Requirements:
Modbus binding
JS transformation
Rules and transform files included here
Transform files add to transform/Solax
Solax_mode.map
-=missing
NULL=NULL
//Battery Mode
0=Self Use
1=ForceTimeUse
2=Back Up Mode
3=Feedin Priority
OFF=OFF
//Inverter Mode
100=Wait Mode
101=Check Mode
102=Normal Mode
103=Fault Mode
104=Permanent Fault Mode
105=Update Mode
106=EPS Check Mode
107=EPS Mode
108=Self-Test Mode
109=Idle Mode
110=Standby Mode
111=Pv Wake Up Bat Mode
112=Gen Check Mode
113=Gen Run Mode
Solax_RunMODE.map
-=missing
NULL=NULL
0=Wait Mode
1=Check Mode
2=Normal Mode
3=Fault Mode
4=Permanent Fault Mode
5=Update Mode
6=EPS check mode
7=EPS mode
8=Self Test
9=Idle Mode
Javascript need to paste to transform/
divide_by_10.js file
(function(i) {
return parseFloat(i) / 10;
})(input)
divide_by_100.js file
(function(i) {
return parseFloat(i) / 100;
})(input)
Thing file (you have to change IP of inverter and you can set refresh value, now is 10s, minimum is 0,5s):
Bridge modbus:tcp:localhostTCP [ host="IP_ADDRESS_OF_INVERTER", port=502, id=2 ] {
Bridge poller inputRegisters [ start=0, length=99, refresh=10000, type="input" ] {
Thing data NetworkVoltage [ readStart="0" , readValueType="uint16", readTransform="JS(divide_by_10.js)"]
Thing data OutputCurrent [ readStart="1", readValueType="int16", readTransform="JS(divide_by_10.js)" ]
Thing data ACPower [ readStart="2", readValueType="int16" ]
Thing data PV1Voltage [ readStart="3", readValueType="uint16", readTransform="JS(divide_by_10.js)" ]
Thing data PV2Voltage [ readStart="4", readValueType="uint16", readTransform="JS(divide_by_10.js)" ]
Thing data PV1Current [ readStart="5", readValueType="uint16", readTransform="JS(divide_by_10.js)" ]
Thing data PV2Current [ readStart="6", readValueType="uint16", readTransform="JS(divide_by_10.js)" ]
Thing data RunMODE [ readStart="9", readValueType="uint16"]
Thing data PowerDC1 [ readStart="10", readValueType="uint16" ]
Thing data PowerDC2 [ readStart="11", readValueType="uint16" ]
Thing data BatteryPowerCharge [ readStart="22", readValueType="int16" ]
Thing data BatteryTemp [ readStart="24", readValueType="int16" ]
Thing data BatterySOC [ readStart="28", readValueType="uint16" ]
Thing data BatteryOutputEnergyToday [ readStart="32", readValueType="uint16", readTransform="JS(divide_by_10.js)" ]
Thing data FeedInPower [ readStart="70", readValueType="int16" ]
Thing data FeedInTotal [ readStart="72", readValueType="int16" ]
Thing data DailyYield [ readStart="80", readValueType="int16", readTransform="JS(divide_by_10.js)"]
}
Bridge poller inputRegisters100 [ start=100, length=99, refresh=10000, type="input" ] {
Thing data feedin_energy_today [ readStart="152", readValueType="uint16", readTransform="JS(divide_by_100.js)"]
Thing data consum_energy_today [ readStart="154", readValueType="uint16", readTransform="JS(divide_by_100.js)"]
Thing data GridCurrent_R1 [ readStart="107", readValueType="int16", readTransform="JS(divide_by_10.js)" ]
Thing data GridPower_R1 [ readStart="108", readValueType="int16" ]
Thing data GridCurrent_S2 [ readStart="111", readValueType="int16", readTransform="JS(divide_by_10.js)" ]
Thing data GridPower_S2 [ readStart="112", readValueType="int16" ]
Thing data GridCurrent_T3 [ readStart="115", readValueType="int16", readTransform="JS(divide_by_10.js)" ]
Thing data GridPower_T3[ readStart="116", readValueType="int16" ]
Thing data Temperature [ readStart="190", readValueType="int16" ]
}
Bridge poller holdingRegisters100 [ start=100, length=99, refresh=10000, type="holding" ] {
Thing data Battery1_MinCapacity [ readStart="140", readValueType="uint16", writeStart="32", writeValueType="uint16", writeType="holding"]
Thing data Language [ readStart="187", readValueType="uint16", writeStart="71", writeValueType="uint16", writeType="holding"]
Thing data Export_Control_User_Limit [ readStart="182", readValueType="uint16", writeStart="66", writeValueType="uint16", writeType="holding"]
Thing data EPS_Mute [ readStart="183", readValueType="uint16", writeStart="67", writeValueType="uint16", writeType="holding"]
Thing data WorkingMode [ readStart="139", readValueType="uint16", writeStart="31", writeValueType="uint16", writeType="holding"]
}
Bridge poller holdingRegisters200 [ start=200, length=99, refresh=1000, type="holding" ] {
Thing data GridTiedLimit [ readStart="274", readValueType="uint16", writeStart="167", writeValueType="uint16", writeType="holding" ]
}
}
Item file:
Group gSolax "Solax Inverter"
Group:Number:SUM gPowerDC "Výkon panelů [%.0f W]" (gSolax)
Number Solax_PowerDC1 "Výkon panelů DC1 [%.0f W]" (gPowerDC) { channel="modbus:data:localhostTCP:inputRegisters:PowerDC1:number" }
Number Solax_PowerDC2 "Výkon panelů DC2 [%.0f W]" (gPowerDC) { channel="modbus:data:localhostTCP:inputRegisters:PowerDC2:number" }
Number Solax_BatterySOC "Nabití baterie [%.0f%%]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:BatterySOC:number" }
Number Solax_TempRadiator "Teplota měniče [%.0f °C]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters100:Temperature:number" }
Number Solax_ACPower "Aktuální Výkon měniče [%.0f W]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:ACPower:number" }
Number Solax_NetworkVoltage "Napětí v síti [%.2f V]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:NetworkVoltage:number" }
Number Solax_OutputCurrent "Výstupní proud měniče [%.2f A]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:OutputCurrent:number" }
Number Solax_PV1Voltage "Napětí panelů PV1 [%.2f V]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:PV1Voltage:number" }
Number Solax_PV2Voltage "Napětí panelů PV2 [%.2f V]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:PV2Voltage:number" }
Number Solax_PV1Current "Proud panelů PV1 [%.2f A]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:PV1Current:number" }
Number Solax_PV2Current "Proud panelů PV2 [%.2f A]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:PV2Current:number" }
Number Solax_RunMODE "Provozní režim [MAP(Solax/Solax_RunMODE.map):%s]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:RunMODE:number" }
Number Solax_ConsumeFromGridToday "Dnešní Spotřeba ze sítě [%.2f kWh]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters100:consum_energy_today:number" }
Number Solax_FeedInPower "Elektřina --ze/do++ sítě [%.0f W]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:FeedInPower:number" }
Number Solax_FeedInTotal "Feed in total [%.2f W]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:FeedInTotal:number" }
Number Solax_FeedinEnergyToday "Dnešní Dodávka do sítě [%.2f kWh]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters100:feedin_energy_today:number" }
Number Solax_Language "Jazyk" (gSolax) { channel="modbus:data:localhostTCP:holdingRegisters100:Language:number" }
Number Solax_HouseConsumption "Spotřeba domu [%.0f W]" (gSolax)
Number Solax_DailyYield "Výroba dnes [%.2f kWh]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:DailyYield:number" }
Number solax_ExportControlUserLimit "Export Control User Limit [%.0f W]" (gSolax) { channel="modbus:data:localhostTCP:holdingRegisters100:Export_Control_User_Limit:number" }
Number solax_WorkingMODE "Working Mode [MAP(Solax/Solax_mode.map):%s]" (gSolax) { channel="modbus:data:localhostTCP:holdingRegisters100:WorkingMode:number" }
Switch solax_EPS_Mute "EPS Mute" (gSolax) { channel="modbus:data:localhostTCP:holdingRegisters100:EPS_Mute:switch" }
Number Solax_BatteryPowerCharge "Nabíjení++/--Vybíjení Baterie [%.0f W]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:BatteryPowerCharge:number" }
Number Solax_BatteryTemp "Teplota baterie [%.0f °C]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:BatteryTemp:number" }
Number Solax_BatteryMinCapacity "Minimální nabití baterie [%.0f%% ]" (gSolax) { channel="modbus:data:localhostTCP:holdingRegisters100:Battery1_MinCapacity:number" }
Number Solax_BatteryOutputEnergyToday "Dnešní výdej baterie [%.2f kWh ]" (gSolax) { channel="modbus:data:localhostTCP:inputRegisters:BatteryOutputEnergyToday:number" }
Number Solax_GridTiedMinSetCapacity "Min. kapacity baterie při napájení ze sítě [%.0f%% ]" (gSolax) { channel="modbus:data:localhostTCP:holdingRegisters200:GridTiedLimit:number" }
Group:Number:SUM gGridCurrentSum "Proud procházející fázemi [%.0f A]" (gSolax)
Group:Number:SUM gGridPowerSum "Spotřeba procházející fázemi [%.0f W]" (gSolax)
Number Solax_GridCurrent_R1 "Proud 1.Fáze [%.1f A]" (gGridCurrentSum) { channel="modbus:data:localhostTCP:inputRegisters100:GridCurrent_R1:number" }
Number Solax_GridPower_R1 "Spotřeba 1. Fáze [%.0f W]" (gGridPowerSum) { channel="modbus:data:localhostTCP:inputRegisters100:GridPower_R1:number" }
Number Solax_GridCurrent_S2 "Proud 2.Fáze [%.1f A]" (gGridCurrentSum) { channel="modbus:data:localhostTCP:inputRegisters100:GridCurrent_S2:number" }
Number Solax_GridPower_S2 "Spotřeba 2. Fáze [%.0f W]" (gGridPowerSum) { channel="modbus:data:localhostTCP:inputRegisters100:GridPower_S2:number" }
Number Solax_GridCurrent_T3 "Proud 3.Fáze [%.1f A]" (gGridCurrentSum) { channel="modbus:data:localhostTCP:inputRegisters100:GridCurrent_T3:number" }
Number Solax_GridPower_T3 "Spotřeba 3. Fáze [%.0f W]" (gGridPowerSum) { channel="modbus:data:localhostTCP:inputRegisters100:GridPower_T3:number" }
For House Load you have to use rule:
rule "Null correction"
when
Item Solax_ACPower received update or
Item Solax_FeedInPower received update
then
if (Solax_PowerDC1.state == NULL) {Solax_PowerDC1.sendCommand(0)}
if (Solax_PowerDC2.state == NULL) {Solax_PowerDC2.sendCommand(0)}
end
rule "House Load"
when
Item Solax_ACPower received update or
Item Solax_FeedInPower received update
then
var Number Consumption
Consumption=(Solax_ACPower.state as Number - Solax_FeedInPower.state as Number)
Solax_HouseConsumption.sendCommand(Consumption)
end
Sitemap:
Text item=gPowerDC icon="solar" label="Solax Inverter" {
Frame label="Basic Data" {
Group item=gPowerDC label="Výkon panelů" {
Text item=Solax_PowerDC1 label="Výkon panelů 1"
Text item=Solax_PowerDC2 label="Výkon panelů 2"
}
Text item=Solax_BatterySOC label="Kapacita baterie"
Text item=Solax_FeedInPower label="Elektřina --ze/do++ sítě" valuecolor=[Solax_FeedInPower==Uninitialized="lightgray", >=1="green", <=0="red"]
Text item=Solax_BatteryPowerCharge label="Nabíjení++/--Vybíjení Baterie" valuecolor=[Solax_BatteryPowerCharge==Uninitialized="lightgray", >=1="green", <=0="red"]
Text item=Solax_HouseConsumption label="Spotřeba domu"
}
Frame label="Enhanced Data" {
Text item=Solax_FeedinEnergyToday label="Dnešní dodávka do sítě"
Text item=Solax_ConsumeFromGridToday label="Dnešní odběr ze sítě"
Text item=Solax_DailyYield label="Dnešní výroba"
Text item=Solax_ACPower label="Aktuální Výkon měniče"
Text item=Solax_TempRadiator label="Teplota chladiče měniče"
Text item=Solax_RunMODE label="Režim měniče"
Group item=gGridCurrentSum icon="solar" label="Proud fází" {
Text item=Solax_GridCurrent_R1 label="Proud 1. fáze"
Text item=Solax_GridCurrent_S2 label="Proud 2. fáze"
Text item=Solax_GridCurrent_T3 label="Proud 3. fáze"
}
Group item=gGridPowerSum icon="solar" label="Výkon fází" {
Text item=Solax_GridPower_R1 label="Výkon 1. fáze"
Text item=Solax_GridPower_S2 label="Výkon 2. fáze"
Text item=Solax_GridPower_T3 label="Výkon 3. fáze"
}
}
Frame label="Battery data" {
Text item=Solax_BatterySOC label="Kapacita baterie"
Text item=Solax_BatteryPowerCharge label="Aktuální Nab++/--Vyb Baterie" valuecolor=[Solax_BatteryPowerCharge==Uninitialized="lightgray", >=1="green", <=0="red"]
Text item=Solax_BatteryTemp label="Teplota baterie"
Text item=Solax_BatteryMinCapacity label="Minimální kapacita baterie"
Text item=Solax_BatteryOutputEnergyToday label="Dnešní výdej z baterie"
}
Frame label="Settings" {
Selection item=Solax_Language label="Language" icon="chicken" mappings=[ 0="English", 1="Deutsch", 2="Français", 3="Polski", 4="Italiano" ]
Selection item=solax_WorkingMODE label="Working Mode" icon="chicken" mappings=[ 0="Self Use", 1="ForceTime Use", 2="Back Up Mode", 3="Feedin Priority" ]
Switch item=solax_EPS_Mute label="Vypnout pípání EPS"
Setpoint item=Solax_GridTiedMinSetCapacity label="Minimální kapacita baterie při připojení sítě" minValue=0 maxValue=100 step=1
Setpoint item=solax_ExportControlUserLimit label="Nastavení max. toku do sítě" minValue=0 maxValue=60000 step=1000
}
}