[SOLVED] Trouble converting negative to positive using Math::abs in a rule

Hi,

Thanks (and apologies, I’m new) in advance for tips. My setup:

  • Hardware: Vsphere VM, 2GB Ram, 2 vcpu, 60GB HDD
  • OS: Ubuntu 16.04
  • Java Runtime Environment: Java 1.8.0_181
  • openHAB version: 2.3.0

Here is my rule file:

rule Office_Total
when
        Item HVAC_LVB_Total received update or
        Item LVB_UPSB_Input_Active_Power received update
then
        if (HVAC_LVB_Total.state instanceof DecimalType && LVB_UPSB_Input_Active_Power.state instanceof DecimalType) {
         Office_Total.postUpdate((LVB_UPSB_Input_Active_Power.state as DecimalType) - (HVAC_LVB_Total.state as DecimalType))
        } else {
          Office_Total.postUpdate(UNDEF)  // or UNDEF on OH2
        }
end

The rule works. Unfortunately the data gathered in HVAC_LVB_Total and LVB_UPSB_Input_Active_Power vary, and so when subtracting one value from the other, the result is sometimes negative.

I want to accept whatever the result from the calculation is as a positive number.

I have read that using a Math function could help specifically Math::abs but I dont know how to write the code to achieve it. MOdifying the rule as follows, the rule works, but makes no difference to the resulting number (I still get a negative), playing with various other positions then the rule doesn’t work at all.

rule Office_Total
when
        Item HVAC_LVB_Total received update or
        Item LVB_UPSB_Input_Active_Power received update
then
        if (HVAC_LVB_Total.state instanceof DecimalType && LVB_UPSB_Input_Active_Power.state instanceof DecimalType) {
        Math::abs( Office_Total.postUpdate((LVB_UPSB_Input_Active_Power.state as DecimalType) - (HVAC_LVB_Total.state as DecimalType)))
        } else {
          Office_Total.postUpdate(UNDEF)  // or UNDEF on OH2
        }
end

Any guidance is much appreciated.

Alex

rule Office_Total
when
    Item HVAC_LVB_Total received update or
    Item LVB_UPSB_Input_Active_Power received update
then
    if (HVAC_LVB_Total.state instanceof DecimalType && LVB_UPSB_Input_Active_Power.state instanceof DecimalType) {
        var power = LVB_UPSB_Input_Active_Power.state as Number
        var total = HVAC_LVB_Total.state as Number
        if ((power - total) < 0) {
            Office_Total.postUpdate(power - total)
        } else {
            Office_Total.postUpdate(total - power)
        }
    else {
        Office_Total.postUpdate(UNDEF)  // or NULL on OH2
    }
end

This applies the abs method to the return value of postUpdate not the value passed to postUpdate:

The subtraction result as you passed to postUpdate is an object while Math:abs expect a primitive. It won’t work if you pass it directly. Therefor you need to pass the primitive value using doubleValue (or if you want integers use intValue) and pass that to the abs method. The whole statement then looks like this:

Office_Total.postUpdate(Math::abs(((LVB_UPSB_Input_Active_Power.state as DecimalType) - (HVAC_LVB_Total.state as DecimalType)).doubleValue))
1 Like

Thank you both for your solutions. Two ways to achieve the same thing…

I opted for the one from Hilbrand, and its working for me.

Alex