Rule with value from last day is not working

Hi,
i want to show the values of an item from the last day, the day before and so on.

All items are number items.

Here is my rule file:

rule "power meter Hausverbrauch des gestrigen Tages"
	when
		Time cron "59 59 23 * * ?" // this one cycles every day, at 23:59 and 59 seconds
	then
		logInfo("Hausverbrauch", "1 --> " + stromzaehler0_hausverbrauch_heute)
		var Number heute=stromzaehler0_hausverbrauch_heute
		logInfo("Hausverbrauch", "2 --> " + heute)
		stromzaehler0_hausverbrauch_vor4tagen.postUpdate(stromzaehler0_hausverbrauch_vor3tagen)
		stromzaehler0_hausverbrauch_vor3tagen.postUpdate(stromzaehler0_hausverbrauch_vor2tagen)
		stromzaehler0_hausverbrauch_vor2tagen.postUpdate(stromzaehler0_hausverbrauch_gestern)
		stromzaehler0_hausverbrauch_gestern.postUpdate(heute)
end

For testing i made it with a variable - see last postUpdate. I tried it with the item-name as well. Same error. I also commented all postUpdate with //, only the last postUpdate was active, but also same error.

I get this errors in logfile:

2017-10-12 16:15:59.002 [INFO ] [smarthome.model.script.Hausverbrauch] - 1 --> stromzaehler0_hausverbrauch_heute (Type=NumberItem, State=8.142010000007081505954265594482421875, Label=Stromzähler Hausverbrauch heute, Category=house, Groups=[gStromzaehler])
2017-10-12 16:15:59.002 [INFO ] [smarthome.model.script.Hausverbrauch] - 2 --> stromzaehler0_hausverbrauch_heute (Type=NumberItem, State=8.145209999997081505954265594482421875, Label=Stromzähler Hausverbrauch heute, Category=house, Groups=[gStromzaehler])
2017-10-12 16:15:59.003 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule power meter Hausverbrauch des gestrigen Tages: An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,java.lang.Number) on instance: null

Anybody knows what´s going wrong?

You need to use stromzaehler0_hausverbrauch_vor4tagen.postUpdate(stromzaehler0_hausverbrauch_vor3tagen.state)

Is there a reason you are not using Persistence for this?

I use persitence to get the value from today, but i don´t know how to get a value from a specific day before.

And i use rrd4j for this, so the values are not very exact, if they are older.

Going back three days will be accurate. It is when data gets weeks and months old that you start to lose accuracy.

MyItem.historicState(now.minusDays(1), "rrd4j").state
MyItem.historicState(now.minusDays(2), "rrd4j").state
MyItem.historicState(now.minusDays(3), "rrdj4").state

The value of today i get in a rule with this inside: the rule is running every minute…

I have two powermeters, one for the energy i get from the electric company and one powermeter, which is measuring my solar power plant. So the difference between this two power meters is the daily usage.

var hausverbrauch_heute = stromzaehler1_erzeugung.deltaSince(now.toLocalDate.toDateTimeAtStartOfDay) - stromzaehler0_einspeisung.deltaSince(now.toLocalDate.toDateTimeAtStartOfDay) + stromzaehler0_bezug.deltaSince(now.toLocalDate.toDateTimeAtStartOfDay)
stromzaehler0_hausverbrauch_heute.postUpdate(hausverbrauch_heute)

I give the today value at 23:59 to the yesterday-item.

Is this working with this also?

I’m not sure why you are using toLoclDate but those calls to deltaSince should work.

You tell me if it works. If not what is the error?

My rule is working. The question is, if your way with nowminusdays(1) is working.

I get absolute powermeter values every minute and this are persisted. So i first have to do some math with this absolute values to get the daily values.

So i don´t think i can use nowminusdays(1) ?

I´m using tolocaldate because i think, there was an error with the other way.

now.minusDays(1) works as expected everywhere I’ve ever used it.

If you want exactly midnight use now.minusDays(1).withTimeAtStartOfDay

Seems to work.

Can you tell me, how i can write this into one single line without the need of the variabel?

var test = stromzaehler0_hausverbrauch_heute.historicState(now.minusDays(5).withTimeAtStartOfDay, "rrd4j").state
stromzaehler0_hausverbrauch_vor5tagen.postUpdate(test)

Will this give me the consumption of the day 5 days ago from 0-24 o´clock?

try

stromzaehler0_hausverbrauch_vor5tagen.postUpdate(stromzaehler0_hausverbrauch_heute.historicState(now.minusDays(5).withTimeAtStartOfDay, “rrd4j”).state)

should work

I get very different values from the two ways of showing the values from the last days:

upper frame is with storing in separate items every day at 23:59:59.

lower frame is with rrd4j rule.

Look here my rules:

rule "power meter Hausverbrauch des gestrigen Tages"
	when
		Time cron "59 59 23 * * ?" // this one cycles every day, at 23:59 and 59 seconds
	then
		stromzaehler0_hausverbrauch_vor5tagen.postUpdate(stromzaehler0_hausverbrauch_vor4tagen.state)
		stromzaehler0_hausverbrauch_vor4tagen.postUpdate(stromzaehler0_hausverbrauch_vor3tagen.state)
		stromzaehler0_hausverbrauch_vor3tagen.postUpdate(stromzaehler0_hausverbrauch_vor2tagen.state)
		stromzaehler0_hausverbrauch_vor2tagen.postUpdate(stromzaehler0_hausverbrauch_gestern.state)
		stromzaehler0_hausverbrauch_gestern.postUpdate(stromzaehler0_hausverbrauch_heute.state)
end


rule "power meter Hausverbrauch des gestrigen Tages - Variante mit Persistence"
	when
		Time cron "59 * * * * ?" // this one cycles every minute at 59 seconds
	then
		var test5 = stromzaehler0_hausverbrauch_heute.historicState(now.minusDays(5).withTimeAtStartOfDay, "rrd4j").state
		stromzaehler0_hausverbrauch_vor5tagen1.postUpdate(test5)
		var test4 = stromzaehler0_hausverbrauch_heute.historicState(now.minusDays(4).withTimeAtStartOfDay, "rrd4j").state
		stromzaehler0_hausverbrauch_vor4tagen1.postUpdate(test4)
		var test3 = stromzaehler0_hausverbrauch_heute.historicState(now.minusDays(3).withTimeAtStartOfDay, "rrd4j").state
		stromzaehler0_hausverbrauch_vor3tagen1.postUpdate(test3)
		var test2 = stromzaehler0_hausverbrauch_heute.historicState(now.minusDays(2).withTimeAtStartOfDay, "rrd4j").state
		stromzaehler0_hausverbrauch_vor2tagen1.postUpdate(test2)
		var test1 = stromzaehler0_hausverbrauch_heute.historicState(now.minusDays(1).withTimeAtStartOfDay, "rrd4j").state
		stromzaehler0_hausverbrauch_gestern1.postUpdate(test1)
end

Can you explain me, where there is an error? Why do i get different values?

lower rule runs every minute, do i have to let it run once a day at 23:59:59 like the upper rule? Could this be the wrong part?

I think your now.minusDays might be off.

For the current time where I’m located, now.minusDays(1) would be 2017/10/17 10:23. If I tack on withTimeAtStartOfDay it becomes 2017/10/17 00:00. That is the value at the start of yesterday. But you want the value at the end of yesterday.

So test1 should be set to now.withTimeAtStartOfDay and test2 should be now.minusDays(1).withTimeAtStartOfDay` and so on.

???

now.withTimeAtStartOfDay

Is this really the right one? Or was this a mistake and it should be now.withTimeAtEndOfDay ?


EDIT: I have seen the mistake … Your advice was not the change of the command, it was the change of the day before…

You think, i get the value of the day before? If you compare the two frames from my screenshot, you can see, that this can be, but it is not the exact same value. There is a difference of 0,05 to 0,15.

I have daily average of 10 kwh, so i used about 0,4 kwh per hour - this is about 0,07 in a minute…

So this could be the one minute between 23:59 and 24:00.

Given that your rules are not executing at exactly the same time I would not expect the numbers to be exactly the same. they should be pretty close but ± a dozen kWh would not surprise me just based on that. And you rightly point out there is a one minute difference between when the first rule runs and the values you are pulling out of the DB which can account for the additional difference. You could add a .minusMinutes(1) which should put the times the two rules are getting the data closer together. They still won’t be exact but the difference should be less.

Also, when you get out to five days, rrd4j might have started compressing the data so you might be losing some precision in the ones and tens place. I am pretty sure that it doesn’t start compressing the data until it is 7 days old but that would need to be confirmed.

Finally, this is not related to your error, but why are you running the historicState rule every minute? The values you are pulling out of the DB are not going to change until the next day. So you really only need to run this rule a little after midnight and perhaps at System started if you are not using restoreOnStartup on these Items.

Ok, i can live with this 1 minute error :slight_smile:

I made therule run every 59 seconds so that i can test some changes. I didn´t want to wait a whole day until the rule will get executed again. The rule is still in test mode, when it is finalized, i will change this to run a short time after midnight.

I also changed the items to show only 1 decimal behind the comma. This high precision is useless for this usage.

Great reason.