Background .. I've never used ST so this is totally new to me!
When I write a Virtual Device .. e.g. a "Momentary" , or Switch, etc
when should I send events?
Should I take care with the stateChanged?
how do I know what "name: " and "value:" I should use in the sendEvent?
Obviously I'm a noob! Where would I find all this clearly explained, docs.hubitat.com is very nearly(but not quite) useless!
You should, based on the functionality of the device you are making a driver for, send State Change events when the state changes on your device...
For a switch, the ON/OFF state change would clearly be a state change. For a button, the button press is clearly a state change (in my opinion, I've seen another developer on here have the opposite opinion).
For name and value I typically copy them from a similar device instead of inventing my own.
sendEvents should occur when something happens to change the state of the attribute in question.
The "name" of the attribute is just that..the attribute name. The value depends on the attribute. Some have enumerated options (eg on or off) other could be a value range (eg 1..100). Custom attributes could be anything your heart desires.
A good place to start is the capabilities list. Attributes are generally attached to a capability. See the list below that shows their respective attributes and values options.
There are many built in Virtual Drivers that cover a lot of the needed options so you may not need to create your own.
Virtual Switch
Virtual Contact Sensor
etc.
Also you can make a virtual momentary switch by creating a Virtual Switch and enabling the "autoOff" preference.
Piggy backing on this....I've got a zwave switch on the way, for connection into my garage door. It will be wired into the dry contact sensor. I'd like to be able to be able to open the garage door from HE.
Would I create a virtual switch, make it momentary (autoOff), and then ??? link/create a rule for the zwave switch. (Also, how does the zwave switch know it's a momentary button press?).
I have just gone through the devices and capabilities list, and I think just the simple act of reformatting into a spreadsheet has helped to clarify..
I think ..
the "name" is the name of the attribute
the "value" is of the "type" e.g. NUMBER, STRING, or one of the ENUM etc
So when I see in someone else's "SWITCH" code sendEvent(name:"switch", value "on") it is because the Switch Capability has an attribute "switch" taking an ENUM of "on" or "off"
the name "switch" is only indirectly related to the fact the that Capability is also called Switch.
I think I got a little confused because (fairly logically) the attributes tend to match fairly closely the capability name.
e.g.
thingySensor tends to have an attribute thingy
thingyMeasurement will likewise usually have a thingy attribute
BUT this is not a RULE! Simply sensible naming, a rule-of-thumb if you like - don't rely on it, you'll probably get unexpected errors.
Similarly for commands for "actuator like capabilities", they're logically named and as a consequence often look like the related attribute (or permitted attribute values) , and in the most part actuators have state.
For people that find this thread.
Some examples of cases where the rule doesn't apply
A Beacon is a pure "Sensor"
the Attribute is "presence" taking "present", "not present" - NOT "beacon" as the rule-of-thumb might suggest
So it sends events name:"presence", value: "not present"/value: "present"
it has NO commands
A developer of a virtual device might want to add present(), notPresent(), or even setState(String) but these are just the developers choice and not required by the Capability, and the names of these commands are arbitrary.
A "Tone" is an example of a pure "Actuator" (pure ones are fairly rare)
It has no attributes (so it doesn't have any pre-defined events it really should send
-- though I'm unclear on whether it can send "arbitrarily named" events and what happens to them!
It has one command - beep() .. a logical name, but nothing like the capability name
The developer of a Device (Virtual or real) really should implement beep() .. it's required by the capability definition., and expected by things that might interact with it (e.g. Dashboard). Again the developer can add other commands, but the naming of these are totally down to her whims.
Many Capabilities (especially Actuator like ones) have BOTH Attributes and Commands because they usually need to store their own state -- as well as being able to turn an outlet on or off via commands they also want to store if the outlet is actually turned on or off, because this is something useful to know (especially for dashboards).
Only tangentially related - In my opinion there is a gap in the capabilities, I might actually want a pure sensor that tells me if an outlet/switch/bulb is on or off without being able to "control" it via commands .. but that's a very different discussion!
On top of all that you can also add custom attributes to your drivers if you would like. There are some cases when you might want to do this, and have a tile display the value on the dashboard.
Another thing you can do is mix capabilities into a driver. There have been many times when trying to test a driver for something such as a contact sensor where I just add the switch capability so I could easily just turn on/off to simulate open/close instead of going to the door and physically opening it.
I also created custom presence devices that have the switch capability. This way I can easily turn on/off presence easily if it ever get stuck.
Once you dig deep into this stuff, you can do some fun stuff.
You could write a rule:
When [Momentary Switch] is [On] >> [Z-Wave Switch] is [On]. If False, [Off]
Set your momentary switch to 250ms, 500ms or whatever it needs. Z-Wave won't know if it's momentary (though, some Z-Wave switches can be assigned momentary values, I think), it will need the hub to communicate on/off if it's not supported by the hardware on the device.
I used to take this approach with the 24v door buzzer in my apartment