I know that this question has been asked in many guises, at many different times but IMHO the answers have been inconclusive, and now that RM has moved to version 5.x with Hub variables I am keen to know what the acknowledged best practice is. So.... why would I use a hub (or a global) variable to indicate state, for example enabling a predicate, when I can use a virtual device instead? Are there pros and cons? Does one give more options than the other?
My heart tells me to use the hub variables because that is the sort of thing that they are designed for but then my head asks why when virtual devices seem to work so well. Is there a performance impact?
What do you guys do and why? All responses welcome!
Just a guess really but I'd say that a device occupies a load more data space than a variable. A contact sensor may only be virtual but it has most of the fields of a real one.
To add to the above, one reason you see virtual devices at all is likely because these were, at one point, the only option--variables in Rule Machine didn't exist yet. But one reason you might want to keep using them is that in some cases, they are easier. For example, if you want a virtual switch to control something about how Rule actions execute (e.g., maybe it's part of a conditional action) and you want to change that state by voice (Alexa or Google), then you'll need a device--the voice assistant integrations only work with devices, not hub or global variables. (You could create a connector for one of these, but connectors are being phased out, so that's not something I'd start with now; they are adding variables to more and more apps, so it's possible they'll eventually add support for them to these somehow, too, but we aren't there yet. And along those lines, if you want to use the variable in an app, most apps aren't yet able to work directly with variables--though a sort of API for this was recently announced, so that may change--so you'll need a device, whether it's a connector or just a virtual device you made for that purpose.)
On the other hand, one reason you might want to use a variable over a device is that Rule Machine provides built-in actions to manipulate the value of variables, so working with their data can be easier in some cases. It's nothing you couldn't ultimately do with a device, too, but you'd have to feed the device attribute into a variable first (though that could be local) and then do the variable operations on it--like adding numbers, searching text, etc.
I suspect the capabilities of hub variables will continue to grow as more apps being to allow their use, but until then, there are some things you can only do with a device (though either way, the app you're using has to support that type of device, though most variables can work with common device types like switch and dimmer that are widely supported). And on the other hand, there are things you can do that are easier with a variable.
So, it probably boils down to what you need to do with the values you're storing...and likely a bit of personal preference.
My previous ST setup quickly grew out of control with virtual devices as I attempted to use them to capture and report various states. When I moved over to Hubitat, one of the things I vowed to do was lessen my dependency on them.
Two examples
I used to have a virtual device for each mode the thermostat could be in. The switches would turn on and off with the modes to let me know status. With Hub variables, it's silly in my opinion to have so many devices that could easily get out of sync, when instead I can just capture the thermostats data and store it as a variable to report out to things. I use that data not only to tell me current state, but also to use it as a condition to check if the thermostat ever gets out of sync with current hub mode.
I kept virtual devices for triggers of certain modes and actions. An example would be presence. My geofence controls a virtual device because should my geofence not work, I want quick access through Alexa or from a physical button on my wall.
For me, the main reason to use a variable instead of a virtual device is just that my system ends up cluttered with virtual devices, and my device list just gets out of hand. Hub Variables offer a much more compact means to set up and use variables, compared to virtual devices. I think virtual devices are pretty much a contrivance for most cases. When RM was first introduced (almost 6 years ago), someone asked if it couldn't do something so people didn't have to use virtual devices. Private Boolean was born, the first 'variable'. It killed off most virtual switches that people were using just to remember a simple on/off state of something.
Virtual devices are great for circumstances where you need device functionality specifically. One example, is that it's much easier to test something complex with a virtual device that you can control form your computer, than a real device where you have to get up and actually trip a motion sensor or open a door. Once whatever it is works, then the virtual device can be easily replaced with a real one. But, that's really sort of a dev trick that I use (all of the time).
And then there is Alexa to consider. She doesn't know about variables at all.
Oh, and finally, a Hub Variable uses fewer hub resources than a virtual device -- no driver, no driver to load, etc.
Could one case for a virtual device be the use in some apps (including built-in ones) where the common option for controlling the behaviour can be a reference to a switch? Or could this use case also be achieved through Hub Variables? The kind of thing I am thinking of is "disable this behaviour or app when this switch is turned on". I'm not advocating it should be this way, if Hub Variables could be used in these cases, then that would be great.
That said, I do tend to think it is a cleaner outcome to have variables being used for the storing of information, including state information, and devices, even virtual one's, being more closely aligned to actual devices.
Thanks to everybody for your responses, that is definitely starting to crystallise in terms of what to use and when
This is particularly interesting and is a factor that would definitely drive using a variable over a virtual device where Alexa or specific device function isn't required. It does raise another question, though, which is around connectors. Where do these fit into the picture? Is @bertabcd1234 correct in saying that these are deprecated and are being phased out and in which case we should avoid using them? They are obviously something of a halfway house and function as a device in every which way (as far as i am aware) so is there a design case for using connectors/variables versus straight virtual devices? Would love to get your view please @bravenel
Connectors were created to provide a means, as @sburke781 talks about, for a variable to be used in a device context. Except, a connector is actually a virtual device. It's clever because changing the connector causes the same change to the variable, and vice versa. When variables were solely within the domain of Rule Machine these made sense. But now, with the introduction of hub-wide variables, they are going to become less and less needed. It would be a good thing to do away with the need for them at all. This, however, won't happen overnight.
So, they will be phased out over time. In the meantime it is perfectly fine to use them all you want. Any connector you create will go on working, and will not need to be replaced. At some point in the future you won't be able to create new ones, but that is a ways off.
A virtual connector IS a virtual device, and carries all of the "baggage" of one. It shows up in your device list, it has a driver, etc. But, it does has the redeeming feature of being tied to a variable.