triggeringItem.name in a cron / system started triggered rule

OH 2.5.10

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

wtf is this???

1st rule leads to:

17:07:37.654 [WARN ] [pse.smarthome.model.script.test.rules] - Test0 null
17:07:37.659 [WARN ] [pse.smarthome.model.script.test.rules] - Test1 null

br!

There is no triggering item when the rule was triggered by cron or started. What were you expecting to see?

You can’t get the name of something that doesn’t exist. I think your openhab.log will be telling you something along those lines.

I would expect null.
but the rule is just NOT execuded. at least not from time cron

I changed the rule a bit, see post 1 plz.

This is the response of rule 1

17:07:37.654 [WARN ] [pse.smarthome.model.script.test.rules] - Test0 null
17:07:37.659 [WARN ] [pse.smarthome.model.script.test.rules] - Test1 null

And rule 2 and 3 just do nothing:

17:46:52.420 [INFO ] [del.core.internal.ModelRepositoryImpl] - Refreshing model 'test.rules'
17:47:35.151 [INFO ] [smarthome.event.ItemStateChangedEvent] - global_ad changed from 2020-11-06T17:46:35.132+0100 to 2020-11-06T17:47:35.135+0100

no error message, nothing

Null does not have a .name method

yes. I understand.
is the rule executed until .name method and then aborted?

How can I solve this?
when using triggeringItem I geht this as a response:
null when it is triggered by cron which I can process

and test_7 (Type=SwitchItem, State=OFF, Label=null, Category=null) when it is triggered by item.
I just need the “test_7” Part

Test if is null before trying to do anything else with it. if()

ok, i had an aproach to do that before.
I thought there must be a better way, just another command or so. but if not ^^
thank you!

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.

18:16:01.530 [WARN ] [del.core.internal.ModelRepositoryImpl] - Configuration model 'test.rules' has errors, therefore ignoring it: [24,1]: missing 'end' at 'rule'

well now this is my approach.

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”

Why don’t you write a rule for cron, and a rule for Item trigger. It’s probably easier.

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 :crazy_face:

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.

thank you.
I have got a solution.

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

That wasn’t my recollection but it’s been a really long time since I ran it. That does make triggeringItem easier to rely upon in many cases.

Yep, I’m sure that is true.