Android 'switch' ignores state returned by "inbound configuration"

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)
    }   

Here is my config:

sw1.items:

  Switch sw1 {mqtt=">[box:topic/sw1/control:command:ON:1],
                    >[box:topic/sw1/control:command:OFF:0],
                    <[box:IoTmanager/sw1/status:state:JS(json_bool.js)]", autoupdate="false"}

The combination of autoupdate="false" and your rule is exactly the same as having autoupdate="true"
Remove both or remove the rule only

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):

sw1.items:

  Switch sw1 {mqtt=">[box:topic/sw1/control:command:ON:1],
                    >[box:topic/sw1/control:command:OFF:0],
                    <[box:IoTmanager/sw1/status:state:JS(json_bool.js)]", autoupdate="false"}

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.

Can you check how the Basic UI behaves in this case?

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?

Exactly the same. Firefox 62.03, if it matters