I hate my speaking voice. Like really hate to hear my self when I’m recorded. Editing video of myself would be torture. So I’m really not excited about trying my hand at YouTube. I have thought about a Rules DSL book, but my fear is by the time if finish it the Experimental Rules Engine would be ready for prime time and the book would be out of date before it’s published (not that I could hope for anything better than a read the docs publication.
Not to mention I could be spending that time just working in the docs themselves.
Most of the stuff I’ve mentioned needing a white board for are really generic programming topics like how C like Classes and Objects relate to each other and the like. In certain rare circumstances having this knowledge is useful, but usually the average user doesn’t need to know details at this level.
The funny thing is that picture was taken by my wife in a hat shop in Santa Fe, New Mexico. I didn’t come home with it but everyone liked it so much I had to order one.
Which is what I’ve been saying all along. When you are a beginner being faced with the full set of programming told is daunting. It represents a barrior to entry into itself. But if you already know all those tools, being faced with the lack of those tools is just as big a barrior to entry. So if you know how to program, please use JSR223. You’ll be much happier.
As of OH 2.3 you can put the items in a Group and use Member of MyGroup changed' (or any of the other Item triggers) and the Item that triggered the rule will be
triggeringItem. Prior to that, you could use
Item MyGroup received update` which want great but worked. The problem was the rule triggered multiple times per update and we had to use a hack with persistence to get the specific item that triggered the rule.
Should not be necessary. If you use Member of
triggers and some of the design patterns like Associated Items you should only need one rule.
Basically, Groups are your data structures in Rules DSL.
As an example:
rule "Keep track of the last time a door was opened or closed"
when
Member of gDoorSensors changed
then
if(previousState == NULL) return;
val name = triggeringItem.name
val state = triggeringItem.state
// Update the time stamp
postUpdate(name+"_LastUpdate", now.toString)
// Set the timer if the door is open, cancel if it is closed
if(state == OPEN) sendCommand(name+"_Timer", "ON")
else postUpdate(name+"_Timer", "OFF")
// Set the message
val msg = new StringBuilder
msg.append(transform("MAP", "en.map", name) + " was ")
msg.append(if(state == OPEN) "opened" else "closed")
var alert = false
if(vTimeOfDay.state.toString == "NIGHT" || vTimeOfDay.state.toString == "BED") {
msg.append(" and it is night")
alert = true
}
if(vPresent.state == OFF) {
msg.append(" and no one is home")
alert = true
}
// Alert if necessary
if(alert){
msg.append("!")
val timer = flappingTimers.get(name)
if(timer !== null) {
logWarn(logName, name + " is flapping!")
timer.cancel
flappingTimers.put(name, null)
}
else {
flappingTimers.put(name, createTimer(now.plusSeconds(3), [ |
aAlert.sendCommand(msg.toString)
flappingTimers.put(name, null)
]))
}
}
// Log the message if we didn't alert
else {
logInfo(logName, msg.toString)
}
end
rule "Timer expired for a door"
when
Member of gDoorsTimers received command OFF
then
val doorName = transform("MAP", "en.map", triggeringItem.name)
aAlert.sendCommand(doorName + " has been open for over an hour")
if(vTimeOfDay.state.toString == "NIGHT" || vTimeOfDay.state.toString == "BED") {
triggeringItem.sendCommand(ON) // reschedule the timer
}
end
The above makes use of Expire based Timers. But basically it’s one rule to handle notifications for all my doors.