Groovy Macros

I'm not groking the use of Groovy Macros (MetaProgramming) and don't even know if it works with Hubitat, any help appreciated.

Want to generate some methods with embedded device.ids taken from user input settings. The method names would be used with 'runIn' commands.

For example: input setting defines a device with id 1234, this would generate a method named: lightOff1234 used with
runIn(600, lightOff1234)

It's a personal app and I could manually code this, just want to get fancy and not have to add code every time I add or change a device.

Currently using this with multiple devices
runIn (600, lightOff, [data: it, overwrite: false])

Where 'it' is a device lighting object. Having a unique method name per device eliminates the need for "overwrite: false" .

So the generated code would look something like this

void lightOff1234()
{
generated logic code here
}

The method you are calling to, lightOff, how are going from the map "it" to an actual device command? Because I have tried doing this:

def lightOff(thing){
     thing.off()
}

and that doesn't work. When a device object is passed to another method it is no longer treated like a device object, it is treated like a map containing all of the fields of a device object. So, in your called method are you finding the object via the device ID or something? I'm curious what your "lightOff" method looks like, if you don't mind sharing.

Most of the meta programming stuff is unavailable in the HE sandbox.

It's in my luxLighing app at GitHub - arnbme/hubitat

I use the device.id to locate the target device in a multiple light input setting

void lightOff(dvcObj)
{
if (settings.logDebugs) log.debug "luxLighting lightOff entered ${dvcObj.id} ${dvcObj.name}"
luxHandler(false,false,dvcObj.id) //light may or may not be turned off based on lux and system status
}

void luxHandler(evt,forceOff=false,onlyLight=false)
globalLights.each
	{
	if (onlyLight && onlyLight != it.id) //dont process this light
		{
		if (settings.logDebugs) log.debug "luxHandler ${it.name} skipped ${it.id} $onlyLight"
		}
	else

Appreciate the answer, but not the one I wanted :slightly_frowning_face:

That's pretty much what I thought you were doing because of the limitations I mentioned. Glad I hadn't completely missed something because I woulda been truly pissed!! Thanks!!

From what I remember, I think what you want to do could be done in ST. However, that's almost two years and a (now unplugged) device ago. And I look back without nostalgia!

1 Like

I don't remember either but yes, I know it was different And since the Groovy IDE is going away anyway, I'm not even gonna take the time to look it up. So there ST.
:stuck_out_tongue:

1 Like

One thing I really miss from ST is

device.command() with a time delay.

Now it needs a runIn and bumps into the issue you described.

from ST docs

"Some commands may expect parameters. All commands can take an optional map parameter, as the last argument, to specify delay time in milliseconds to wait before the command is sent to the device:

// wait two seconds before sending on command
mySwitch.on([delay: 2000])"

1 Like

Created a workaround for this