I've built an ultrasonic distance (position) measuring sensor and with to use a Zigbee radio (Haas) to communicate with my hub.
My question has to do with events and attributes.
Events
Am I correct in assuming an event received by the hub will be one of the hub listed capabilities from the "Driver Capabilities List" and the parse function can somehow distinguish is as such when received?
AND when a string is received that is not a Driver Capability and not in whatever format the event would be in the parse function realizes it is not an event this and just passes it on?
Attribute
I believe I can create a DB entry for an Attribute. I recall reading somewhere the attribute entry has some limitations that Capabilities don't.
Can I use an attribute change as an RM trigger?
I'm not quite sure how to answer either question since I think there's a bit of confusion over how both work, but I think that this collection of facts about events, attributes, capabilities, and drivers may answer both of your questions:
"Capabilities" are basically just standardized collections of commands and/or attributes. Drivers declaring that they implement a capability must implement all commands (methods in Groovy) and report the specified attributes (more on attributes/events below). For example, the "Switch" capability requires that you implement the on() and off() commands and report a switch attribute, with valid values for that attribute being either on or off. (This is a simple example and almost unfortunate in that some attribute names and attribute values match the capability or command names; there is not necessarily any connection between these, aside from the fact that commands generally exist to modify something that will somehow result in an attribute value change.)
Events on Hubitat are just the result of an attribute's value changing. For example, if the switch attribute mentioned above changes from on to off or vice versa, that is an event. (Technically, the value doesn't have to change, as there are ways for the driver to force an event to be created even if the new value is the same, but attributes are how events happen regardless.)
You as the driver author must call sendEvent() to make an event happen (or createEvent(), but this only works inside parse() and I've followed advice to just use sendEvent() everywhere to not have to worry about this). When information comes into parse() (or however this might happen for the type of driver you're writing), it's the driver's job to figure out what everything means and create events when needed. (Just like how it's the driver's job to create the result needed when commands are issued to it--e.g., turning off the switch when off() is called.)
I assume your last question refers to custom attributes. You can define custom attributes, which just means ones that aren't part of a capability. The only reason these are less desirable, I'd say, is that the "standard" (capability) attributes are generally usable across any app that looks for devices with those capabilities, whereas with custom attribute you'll have to have an app or rule that "knows" about those specifically. Same for custom commands.
This also assumes that the Zigbee device communicates directly to Hubitat. If you have it on another hub like Home Assistant integrated via the LAN, then this would probably all have to be figured out over there, and by the time it gets to Hubitat, it's just a LAN device that hopefully another integration would already take care of handling the communication with for you; but if not, same rules as above apply (except how to communicate with a LAN device is usually a bit different).
Thank you for the detailed description. It was very helpful
Some of the parse abilities I understand but sometimes don't "get". It helps me to connect them to what they "physically" do. In this case (I believe) sendEvent() make changes in the Hubitat database and createEvent() creates an entry in the database.
BTW My Zigbee "radio" is a Haas implementation of the TI cc2530 device. Its really a cool device, but seems to communicate with the hub without using standard capabilities. All the commands are in a text form. The good news one can send any text command (up to 15 bytes) to the hub. This allows the designer to create all sorts of inputs / outputs and not be limited to the standard capabilities. Or at least this is my overall understanding.
sendEvent() and createEvent() are identical in outcome, but the latter only works if you're in parse(). I always use the former so I don't have to remember this. Both are used to change attribute values, which is how events are generated in Hubitat. We know that attribute values are stored in the database.
I just thought of something that might be what you're thinking of with there being some differences regarding attributes and the database: if you create an event (with sendEvent() or createEvent(); again this, doesn't matter) and that attribute doesn't really exist--by which I mean that it's not an attribute required by a capability you're implementing or a custom attribute that you've declared--then ... I guess it's behavior is technically undefined, but what happens at the moment is it appears under "Current States" on the device page and then disappears when that page is reloaded. It's likely that what this means is that it therefore does not get committed to the database. (I don't recall off the top of my head whether it stays in the "Events" page or is usable for subscriptions in apps, but again this behavior isn't really documented, so I wouldn't count on it working or continuing to work in any specific way.)