Using OpenHAB 3.4.1 on Ubuntu 20.04 Intel 64-bit, Java 11.0.7+8.
I’m attempting to use the new privateCache in the Rules DSL and only finding errors. My goal is to have a security motion sensor that OPENs momentarily update a presence Switch with a 30 second minimum hold time. I do not want to create a timer var for each possible target item. I just want to set a timer and fetch it later if the rule needs to update that timer.
Rule (not all {name}_Presence exist, so there is a check to avoid errors)
rule "Motion to Presence"
when
Member of gIndoor_Motion_Sensors changed
then
val triggeringItem = ScriptServiceUtil.getItemRegistry.getItem(triggeringItemName)
val actionItemName = triggeringItem.name.toString.replace("_Motion","_Presence")
if (ScriptServiceUtil.getItemRegistry.getItems(actionItemName).length < 1) return
var actionItem = ScriptServiceUtil.getItemRegistry.getItem( actionItemName )
var newValue = if (triggeringItem.state == OPEN) ON else OFF
logWarn("security", "transforming {}={} to {}={}", triggeringItem.name, triggeringItem.state, actionItem.name, newValue)
var presenceTimer = privateCache.get(actionItem.name.toString)
if (newValue == ON) {
actionItem.sendCommand(newValue)
if (presenceTimer === null) privateCache.put(actionItem.name.toString,
createTimer(now.plusSeconds(30)) [|
logWarn("presence", "{} timeout", actionItem.name.toString)
actionItem.sendCommand(OFF)
privateCache.remove(actionItem.name.toString)
]
) else presenceTimer.reschedule(now.plusSeconds(30))
}
end
Logs indicate privateCache is not defined in this scope.
2023-01-19 14:12:38.978 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BedroomsUp_Motion' changed from CLOSED to OPEN
2023-01-19 14:12:38.984 [WARN ] [g.openhab.core.model.script.security] - tranforming BedroomsUp_Motion=OPEN to BedroomsUp_Presence=ON
2023-01-19 14:12:38.985 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'security-14' failed: The name 'privateCache' cannot be resolved to an item or type; line 214, column 23, length 12 in security
The code looks like it should be in scope here. What am I doing wrong?
That code is part of a commit from two weeks ago, after 3.4 was released. The private and shared cache variables may not be available for Rules DSL until OH 4. Or it might be possible that it’s only available in UI rules. You don’t really need it in text based rules, just declare a variable outside the rule at the top of the .rules file.
You don’t need to. Create a Map.
val timers = createHashmap
It has the same put and get methods that the privateCache uses (since it’s a Map that backs that as well).
Ah, thanks! I wanted to use a map, but couldn’t find the proper search incantation. The solution below seems to be working (note newHashMapnot createHashMap). To be clear, if I actually wanted the global scope of sharedCache to make a value available between rules, I would need to run a nightly, move to another scripting engine, or wait for a release that includes it for Xtend? No other workaround for global scope?
import java.util.Map
val Map<String, Timer> timers = newHashMap
rule "Motion to Presence"
when
Member of gIndoor_Motion_Sensors changed
then
val triggeringItem = ScriptServiceUtil.getItemRegistry.getItem(triggeringItemName)
val actionItemName = triggeringItem.name.toString.replace("_Motion","_Presence")
if (ScriptServiceUtil.getItemRegistry.getItems(actionItemName).length < 1) return
var actionItem = ScriptServiceUtil.getItemRegistry.getItem( actionItemName )
var newValue = if (triggeringItem.state == OPEN) ON else OFF
logWarn("security", "transforming {}={} to {}={}", triggeringItem.name, triggeringItem.state, actionItem.name, newValue)
var presenceTimer = timers.get(actionItem.name.toString)
if (newValue == ON) {
actionItem.sendCommand(newValue)
if (presenceTimer === null) timers.put(actionItem.name.toString,
createTimer(now.plusSeconds(30)) [|
logWarn("presence", "{} timeout", actionItem.name.toString)
actionItem.sendCommand(OFF)
timers.remove(actionItem.name.toString)
]
) else presenceTimer.reschedule(now.plusSeconds(30))
}
end
2023-01-19 14:23:37.847 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BedroomsUp_Motion' changed from OPEN to CLOSED
2023-01-19 14:23:37.853 [WARN ] [g.openhab.core.model.script.security] - transforming BedroomsUp_Motion=CLOSED to BedroomsUp_Presence=OFF
2023-01-19 14:23:41.638 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BedroomsUp_Motion' changed from CLOSED to OPEN
2023-01-19 14:23:41.643 [WARN ] [g.openhab.core.model.script.security] - transforming BedroomsUp_Motion=OPEN to BedroomsUp_Presence=ON
2023-01-19 14:23:45.871 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BedroomsUp_Motion' changed from OPEN to CLOSED
2023-01-19 14:23:45.877 [WARN ] [g.openhab.core.model.script.security] - transforming BedroomsUp_Motion=CLOSED to BedroomsUp_Presence=OFF
2023-01-19 14:24:11.646 [WARN ] [g.openhab.core.model.script.presence] - BedroomsUp_Presence timeout
2023-01-19 14:24:11.647 [INFO ] [openhab.event.ItemCommandEvent ] - Item 'BedroomsUp_Presence' received command OFF
2023-01-19 14:24:11.648 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BedroomsUp_Presence' changed from ON to OFF
2023-01-19 14:24:11.648 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'gEntry_Presence' changed from ON to OFF through BedroomsUp_Presence
I believe the sharedCache should already be available in OH 4 for Rules DSL, but again, I don’t know if it has universal support or only UI rules support.
And of course, another option is to move the rules to the UI if that is in fact the limitation here.
Yet another option is to put all your rules into one file.
I try to use the sharedCache feature in my DSL rules but I have errors on OH 4.1.1 (via Docker).
My rule:
rule "Test SharedCache in OH 4.1.1 / DSL Engine"
when
Time cron "*/30 * * * * ?" // Every 30 secondes
then
var testSharedCache = sharedCache.get('foo')
logInfo("testSharedCache", "testSharedCache = " + testSharedCache)
end
openhab.log:
2024-01-11 14:31:00.132 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'intrusion_extension-3' failed: The name 'sharedCache' cannot be resolved to an item or type; line 104, column 27, length 11 in intrusion_extension
2024-01-11 14:31:30.131 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'intrusion_extension-3' failed: The name 'sharedCache' cannot be resolved to an item or type; line 104, column 27, length 11 in intrusion_extension
Thank you @rlkoshak or your response
Indeed, if it works on your DSL engine on OH 4.1.1, that’s curious.
I will try to isolate this rule in a new simpler file in order to see the behavior on my OH 4.1.1 instance.