Show OpenHab Uptime in Sitemap

This here is a litte projekt how to show your OpenHab uptime since last restart.
It does not show the uptime of your Raspi this could be much longer.

Its running on my rpi3b+ on OH 2.4.

My approach was the following:

If you type “openhab-cli uptime” at the raspi console you will return a message like this:

A systemd service configuration exists...
Use 'sudo /bin/systemctl status openhab2.service' to find the status of an openHAB service
openHAB is running with PID: 2066 and has been running for 82-11:36:28

In the end of this string we see: “the runtime of OpenHab is: 82 days 11 hours 36 minutes 28 seconds”
I want to put that in the sitemap.

First you need the Exec Binding.
Then create a the following thing:

Thing exec:command:openhabuptime2 [command="openhab-cli status", interval=3600, timeout=5] //OpenHab Uptime

For this we need two items.
The first item receives what the command “openhab-cli status” returns as a string.
The second item then receives the concatenated string of the values for the sitemap via a rule.
Here are the items:

String      BefehlOutputOpenHabUptime    "Rückgabewert"  {channel="exec:command:openhabuptime2:output"} 
String      OpenHabUptime                "OpenHab uptime [%s]"

And the Rule that splits the String und put it in to the Item for the Sitemap:

// https://openhabforum.de/viewtopic.php?f=15&t=3855
rule "OpenHab Uptime"
when
Item BefehlOutputOpenHabUptime changed
then
//  Suche nach 'running for'
var newValue = BefehlOutputOpenHabUptime.state.toString.split('running for ').get(1).trim
newValue = newValue.substring(0,11)

// log das Ergebnis
logInfo('OpenHab Uptime String:',newValue)

val Tage     = newValue.split('-').get(0).trim
val Zeit     = newValue.substring(3,11)
val Stunden  = Zeit.split(':').get(0).trim
val Minuten  = Zeit.split(':').get(1).trim

// log das Ergebnis
logInfo('OpenHab Uptime Tage:',Tage)
logInfo('OpenHab Uptime Zeit:',Zeit)
logInfo('OpenHab Uptime Stunden:',Stunden)
logInfo('OpenHab Uptime Minuten:',Minuten)

// post the new value to the Item
OpenHabUptime.postUpdate((( Tage + " DAYS, ") + (Stunden + " HOURS, ")) + ((Minuten + " MINUTES" )))

end

It look like that at the sitemap:

Have fun!

8 Likes

How does your exec.whitelist look for the openhab-cli command?

I’m still on OH 2.4 so I’ve never had any problems with that whitelist.

For OH 2.5 it is “openhab-cli status”. Nice way to get the info, thanks for the info!

have a look into the openhab log files.
There should be an entry complaining about a missing entry in the whitelist.
Take ( copy ) the command as it is stated in the log file and paste it into the whitelist.

1 Like

Strange - I have that line in my whitelist file, but it gives me an error

Did you already restart openHAB?

1 Like

I got it working after a cleanup of the cache and tmp folder :slight_smile:

Am I correct in saying that the command could be run directly from the rule? (Avoiding all of the white list issues)

Using something along the lines of —

rule "OpenHab Uptime"
when
Time cron (* 5 * * * * *) // that's not right, but you get the idea
then
var status = executeCommandLine("openhab-cli status", 5000) // or ("openhab-cli uptime", 5000)
var newValue = status.toString.split('running for ').get(1).trim
newValue = newValue.substring(0,11)

So instead of the rule being triggered by the Item changing every n seconds, a Cron could be used to trigger the rule?

2 Likes

yep I have done it also this way with a cron trigger.

However one important thing is that you have to check for the length of the substring. If it’s running for at least one day, then 11 is fine. If it’s running for less, an error will be thrown. I’m not at my desk to paste the code, however I check for the length of the string to evaluate the substring

Would you kindly post your code for evaluate the substring?

I already do this by setting a DateTime at system startup and then doing a calculation of now minus the startup time every minute. Works a charm

1 Like

sure, here is my current rule. Took the part from yours and adapted quickly just some personal preferences

    // OH Uptime with CLI
rule "Get OH Uptime CLI command"
when
    Item Sw_v_OH_uptimeCli_get changed to ON or
    Time cron "0 0 0/12 1/1 * ? *" // 2 mal am Tag um 00:00 und 12:00 Uhr
then
    St_v_OH_uptimeCli.postUpdate("")
    St_v_OH_uptimeCli_display.postUpdate("")
    var status = executeCommandLine("openhab-cli status", 5000)
    var uptime = status.toString.split('running for ').get(1).trim
    uptime = uptime.substring(0,uptime.length())

    St_v_OH_uptimeCli.sendCommand(uptime.toString)

    var Number Sekunden = 0
    var Number Minuten = 0
    var Number Stunden = 0
    var Number Tage = 0

    switch(uptime.length()) { 
        case 2: {   // bis Sekunden
            Sekunden = uptime.substring(uptime.length() - 2, uptime.length())
            St_v_OH_uptimeCli_display.sendCommand(Sekunden.toString + "s")
        }
        case 5: {   // bis Minuten
            Sekunden = uptime.substring(uptime.length() - 2, uptime.length())
            Minuten = uptime.substring(uptime.length() - 5, uptime.length() - 3)
            St_v_OH_uptimeCli_display.sendCommand(Minuten.toString + "m " + Sekunden.toString + "s")
        }
        case 8: {   // bis Stunden
            Sekunden = uptime.substring(uptime.length() - 2, uptime.length())
            Minuten = uptime.substring(uptime.length() - 5, uptime.length() - 3)
            Stunden = uptime.substring(uptime.length() - 8, uptime.length() - 6)
            St_v_OH_uptimeCli_display.sendCommand(Stunden.toString + "h " + Minuten.toString + "m " + Sekunden.toString + "s")
        }
        default: {
            Sekunden = uptime.substring(uptime.length() - 2, uptime.length())
            Minuten = uptime.substring(uptime.length() - 5, uptime.length() - 3)
            Stunden = uptime.substring(uptime.length() - 8, uptime.length() - 6)
            Tage     = uptime.split('-').get(0).trim
            St_v_OH_uptimeCli_display.sendCommand(Tage.toString + " Tage " + Stunden.toString + "h " + Minuten.toString + "m " + Sekunden.toString + "s")
        }
    }

    if(uptime.length() > 8) {
        Sw_v_OH_uptimeCli_recent.sendCommand(OFF)
        Sw_v_OH_uptimeCli_get.sendCommand(OFF)
        return
    }

    // Set notification
    val Number Sekunden_number = Float::parseFloat(String::format("%s",Sekunden)) 
    val Number Minuten_number = Float::parseFloat(String::format("%s",Minuten)) 
    val Number Stunden_number = Float::parseFloat(String::format("%s",Stunden)) 
    val Number Tage_number = Float::parseFloat(String::format("%s",Tage))
    val Number sekoverall = Sekunden_number + Minuten_number * 60 + Stunden_number * 3600 + Tage_number * 24 * 3600

    if(sekoverall < (24 * 3600)){
        Sw_v_OH_uptimeCli_recent.sendCommand(ON)
    } else {
        Sw_v_OH_uptimeCli_recent.sendCommand(OFF)
    }

    Sw_v_OH_uptimeCli_get.sendCommand(OFF)
end

This was pulled together from many sources on the forum.

Items

// OH Up Time
//
DateTime	OH_Uptime					"Up Time [%1$tm.%1$td.%1$tY %1$tH:%1$tM]"		<time>				(HomeState)
String		OH_Uptime_HumanReadable		"Readable Up Time [%s]"												(HomeState, Group_HabPanel_Dashboard)

Rules

Startup Area

		OH_Uptime.postUpdate(new DateTimeType())		// Set Start Up Time

rule "OH Readable Up Time "
	when
    	Item OH_Uptime changed or
		Time cron "1 1 * * * ?"
	then

		if (systemStarted.state != ON && OH_Uptime.state != NULL) {
	
			var DateTime dateTime_OH_Uptime = new DateTime((OH_Uptime.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
			var diff						= now.millis - dateTime_OH_Uptime.millis
			var String tmp					= null
	
			// 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;
	
			if (diff < MINUTE_MILLIS) {
				tmp = "just now";
			} else if (diff < 2 * MINUTE_MILLIS) {
				tmp = "a minute";
				} else if (diff < 50 * MINUTE_MILLIS) {
					tmp = String::format("%.2f", diff / MINUTE_MILLIS) + " Minutes";
					} else if (diff < 90 * MINUTE_MILLIS) {
						tmp = "an hour ago";
						} else if (diff < 24 * HOUR_MILLIS) {
							tmp = String::format("%.2f", diff / HOUR_MILLIS) + " Hours";
							} else if (diff < 48 * HOUR_MILLIS) {
								tmp = "since yesterday";
								} else {
									tmp = String::format("%.1f", diff / DAY_MILLIS) + " Days";
								}
	
			OH_Uptime_HumanReadable.postUpdate(tmp)
	
			tmp = NULL
	
			logInfo("OHUpTime", "-----------------------------------------------------------------------------")
			logInfo("OHUpTime", "Human Readable Time is " + OH_Uptime_HumanReadable.state)
			logInfo("OHUpTime", "-----------------------------------------------------------------------------")
		}
end

Best, Jay

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.