I have read a bunch of discussions about how all of the things that can be done in Rule Machine could be done in Groovy, but how Rule Machine can make things simpler for those looking to avoid any programming. I am looking for the opposite. If I wanted to put together via Groovy some logic that could just as easily be done in Rule Machine, what would that look like? I would love to see the Groovy App equivalent of this logic from Rule Machine:
I would try to post this in the Developer category, might get a faster reply there.
+1 for the question!
I've moved this to a Developer category as suggested above. Hope you don't mind! Hubitat has a few basic app examples on their Github. That may be a good place to start:
Most of these are very simple but will give you an idea of how inputs/preferences and whatnot work. Most of the rest you'd need would be general Groovy knowledge. There at also a ton of community apps you can look at.
It ends up being relatively simple to write apps once you get started, but getting started takes a bit of learning.
I bumped around through the developer docs as well as a lot of really useful existing app code examples from the community (especially @jwetzel1492's for examples of installation and configuration pages for parent and child apps).
Here's a quick example that shows how to do what you have in your RM snippet.
EDIT: @chuck.schwer's example included the unsubscribe() call that I omitted. I edited mine to show that. His is a simpler example, to boot, so you should totally use that one.
/*
*/
definition(
name: "Simple Triggered App Instance",
namespace: "tomw",
author: "tomw",
description: "simple triggered app example",
category: "Convenience",
iconUrl: "",
iconX2Url: "",
iconX3Url: "")
preferences
{
page(name: "mainPage1")
}
def mainPage1()
{
dynamicPage(name: "mainPage1", title: "", install: true, uninstall: true)
{
section
{
input name: "inputMotionSensors", type: "capability.motionSensor", title: "Input Motion Sensors", multiple: true, required: true
}
section
{
input name: "outputSwitches", type: "capability.switch", title: "Output Switches", multiple: true, required: true
}
section
{
input name: "instanceName", type: "string", title: "Name For This App Instance", required: true
input name: "enableLogging", type: "bool", title: "Enable Debug Logging?", defaultValue: true, required: true
}
}
}
def logDebug(msg)
{
if(enableLogging)
{
log.debug "${msg}"
}
}
def installed()
{
logDebug("installed()")
app.updateLabel("Simple Triggered App Instance - ${instanceName}")
initialize()
}
def updated()
{
logDebug("updated()")
installed()
}
def initialize()
{
logDebug("initialize()")
unsubscribe()
subscribeToEvents()
}
def uninstalled()
{
logDebug("uninstalled()")
unsubscribe()
}
def subscribeToEvents()
{
logDebug("subscribeToEvents()")
inputMotionSensors.each
{ ms ->
subscribe(ms, "motion", changedHandler)
}
}
def changedHandler(evt)
{
logDebug("evt.getDevice().name = ${evt.getDevice().name}")
logDebug("evt.name = ${evt.name}")
logDebug("evt.value = ${evt.value}")
// see other Event Object members here: https://docs.hubitat.com/index.php?title=Event_Object
evtTime = evt.getUnixTime()
Date tempDate = new Date()
logDebug("event lag = ${tempDate.getTime() - evtTime}")
outputSwitches.each
{
switch(it.currentValue("switch"))
{
case "on":
it.off()
break
case "off":
default:
it.on()
break
}
}
}
There are some advanced coding practices in the above example, here is the simplest example I could come up with, I don't understand the use case you presented, but here is the example app that does what you want:
definition(
name: "Simple App Example",
namespace: "anonymous",
author: "anonymous",
description: "Toggle output switch when motion and logic switch is on.",
category: "Convenience",
iconUrl: "",
iconX2Url: "",
iconX3Url: "")
preferences
{
section
{
input name: "motionSensor", type: "capability.motionSensor", title: "Motion Sensor", multiple: false, required: true
input name: "logicSwitch", type: "capability.switch", title: "Logic Switch", multiple: false, required: true
input name: "outputSwitch", type: "capability.switch", title: "Output Switch", multiple: false, required: true
}
}
void installed()
{
updated()
}
void updated()
{
unsubscribe()
subscribe(motionSensor, "motion", eventHandler)
}
void uninstalled()
{
// unsubscribe to all events
unsubscribe()
}
void eventHandler(evt)
{
// we don't care if the motion was active or inactive, so don't check the status of the motion event just continue with our logic below.
// otherwise we would check evt.value or we would subscribe to motion.active or motion.inactive depending on what we wanted to do.
// check if logic switch is on
if(logicSwitch.currentValue("switch") == "on") {
// toggle outputSwitch, need to check which method to run.
if(outputSwitch.currentValue("switch") == "on")
outputSwitch.off()
else
outputSwitch.on()
}
}
Thank you all. I am not sure why it didn't occur to me to put this in the developer category. I also agree that my example was a bit nonsensical or at least impractical. That said, these code examples are great. They are just what I am looking for. Having 2 versions is especially great.
I had been looking at the examples, but I really appreciate the time you put into giving me an example where I can focus on the code because I know exactly what it is trying to accomplish.
Yeah, agree. Small steps at a time usually leads to great knowledge over time.
Small step for man, a great new contributor to HE community?
RogerThat
I have a suite of apps for different things, that I've been working on for a long time, having started where you're at. I'd like to think they're now moderately advanced, while doing a relatively wide variety of tasks. I don't have the very first versions on GitHub, but the earliest ones are relatively rudimentary. I know it would have helped me to see a progression, while have a wide(ish) base of use-case scenarios.
Earliest commits: GitHub - roguetech2/hubitat at c34aa1877e19ad59e03de950afa7304e4b78e2f2
Thanks for the pointer. This looks like an interesting way for me to move beyond the basics in the future. My single feedback is that it would be great if your github repository had a readme to explain what each these items is for and how they fit together.
I was able to track it down by searching in the community and finding this post:
Introduction to roguetech's app.
Thanks. I will in time. Still working on getting it ready for release. edit: It's on my "to-do" list, as well as maybe starting a change log.