When switching from another driver, Matter buttons may generate non-real presses

This is feedback in anticipation for future issues -unintended automations running- when custom drivers for buttons are shared by the community.

Ideally custom drivers should not be needed for Matter, but there are features that can’t be realistically expected from stock drivers, like multi-tap emulation or held auto-repeat, and others that are expected but are not there, like the long press release event or being able to rename “Button7” to something useful.

Let’s cut to the chase, when you add a button, the stock Matter driver initializes the button capability by sending a non-real pushed event with a misleading state_change = false:

That’s presumably so the app doesn’t get nervous with an uninitialized state (can’t it just wait until you press an actual button?) and for a new device is not a problem since you haven’t even created automations yet so, even if the event fires, nothing happens.

However, if the device was already in use and the user just switched back to stock driver it has a nasty side-effect: unintended automations may run if the latest event was not a pushed. As SmartThings documentation reminds:

It is important to note that state_change = false is not guaranteed to be treated as not a state change, as a value _different_ from the previous state value will always be treated as a state change regardless of this field

Hopefully they can find a way to avoid the false pushed event so switching drivers doesn’t have side-effects. Tagging @nayelyz so she can forward the note :grin: .

Edit: Also see this comment, looks like the line is not even needed and can just be deleted.

1 Like

That’s interesting, I had noticed the use of state_change = false while browsing stock drivers and was wondering what it was meant to achieve given that it has always been well documented that false means the default behaviour is unchanged and only true actually changes anything.

That’s my understanding too. I’d much rather know the state is uninitialized and get unhindered access to everything else on the device, especially if that might result in the state being initialized.

It would appear to be a variation on the problem I had with virtual devices. I had dutifully emitted events in the added handler but when ‘hub replace’ and ‘hub backup’ came along the added handler was called again when a device was added to the replacement hub. I raised an issue on the Edge drivers repo about this but closed it as it seemed like the wrong venue. As luck would have it PR 2357 quickly came along addressing the same issue for a number of Zigbee drivers and using the same approach that I was hoping to be able to adopt but wasn’t confident about, which was to test for the latest state of the attribute being nil before emitting the event. I haven’t tested it myself but it passed through the PR unchallenged so I took that as a good sign.

Perhaps a similar approach would work here.

1 Like

I actually tried that workaround before but it did not work when switching drivers. The new driver will always return nil for any attribute even if the component IDs are the same and they have a previous value.

Only when you write them from the new driver they become available in get_latest_state. Might be a hub firmware bug, I don’t know if that’s the expected behaviour or not.

Edit: typo

That was the sort of thing I’d been worrying about in my example. It certainly doesn’t seem like desirable behaviour whether it is expected or not.

1 Like

In the end checking get_latest_state is a hack, even if it worked, since it depends on the cache that could be not available or out of sync.

As discussed earlier, drivers should not emit events unless they reflect the device state or user interaction. Making up values or events feels wrong.

Even if we took for granted that some app user interfaces need to display “something” so you must give it “something” to display, that doesn’t happen for buttons.

The app does not even care about the current button state! It will display “Standby” regardless of the last state and only briefly reacts to a state change to notify the type of press to then change to display “Standby” again.

Well, I deleted the line that emits the event and guess what happens: nothing! :sweat_smile:

It works just fine, the app won’t even nag you with the non initialized attributes. In the AWA they just show as blank.

I even created an automation with one of the buttons without touching the other one, and it works fine.

It looks like that line is not needed and only brings trouble when the device is re-added.

1 Like

Hi, @mocelet

I asked the engineering team about this. Once I get their feedback, I’ll let you know.

1 Like

Fun fact, Zigbee drivers for buttons only emitted that initializing event to the main component, which normally was not used for automations since there used to be a convention for main that wasn’t one of the buttons but a catch-all component. So in Zigbee that never was a problem, no button could receive non-real presses since they were never sent.

That adds more proof to the fact that the initialization events are not needed, and for sure not for every single button since that has never been done before.

1 Like