Day of month gas cost rule

  • Win 10
    Running on laptop
    Java Runtime Environment: 8 Build 181
    Openhab 1.8

This rule works if I use a day of the 1st but fails if I use the 20th.
How can I use the 20th of last month if its 1-20th this month?

rule "Update gas Costs"
    Item  Gas_usage changed     //received update  //for testing
    // all gas cost rules using db40
    var Number MonthagoReadingtemp
    var Number midnightReading
    var Number yesterdayMidnightReading
    var Number days2agoMidnightReading
    var Number currentReading
    var Number days2agoUsageCF
    var Number yesterdayUsageCF
    var Number todayUsageCF
    var Number yesterdayCost
    var Number days2agoCost
    var Number todayCost
    var Number CFCost = 3.3120 

    if (Gas_usage.state instanceof DecimalType)  {
    	MonthagoReadingtemp = (Gas_usage.deltaSince(now.toDateMidnight().withDayOfMonth(20)))
    //	MonthagoReadingtemp = (Gas_usage.sumSince(now.withDayOfMonth(20), "db4o"))
    //	MonthagoReadingtemp = (Gas_usage.sumSince(now.toDateMidnight().withDayOfMonth(1), "db4o"))
    //	MonthagoReadingtemp = (Gas_usage.historicState(now.withDayOfMonth(1)).state as DecimalType)
        days2agoMidnightReading = (Gas_usage.historicState(now.toDateMidnight.minusDays(2)).state as DecimalType)
        yesterdayMidnightReading = (Gas_usage.historicState(now.toDateMidnight.minusDays(1)).state as DecimalType)
        midnightReading = (Gas_usage.historicState(now.toDateMidnight).state as DecimalType)
        currentReading = Gas_usage.state as DecimalType
        days2agoUsageCF = ((yesterdayMidnightReading - days2agoMidnightReading)/1000)
        yesterdayUsageCF = ((midnightReading - yesterdayMidnightReading)/1000)
        todayUsageCF = ((currentReading - midnightReading)/1000)
        todayCost = todayUsageCF*CFCost
        days2agoCost = days2agoUsageCF*CFCost
        yesterdayCost = yesterdayUsageCF*CFCost
        //logInfo("MonthagoReadingtemp before math", (MonthagoReadingtemp.toString))
  		MonthagoReadingtemp = MonthagoReadingtemp/1000
        //logInfo("MonthagoReadingtemp after math", (MonthagoReadingtemp.toString))
  		MonthagoReadingtemp = MonthagoReadingtemp*CFCost
  		// postUpdate(MonthagoReading,MonthagoReadingtemp)
        logInfo("MonthagoReadingtemp new cost", (MonthagoReadingtemp.toString))
        postUpdate(GasTodayUsage, todayUsageCF)
        postUpdate(GasTodayCost, todayCost)
        postUpdate(GasYesterdayUsage, yesterdayUsageCF)
        postUpdate(GasYesterdayCost, yesterdayCost)
        postUpdate(Gas2DaysAgoUsage, days2agoUsageCF)
        postUpdate(Gas2DaysAgoCost, days2agoCost)

this is the error

2020-01-01 10:43:40.065 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Update gas Costs’
java.lang.NullPointerException: null
at org.openhab.model.script.lib.NumberExtensions.operator_divide( ~[na:na]
at sun.reflect.GeneratedMethodAccessor95.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_151]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_151]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation( ~[na:na]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._featureCallOperation( ~[na:na]
at sun.reflect.GeneratedMethodAccessor46.invoke(Unknown Source) ~[na:na]

You are using the postUpdate action instead of the method
Do this:


instead of:

postUpdate(GasTodayUsage, todayUsageCF)

The Action requires strings or will try to convert to strings. If it can’t you’ll get this error
The method is far more forgiving in terms of types.

Change all your actions to methods. One other reason is here:

Also add some logging after each line so you will know exactly at what point the rule fails

This error only happens when the line is -
MonthagoReadingtemp = (Gas_usage.deltaSince(now.toDateMidnight().withDayOfMonth(20)))

And the rule works when I use this -
MonthagoReadingtemp = (Gas_usage.deltaSince(now.toDateMidnight().withDayOfMonth(1)))

Seems like .withDayOfMonth(20))) can not get the 20th of last month


No because we are the 1st of Jan and the 20th is in the future

1 Like

To elaborate on Vincent’s answer, withDayOfMonth(20) will give you the 20th of the current month. To get the reading from the 20th last month, you need to use now.minusMonths(1).withDayOfMonth(20) which jumps back to the previous month and then to the 20th day of that month.

1 Like

Well in my testing, I got a bad gas RRD4J file so I need to wait till next month on the 20th to test.
Thanks for your help

Now that we are in the next month the line
MonthagoReadingtemp = Gas_usage.deltaSince(now.toDateMidnight().minusMonths(1).withDayOfMonth(20), “db4o”)
works as long as there is rrd4j data available. And you need the toDateMidnight().
thanks rlkoshak