[Solved] OH3: Need Help migrating a rule with historic items

Hello community,

I tried to convert a simple rule to work in OH3. I use MySQL-Persitence to story my energy consumption. Every 5 Minutes I want to calculate the difference between Start of day and now.

I tried this:

val  ZonedDateTime 	zdt = ZonedDateTime.now()
var  ZonedDateTime 	start_of_day = zdt.toLocalDate().atStartOfDay(zdt.getZone())
var  SV0 = ZaehlerstandHeizung.deltaSince(now.with(start_of_day))

postUpdate(HeizungVerbrauchTag, SV0)

But when running, openhab.log shows this:

2021-01-02 14:35:03.678 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '30fd72abc6' failed: val  ZonedDateTime 	zdt = ZonedDateTime.now()
var  ZonedDateTime 	start_of_day = zdt.toLocalDate().atStartOfDay(zdt.getZone())
var  SV0 = ZaehlerstandHeizung.deltaSince(now.with(start_of_day))

postUpdate(HeizungVerbrauchTag, SV0)
   1. Ambiguous feature call.
The methods
	postUpdate(Item, State) in BusEvent and
	postUpdate(Item, Number) in BusEvent
both match.; line 5, column 194, length 10

I have no idea what I am doing wrong, any hints?

Found a working solution calculating it in another way:

val  ZonedDateTime 	zdt = ZonedDateTime.now()
var  ZonedDateTime 	start_of_day = zdt.toLocalDate().atStartOfDay(zdt.getZone())
var SV0 = ZaehlerstandHeizung.historicState(start_of_day).state as Number
var SV1 = ZaehlerstandHeizung.state as Number 
var SV3 = (SV1 - SV0)

postUpdate(HeizungVerbrauchTag, SV3)
1 Like

I think you can use directly deltaSince(start_of_day) instead of historicState(start_of_day). With that you don’t need SV1 and SV3.

The issue is that ‘var SV0’ doesn’t provide a type and hence the code can’t predict which postUpdate method to use.

I haven’t tested, but this should work:

var  ZonedDateTime 	start_of_day = zdt.toLocalDate().atStartOfDay(zdt.getZone())
var  SV0 = ZaehlerstandHeizung.deltaSince(now.with(start_of_day)) as Number

postUpdate(HeizungVerbrauchTag, SV0)

I tried like this already yesterday:

rule "Tagesverbrauch Allgemein mig"
when
Time cron "0 0/5 * * * ? *" 
then
val  ZonedDateTime 	zdt = ZonedDateTime.now()
var  ZonedDateTime 	start_of_day = zdt.toLocalDate().atStartOfDay(zdt.getZone())
var  SV0 = ZaehlerstandAllgemein.deltaSince(now.with(start_of_day)) as Number
postUpdate(AllgemeinVerbrauchTag, SV0)
end

It gives me this error:

2021-01-03 16:17:56.614 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'migrated-1' failed: An error occurred during the script execution: Could not invoke method: java.time.ZonedDateTime.with(java.time.temporal.TemporalAdjuster) on instance: 2021-01-03T16:17:56.613471+01:00[Europe/Berlin] in migrated

This is why I ended up in getting historic state and substract :wink:

Can you try?

var SV0 = ZaehlerstandAllgemein.deltaSince(start_of_day) as Number
postUpdate(AllgemeinVerbrauchTag, SV0)

Thank you, this did the trick :wink:

Here the complete rule again in case someone wants to use it:

rule "Tagesverbrauch Allgemein mig"

when
    Time cron "0 0/5 * * * ? *" 
then
	val  ZonedDateTime 	zdt = ZonedDateTime.now()
        var  ZonedDateTime 	start_of_day = zdt.toLocalDate().atStartOfDay(zdt.getZone())
        var SV0 = ZaehlerstandAllgemein.deltaSince(start_of_day) as Number
        postUpdate(AllgemeinVerbrauchTag, SV0)
end
1 Like

Hello, thanks for the rule, is exactly what I was looking for, but how does this rule work for weeks, months and annual consumption?

I did it like this, but it doesn’t work because the same value is always displayed.

rule "Power Consumption"

when

    Time cron " 0/5 * * ? * * * "  

then
    
    val  ZonedDateTime 	zdt = ZonedDateTime.now()

    var  ZonedDateTime 	start_of_day = zdt.toLocalDate().atStartOfDay(zdt.getZone())
    var  ZonedDateTime 	start_of_week = zdt.toLocalDate().atStartOfDay(zdt.getZone())
    var  ZonedDateTime 	start_of_month = zdt.toLocalDate().atStartOfDay(zdt.getZone())
    var  ZonedDateTime 	start_of_year = zdt.toLocalDate().atStartOfDay(zdt.getZone())

    var power_Today = ElectricityMeter_kWh.deltaSince(start_of_day) as Number 
    var power_Week = ElectricityMeter_kWh.deltaSince(start_of_week) as Number
    var power_Month = ElectricityMeter_kWh.deltaSince(start_of_month) as Number
    var power_Year = ElectricityMeter_kWh.deltaSince(start_of_year) as Number

    postUpdate(PowerConsumptionToday, power_Today)
    postUpdate(PowerConsumptionWeek, power_Week)
    postUpdate(PowerConsumptionMonth, power_Month)
    postUpdate(PowerConsumptionYear,  power_Year)


end

Thanks in advance

Those are identical, why should it point to any different date/time? You need to do something if you want to point at last week, .minusDays(7) might be a useful method on a zonedDateTime…