Limited maths in rules?

I’m having trouble getting basic maths to work in the following rule:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import java.lang.Math.*
import org.joda.time.*

//Power Lights/Aircon/Oven calculation
rule “Power sum1”
when
//Item PWR_I2 received update or
Item PWR_I3 received update
then

  var Number power2=PWR_I2.state
  var Number power3=PWR_I3.state
  postUpdate(PWR_Isum1, (power2 - power3))
  var Number myNow = now.millis
  var Number myMidnight = now.withTimeAtStartOfDay().millis
  logWarn("test","-----------")
  
  var Number minsSinceMidnight = ((myNow - myMidnight)/1000)
  
  var Number avPowerA = (PWR_I2.averageSince(now.toDateMidnight, "rrd4j")).format("%.2f")
  logWarn("average power today",avPowerA.toString)
  
  var Number avPowerkw= avPowerA * 235
  avPowerkw=avPowerA / 1000
  logWarn("kW on average",avPowerA.toString)
      
  //Convert kW to kWh
  var Number avPowerKwh = (avPowerkw.toString*(minsSinceMidnight/60)).format("%.2f");
  
  logWarn("test",avPowerKwh.toString)
  //postUpdate(PWR_UseTodayKW,avPowerKwh.toString)

end

Here is the response:

2016-10-03 00:54:41.159 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Power sum1’: Could not invoke method: org.openhab.model.script.lib.NumberExtensions.operator_multiply(java.lang.Number,java.lang.Number) on instance: null

I have other rules working with more complexity than this, but can’t seem to make this work.

Hi,

looks like you’re trying to do a math operation on a number converted to string:
avPowerkw.toString *(minsSinceMidnight/60))
Regards,
-OLI

You also bay need to cast the state to a DecimalType.

power2=PWR_I2.state as DecimalType

Thanks Oli, Rich,
Unfortunately no difference in result:

2016-10-03 10:26:01.928 [WARN ] [org.openhab.model.script.test ] - -----------
2016-10-03 10:26:04.683 [WARN ] [del.script.average power today] - 2.51
2016-10-03 10:26:05.012 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Power sum1’: Could not invoke method: org.openhab.model.script.lib.NumberExtensions.operator_multiply(java.lang.Number,java.lang.Number) on instance: null

Also make sure all of your Item’s actually have a state and are not undefined.

Double check that everywhere you get a Number Item’s state you cast out to DecimalType.

Make sure to have a hard look at your calculation of avPowerKwh. It looks like you are trying to use String formatting to round the value, which will not work. Do the rounding stuff.

1 Like

You nailed it Rich,

Solved the issue by removing the string formatting .format() stuff and casting all numbers out as decimalType. Very happy!

Here’s my working rule:

rule “Power sum1”
when
Item PWR_I3 received update
then
logWarn(“test”,“-----------”)
var Number step1rate = 0.21384 //in dollars
var Number step2 = 6.57532 //in Kwh
var Number step2rate = 0.24662 //in dollars

  var Number power2=PWR_I2.state as DecimalType
  var Number power3=PWR_I3.state as DecimalType
  postUpdate(PWR_Isum1, (power2 - power3))
  var Number myNow = now.millis
  var Number myMidnight = now.withTimeAtStartOfDay().millis
  var Number minsSinceMidnight = ((myNow - myMidnight)/60000)
  logWarn("Time since midnigh",minsSinceMidnight.toString)
  var Number avPowerA = (PWR_I2.averageSince(now.toDateMidnight, "rrd4j"))
  logWarn("average power since midnight",avPowerA.toString)
  
  var Number avPowerkw= (avPowerA * 238) / 1000
  logWarn("kW on average",avPowerkw.toString)
  	        
  //Convert kW to kWh
  var Number KwhUsedToday= (avPowerkw * (minsSinceMidnight/60))
  logWarn("Kwh used today",KwhUsedToday.toString)
  
  //Calculate costs
  var Number myCost = 0
  if(KwhUsedToday>= step2) {
  	//Greater than step2, 2 step pricing
  	var Number myDifference = KwhUsedToday - step2
  	myCost = ((step2 * step1rate) + (myDifference * step2rate))
  } else {
  	myCost = (KwhUsedToday * step1rate)		
  }
  
  logWarn("My cost",myCost.toString)
  
  postUpdate(PWR_UseTodayKW,KwhUsedToday.toString)
  postUpdate(PWR_CostToday,myCost.toString)

end