Calculate time on and energy use for an item/switch rule

Rich thank you very much! This is now perfect and calculates time on and energy used in kWh.
This is the full working setup for anyone looking to do this in the future:
ITEMS:
Number RoofRuntimeHours “Roof Cable Runtime [%.2f h]”// used on sitemap
Number RoofRuntimeMsec // used to store intermediate values which get rounded
Number RoofEnergy “Roof Energy used [%.2f kWh]”

SITEMAP:
Text item=RoofRuntimeHours icon=“selfEnergy”
Text item=RoofEnergy icon=“selfEnergy”

RULE:
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import java.util.*
import java.text.SimpleDateFormat
import java.lang.Math
import org.joda.time.*

var org.joda.time.DateTime whenStarted = null
var Number RoofPower = 1650

rule "Roof started"
when
Item Roof received command ON
   then
whenStarted = now
   end

rule "Roof stopped"
    when
Item Roof received command OFF
    then
if(whenStarted != null) {
}
whenStarted = null
    end

rule "Increment Roof Runtimes"
when
Time cron "* */1 * * * ?"
then

if(Roof.state == ON && whenStarted != null){
val long nowMsec = now.millis
val long wsMsec = whenStarted.millis
whenStarted = now
val long timeSinceLastUpdate = nowMsec - wsMsec
val long oldVal = if(RoofRuntimeMsec.state == Undefined || RoofRuntimeMsec.state == Uninitialized) 0 else (RoofRuntimeMsec.state as DecimalType).longValue
val long totalMsec = oldVal + timeSinceLastUpdate // calculate total runtime
RoofRuntimeMsec.postUpdate(totalMsec) // post the full runtime
val double hours = (totalMsec/1000.0/60.0/60.0).doubleValue
RoofRuntimeHours.postUpdate(hours)
RoofEnergy.postUpdate(hours*RoofPower/1000)
}
else if(Roof.state == ON && whenStarted == null){
whenStarted = now
}
else {
}
end

1 Like