I tried to create rules that react different depending on how they are triggered.
I learned that system started and Time cron leads to returning null wenn using triggeringItem and I can understand that both methods have no name so that triggeringItem.name cannot deliver that.
but when I add triggeringItem.name into the rule, the rule is not executed by system start or cron. and this is what I don’t understand.
All three rules can be triggered by changing Item test_7
this rule is working:
rule "Test1"
when
System started or
Time cron "* 0 * ? * * *" or
Item test_7 changed
then
val source1 = triggeringItem
logWarn("test.rules", "Test0 " + source1)
logWarn("test.rules", "Test1 " + triggeringItem)
logWarn("test.rules", "Test2 " + triggeringItem.name)
logWarn("test.rules", "Random text")
end
this one not:
rule "Test2"
when
System started or
Time cron "* 0 * ? * * *" or
Item test_7 changed
then
val source1 = triggeringItem
val source2 = triggeringItem.name
logWarn("test.rules", "Test0 " + source1)
logWarn("test.rules", "Test1 " + triggeringItem)
logWarn("test.rules", "Test2 " + triggeringItem.name)
logWarn("test.rules", "Test4 " + source2)
logWarn("test.rules", "Random text")
end
even if I change the order of logWarn it stops working.
rule "Test3"
when
System started or
Time cron "* 0 * ? * * *" or
Item test_7 changed
then
val source1 = triggeringItem
logWarn("test.rules", "Test2 " + triggeringItem.name)
logWarn("test.rules", "Test0 " + source1)
logWarn("test.rules", "Test1 " + triggeringItem)
logWarn("test.rules", "Random text")
end
I think your error logging is messed up too, or you are looking in the wrong place. Try making a deliberate mistake and see if you get an error message.
rule "Test1"
when
System started or
Time cron "* 0 * ? * * *" or
Item test_7 changed
then
val source1 = triggeringItem
//val source2 = triggeringItem.name
if (source1 === null) {
logWarn("test.rules", "do nothing " + source1)
}
else {
val source2 = triggeringItem.name
logWarn("test.rules", "do something " + source2)
test_proxy.postUpdate(source2)
}
logWarn("test.rules", "do something " + test_proxy.state)
logWarn("test.rules", "Random text")
end
I used the proxy item because I was not able to get source2 = triggeringItem.name working when source2 is declared global.
“Type mismatch: cannot convert from String to Item”
It’s not null. It doesn’t exist. Thus any attempts to reference triggeringItem in a rule that wasn’t triggered by an Item will result in an exception whic, as rossko57 indicates, would be in openhab.log. Are you not seeing any errors?
I don’t think that will work. This is a limitation of Rules DSL and triggeringItem. Either it exists or it doesn’t exist. If it doesn’t exist you can’t compare it to null because there is nothing to compare too. Variable have to exist before you can do anything with them and triggeringItem doesn’t unless the rule is triggered by an Item.
There are two ways to define a variable. One is val which means that the variable is a constant and final and cannot be reassigned. You probably wan to to use var when it’s defined as a variable.
Ultimately, you will not be able to do what you are trying to do. Rules DSL has no way to check whether or not a variable has been defined or not. If you really need this you need to use Jython or JavaScript to write your rules.
Afraid I gotta do the “well actually” thing - this implicit variable has one weird trick up its sleeve
If you have only non-Item rule trigger(s) - a cron,.or a Thing change, etc. - then this holds true. triggeringItem simply does not exist, any attempt to reference it in the rule will blow up with “undefined variable” or similar.
when
System started
then
if (triggeringItem === null) // WILL error and stop execution
however -
If there is any Item trigger variety present, then triggeringItem will be conjured into existence at every rule run. It doesn’t need to be the Item trigger that was called.
This has the odd consequence that if you have a rule triggered by both Item and by cron, then even on cron triggered runs triggeringItem will exist.
But of course it will be null if there isn’t really an Item involved, and triggeringItem.name, triggeringItem.sendCommand etc. are going to fail because null has no methods.
when
System started or
Item test_7 changed
then
if (triggeringItem === null) { // it exists and is testable
logInfo("test", "This is a System Started run")
If you wanted, you could add a trigger for an imaginary Item to any rule and pointlessly produce a triggeringItem with null value.
I don’t think this by any particular design, just DSL weirdness.
It does mean @kleiner-irrer later rule will work as intended.
Note for later readers - this is under OH2 DSL rules engine. Do not expect the same behaviour under OH3 rules engine, that is still in flux.
Problem is that I’ve got a Rollershutter that is controlled by a rule, triggered by several Items and cron.
(go down if Time is night or darkness is xyz but 10PM at latest - systemstart shoul sync the rule in case of a longer restart)
BUT if someone is manually controling the RS it should not be overwritten by rules.
Here the working rule:
rule "Rollershutter"
when
System started or
Time cron "* 0 * ? * * *" or
Item Rollershutter1 changed or
Item test_7 changed or
Item test_8 changed
then
val source1 = triggeringItem // as rossko mentioned somehow the result is "null"
var source2 = "triggeringItem"
if (source1 === null) {
// do nothing
}
else {
source2 = triggeringItem.name
}
if (source2 == "Rollershutter1") {
// do the stuff
}
else if (source1 === nlll {
// do the systemstart & cron stuff
}
else {
// do the rule
}
end