Could not invoke method on null?

Hi again,

here is something very strange to me …
Look at the code

var int dayLightValueMin = 12000
var int dayTimeTimeout = 10
var int nightTimeTimeout = 60





val org.eclipse.xtext.xbase.lib.Functions$Function4 calculateTimeOut = [
	int p_lightValue,
	int p_dayLightvalueMin,
	int p_dayTimeTimeout,
	int p_nightTimeTimeout
	|
	
	logInfo("Powersaving", "NEW LIGHTSAVING calc "+p_lightValue+","+p_dayLightvalueMin+","+p_dayTimeTimeout+","+p_nightTimeTimeout)
	

	if(p_lightValue < p_dayLightvalueMin)
		p_dayTimeTimeout	
	else
		p_nightTimeTimeout
] 

Here is the triggering rule

rule "Light Timeout switchlight_erdgeschosseg_toilettedeckenlampe"
	when
		Item switchlight_erdgeschosseg_toilettedeckenlampe changed                                                                            
	then
	
	
		logInfo("Powersaving", "NEW LIGHTSAVING START")
		var lightValue = illumination_sensor_aussendachmastlicht.state
		logInfo("Powersaving", "NEW LIGHTSAVING LV "+lightValue)
		val int timeoutValue = calculateTimeOut.apply(lightValue, dayLightValueMin, dayTimeTimeout, nightTimeTimeout) as Integer
	
		logInfo("Powersaving", "NEW LIGHTSAVING DEBUG ITEM("+switchlight_erdgeschosseg_toilettedeckenlampe+")")
		logInfo("Powersaving", "NEW LIGHTSAVING DEBUG TIMEOUT("+timeoutValue+")")
		lightTimers.apply(timerTable,switchlight_erdgeschosseg_toilettedeckenlampe, timeoutValue)
	end 

In the calculateTimeOut Lambda i get an

[ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Light Timeout switchlight_erdgeschosseg_toilettedeckenlampe': Could not invoke method: org.eclipse.xtext.xbase.lib.IntegerExtensions.operator_lessThan(int,int) on instance: null

But the debug msg says, all variable are set and have values:

NEW LIGHTSAVING calc 100,12000,10,60

When I remove the comparission it works fine …

How is this possible ?

I would guess that one or more of the values you are passing to the lambda are not ints. An indeed, lightValue is of type DecimalType, or Number, not the primitive int.

var lightValue = (illumination_sensor_aussendachmastlicht.state as Number).intValue
val int timeoutValue = (calculateTimeOut.apply(lightValue, dayLightValueMin, dayTimeTimeout, nightTimeTimeout) as Number).intValue

Honestly, it is stuff like this that makes me recommend to avoid the use of Primitives and to stick with the less specific Number where ever possible.

import org.eclipse.xtext.xbase.lib.Functions

val dayLightValueMin = 12000 // since this is a constant you should use val
val dayTimeTimeout = 10
val nightTimeTimeout = 60

// This way to define a lambda lets you set the type of the return value
val Functions$Function4<Number, Number, Number, Number, Number> calculateTimeOut = [
    p_lightValue, p_dayLightValueMin, p_dayTimeTimeout, p_nightTimeTimout |

  logInfo("Powersaving", "NEW LIGHTSAVING calc "+p_lightValue+","+p_dayLightvalueMin+","+p_dayTimeTimeout+","+p_nightTimeTimeout)

  if(p_lightValue < p_dayLightvalueMin)
    p_dayTimeTimeout	
  else
    p_nightTimeTimeout  
]

rule "Light Timeout switchlight_erdgeschosseg_toilettedeckenlampe"
	when
		Item switchlight_erdgeschosseg_toilettedeckenlampe changed                                                                            
	then
	
	
		logInfo("Powersaving", "NEW LIGHTSAVING START")
		var lightValue = illumination_sensor_aussendachmastlicht.state as Number
		logInfo("Powersaving", "NEW LIGHTSAVING LV "+lightValue)
		val timeoutValue = calculateTimeOut.apply(lightValue, dayLightValueMin, dayTimeTimeout, nightTimeTimeout) 
	
		logInfo("Powersaving", "NEW LIGHTSAVING DEBUG ITEM("+switchlight_erdgeschosseg_toilettedeckenlampe+")")
		logInfo("Powersaving", "NEW LIGHTSAVING DEBUG TIMEOUT("+timeoutValue+")")
		lightTimers.apply(timerTable,switchlight_erdgeschosseg_toilettedeckenlampe, timeoutValue) // Redefine this lambda as above
	end