System Uptime Info and an Automatic Reboot

I would like to share my setup for tracking uptime, adapted from the posts here and extended using java specific functionality.

I am using the following for tracking PC uptime (“CPU uptime”) and openHAB uptime. The solution uses java’s ManagementFactory to access the uptime of the openHAB java process, and systeminfo addon to access PC uptime (“cpu uptime”). The rules are setup such that they do not rely on persistence, and the values are restored even if items are re-created, e.g. when modifying the items file.

import java.lang.management.ManagementFactory
import java.time.ZonedDateTime
import java.time.Instant
import java.time.ZoneOffset

val formatDurationToText = [ Number millis |
	// http://stackoverflow.com/questions/13018550/time-since-ago-library-for-android-java
	val Number SECOND_MILLIS = 1000;
	val Number MINUTE_MILLIS = 60 * SECOND_MILLIS;
	val Number HOUR_MILLIS   = 60 * MINUTE_MILLIS;
	val Number DAY_MILLIS    = 24 * HOUR_MILLIS;

	var String tmp;
	if (millis < MINUTE_MILLIS) {
		tmp = "less than a minute";
	} else if (millis < 2 * MINUTE_MILLIS) {
		tmp = "couple of minutes";
	} else if (millis < 50 * MINUTE_MILLIS) {
		tmp = String::format("%.2f", millis / MINUTE_MILLIS) + " minutes";
	} else if (millis < 90 * MINUTE_MILLIS) {
		tmp = "an hour ago";
	} else if (millis < 24 * HOUR_MILLIS) {
		tmp = String::format("%.2f", millis / HOUR_MILLIS) + " hours";
	} else if (millis < 48 * HOUR_MILLIS) {
		tmp = "since yesterday";
	} else {
		tmp = String::format("%.1f", millis / DAY_MILLIS) + " days";
	}
	return tmp
]


rule "Openhab Uptime"
when
	Time cron "0/10 * * * * ?"
then
	val runtime = ManagementFactory::getRuntimeMXBean();
	val long startedMillis = runtime.getStartTime()
	if(Openhab_Started.state == NULL || Openhab_Started.state == UNDEF) {
		Openhab_Started.postUpdate(new DateTimeType(ZonedDateTime.ofInstant(Instant.ofEpochMilli(startedMillis), ZoneOffset.UTC)))
	}
	var uptimeAsText = formatDurationToText.apply(now.millis - startedMillis)
	postUpdate(Openhab_Uptime, uptimeAsText)
end


rule "CPU Uptime readable"
when
    Item CPU_Uptime changed or
	Time cron "0/10 * * * * ?"
then
	if(CPU_Uptime.state != NULL && CPU_Uptime.state != UNDEF) {
		// CPU_Uptime is in minutes, convert it to millis
		var cpuUptimeMillis = (CPU_Uptime.state as Number).longValue * 60 * 1000
		var uptimeAsText = formatDurationToText.apply(cpuUptimeMillis)
		postUpdate(CPU_Uptime_Text, uptimeAsText)
	} else {
		postUpdate(CPU_Uptime_Text, "-")
	}
end

items:


DateTime Openhab_Started "openHAB started [%1$td.%1$tm.%1$tY %1$tH:%1$tM:%1$tS]" <status> 
String Openhab_Uptime "openHAB uptime [%s]"                                    <status> 

String CPU_Uptime_Text "Raspi uptime [%s]" <status>


Number CPU_Uptime                    { channel="systeminfo:computer:systemdata:cpu#uptime" }

EDIT 2023-11-12: I noticed that runtime.getStartTime() can return the time in local epoch milli… I worked around these issues using uptime:

// We calculate JVM start time using uptime
// runtime.startTime epoch milli can be in UTC millis or local millis, making
// it less convenient
var Instant = Java.type("java.time.Instant");
var startedZoned = ZonedDateTime.ofInstant(
  Instant.now().minusMillis(runtime.getUptime()),
  ZoneId.systemDefault())
		Openhab_Started.postUpdate(new DateTimeType(startedZoned )
9 Likes