Advanced Button Controller (ABC)

Ramp Up/Down should activate the LevelChange command on devices that support it.

Ramp Up/Down only has the "Held", not "Pushed". In that case, how would you recognize a push of the lower paddle?

Also, how about the StopLevelChange? How does Ramp Up/Down know when to stop brightening/dimming? Thanks

Right now, if I pause the rule for the StopLevelChange event, my hue light bulbs would continue dimming up/down till 100%/1% even if I only hold the paddle for a quick second. To get it to stop dimming when I release the paddle, I have to use the StopLevelChange on the button that corresponds to the "release" event.

Sorry for the late reply.
The ramp up/down in ABC was designed to work with button controllers that aslo support the "released" event. It sounds like your switch has this implemented.

I did not implement the stopLevelChange as a separate option as it should occur automatically on the released event. I'm wondering if this device has the proper HE implementation of the released event.

Are you using a cutom driver..if so, please post a link to it and I will skim the code.

2 Likes

@yototogblo, I skimmed the code for the "Inovelli Switch NZW30/NZW30T w/Scene" driver and I see that it sends pushed and held events but does not send released events. Unfortunately this device won't work with the level change implementation of my ABC app. I may look into adding a stopLevelChange option in the future but it won't be anytime soon as my time for coding is at a minimum these days. I would recommend you use RM if you need to send the stop command separately.

Thanks. The manufacturer posted instructions on how to add the released event to the code and that's what I'm using. It's essentially sent as a separate event from the held event.

Should I post the code here? Since it's 2 separate events (and thus buttons), chances are that it's not based on the proper HE implemention.

Also, it's the LZW30-SN

ABC would send stopLevelChange if Inovelli sent a real "released" event though, right? I modified the driver to get rid of their "held" nonsense for the down paddle (a cute ST workaround, maybe?) and use held and released for their real meanings, plus separate button numbers for each single or multi-tap, if that would help.

As long as the device sends a proper released event from the same button number as the one that initiated the startLevelChange (Ramp) it should work fine.

Cool thanks.

So what do "pushed" and "held" mean in your smartapp? Currently, it looks like they map to different buttons (Up and Down paddle). Are they meant to be the same button and to indicate when the button is pushed and held? So each button would have "pushed", "held" and "released"? Also, if that's the case, would a "released" event only be sent after the "held" and not the "pushed"?

Pushed and held aren't really dictated by my smart app. It is dictated by Hubitat's implementation of button devices. I wrote my smart app based on this implementation.

How a button device driver implements this can be different so it really depends on the hardware limitations and what the developer does to workaround those limitations. Most if not all button devices have the pushed event. A large portion have the held event. The released event is a bit "rare".

The driver determines this not my app.
As an example, the Lutron pico's have 2 separate drivers for the same 5 button device. One built for speed and one built for flexibility.
The fast pico sends the pushed events as soon as the button is pushed, followed by a released event when the button is released. This way you get a faster response time for anything listening for pushed events.

The other option waits for the button to be released before sending the pushed event. The reason is that this version of the driver also supports held events and the driver would need to calculate how the the button is being held down before sending a pushed or held event. The fast pico driver gets faster response time but does not support held events.

All of that is to show that the same hardware can be implemented in different ways by using a different driver..it all depends on what the driver is trying to accomplish.

My app is designed to use the standard implementation of button devices where each button sends a pushed, held or released event. This will be the case where the device natively supports these features. Some hardware do not support these features and instead use workarounds in the driver to mimic this functionality. As long as they send all events from the same button, it should work with my app. If their workaround requires you to do something else to simulate a released event, it won't work with changeLevel() functions.

Thanks for the detailed response. Greatly helped my understanding of how this works. Clearly, the Inovelli driver is implementing this in the same way as ST and sending separate events (and thus buttons) for each action (pushed, held, doubleTap, tripleTap, 4 taps, 5 taps and released). I guess for tripleTap and taps more than that, separate buttons have to be used regardless since Hubitat only seems to support up to 2 taps.

Out of curiosity, what would happen if the driver has the released event tied to the same button and it's automatically sending StopLevelChange()? Would it be able to control devices that don't support LevelChange() e.g. switches? My guess is yes and it'd just ignore the StopLevelChange() but just wanted to confirm.

In my case, seems my only real option is to wait for you to implement both the StartLevelChange() and StopLevelChange() functions separately. That way, both the up and down paddles (1 button currently implemented as "pushed" and "held" respectively) can be used to startlevelchange up and down; while another button (representing the "released" event and also implemented as "pushed" and "held" respectively for the up and down paddles) can be used to stoplevelchange.

I guess if you're not writing the driver, it doesn't matter, but doulbeTapped is a specific thing (Hubitat-only, not ST) and not a generic term, and "tripleTap" isn't a thing on ST or Hubitat. That's why SmartThings needs "button-number math" to handle even double taps: your options for a single button number are pushed or held. If you need more attribute values than that, e.g., to handle double-taps or triple-taps, you'll need a workaround like extra button numbers. Inovelli handles this by reporting a double-tap up as "button 2 pushed," a triple-tap up as "button 3 pushed," and so on on SmartThings (even though these are all the same button that registers a regular push as button 1, hence my "button-number math" term).

Hubitat handles this differently by adding a doubleTapped attribute for buttons (the rest of the model is technically a bit different, but if you're not writing a driver, those details don't really matter). This means you get one more free tap option for the same button number without needing to resort to "button-number math." For example, Inovelli could have implemented their driver as reporting one tap up as "button 1 pushed" (same as ST), two taps up as "button 1 double-tapped" (not possible on ST), but then you run into the "button-number math" problem for 3 and up because there is no "tripleTapped" attribute--so Inovelli decided to do the same they did on ST here regardless. I bet that if you used Hubitat's Generic Z-Wave Central Scene switch driver for the Inovelli, you'd get pushed and doubleTapped when you expect it (button 1 = up, button 2 = down) and nothing--besides debug log output, probably--for higher numbers of taps.

The biggest problem with the Inovelli, in my opinion, is that they traded "button-number math" for "button-attribute mangling" in both DTHs/drivers. They're usurping the held value/attribute for taps of the down paddle, not actual holds. Their device actually does support holding (and releasing) the paddle in either direction as something that registers a Z-Wave event. So now they have two problems: held is already being used for an unintended purpose and therefore isn't available to use as the same button number for an actual hold of that button, and they apparently refuse to use released (like doulbeTapped, also Hubitat-only), presumably because it makes it harder to port the DTH from ST, where it was clearly originally written.

They handled this by...not doing anything for holds and releases in their stock driver at all. They posted a modification in their forums that will map the events as "button 8 pushed" when the top button is held and "button 6 pushed" when the top button is released (what?!). Similarly, "8 held" and "6 held" will report for a hold and release of the bottom button.

I'm not sure I understand. Apps, not drivers, send stopLevelChange(). If you send stopLevelChange() to a device that does not implement that command, an error will be thrown, and (in a good case) nothing will happen. This would include most switches, but I'm not sure why you'd be in a situation where this would be happening in the first place since it's not like they'd support the corresponding startLevelChange command.

You could also modify the driver to report events in a manner more consistent with the way in which most other devices do and in which most apps expect them to work. I've done that, plus a few other changes, here for the Inovelli: https://github.com/RMoRobert/Hubitat/blob/master/drivers/inovelli-switch-red-series-lzw30-sn-advanced.groovy:

Modified buttons as follows:
 *  1-5 taps up = buttons 1, 3, 5, 7, 9 pushed
 *  1-5 taps dn = buttons 2, 4, 6, 8, 10 pushed
 *  Up buttton held/released = button 1 held/released
 *  Down button held/released = button 2 held/released
 *  Config button pressed = button 11 pushed

but I don't have any of those switches in use right now so can't test this (I think I somehow broke their "notification child" device creation, so I'd use the stock driver for changing any of that and switch back to this for the button events if you use those other features). You could also just copy my entire zWaveParse method into their driver.

Thanks man. I've actually been following your changes on the Inovelli forum so was aware of your changes and how Inovelli implemented the Hubitat driver the ST way. I also had a custom GE driver in ST that still implemented it the ST way and now that it's in Hubitat, they've changed it to the logical way.

I'm curious, why didn't you add double tap to yours as part of button 1? That way, you'd only have 9 buttons. I think you should make that change if you can.

From what @stephack said here:

it appears the driver is responsible for implementing the stoplevelchange() on on a released event. I might be misinterpreting that though but I'd think drivers can definitely send that also. Association class 4 of the Inovelli dimmers sends a stoplevelchange() upon a release event.

I've thought about it but since the device supports way more than double taps, it doesn't eliminate the problem of "button math," and I think it would make it way more confusing if I did. Right now, odd-numbered buttons 1-9 correspond to events on the up paddle, and even-numbered events 2-10 correspond to events on the down paddle. If I implemented doubleTapped, there'd still be a lot to fill in and I think it would make the "button math" harder if I want to maintain consistency with Hubitat's convetion of 1 for up and 2 for down (so...maybe taps 1-5 up are button 1 pushed, button 1 double-tapped, button 3 pushed, button 5 pushed, and button 7 pushed? is that actually easier? I don't see a way to win here...haha).

No, not to speak for him, but ABC asssumes button devices present events in a logical fashion and fills in that logic for you: ABC, the app, will send startLevelChange() when you request it and stopLevelChange() on release of that same button number. The driver is responsible only for translating those commands--which must be issued by an app (or the user directly)--into something the device understands. I'm sure you're familiar with what these commands do, but the former basically starts ramping the level up/down (like turning a dimmer knob or moving a slider on a real dimmer), and the latter stops the level change wherever you landed (how would the driver know when to do this without being told? if you want to go all the way up or down, just do that instead--you don't need these commands for that).

Drivers also don't know about apps or other (non-child) devices. Apps subscribe to devices, and apps can boss devices around, but devices basically only report states/attributes and respond to commands. You need an app like ABC in the middle to respond to a released event from one device and send stopLevelChange to your other device--two different devices and drivers with whatever app/automation you want (Rule Machine with a Button Device trigger is basically Button Controller and can already do this since you can choose your own button number/events for each) in the middle.

could you post it here or link to it? I'm interested in doing something similar.

Is there a particular reason β€œShades” don’t support the windowShade capability? Looks like only my garage doors show up. Should I be selecting something else to control windowShades (open/close/stop).

Thanks!

Lol..because you may be the first person ever to try to use a device that supports the windowShade capability...which I don't think existed when the app was first built over in ST. I will have to look at the capability in the docs and see if it can be easily added.

Ha. No hurry. RM works fine for now but was giving this a shot.

Hi @stephack,

Been scratching my head on this one a little bit, hoping you could help debug this issue. If I create a new button mapping for a 4 button pico inevitably on the commit for the 4th button I get "Unexpected Error - check logs (something to that effect)". On my first Pico mapping I set up I was able to overcome this by removing/reinstalling ABC and it's child 2x, but on the second Pico mapping (a few days later) it just happened again. I can function at 75% by simply committing 3 of the 4 button mappings and stopping.. but I'm wondering what causes the error. I know I should be providing a proper log, but I'm not on site right now.. will try to provide if this is not a simple answer. I doubt it's related, but I'm using the 4 button pico to pick 3 different Hubitat defined scenes for a room, and the 4th button to turn everything off of explicitly. FWIW this would be the third hubitat/ABC install I've done, and I couldn't be more thrilled with the app. Thank you for providing the community with such a robust tool.