I’m working with the latest stable version of OH and I’m trying to setup a timer to turn off my sprinklers after a variable delay period.
The period is based on the current temperature (from the ‘Number Day1AirTemperature’ item in the BOM plugin). After lots of testing I’ve got to this point:
This gives an error on the last line of code above:
Could not invoke method: org.eclipse.xtext.xbase.lib.IntegerExtensions.operator_divide(int,int) on instance: null
Now I’m not sure what object this is referring too since it’s an expression, so I’m not sure what is ‘null’.
This is all very odd because ‘current_temp’ and ‘10’ both appear to be integers, so I though I’d add this line to test the type the variable.
logInfo(“my.rules”, “Type of current_temp =’”, typeof(current_temp), “’”)
Running this rule gives the error:
[ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Test’: current_temp
So it seems that you can’t get the typeof a variable…
Thanks for taking the time to responsd - so I’ve taken your advice and taken the types of my var definitions. Same error: org.eclipse.xtext.xbase.lib.IntegerExtensions.operator_divide(int,int) on instance: null
Thinking about the problem, I decided to move the var declaration for my temporary variable outside of the code block to the top of the rule. When I did this I get a different error: Couldn’t invoke ‘assignValueTo’ for feature JvmVoid: (eProxyURI: thomashome.rules#|::0.2.1.2.0.4.1.0.0::0::/1)
So the error appears to be linked to the scope of the declaration:
Rule …
then
var Delay_Period = 180
if (...)
{
var current_temp = 0
current_temp = Day1AirTemperature.state
Delay_Period = current_temp / 10
}
– This gives the error operator_divide(int,int) on instance: null
Rule …
then
var Delay_Period = 180
var current_temp = 0
Narrowed things down a little more:
…
Rule
then
var Delay_Period = 180
if (. . .)
{
var current_temp = 0
current_temp = Day1AirTemperature.state
Delay_Period = current_temp / 10
}
generates error: operator_divide(int,int) on the expression 'current_temp / 10'
But this works just fine:
...
Rule
then
var Delay_Period = 180
if (. . .)
{
var current_temp = 0
current_temp = Day1AirTemperature.getStateAs(DecimalType).intValue
Delay_Period = current_temp / 10
}
A ‘var’ declaration creates a typeless variable - it takes on the type of the attribute assigned to it
If you set the initial type of a ‘var’ with a something like ‘int’, then this only sets the type until the next assignment (so generally a pretty pointless modifier)
Strange errors can occur in expressions if the type of the arguments has shifted, in my case assign the ‘.state’ cause my variable to take on the type of a State (which isn’t an int)
Thanks, this was helpful. I always struggle with types in rules. It’s even more confounding when things will cast to string in a log message, but not to a number type in order to do math.
var int myInt
myInt = 5 // no error, as 5 is integer
myInt = 5.5 // either an error, as 5.5 is not integer, or myInt == 5
myInt = (5.5).intValue // no error
I’m pretty sure that myInt = 5.5 will result in an error, as myInt is a primitive.
Now:
var Integer myInt
myInt = 5 // no error, as 5 is integer
myInt = 5.5 // either an error, as 5.5 is not integer, or myInt == 5
myInt = (5.5).intValue // no error
I’m pretty sure that this time myInt = 5.5 will result in myInt == 5, as myInt now is an object. But I did not test this.