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
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)
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
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
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
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
MeterDayBegin = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount)) as Number
MeterDayEnd = MiningPC_ElectricMeterKWh.historicState(now.minusDays(DayCount-1)) as Number
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
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
@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…
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
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.