The ST device.command with delay is not supported in HE, EG it.beep(2,[delay: 4000])
I decided to make a rudimentary delayCommand function, but my Groovy skills either are not sufficient or what i'm attempting is just not supported by the language. It throws an error attempting to execute the command. Hopefully someone knows how to do this without using a wait or delay that stop the code.
Are you trying to get the device to beep every 2 seconds? What about instead of delaying it you use
runIn (2,beep)? But i'm no groovy expert...that's just what came to mind immediately for me. I might be completely wrong.
I'm attempting to create a generic function to avoid wring many target functions. I have numerous varying device.commands with delays, beep was just an example. I also want millisecond timing delays to get half second timing, runin allows only seconds.
I was literally typing that very response when you posted @mike.maxwell. I finally know something and you steal all my thunder! jk. It's good to know I may finally be learning a thing or two though. hehe
This is a sample of what I'm attempting to convert. I realize I have to convert the "it" to the actual device id for the delay in HE. My issue is how do I create handlerMethods for each random user device id?
// when siren is defined: wait 2 seconds allowing people to get through door, then blast a siren warning beep
thesiren.each
{
if (it.hasCommand("beep"))
{
it.beep([delay: 2000])
}
else
{
it.off([delay: 2500]) //double off the siren to hopefully shut it
it.siren([delay: 2000])
it.off([delay: 2250])
}
}
I've been trying various incarnations of the following code, but my Groovy skillset is not up to the task. I somehow need to pass and receive the device as an Object (I think) but depending on how I send it, it results in
a string: runIn(2, delayBeep, [data: [it: ${it}]])
or
LazyMap: runIn(2, delayBeep, [data: [it: it]])
Could really use some help with this.
thebeepers.each //thebeepers is an input setting of devices
{
if (it.hasCommand("beep"))
{
log.debug "issued beep delayed 2000"
// it.beep([delay: 2000])
runIn(2, delayBeep, [data: [it: it]])
}
def delayBeep(map)
{
log.debug "delayBeep entered: ${map}"
// thebeepers.beep() this works but cant be used
def it=map.it
it.beep() //this fails
}
groovy.lang.MissingMethodException: No signature of method: groovy.json.internal.LazyMap.beep() is applicable for argument types: () values: [] Possible solutions: grep(), grep(java.lang.Object), sleep(long), sleep(long, groovy.lang.Closure), dump(), get(java.lang.Object) on line 141 (delayBeep)
Basically, a little queue of things to do that the delayMe handler gets called upon to execute (via runInMillis)
I haven't tried passing Device objects as the values, so you could try that for your use-case. If it doesn't work correctly, then these can be the NID's of the target devices, and a Device lookup via it's handle can be made inside the delayMe function.
I'd avoid redefining/re-using the it variable for another purpose, to avoid any potentially whacky behaviour
Appreciate the response.
Developing the command structure to replace the ST command delay or filtering out the delay: nnnn map is not the problem, the big issue for me is attempting to get dynamic device and command names to execute in the target routine, your "delayMe".
That is how you can parameterize the method that is called. Rule 3.0 uses this approach extensively. One thing to note, this won't work inside a closure, as this would refer to the closure, not to the app or driver as you want it to. However, you could simply put that code outside the closure and call it from the closure to get it to work.
Appreciate the response. However I need a targetMethod that handles a dynamic deviceid, versus the input setting device name as shown in my earlier example below
def delayBeep(map)
{
log.debug "delayBeep entered: ${map}"
// thebeepers.beep() this works but cant be used
def dvc=map.it
dvc.beep() //this fails with a lazyMap error
}
```.
There is not a method available that converts device id to a device. That would represent a security hole, where an app could take over devices without the user having selected them.
Everything is running local on HE, and I somehow obtained a non owned foreign device id, would it even be possible to target that device from my local hub by issuing a command? For example if someone's device id (not real) is D0B0064:050C I could issue a command to it?
I understand the security issue and not wanting to have a user target a device id they do not own, but would it be too much overhead to verify the user owns the dynamic device prior to executing the command.
This can go further if the device commands take parameters. This is how Custom Commands in RM are built and work. There are Custom Actions coming that use a similar technique to send any command and any parameters to any device.