When the result of the commandString is to cause some action (e.g. turn on a light, change a thermostat to a new temperature, etc.) then use sendCommand. When interacting with widgets on the user interfaces commands are sent to the Items.
You should see in the logs, if debug is switched on for the binding, DEBUG org.openhab.binding.sunsynk.internal.api.DeviceController Trying to send commands to inverter: xxxxxxx between the token message and get STATE message as below:
INFO openhab.event.ItemStateChangedEvent
Item 'Interval2GridCapacity' changed from 93 to 90
...
DEBUG
org.openhab.binding.sunsynk.internal.api.AccountController
Account configuration token not expired.
DEBUG
org.openhab.binding.sunsynk.internal.api.DeviceController
Trying to send commands to inverter: xxxxx
DEBUG
org.openhab.binding.sunsynk.internal.api.DeviceController
Will get STATE for Inverter inverterName serial xxxxxx
You get the same result as .sendCommand if you use the Main GUI Go to the Inverter Thing channels and check show advanced, click on the ‘V’ for the channel you want to change. Then click on the drop down, then click on the ‘Item’ and you should see a control for the item, change that and watch your logs.
Commands sent (from openHAB) to Sun Synk are buffered up until the next refresh interval and as they take a while to propagate through to your inverter, some channels are not refreshed (read back) from Sun Synk Connect until the next minute.
so don’t check the SunSynk Connect App until a short while after you see Trying to send commands to inverter: xxxxxxx
@LeeC77 Many thanks - stupid error on my side! You are correct and sendCommand is what I should have been using. Sorry to have bothered you unnecessarily.
However changing, say the grid_charge (switch) from ON to OFF or visa versa does work as expected, and the ‘value’ does not temporarily bounce to the new required value and then back to the original value:
12:19:19.832[INFO] [openhab.event.ItemCommandEvent] - Item 'SunSynk_Inverter_Interval_4_Grid_Charge' received command OFF (source: org.openhab.core.automation.module.script)
12:19:19.835[INFO] [openhab.event.ItemStatePredictedEvent] - Item 'SunSynk_Inverter_Interval_4_Grid_Charge' predicted to become OFF
12:19:19.838[INFO] [openhab.event.ItemStateChangedEvent] - Item 'SunSynk_Inverter_Interval_4_Grid_Charge' changed from ON to OFF (source: org.openhab.core.autoupdate.optimistic)
Turning on Debug logging reveals an error being reported:
12:29:02.556[INFO] [openhab.event.ItemCommandEvent] - Item 'SunSynk_Inverter_Interval_4_Charge_Target' received command 95 % (source: org.openhab.core.automation.module.script)
12:29:02.557[INFO] [openhab.event.ItemStatePredictedEvent] - Item 'SunSynk_Inverter_Interval_4_Charge_Target' predicted to become 95 %
12:29:02.560[INFO] [openhab.event.ItemStateChangedEvent] - Item 'SunSynk_Inverter_Interval_4_Charge_Target' changed from 100 % to 95 % (source: org.openhab.core.autoupdate.optimistic)
12:29:02.566[ERROR] [org.openhab.core.internal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.handleCommand()' on 'org.openhab.binding.sunsynk.internal.handler.SunSynkInverterHandler@777d760f': For input string: "95 %"
12:29:30.886[DEBUG] [org.openhab.binding.sunsynk.internal.api.AccountController] - Account configuration token not expired.
12:29:30.887[DEBUG] [org.openhab.binding.sunsynk.internal.api.DeviceController] - Will get STATE for Inverter [INVERTERNAME] serial [SERIALNUMBER]
12:29:30.887[DEBUG] [org.openhab.binding.sunsynk.internal.api.DeviceController] - Trying Common Settings
12:29:30.919[DEBUG] [org.openhab.binding.sunsynk.internal.api.DeviceController] - Trying Grid Real Time Settings
12:29:30.991[DEBUG] [org.openhab.binding.sunsynk.internal.api.DeviceController] - Trying Battery Real Time Settings
12:29:31.056[DEBUG] [org.openhab.binding.sunsynk.internal.api.DeviceController] - Trying Temperature History
12:29:31.193[DEBUG] [org.openhab.binding.sunsynk.internal.api.DeviceController] - Trying Real Time Solar
12:29:31.297[DEBUG] [org.openhab.binding.sunsynk.internal.api.DeviceController] - Trying Plant Summary
12:29:31.330[DEBUG] [org.openhab.binding.sunsynk.internal.handler.SunSynkInverterHandler] - Successfully got and parsed new data for Inverter [INVERTERNAME] serial [SERIALNO] at plant [PLANTNAME]0 504235
12:29:31.330[DEBUG] [org.openhab.binding.sunsynk.internal.handler.SunSynkInverterHandler] - Retrieved state of inverter [INVERTERNAME].
12:29:31.334[DEBUG] [org.openhab.binding.sunsynk.internal.handler.SunSynkInverterHandler] - Updating Channels
12:29:31.361[INFO] [openhab.event.ItemStateChangedEvent] - Item 'SunSynk_Inverter_Interval_4_Charge_Target' changed from 95 % to 100 % (source: org.openhab.core.thing$sunsynk:inverter:97fc9b6a4b:E47W248005422502132030:interval-4-grid-capacity)
(Note I have changed the inverter name, serial number and plant name in the log as I’m unsure if these should be visible generally)
Would be really grateful for any ideas / ways to overcome this. Many Thanks.
Looks correct, command shoud be of the form: Interval4GridCapacity.sendCommand(95)
I have tested your specific command and it works for me. I use the binding all the time without issue, doesn’t mean your fault is not real, but need more info.
In your logs you get an error for sendCommand("95 %") don’t use this form.
2:29:02.566[ERROR] [org.openhab.core.internal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.handleCommand()' on 'org.openhab.binding.sunsynk.internal.handler.SunSynkInverterHandler@777d760f': For input string: "95 %"
Looks like you are on latest release openHAB 5.1.0, it includes the offical release of the binding? Are you using the official binding or the .jar from my github.
Are you logged into the Sun Synk App at the same time you are doing the tests? I have had some funnies with that.
Perhaps you could test some more:
Update to openHAB 5.1.0 binding not the .jar in your addons.
Keep the Sun Synk App closed for at least a minute since your last sendComand() once you have checked the value in the App close it?
Is there something about timing, does it happen every time.
Do you see the log DEBUG entry Trying to send commands to inverter: and Sent command: to inverter
14:28:55.104 DEBUG
org.openhab.binding.sunsynk.internal.api.AccountController
Account configuration token not expired.
14:28:55.105 DEBUG
org.openhab.binding.sunsynk.internal.api.DeviceController
Trying to send commands to inverter: XXXXX
14:28:55.212 DEBUG
org.openhab.binding.sunsynk.internal.api.DeviceController
Sent command: to inverter XXXXX.
14:28:55.213 DEBUG
org.openhab.binding.sunsynk.internal.api.DeviceController
Will get STATE for Inverter XXXXX serial XXXXX
**Known issue: At the moment values changed in the Sun Synk App for the battery settings are not always syncing back with openHAB.**
If your not using the .items file:
Use the Semantic Model: Edit the Item and set the “Point” tag to “Setpoint”. This tells openHAB that the value is intended to be changed, and it will often automatically provide a slider or stepper widget.
Hi
Sunsynk have changed the App again, this time to combat “headless” session hijacking and to enable refresh token rotation. This means that at the moment the binding will fail when it tries to refresh the bearer token. This can be fixed I think, but I need to reverse engineer the Connect App.
In the mean time, there are a few workarounds
Manually disable and re-enable the account thing every couple of days.
Wait for the account thing to go OFFLINE and re-enable manually
Use the quick and dirty DSL rule below (edited 01/02/2026).
var Timer cooldownTimer = null
val Integer coolDownTime = 1 // mins
val String accountThingUID = "sunsynk:account:xxxxxxx" // <THING_UID>
val String inverterThingUID = "sunsynk:inverter:xxxxxx:EXXXXXRXXXXXXX" // <THING_UID>
val String apiToken = "<RESTToken>" // REST API Token
val String serverHostName = "loacal.host" // or IP Address
rule "Detect and Reset Offline Thing"
when
Thing "sunsynk:account:xxxxxxx" changed to OFFLINE or
Thing "sunsynk:account:xxxxxxx" changed to UNKNOWN
then
// 1. Check if we are in cool-down
if (cooldownTimer !== null) {
logInfo("ThingReset", "Thing {} is offline, but cool-down is active. Skipping restart.", accountThingUID)
return;
}
logWarn("ThingReset", "Thing {} went OFFLINE. Attempting restart...", accountThingUID)
// 2. Disable the Thing
val headers = newHashMap("Authorization" -> "Bearer " + apiToken, "Content-Type" -> "text/plain")
val String urlAcc = "http://" + serverHostName + ":8080/rest/things/" + accountThingUID
sendHttpPutRequest(urlAcc + "/enable", "text/plain", "false", headers, 5000)
Thread::sleep(5000)
val String urlInv = "http://" + serverHostName + ":8080/rest/things/" + inverterThingUID
sendHttpPutRequest(urlInv + "/enable", "text/plain", "false", headers, 5000)
// 3. Re-enable after a short pause and start cool-down timer
createTimer(now.plusSeconds(5), [|
sendHttpPutRequest(urlAcc + "/enable", "text/plain", "true", headers, 5000)
sendHttpPutRequest(urlInv + "/enable", "text/plain", "true", headers, 5000)
logInfo("ThingReset", "Thing {} re-enabled. Starting {}-minute cool-down.", accountThingUID, coolDownTime)
// Start cool-down (e.g., coolDownTime minutes) to prevent infinite loops
cooldownTimer = createTimer(now.plusMinutes(coolDownTime), [|
cooldownTimer = null
logInfo("ThingReset", "Cool-down finished for {}.", accountThingUID)
])
])
end
Update 22 March 20026: The SunSynk App no longer uses token refresh, but forces the user to log in again when the token is no longer valid. I will update the binding to mimic this behaviour.
If you want to try it out get the .jar from here.
openHAB releases after this date will include this new behaviour.