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