Integer Divide

I guess, I will never understand the openHAB script langauge

e.g
var Integer xx
xx= (299/3).toFixed(0)

results with “failed: ‘toFixed’ is not a member of ‘int’;”

also
xx = parseFloat(299/3)

results with “failed: The name ‘parseFloat’ cannot be resolved to an item or type;”

First things first: there are, at this point, several different scripting languages available for OH. This is both a blessing and a curse for OH. It means that users with different experience or preference can have a scripting language that best suits them, but it also means that help and examples have become very fragmented.

This means, when you are looking around at examples, that you have to be careful that the example you see is using the same language you are. For many of the languages, there are many similarities, so sometimes it can be difficult to tell, even for experienced users.

Along the same lines, it can be very difficult for us to tell which language you want to be using if you don’t specify it in your question and give more context for how you are trying to create these scripts. It’s not 100% clear from your post which language you are trying to use, but based on the two examples that you’ve posted, I’m going to guess that you are trying to use rulesDSL for your script.

This is not surprising in any of the scripting languages. An integer, by definition has no decimal component. So, it doesn’t make sense for it to have a method that controls the number of decimal places. You should really only expect number types that can hold numbers with decimals to have a toFixed method.

In some of the scripting languages, this would work, but not in RulesDSL. You need to specify a source for the parseFloat command, which in this case if the Float class Float::parseFloat. However, that’s not the only problem here. parseFloat is really only intended to find floating point numbers in a string and 299/3 is not a string it’s already a number type so casting it to another number type is likely to be most easily achieved in some other manner.

It looks to me like, in this case, your best chance for getting a clear answer to this particular difficulty (and in general) and learning more about the OH scripting options, is to put far more information into your question (if you go back and look at your original post, it, in fact, doesn’t even include a question so perhaps you are just looking to blow of steam and not actually requesting assistance in the first place?). What language are using, what does the full script look like, what are you attempting to do with the script?

Hi Justin
thanks taking time to answer my implicit question. Indeed I’m using RulesDSL and I tried to simplify my problem. The original problem started with:
doing some calculation for creating a a timer:
var tm=now.plusSeconds(actMins)||

this caused an error: “An error occurred during the script execution: Could not invoke method: java.time.ZonedDateTime.plusSeconds(long) on instance: 2022-07-17T10:09:04.651703700+02:00[Europe/Berlin] in watering”

My thinking was this error resulted because of wrong data format of “actMins”. This is defined as

var Number minsWatering=300
var Number actSplittSet=3
var int actMins= minsWatering / actSplittSet

But the debug shows actMins as “100.0000000” → as a floating value. The division seems to produce a float type.

So next try was to create a real integer - but how?
regards
Toni

When adding code to your posts it is always best to put it in code fences. This sets it off from the rest of the text and makes it easier to read and debug the code.

```
script code here
```

In this case the trouble is that fact that you have declared the first two values as Number type variables. Going back and forth from these to other things, such as the long required for plusSeconds, requires some specific calls. There are two solutions: get rid of the Number type in the declarations and just let RulesDSL handle the typing, which it can often figure out (easier, but less formal), or keep the Number types and use the intValue property to cast the final result into something compatible with plusSeconds (more formal).

var minsWatering = 300
var actSplittSet = 3
var actMins = minsWatering / actSplittSet

or

var Number minsWatering = 300
var Number actSplittSet = 3
var actMins = (minsWatering / actSplittSet).intValue

that was the problem. My thinking was that the result of the division will be automatically converted to the type of the result variable. But the result variable receives the type of the division.
Many thanks

As a general rule, all numbers in Rules DSL want to be a BigDecimal which is a type of Number. If you just provide a constant number it’s going to be a BigDecimal. If you do a calculation, no matter what the types of the operands, the result is going to be a BigDecimal.

Consequently it’s usually best to just let it do that and then convert to a specific type where necessary (e.g. in a call to now.plusMinutes() which needs a primitive int or long). In those cases, use the methods on Number (remember BigDecimal is a Number) to convert the value (e.g. intValue). It will handle rounding for you.

One final note. BigDecimal, Number, now, and even the call to createTimer are all interacting with Java Objects. It is usually at this intersection between Rules DSL and Java where you run into type problems like these.

1 Like

Thanks for the explanation