Long story short:
‘Switch’ item in android app instantly changes it’s state on click, ignoring ‘return’ status.
Details:
Let’s say I have a switch, and it’s in the OFF state.
I’m clicking on the switch in android app and it instantly changing state to ON. But the controlled device(mqtt) is actually offline and didn’t returned any state.
Now I’m refreshing the screen(just swiping down) and boom… the switch returns to the device’s actual state(OFF).
I suppose there are no checks done, android is just switching a local variable and sends the command.
I’ve spent like 8 hours trying to figure out what’s wrong and how to fix it, so as the last resort I decided to create topic here.
Is it expected behavior? Any workarounds?
I tried to use the following dirty hack to force UI refresh and it actually works, but causes some glitches on the android UI at the switch moment.
So that’s not an option.
when
sw1 received command
if (triggeringItem.state == OFF) {
triggeringItem.postUpdate(ON)
triggeringItem.postUpdate(OFF)
}
if (triggeringItem.state == ON) {
triggeringItem.postUpdate(OFF)
triggeringItem.postUpdate(ON)
}
The combination of autoupdate=“false” and your rule is exactly the same as having autoupdate=“true”
Remove both or remove the rule only
It’s not the same actually(offtopic here, but i could explain if you want to), though I can completely remove the rule and leave just autoupdate=false.
It’s an artifact left from my experiments with a workaround, sorry for that. I’ll fix the initial post.
Anyway, that won’t help with the issue, UI still don’t get the right state until I refresh it manually even with this config(with no rules at all):
I think this is expected behavior. The UI doesn’t wait for OH to report back whether or not the Item changed state so what is happening is:
switch is toggled on the UI
command sent to the Item, Item doesn’t change state because of the autoupdate=false
command sent to binding
message sent out to device
device is offline so no return message is received
Item remains unchanged
because the Item remains unchanged there is no event to publish back to the UI to tell it that the displayed state doesn’t match the Item’s actual state.
The challenge here is that the UI needs to be responsive. The Switch needs to show that it has been toggled immediately on being tapped so give you, the user, the feedback that tells you that you have successfully issued the toggle command by tapping on it. So the UI can’t wait for the changed event on the Item to update the UI.
I’m not sure there is a good solution for this. Maybe something along the lines of:
var OnOffType lastCommand = null
var Timer failSafeTimer = null
rule "MQTT Item fail safe"
when
Item sw1 received command
then
failSafeTimer?.cancel
lastCommand = receivedCommand
failSafeTimer = createTimer(now.plusSeconds(1), [ |
val currState = sw1.state
if(currState != lastCommand) {
sw1.postUpdate(lastCommand)
sw1.postUpdate(currState)
}
])
end
The above will trigger when the Item receives a command. It creates a timer that waits a second (use what ever time makes sense). If after that second the state of sw1 doesn’t match the received command we do a quick toggle of sw1 to generate the events needed to update the UI.
rlkoshak, thanks for the clarification and especially for the code snippet, I got the idea and will try it.
As for the solution, one of the options is toggle the switch but make it’s background gray(for example) till the confirmation receivied.
Can you check how the Basic UI behaves in this case?