Subtraction in Rules Not Working

This might be a really simple one and maybe I just need a fresh pair of eyes on it but I have a rule and in that rule, I am trying to do a simple arithmetic subtraction but it won’t work and I can’t figure out why.

I have two variables of a Number type:

var Number upperTemp = 20.8
var Number offset = 0.3

All I want to do is upperTemp minus offset.

I can add my code if it helps but the reason I am doing this calculation (and not just typing 20.5 as a hard value) is because both variables are used multiple times in the code and I need an easy way to amend them if I need to in the future.

However, if I do:

logInfo("Diff", "Diff is "+ upperTemp-offset)

I get an error as below

2024-12-11 17:13:00.755 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'downstairsHeating-2' failed: Unknown variable or command '-'; line 65, column 39, length 250 in downstairsHeating

If I add an extra variable called diff as below:

var Number upperTemp = 20.8
var Number offset = 0.3
var Number diff = upperTemp - offset

diff is always null

The variables in question are just that - variables. Having searched the forum, a number of people have had a similar issue but it appears to be because they’re trying to do a calculation on an Item value whereas mine are not Items.

As an FYI, if I do:

logInfo("Output", "Upper Temp is "+ upperTemp+". Offset is "+offset)

the correct values are logged.

What am I doing wrong with this simple calculation?

Rules DSL has a somewhat broken typeing system. Any time you have an operation, the first operation dictates the type it tries to coerce the second one into.

So what is happening is you have String + upperTemp (remember PEMDAS) so it tries to coerce upperTemp to a String which it can easily do because everything has a toString method. Next we have String - offset. String doesn't have a subtract operator so it treats the -as a variable instead of an operator and of course there's no such thing as the-` operator.

This kind of stuff comes up all the time in Rules DSL and it’s the main reason I recommend against doing any new rules development in Rules DSL and moving to any of the other options.

So how do you make this work in Rules DSL? Put the subtraction in parens should do it.

"Diff is " + (upperTemp-offset)

Given PEMDAS Rules DSL will do the upperTemp-offset which is Number - Number. Then it will do the String + <result of subtraction>. And since the result of all math operations in Rules DSL are a Number and Numbers have a toString and it will be able to coerce the type to what is needed.

This one is weird.

So another thing that Rules DSL doesn’t like is when you try to force the type. It’s definitely a catch-22 because when you fail to define the type sometimes Rules DSL gets it wrong but when you do define the type Rules DSL punishes you.

I don’t think this is the cause but try:

var upperTemp = 20.8
var offset = 0.3
var diff = upperTemp-offset

I’m pretty sure that’s not going to be why it’s null but we can at least eliminate that as a cause.
Without more experimentation :person_shrugging: .

Created with blockly looks like this:

var test1, test2, ergebnis;


test1 = 10;
test2 = 3;
ergebnis = test1 - test2;
console.info(('Ergebnis' + String(ergebnis)));

Blockly compiles to JS which is a completely different language from Rules DSL which OP is using. But indeed, Blockly handles the types and order of operations better than Rules DSL in this use case.