Rule Error why?

(Thomas Bail) #1

Hi There,

i have created a rule to process pertolstation prices based on the tankerkoenig binding. I sort the prices a set some item labels. But i get errors an i have no idea why. The log is something like:

2018-03-20 15:28:40.707 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Process Petrolstation Information': null
2018-03-20 15:28:40.708 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Process Petrolstation Information': null
2018-03-20 15:28:40.715 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Process Petrolstation Information': null
2018-03-20 15:28:40.846 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Process Petrolstation Information': null
2018-03-20 15:28:40.891 [INFO ] [rule.ProcessPetrolstationInformation] - Petrol prices updated!
2018-03-20 15:28:40.905 [INFO ] [rule.ProcessPetrolstationInformation] - Petrol prices updated!

Based on six stations i query i got four errors and two loginfos. Following you will find the rule.

rule "Process Petrolstation Information"
when

    Member of GRP_Petrolstation_Price received update

then

    var i = 1 // Additional counter variable

    for (aPrice : GRP_Petrolstation_Price.members.sortBy[ state as DecimalType ]) { // Another loop to overcome the "Final Variable" vs "Lambda" problem

        val String counter = new String(String::format("%02d", i))
        val String namePrefix = aPrice.name.substring(0, aPrice.name.lastIndexOf('_')-2)
        var StringItem aDisplay = GRP_Petrolstation_Display.members.filter[ f | f.name == namePrefix+counter+"_Display" ].head as StringItem
        var ContactItem stationOpen = GRP_Petrolstation_Open.members.filter[ f | f.name == namePrefix+counter+"_Open" ].head as ContactItem

        aDisplay.label = aPrice.label
        
        if (stationOpen.state == OPEN) {
            aDisplay.postUpdate(String::format("%.3f €", (aPrice.state as DecimalType).doubleValue()))
        } else {
            aDisplay.postUpdate(transform("MAP", "contact.map", stationOpen.state.toString))
        }

        i = i+1

    }

    VT_Petrolstation_LastUpdate.postUpdate(new DateTimeType())

    logInfo("rule.ProcessPetrolstationInformation", "Petrol prices updated!")

end

Someone any idea?

Thomas

0 Likes

Dynamic ordering of items in sitemap
(hr2) #2

I have never seen a rule trigger “Member of” before.
Do you have any information about?

0 Likes

(Thomas Bail) #3

This is an new trigger introduced with OH 2.3. I think ist is self explanatory. Within the rule you could acces the items that has triggered the rule with triggeredItem.

0 Likes

(hr2) #4

I would check a.Price.state for null before.

0 Likes

(Thomas Bail) #5

If this is the problem, than i would expect a differend error message that points me to a special line in the rule

0 Likes

(hr2) #6

Try logInfo() before and after this line, to see where is the problem.

0 Likes

(Vincent Regaud) #7

val contactItem
and
val stringItem

var will not work, you are duplicating the instance of the object and not pointing at the actual item

0 Likes

(hr2) #8

Two cycles seems to work.

0 Likes

(Thomas Bail) #9

changed it, same error

0 Likes

(hr2) #10

Than write a logInfo() before every line.

0 Likes

(Joachim Boeddeker) #11

No, but this error is quite some time around.

I already tried to log everything, this error stays.

The triggeringItem/Member of did not help either, this error stays, not all the time but every once in a while.

Thanks for the for-loop, i did not know that this was existing. I also have a variable/lambda problem. :slight_smile:

0 Likes

(Rich Koshak) #12

See Features for Rules that work with Groups for details on Member of.

And I’ll agree with hr_2. You only get line numbers for syntax errors. Trying to use an object that is null or in a way that is not valid (e.g trying to parse a string into a number that cannot be parsed) will result in errors like the above.

What I don’t understand is why the rule executes six times when using the Member of trigger. Are all six updated at the same time?

Unless I misunderstand how it works, you shouldn’t have to loop through all the members for each trigger of the rule. The point of Member of is that it will cause triggeringItem to point to the member that was updated. So drop the loop, set aPrice to triggeringItem, drop the counter and you are good to go. The rule will be called once for each member of the group as they are individually updated.

I suspect what is happening is the first few times the rule triggers not all of the members have been populated so you are getting null exceptions. The last two work because by the time the last one runs all of the members have a usable value.

0 Likes

(Thomas Bail) #13

On the error message: I will try to add logInfo messages but it think i will not get any results that are usable, but i will try

On six times triggering: Yes more or all the item in the group will be updated by the binding more or less at the same time

On the loop thing: becaue i sort the fuelstation prices to display the cheapest at the top i have to iterate trough all items. Simple: If a price changes -> sort all prices new

On the population thing: all items hav persitence enables even at startup.

So any more ideas?

0 Likes

(Jürgen Baginski) #14

Maybe a dumb question, but when do you observe these errors? All the time or only after a restart of OH or the binding? In case of the last, the first prices migth not be updated by a persistence or the binding.

0 Likes

(Thomas Bail) #15

I have not found any regular occurence. Normaly after a restart, but in between too. added a reentrat lock today so that each triggering could be processed in total.

0 Likes

(Rich Koshak) #16

In that case I’d change the group to keep the sum of the values and use a changed trigger so the rule doesn’t trigger so many times.

There is a lot going on at the same time when an update occurs and when you update a bunch of items at the same time it is very easy for timing to become an issue.

There is an item registry that keeps all the items current states. It takes some time (milliseconds) for the registry to get updated and if you try to use an item’s state while it is being updated it might be possible you will get null or an old value or the like. This is why you can’t rely on an item’s state for a received command triggered rule and need to use receivedCommand.

So I would focus on making the role only trigger once. Then I would focus on delaying the role from executing until all the items are done being updated in the registry using a timer or thread sleep. Then is being willing to bet the errors will go away.

0 Likes

(Thomas Bail) #17

First i changed the trigger to “changed” and the i enclosed the rule with a lock. At the moemnt i do not see any error, but thats is maybe an effekt of having lots of other errors :slight_smile:

Thanks for your suggestions

0 Likes