Hello all,
I have an item boiler_status that gets updated once my boiler is powered on and off. I persist the change of the state but now I would like to measure the time the boiler is on and keep a total counter.
I came up with the below to start with but I am confused right now and do not know if it going to work.
In my items file I have
Number boiler_counter
Number boiler_counter_total
Number mqtt_boiler_status “Boiler” { mqtt="<[has:/hab/heating/boilerStatus:state:default]" }
and my rule is
var long LastUpdate = 0
rule "start_boiler_counter"
when
Item mqtt_boiler_status changed from 0 to 1
then
var long currentTime = now.millis
LastUpdate = currentTime
postUpdate(boiler_counter, currentTime)
end
rule "stop_boiler_counter"
when
Item mqtt_boiler_status changed from 1 to 0
then
var long timeElapsed = currentTime - LastUpdate
postUpdate(boiler_counter_total.previousState + timeElapsed)
end
currentTime was local to your ‘start’ rule ; and presumably you want to recalculate a new ‘now’ based value anyway.
As you haven’t yet added the current run period, I don’t think you want to add previousState, just the current state. You’ll probably have to convert it to a DecimalType to do maths on it.
In similar situations I usually write a stub rule that actually only uses logInfo() or logDebug() to show output in the console. Then only when I am satisfied with the results I actually start updating and persisting items.
Thank you for your replies.
Looking in different solution came up with the below that works. You need to add a Number item to your .items file to persit the boiler_counter_total and a DateTime item boiler_counter to keep log of the time
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.joda.time.*
import org.joda.time.format.*
rule "Heating autonomy panel"
when
Item mqtt_boiler_status changed
then
if(mqtt_boiler_status.state == 1 ){
postUpdate(boiler_counter, new DateTimeType())
logInfo("rulesboiler","Boiler started ")
}else{
var DateTimeType prevOnState = boiler_counter.state as DateTimeType
logInfo("boiler","PrevOnState at " + prevOnState)
logInfo("boiler","Now at " + now)
var Number execDuration = Seconds::secondsBetween(new DateTime(prevOnState.calendar.timeInMillis), now ).getSeconds()
logInfo("boiler","The boiler functioned for " + execDuration + " secs.")
var Number add2total = (boiler_counter_total.state as DecimalType).intValue + execDuration
postUpdate(boiler_counter_total,add2total )
logInfo("boiler","New boiler counter total " + add2total)
}
end
The solution and rule discussed in this topic are from 4 years ago… so OH 1.x! A lot has changed since then, so it is not surprising that the rule has issues. Also, DateTimeType is definitely not deprecated.