How does a dashboard switch work?

I wrote a driver for a virtual switch. Very simple driver with nothing weird or wild.
I made a dashboard of that switch and a real bulb for testing.
I made 2 rules, one to turn the bulb on, one to turn it off.
The dashboard works perfectly.
I 'reverse' the switch - so On is off and Off is on. When in reversed mode, the switch works great visually if I trigger on/off from another screen while leaving the dashboard open. However. If I CLICK on the dashboard switch expecting it to change state it just momentarily flashes an hourglass. It is as if the dashboard switch template has some form of hardcode in it for 'On/Off' commands. When my driver is in normal mode (unreversed?) It functions.
How do I see the code for the tile? Any ideas why the switch won't work Reversed? it was sort of the whole reason I wrote the driver!

Hubitat Dashboard is closed source (at least the Hubitat app-side implementation--not sure the HTML/CSS/JS will help you much), so that much isn't an option. But what you can do is see what commands it is sending to your device and when. I assume you have a "debug log" option in your driver that will log when commands are executed (usually as the first line of the associated method), based on code I've seen, so that may help.

That being said, from experience, here is how I think Hubitat Dashboard works with "Switch" tiles: the visual representation of the tile, the switch being on or off, is read from the current state of the device's switch attribute (you can see this under "Current States" on the device page). If you tap the tile and the switch is currently reporting as on, it will send an off() command; conversely, if it's currently reporting as off, it will send an on() command. Then, you'll see an hourglass appear (after tapping the tile) as Dashboard waits to hear back from the device. (There is probably a timeout, maybe a few seconds, built in here, but I don't know for sure.) If/when the current state of the device changes, the tile will update to reflect that state.

Along those lines, these tile changes are driven by actual events, not "optimism." So if your device reports that switch is on and you tap the tile, running an off() command, the tile will not just optimistically change to show that it's off--it will wait to hear back (with the hourglass in the meantime). And if you do something unconventional, like set switch to off in response to an on() command (sounds like that's what you might be doing), the behavior of Dashboard will be unpredictable but probably not desirable.

2 Likes

Thanks... it's a good explanation- but something still isn't making sense to me.
I dont need to see the HTML/CSS or JS - what I'm looking at is why the tile is tied to the on/off state. I mean specifically - the device has an on/off state ("switch"). The tile is reading that state and coloring On or Off. It's well known how it works and everyone accepts it.
My confusion comes from the tile being tied to it and not itself being controllable - so to speak.

Imagine this: I buy a switch at lowes, generic - standard switch for $2.54 I open the wall plate and purposefully install it with the On position down and the Off position up. Perfectly reasonable.
Because the tile is tied to On() and Off() instead of 'position0()' and position1()' I the hack developer have no way to make it do what I want. I'm forced into the mold of the switch position.
I'm not a developer. I freely admit that but it seems to me that hardcodes are limiting. I get that for expedience, and 99% coverage of functionality, it is what it is, but in my little world (doing PHP and stuff) when you tied two bools together you had options on how you did it. In this case, the switch tile is tied hard to the device.

I wish the capability had more flexibility - either add an inverse parm or a way to connect to the tile and control up=off or up=on sort of thing. I know I'm dreaming tho.

I wrote what I was so excited about - a virtual switch that could handle inversion. I was learning about device state, timing and interface to HE - only to find out I wasted my time and it is not possible AFAICT to be in control of a dashboard tile.

I'm wondering if this is an APP sort of thing instead - and most likely someones done it already. Time to go delve into that. I see that BPTWorld has some good examples of tile management - maybe I can do it that way. sigh.

Maybe I'm not understanding you, but regardless of the physical switch position (up or down) off is still off and on is still on. Are you saying you want the device to report as off when it's on and report on when it's off? Code should be able to do that and the tile itself will show the attribute stated. An easier way I would think to achieve that is simply code the driver to express the reverse attributes then make the tile read the attribute you specify...

heya - I have the device already reporting off as on / on as off (I called it reversed). It works perfectly in the device screen. It is a virtual switch driver. When I put the virtual switch on a dashboard, I assumed click it 'on' would function just as the On() and Off() capabilities in the device screen. When the virtual switch is in 'normal' mode, the switch and the tile work nicely, just as expected. When I 'reverse' my tile it hourglasses and stays on (or off) and doesn't change state. I sort of expect it to 'toggle'... not to confuse with x06 x02 outlet driver functionality for a true toggle.

In assume that with your tile, "toggling" is probably what you want to do, but this is not a standard device command on Hubitat; it is an app-level feature, and generally the app will read the current switch value and run on() or off() as needed to get it into the opposite state of what it is currently reporting). So if running off() on your switch really changes the switch attribute to on, Dashboard is going to show a switch in the "on" position, and tapping it is going to run off() -- which will have no net effect if your commands are "reversed" since that will still keep it on.

What you could do instead is use one tile to display the state and either:

  • one additional tile to toggle the state (use a Rule or Button Rule to read the current state and run whatever command you want to get it into the opposite state); or
  • two additional tiles to explicitly run the on() or off() commands when tapped

That being said, I would probably try to find a way to make a "normal" switch driver work with whatever app you're using instead of going down this path, which seems rife with confusion for both humans and apps. But it's really just non-conventional and not a rule per se, I suppose, as long as you're willing to work around the instances where it defies convention and causes issues, like Dashboard, if I understand how your virtual device works.

2 Likes

Thank you @bertabcd1234 as always for your patience. I gain so much from reading your responses.
This began for me when I had an app that could be enabled/disabled with a switch. I wanted the switch to reflect the app state. - ie; when the switch was on, the app was on.
But the app worked the opposite - if the switch was On, the app was off. and I think I now have 3 apps that have this same issue. I deemed it would be useful to create a reversed switch and set about that task. I was oh so close!

I thought about the switch to a switch, I've thought about using a driver with contacts so I could control it, I asked one dev to add the ability to inverse it inside his app... and I also now am wondering about others who walked this path before me. Well. it's all a learning curve! I'm just slower than most.