[SOLVED] Using deltaSince to get data for every day of the week

I am trying to create a rule to send me the daily power usage of an item. it is a Aeotec Smart switch which logs total KWh used. I have the following rule made but it does not give me the result of each day it just gives me the results from the day until now. Am I going about this wrong is there a better way? Also I would like to round the results to 2 decimal places but could not get that to work either.

// Imports
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
rule "Report Power Useage Per Day of the week"
when
	Time cron "0 0 0 * * 0"
	//Time cron "0 * * * * ?" //for debug
then
	var Number MondayUse = MiningPC_ElectricMeterKWh.deltaSince(now.minusDays(6).minusDays(7)) as Number
	//var MondayUse= String::format("%.2f", (MondayUse as DecimalType).floatValue())
	logInfo("Test", "Monday Use{}", MondayUse)
	var Number TuesdayUse = MiningPC_ElectricMeterKWh.deltaSince(now.minusDays(5).minusDays(6)) as Number
	var Number WednesdayUse = MiningPC_ElectricMeterKWh.deltaSince(now.minusDays(4).minusDays(5)) as Number
	var Number ThursdayUse = MiningPC_ElectricMeterKWh.deltaSince(now.minusDays(3).minusDays(4)) as Number
	var Number FridayUse = MiningPC_ElectricMeterKWh.deltaSince(now.minusDays(2).minusDays(3)) as Number
	var Number SaturdayUse = MiningPC_ElectricMeterKWh.deltaSince(now.minusDays(1).minusDays(2)) as Number
	var Number SundayUse = MiningPC_ElectricMeterKWh.deltaSince(now().minusDays(1)) as Number
	sendMail("email@gmail.com", "Weekly Power Usage!!!", "Monday Usage "+MondayUse+" kWh \n Tuesday Useage "+TuesdayUse+" kWh \n Wednesday Useage "+WednesdayUse+" kWh \n Thursday Usage "+ThursdayUse+" kWh \n Friday Usage "+FridayUse+" kWh \n Saturday Usage "+SaturdayUse+" kWh \n Sunday Useage "+SundayUse+" kWh")
end

Thanks for any help.

Hello Heath_P,

your problem is, that you can’t get the difference between two different dates in history. With deltaSince you can only get the diffrence between now and the given date/time.

I think you have to wotk with two variables to get the value from beginning of the day and one value for the end of the day (or beginning of the next day.

rule "Report Power Useage Per Day of the week"
when
	Time cron "0 0 0 * * 0"
	//Time cron "0 * * * * ?" //for debug
then

  var Number MeterDayBegin = 0
  var Number MeterDayEnd = 0
  var Number MeterUse = 0
  var Number DayCount = 7

  while (DayCount > 0) {
    MeterDayBegin = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount))
    MeterDayEnd = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount-1))
    MeterUse = MeterDayEnd - MeterDayBegin
 
    switch DayCount {
      case 7: MondayUse = MeterUse
      case 6: TuesdayUse = MeterUse
      case 5: WednesdayUse = MeterUse
      case 4: ThursdayUse = MeterUse
      case 3: FridayUse = MeterUse
      case 2: SaturdayUse = MeterUse
      case 1: SundayUse = MeterUse
    }
    DayCount--;
  }
end

Maybe you can extend your rule to run every day and set the usage for the last seven days… ( a little bit more complicated)

Best Regards,
Andreas

Thanks for the reply Andres, I see what you are getting at the only problem is I get an error when trying to do it the way you said, I have no idea what it means as everything seems to be right.

19:51:00.355 [ERROR] [untime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Report Power Useage Per Day of the week': An error occurred during the script execution: Could not invoke method: org.joda.time.DateTime.minusDays(int) on instance: 2018-07-19T19:51:00.354+08:00

Regards,
Heath

var int DayCount = 7

Thanks that fixed that error now I have another.

21:10:00.406 [ERROR] [untime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Report Power Useage Per Day of the week': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.lib.NumberExtensions.operator_minus(java.lang.Number,java.lang.Number) on instance: null
    MeterDayBegin = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount)).state as Number
    MeterDayEnd = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount-1)).state as Number
    MeterUse = MeterDayEnd - MeterDayBegin

Thanks Vincent fixed that problem but now I have another problem.

07:34:00.541 [ERROR] [untime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Report Power Useage Per Day of the week': An error occurred during the script execution: Couldn't invoke 'assignValueTo' for feature JvmVoid:  (eProxyURI: reports.rules#|::0.2.0.2.0.4.1.0.3.1.0.1::0::/1)

My .rules file at the moment is this:


// Imports
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
rule "Report Power Useage Per Day of the week"
when
	Time cron "0 0 0 ? * SUN"
	//Time cron "0 * * * * ?" //for debug
then

  var Number MeterDayBegin = 0
  var Number MeterDayEnd = 0
  var Number MeterUse = 0
  var int DayCount = 7

  while (DayCount > 0) {
    MeterDayBegin = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount)).state as Number
    MeterDayEnd = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount-1)).state as Number
    MeterUse = MeterDayEnd - MeterDayBegin
 
    switch DayCount {
      case 7: MondayUse = MeterUse
      case 6: TuesdayUse = MeterUse
      case 5: WednesdayUse = MeterUse
      case 4: ThursdayUse = MeterUse
      case 3: FridayUse = MeterUse
      case 2: SaturdayUse = MeterUse
      case 1: SundayUse = MeterUse
    }
    DayCount--;
  }
	sendMail("email@gmail.com", "Weekly Power Usage!!!", "Monday Usage "+MondayUse+" kWh \n Tuesday Useage "+TuesdayUse+" kWh \n Wednesday Useage "+WednesdayUse+" kWh \n Thursday Usage "+ThursdayUse+" kWh \n Friday Usage "+FridayUse+" kWh \n Saturday Usage "+SaturdayUse+" kWh \n Sunday Useage "+SundayUse+" kWh")
end

On a side note I also fixed up the Time cron expression to the correct formatting, using https://www.freeformatter.com/cron-expression-generator-quartz.html

  var Number MeterDayBegin = 0
  var Number MeterDayEnd = 0
  var Number MeterUse = 0
  var int DayCount = 7
  var MondayUse = 0
  var TuesdayUse = 0
  var WednesdayUse = 0
  var ThursdayUse = 0
  var FridayUse = 0
  var SaturdayUse = 0
  var SundayUse = 0

Now another new error.

19:33:00.363 [ERROR] [untime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Report Power Useage Per Day of the week': cannot invoke method public abstract org.eclipse.smarthome.core.types.State org.eclipse.smarthome.core.persistence.HistoricItem.getState() on null

Remove the ; after daycount++

and:

    MeterDayBegin = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount)) as Number
    MeterDayEnd = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount-1)) as Number

Now another error.

21:00:00.266 [ERROR] [untime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Report Power Useage Per Day of the week': Could not cast org.openhab.core.persistence.internal.QueryablePersistenceServiceDelegate$1@c741f83 to java.lang.Number; line 24, column 21, length 74

My Current .rules file is

// Imports
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
rule "Report Power Useage Per Day of the week"
when
	//Time cron "0 0 0 ? * SUN"
	Time cron "0 * * * * ?" //for debug
then

  var Number MeterDayBegin = 0
  var Number MeterDayEnd = 0
  var Number MeterUse = 0
  var int DayCount = 7
  var MondayUse = 0
  var TuesdayUse = 0
  var WednesdayUse = 0
  var ThursdayUse = 0
  var FridayUse = 0
  var SaturdayUse = 0
  var SundayUse = 0

  while (DayCount > 0) {
    MeterDayBegin = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount)) as Number
    MeterDayEnd = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount-1)) as Number
    MeterUse = MeterDayEnd - MeterDayBegin
 
    switch DayCount {
      case 7: MondayUse = MeterUse
      case 6: TuesdayUse = MeterUse
      case 5: WednesdayUse = MeterUse
      case 4: ThursdayUse = MeterUse
      case 3: FridayUse = MeterUse
      case 2: SaturdayUse = MeterUse
      case 1: SundayUse = MeterUse
    }
    DayCount--
  }
	sendMail("email@gmail.com", "Weekly Power Usage!!!", "Monday Usage "+MondayUse+" kWh \n Tuesday Useage "+TuesdayUse+" kWh \n Wednesday Useage "+WednesdayUse+" kWh \n Thursday Usage "+ThursdayUse+" kWh \n Friday Usage "+FridayUse+" kWh \n Saturday Usage "+SaturdayUse+" kWh \n Sunday Useage "+SundayUse+" kWh")
end
  while (DayCount > 0) {
    logInfo("TEST1", MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount)).toString)
    logInfo("TEST2", MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount)).state.toString)
    MeterDayBegin = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount)) as Number
    MeterDayEnd = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount-1)) as Number
    MeterUse = MeterDayEnd - MeterDayBegin

What’s in the log?

historicState returns a HistoricItem, which has .state and .timestamp methods. So you’ll need…

MeterDayBegin = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount)).state as Number
MeterDayEnd = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount-1)).state as Number

I HIGHLY recommend you setup VS Code!

@5iver
I know about vs code, it’s just that my tablet don’t run it.
We tried the .state before and that didn’t work either so I went to the docs and saw:

.historicState(AbstractInstant) Retrieves the State of an Item at a certain point in time

So I thought we had a state returned as it say in the docs…

My suggestion was for @Heathyp :slight_smile:.

Try this (the imports are not needed in OH2)…

rule "Report Power Useage Per Day of the week"
when
    //Time cron "0 0 0 ? * SUN"
    Time cron "0 * * * * ?" //for debug
then
    var Number MeterDayBegin
    var Number MeterDayEnd
    var Number MeterUse
    var int DayCount = 7
    var Number MondayUse
    var Number TuesdayUse
    var Number WednesdayUse
    var Number ThursdayUse
    var Number FridayUse
    var Number SaturdayUse
    var Number SundayUse

    while (DayCount > 0) {
        MeterDayBegin = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount)).state as Number
        MeterDayEnd = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount-1)).state as Number
        MeterUse = MeterDayEnd - MeterDayBegin
    
        switch DayCount {
        case 7: MondayUse = MeterUse
        case 6: TuesdayUse = MeterUse
        case 5: WednesdayUse = MeterUse
        case 4: ThursdayUse = MeterUse
        case 3: FridayUse = MeterUse
        case 2: SaturdayUse = MeterUse
        case 1: SundayUse = MeterUse
        }
        DayCount--
    }
    sendMail("email@gmail.com", "Weekly Power Usage!!!", "Monday Usage "+MondayUse+" kWh \n Tuesday Useage "+TuesdayUse+" kWh \n Wednesday Useage "+WednesdayUse+" kWh \n Thursday Usage "+ThursdayUse+" kWh \n Friday Usage "+FridayUse+" kWh \n Saturday Usage "+SaturdayUse+" kWh \n Sunday Useage "+SundayUse+" kWh")
end
1 Like

I was working with some LinkedHashMaps today and it made me think back on your rule. Here’s another way to do it…

import java.util.LinkedHashMap
import java.time.DayOfWeek

rule "Report Power Usage Per Day of the week"
when
    //Time cron "0 0 0 ? * SUN"
    Time cron "0 * * * * ?" //for debug
then
    var LinkedHashMap<String,String> usageHash = newLinkedHashMap
    for (dayCount : (1..7)) {
        usageHash.put(DayOfWeek.of(dayCount).toString.toLowerCase.toFirstUpper, ((MiningPC_ElectricMeterKWh.historicState(now.minusDays(dayCount-1)).state as Number) - (MiningPC_ElectricMeterKWh.historicState(now.minusDays(dayCount)).state as Number)).intValue.toString + " kWh")
    }
    sendMail("email@gmail.com", "Weekly Power Usage!!!", usageHash.toString.substring(1, usageHash.toString.length - 1))
end

Thanks everyone for all your help, it is finally working.
With one small change the cron job should say “MON” not “SUN” otherwise everything is working great now. I haven’t tried the LinkedHashMap solution. I might give it a try when I get more time. Sorry I took so long to update I have be sick for the last few days and haven’t been up to doing much.

Thanks again.

1 Like

Hello,

Openhab is new for me, what did you use as item and sitemap?

Thank you.