Hi folks,
I came across this post as I struggled with my “simple” lambda as well and I think it would make sense to summarize the working script and another trap a newby (like me) struggled with while adapting the lambda.
first of all, the entire rule (copy from above with typo’s removed, I hope)
import org.eclipse.xtext.xbase.lib.*
// imports the Functions object. This is the base object of a lambda
val Functions$Function1 Foo = [ String s |
// a lambda is a global variable like any other. By using val as opposed to various we are saying
// that Foo is final and cannot be reassigned. If you try to have a line that starts with "Foo =" you
// will get an error.
// Next you will see Functions. This is the root object of a lambda. Then you have $ which
// is a way to reference a subclass of Functions. Finally there is Function1. This is the subclass
// and the important part is the 1. This numbe must match the number of arguments the lambda
// will accept. You can have up to 7.
// The [ denotes the start of a lambda. You may have seen these square brackets before in
// timers and forEach. Those are lambds too. The only thing we are doing differently here is
// we are giving the lambda a name so it can be reused.
// Immediately after the bracket you list your arguments. In this cas we have only one and it
// is a String.
logInfo ("lambda", s)
true // return true in any case as last statement in lambda
// All this lambda does is log the passed in argument. You can do almost anything in a
// lambda t b at you can do in a rule.however, the lambda has no context so if you need
// to reference global vars or vals or rule local vars and vals you must pass them to the
// lambda as an argument.
]
// The closing bracket denotes the end of the lambda
...
// somewhere in a rule
Foo.apply ("bar")
// to call a lambda use its name followed by apply and the arguments in parents.
important:
- the import should be on the very top of your rule file.
- the lambda function can only called from the same rules file. It’s not globally available
- the number after Functions$Function1 specifies the number of parameters to handle
- lambdas seem to ignore global variables. So ensure everything you need inside of the lambda is given as a parameter.
And below my adapted version of above. My purpose is to change all the 3 items from a RGB switch with a single line for a given item name.
import org.eclipse.xtext.xbase.lib.*
val Functions$Function4 changeLED = [
String itemname,
int red,
int green,
int blue |
sendCommand( itemname + "_R", red.toString() )
sendCommand( itemname + "_G", green.toString() )
sendCommand( itemname + "_B", blue.toString() )
true
]
rule "LED on blue"
when
Item V_kitchen_led_b changed to ON
then
changeLED.apply("kitchen_led", 0, 0, 100 )
logInfo("Kitchen","LED on in blue")
end
rule "LED on red"
when
Item V_kitchen_led_r changed to ON
then
changeLED.apply("kitchen_led", 100, 0, 0 )
logInfo("Kitchen","LED on in red")
end
my items are called according a pattern like
kitchen_led_R
kitchen_led_G
kitchen_led_B
kitchen_led2_R
kitchen_led2_G
kitchen_led2_B
…
so all I give to the lambda is the unique name for the item in front which than is added with the 3 options for the RGB channels plus the 3 values I like to set the channel to (represents the percentage of brightness so a 100 goes to 100% brightness for that channel)
I hope above helps others as I struggled through it for several hours. All I was missing the right number after the function doh
Should I have overlooked a typo or made a new one: please let me know and I’ll edit it