[SOLVED] OH2 - iterate through group members, porting from OH1

I have an issue with the rule I am trying to port from OH1.

I want to update every minute the time since security system zone was triggered. The rule used to work on OH1, but it gets rejected by OH2.

rule "Update time since open"
when
    Time cron "20 * * ? * *"
then
    Zone_Times?.members.forEach (zone|
       var Number minutes = 0
       if (zone.state instanceof DecimalType) {
          minutes = zone.state as DecimalType
          if (minutes < 49)
              minutes = minutes + 1
	  else
          if (minutes > 49 && minutes < 99)
              minutes = minutes + 1
        }
	postUpdate (zone,90)
        //logInfo("DSC","Updating zone to {} minutes",minutes)
    )
end

I get the following error message:

2018-05-26 21:49:53.290 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'dsc.rules' has errors, therefore ignoring it: [78,8]: no viable alternative at input 'var'
[89,5]: extraneous input ')' expecting 'end'

What is the right syntax?

I have found the right syntax by trial and error: {} around the code did the trick:

rule "Update time since open"
when
    Time cron "20 * * ? * *"
then
    Zone_Times?.members.forEach (zone|
    {   var Number minutes = 0
       if (zone.state instanceof DecimalType) {
          minutes = zone.state as DecimalType
          if (minutes < 49)
              minutes = minutes + 1
       else
          if (minutes > 49 && minutes < 99)
              minutes = minutes + 1
       }
       postUpdate (zone,90)
        //logInfo("DSC","Updating zone to {} minutes",minutes)
    }
    )
end

I think minutes could be a reserved word. Try

var Number xminutes

or suchlike.

In your reworked short rule, you must use {} for a multiline if, same as you do in your original rule.

Ah. OK you got that.

Thanks, I added curly brackets {} around the code and it worked…

Ok, that is weird syntax. I’m surprised it works. I’ve never seen a lambda defined like that. I’ll have to remember it.

There more standard syntax would be:

Zone_Times?.members.forEach[ zone|
    ...
]

Note the space after the [ which is a new requirement in 2.3. However, it should still work using parents like you have it.

The curly brackets rossko57 are referring to the still not quite right in your code assuming you indents indicate what you intend. It should be:

Zone_Times?.members.forEach[ zone|
       var Number minutes = 0
       if (zone.state instanceof DecimalType) {
          minutes = zone.state as DecimalType
          if (minutes < 49)
              minutes = minutes + 1
        }
       else {
          if (minutes > 49 && minutes < 99)
              minutes = minutes + 1
       }
       postUpdate (zone,90)
        //logInfo("DSC","Updating zone to {} minutes",minutes)
    ]

I’m pretty sure this code will do nothing except setting each member state of Zone_Times to 90.

:slight_smile:

1 Like

You’re right, the original OH1 posted variable minutes of course, but what I pasted was a version I was playing around with, trying to figure out why it complains on syntax.