Week/Month sum of midnight values

I have a energy measurement which increase every day and in the midnight goes to 0
To show a previous day I used persistence item.historicState(actual_day.minusSecond(1)) where actual day is :

val ZonedDateTime zdt = ZonedDateTime.now()
val actual_day = zdt.withHour(0).withMinute(0).withSecond(0)

To show a actual consumption is used item.deltaSince(actual_day.plusSeconds(2))

It’s working. But now I’m not sure how to make a week/month sum. I know that for this sum I must use a value of each day at 23:59:59, but for me not clear how to specify days and period.

data looks like this:

Thank you for help

You can check my energy widget and the used rule templates

Thank you. It looks very complicated. :frowning:
Where I can find sum calculation day + day ? In the rule I can’t find.
Is you energy value still increasing or goes into 0 on the end of each day ?

The Widget, used Items and rules are intended to be used with smart meters, where the counter value does not reset to 0. Day by Day consumption is calculated as the difference between last value of day before and actual meter reading and stored to todays consumption Item.
The second rule does this for daily, weekly, monthly or yearly consumption, checking if it is start of the day or the first day of week, month or year.

it’s for me too complicated.
I’m trying go other way like this :

val ZonedDateTime zdt = ZonedDateTime.now()
val actual_day = zdt.withHour(0).withMinute(0).withSecond(0)
var Number result = 0
for(var i=0; i<1; i++){
val read = cons_sum.historicState(actual_day.minusDays(i).minusSeconds(2)).state as Number
result = result + read
}
postUpdate(output, result.toString)

It’s working to sum values from 23:59:58 for requested quantity of days
Question is if it’s possible somehow set correct quantity of days for each Month

I’m not sure how to write it properly in DSL, but I did something similar just few days ago in javascript. The algorithm could be the same as it also uses ZonedDateTime. Just try to convert the syntax to DSL.

var intervalStart = time.toZDT('23:59:58').with(time.TemporalAdjusters.previousOrSame(time.DayOfWeek.MONDAY)); // last Monday
var intervalEnd = time.toZDT('23:59:58'); // today before midnight

console.log("Counting weekly value from %s to %s", intervalStart.format(time.DateTimeFormatter.ISO_LOCAL_DATE), intervalEnd.format(time.DateTimeFormatter.ISO_LOCAL_DATE));

var dt = intervalStart;
var weekly = 0;
while (intervalEnd.compareTo(dt) >= 0) {
  let daily = items.DailyEnergy.history.historicState(dt).numericState;
  weekly += daily;
  dt = dt.plusDays(1);
}

console.log("Weekly value till today: %s", weekly.toFixed(1));

ok, thanks, but for actual Month I used this :

val ZonedDateTime zdt = ZonedDateTime.now()
val actual_day = zdt.withHour(0).withMinute(0).withSecond(0)
var Number result = 0
for(var i=0; i<(zdt.getDayOfMonth-1); i++){
val read = cons_sum.historicState(actual_day.minusDays(i).minusSeconds(2)).state as Number
result = result + read
}
postUpdate(output, result.toString)

It’s working and after one month this value I can read as value Month before :slight_smile:

Yes, I must implement somehow start of the next month