I transfer my DSL rules into oh3 and I will use main UI for it. I have a rule with a lambda expression and for this I need to define a global variables. Where I have to do this, I have no clue… Can somebody give me a hint.
There are several recent threads about this on this forum. None of them contain good news - your simplest option is to keep your DSL rules in xxx.rules files, which will work as before.
So this is really more of an XY Problem. You currently implement something in a global lambda, but is that the best approach to achieve what you are trying to with that lambda? In my experience the answer is probably not. Global lambdas are a code smell to me and there are only a few specific circumstances where they should be used.
then
val telegramAction = getActions(“telegram”,“telegram:telegramBot:49b7f025cb”)
if (gWindowsfind.state == OPEN) {
var String open_windows_read
var String open_windows1 = “Offene Fenster/Türen: \n”
gWindowsfind.members.forEach [ window |
if (window.state == OPEN) {
open_windows_read = (transform(“MAP”, “fenster.map”, window.name))
open_windows1 = open_windows1 +“-”+ open_windows_read + " \n"
}
]
telegramAction.sendTelegram(“”+ open_windows1 +“”)
end
If I use this rule inside a rule file in oh3 everthing is ok and runs without any error, as rule in the main UI I get the following error:
Cannot refer to the non-final variable open_windows_read inside a lambda expression; line 12, column 475, length 17
Cannot refer to the non-final variable open_windows1 inside a lambda expression; line 13, column 562, length 13
Cannot refer to the non-final variable open_windows1 inside a lambda expression; line 13, column 578, length 13
Cannot refer to the non-final variable open_windows_read inside a lambda expression; line 13, column 598, length 17
I found a thread in the community where the info was given to declare the variable as global variable to solve the problem.
But I think you are right, its time to go a step deeper in the new languages, but first I would migrate my system to oh3 and then I will start to improve my rules.
You should be getting the error in .rules files too. It’s always been the case that you cannot modify a var inside a forEach.
If you move the open_windows_read declaration inside the forEach and switch to using a StringBuilder val it will work just fine. Or you could use a map/reduce.
Thank You Rick! I have tried your approach but I get the following error according to .reduce expression:
Assignment to final parameter; line 7, column 362, length 6
I have checked your Design Pattern Working with Groups in rules but I can not find the failure. Your mentioned the expression could be backwards but in my opinion it is correct.
actually I try to rebuild my rules to ECMA rules in the ui, but I don’t find a solution to port the quoted expression to javascript. Please can you give me a hint?
I haven’t had time to update the Working with Groups in Rules DP with JavaScript yet.
You have two options. You can convert the list returned by members to a native JavaScript array and use the stuff built into JavaScript to do the operations. But openHAB has Nashorn as the JS engine which is ECMAScript 5.1 and lacks some important features like filter.
OK, the reduce returns an Optional. That way there is something to return even if the reduce has nothing. I thought that toString() would give you the String but apparently it adds some stuff to it. You need to call get() on the result of the reduce to get at the String Object and then call toString().