You may have noticed that some devices on the hub use a parent/child relationship. Some child devices have another device as a parent (this is easily seen in the Devices list, where child devices display indented under the parent device). However, child devices can also have an app rather than device as the parent. While these are harder to see at first glance, such devices will have a "Parent app" listed in the "Device Details" table towards the bottom of their device detail page.
Examples of built-in apps and drivers that create child devices include:
- The Philips Hue Integration, Lutron Integrator, and similar apps create child devices of the app (e.g., each Hue bulb or group is a child device of the Hue Bridge Integration app)
- Many multi-endpoint/multi-channel Zigbee, Z-Wave, and LAN devices like power strips with individually controllable outlets, dual switches and outlets, or combination fan/light controllers expose each outlet, switch, or other device as a child device of a parent device
While there are multiple approaches that parent/child devices or apps can use, it is typical for the parent driver or app to handle all the Z-Wave, Zigbee, Matter, LAN/cloud, or other communication and either use the built-in Hubitat "Generic Component..." drivers (if any has matching capabilities) or to write or use a fairly simple child device driver that follows this convention.
For a pair of parent/child drivers that mimic how most parent/child drivers built into Hubitat work, see:
Key notes:
- The addChildDevice() method can be called from either an app or driver to create a child device of that app or device
- The namespace of built-in component drivers is
"hubitat"
, but you will need to use the namespace specified in your child driver code if writing your own child driver
- The general pattern, for commands, as can be seen in the example drivers above, is to call
componentXyz()
methods from the child on the parent when the child Xyz()
command is called, passing a reference to the child device as the first parameter (along with any other required parameters after).
- The parent driver or app typically handles all Zigbee, Z-Wave, Matter, LAN/cloud, etc. communication after this point
- The general pattern for events, as can also be seen in the example drivers above, is for the parent to call
parse()
on the child device(s) and pass in a List of Event maps. The built-in component drivers will generate events for any attributes the component driver is designed to handle.
- Writing your own child (and parent) drivers allows you to use any convention, and there is no requirement to follow the above conventions — but using built-in component drivers where possible means fewer custom drivers for your users to install, and following similar conventions in your own drivers means it's easy to switch between built-in or custom component drivers if needed.
Child devices offer several differences from "regular" devices:
- If the parent is an app: unlike an arbitrary device selected in an app (e.g., by an
input
), parent apps can call any method on a child device, not just those corresponding to commands. Similarly, the child device can also call any method in the parent app.
- If the parent is a child: two devices on the hub normally cannot "see" each other at all, but parent devices can call any method on the child device (including reading current attribute values — or anything else). Similarly, the child device can also call any method in the parent device.
- Child devices also generally make sense when there is a real-world relationship between the devices, e.g., a dual smart outlet (where each outlet might be a child device of the parent device and the parent does little more than handle the Zigbee, Z-Wave, etc. communication and coordinate with the child devices that offer all the attributes, commands, etc. expected for each part of the device) or integration apps that create child devices that are all part of the same device or service (e.g., Philips Hue Bridge integration or Lutron integration).