Basics of a Lambda expression

rules
Tags: #<Tag:0x00007fe058941868>

(Heath B) #1

I’ve spent hours searching for a simple answer, but there are so many bits and pieces of different answers (some outdated) scattered that I have to ask. What am I missing? The function won’t run. In the console I keep seeing
“There is no context to infer the closure’s argument types from. Consider typing the arguments or use the closures in a more specific context.
This expression is not allowed in this context, since it doesn’t cause any side effects.
The field Tmp_homeRules.updateLight refers to the missing type Object”

Switch Light1 "Light1"	<light>  (MasterBedroom, gLight)	{channel="hue:0210:0017886e15d9:6:color"}
val Functions$Functions1<SwitchItem, Boolean> updateLight= [ lamp |
    val DateTime sunset = parse(Sunset_Time.state.toString)
    val DateTime currentTime = parse(Current_time.state.toString)
    val Number pastSunset = currentTime.compareTo(sunset)

    val eveningTemp = 55
    val dayTemp = 23

    if(pastSunset>=0) {
        sendCommand(lamp, eveningTemp)
    } else {
        sendCommand(lamp, dayTemp)
    }
    true
]

rule "Light1 ON"
when
    Item Light1 changed from OFF to ON
then
    updateLight(Light1 )
end

(Vincent Regaud) #2

First, please use the code fences.

Did you try this:

rule “Light1 ON”
when
    Item Light1 changed from OFF to ON
then
    updateLight.apply(Light1)
end

(Vincent Regaud) #3

But I am not sure that the use of a lamba if the best way here
If you have only one lamp that put the function in the rule
If you have several then please see:


(Heath B) #4

Adding apply was one of the first things I tried. When I add it to updateLight I end up with this error when the rule runs.

[ERROR] [untime.internal.engine.RuleEngineImpl] - Rule 'Light1 ON':  'apply' is not a member of com.sun.proxy.$Proxy146'; line 44, column 5, length 35

I want to use a lamda because I have many lights that all need the same rule, not necessarily at the same time. Light1 is just the name I gave the rule during development.

Also do I need to import anything? I saw some examples that included imports and others that didn’t.


(Michael Cumming) #6

This is best done using groups. Place all the items in the same group. Then create a rule that uses the member of trigger. The triggeringItem will contain the item that triggered the rule.


(Vincent Regaud) #7

You need to add
import org.eclipse.xtext.xbase.lib.Functions
To the top of the rules file


(Rich Koshak) #8

I agree with Vincent and Michael. The better approach is to use Groups, a single Rule and the Memeber of trigger and triggeringItem implicit variable as documented in the Associated Items DP.

But, for completeness, the correct and better way to define your lambda would be as follows:

val updateLight [ SwitchItem lamp |
    val DateTime sunset = parse(Sunset_Time.state.toString)
    val DateTime currentTime = parse(Current_time.state.toString)
    val Number pastSunset = currentTime.compareTo(sunset)

    val eveningTemp = 55
    val dayTemp = 23

    if(pastSunset>=0) {
        sendCommand(lamp, eveningTemp)
    } else {
        sendCommand(lamp, dayTemp)
    }
]