Getting started with events and children

I’ve put together a fairly robust lighting controller for my home. Now I would like to learn about child objects and triggering events.

For example, say I wanted to make a clone of the zone controller. Where would be a good starting place to learn how to code it?

I figure this is a good example to play with. The goal would be to create a child zone with a list of sensors, send an active event when any of them is triggered and then an inactive event when they all are inactive. If I can successfully do that I should be able to use it to create anything I need.

You can find some examples of parent/child drivers in Hubitat's example repo, notably:

These are both drivers, but the way you'd create a child device of a parent app is basically the same, as is the typical method you'd pass commands (calling componentX() on the parent and handling it there, where X is the child command) and events (calling parse() with a list of event maps on the child) between the two.

Or at least this is the pattern used in most Hubitat apps/drivers and the one you'd need to follow if using their built-in Generic Component drivers. (Some of these are newer than some drivers and apps that were originally written with custom child drivers; if they were to re-do those today, perhaps they would use these instead. ZMC strikes me as one that could have been one of them.) You can write your own child drivers and do whatever you want to make communication happen between them; the advantage of doing it this way is that you can take advantage of the built-in drivers, so you or the user doesn't have to install anything extra.

Oh, that’s completely different than the repo I followed from the docs. I installed a sample from the other repo and it gave my two instances.

You can see the two my test instances where I was going for a relationship like the motion and mode app above.

I’ll take a look at that other repo. Thanks.

Ah, I see now you're not looking at devices/drivers, as I had assumed -- Motion Lighting is a child app of Mode and Motion Lighting. ZMC actually does both -- a child app for each instance, and each of those apps creates a child motion sensor device. That last thing is all I was really thinking about in my response above.

In many cases, a parent app in this case is often little more than a way to "group" related apps. (In others, it serves some app-wide function, like communicating between different child apps, presumably how Rule Machine handles things like "Run rule actions" and pausing/resuming one rule from another.) In this case, it's pretty simple: write the child app more or less like normal, as in your "Switch-Contact" example above, but in its definition, include a key/value like:

parent: "MyNamespace:MyAppName"

Then, write an app with that namespace and name (spaces are allowed, at least in the app name; other characters get...tricky from what I recall). Somewhere in that app page, you can show child apps and allow creating new ones (this will automatically do both) by writing a line like:

app name: "childAppList", appName: "MyChildAppName", namespace: "MyChildAppNamespace", title: "Add New (child app name)", multiple: true

This goes inside a section on a page, just like input and friends do.

Often with parent apps, you'll also want to add something like this to their definition:

   singleInstance: true,
   installOnOpen: true,

This will only let the user install a single instance of the parent (not always desirable, but it often is) and automatically "install' the app when opening, avoiding the need for the user to "Done" or "Install" out of it before it begins permanently residing in the "Apps" list, possibly saving some frustration later if they begin creating child apps before finishing things up with the parent app.

I'm not seeing anything exactly like this in the example, but there should be plenty of community apps. Here's a simple one of mine: Hubitat/apps/TimedSwitchHelper at master · RMoRobert/Hubitat · GitHub

But since you mentioned "events," I assume you may still be interested in devices. The example app above is a bit odd in that it uses a virtual instead of component driver for the child, but I suppose that's still one way you can do this.

1 Like

OK that explanation and app was helpful. I have an app that does nothing but has a parent/child relationship.

image

Now I need to figure out if I need a driver instead of a child app. I'm guessing I'll need to dive into a driver but gave me the next piece of insight I needed.

1 Like

After some serious hacking I now have a custom app that creates a child app and associated child device I can see in the device list. It is ugly but I have my framework.

Thanks for the pointers.

2 Likes

LOL, I don't think device drivers get any simpler than this.

metadata {
	definition (name: "Virtual Motion with Cooldown", namespace: "jlkSpace", author: "Jeff Knox") {
		capability "Sensor"
		capability "Actuator"
		capability "Motion Sensor"
		capability "Switch"

		command "active"
		command "inactive"
	}

	preferences {
	}
}

def installed() {
}

def updated() {
}

def on() {
	sendEvent(name: "motion", value: "active")
}

def off() {
	sendEvent(name: "motion", value: "inactive")
}

def active(){
	on()
}

def inactive(){
	off()
}

Now onto the child apps.

I know I could have used one of the virtual drivers but it had extra fields I don't want to deal with right now. This driver might also evolve as I figure out what I want to accomplish. Even though it might be redundant it is a good exercise in learning how HE and Groovy are put together. It has been too long since I have done semi-serious coding.

In case anybody is interested I'm putting together a zone motion controller that has a presence cooldown factor. The more it is triggered the longer the cooldown. My current lighting controller has it built in but it would be much simpler if that was handled by the zone handler. I would also like to add another state to the trigger but that's later.

... Oh my, as I was typing this I just realized that adding another state is easy.

image

Now I need to move my logic from the child app to the driver. Not an issue, just figuring this out as I go. :slight_smile:

Be aware: you are using the "standard" capability "MotionSensor" and its required motion attribute, which per the specs has two defined values of "active" or "inactive". You may break apps if you use values outside this set.

Oh, good to know. In this case it is fine because it is all custom code and not intended for general consumption. After I get this phase done I'll look into how to do it "correcly." :wink:

Download the Hubitat app