Show openHAB uptime

hello, i’ve tried to make work Uptime openHAB but doesn’t work.
i ha ve this result.


can anyone give some minutes of his time to help me?
here are my files:

uptime.items

Number System_CPU_Uptime "Uptime server [JS(duration.js):%s]" { channel="systeminfo:computer:local:cpu#uptime" }

String System_openHAB_Uptime_output "Uptime openHAB [%s]" { channel="exec:command:uptime:output" }
Number System_openHAB_Uptime "Uptime openHAB [JS(duration.js):%s]"

exec.rules

val String _logger = "rules.exec"

// This rule is used to update the Number out of the returned string from the command line. 
// Only Works since openhab 2.2.
rule "Convert String to Item Type"
  when
    Item System_openHAB_Uptime_output changed
  then

    // Get name of Number Item by removing "_output" from the name of the String Item
    val toUpdate = triggeringItem.name.toString.split("_output").get(0)
    
    // post the new value to the Number Item
    postUpdate( toUpdate.toString , triggeringItem.state.toString )

    logDebug(_logger, "Item '" + toUpdate + "' state: " + triggeringItem.state) 
 end

scripts/uptime.sh (i had to remove " | bc" because it was retrieving me an error in the script.

#!/usr/bin/env bash

PID=`ps aux --sort=start_time | grep openhab.*java | grep -v grep | awk '{print $2}' | tail -1`
UPTIME=`ps -o etimes= -p "${PID}"`
echo $UPTIME/60

reboot.sitemap

sitemap reboot label="Controllo Sistema" {

	Frame label="openHAB" {
                Text item=System_CPU_Uptime
                Text item=System_openHAB_Uptime_output
                Text item=System_openHAB_Uptime
	}

}

uptime.things

Thing exec:command:uptime [command="/etc/openhab2/scripts/uptime.sh", interval=60, timeout=2]
Thing systeminfo:computer:local [interval_high=2, interval_medium=60]

transform/duration.js

// computes nicely formatted duration from given minutes
(function(i){ 

	var d = Math.floor(i / (24 * 60));
	var h = Math.floor((i / 60) - (24 * d));
	var m = Math.round(i - 60 * (24 * d + h));
	var result = '';

	// days
	if (d > 0) { 
		result = result + d + ' day(s) ';
	}
	
	result = result + ("00" + h).substr(-2,2) + ":" + ("00" + m).substr(-2,2);

	return result;
})(input)

this is the only openhab.log info that could help:

2018-10-08 13:07:29.674 [WARN ] [rthome.model.script.actions.BusEvent] - Cannot convert '798/60' to a state type which item 'System_openHAB_Uptime' accepts: [DecimalType, QuantityType, UnDefType].

thanks a lot

echo $UPTIME/60 returns a String with the number and /60 attached at the end
Therefore the transformation fails
divide by 60 inside the transformation instead

bc returned an error because it is not installed
bc stands for basic calculator, a command line calculator tool
Install it on your system. then it should work without modification. don’t forget to add the | bc to the end of the last line of the sh script

perfect! learnt another thing :slight_smile:
thanks a lot!

Alternative way without any external scripts System Uptime Info and an Automatic Reboot

Hi

I got this aswell:
Uptime openHAB aN:aN, whats wrong?

No one?

No one will answer a what’s wrong question like that.
Post your items, sitemap and rule file

My itemsfile:
/* Network information*/
String Network_AdapterName { channel=“systeminfo:computer:openHABianPi:network#networkDisplayName” }
String Network_Name { channel=“systeminfo:computer:openHABianPi:network#networkName” }
String Network_IP { channel=“systeminfo:computer:openHABianPi:network#ip” }
String Network_Mac { channel=“systeminfo:computer:openHABianPi:network#mac” }
Number Network_DataSent { channel=“systeminfo:computer:openHABianPi:network#dataSent” }
Number Network_DataRecevied { channel=“systeminfo:computer:openHABianPi:network#dataReceived” }
Number Network_PacketsSent { channel=“systeminfo:computer:openHABianPi:network#packetsSent” }
Number Network_PacketsRecevied { channel=“systeminfo:computer:openHABianPi:network#packetsReceived” }

/* CPU information*/
String CPU_Name { channel=“systeminfo:computer:openHABianPi:cpu#name” }
String CPU_Description { channel=“systeminfo:computer:openHABianPi:cpu#description” }
Number CPU_Load { channel=“systeminfo:computer:openHABianPi:cpu#load”}
Number CPU_Load1 { channel=“systeminfo:computer:openHABianPi:cpu#load1” }
Number CPU_Load5 { channel=“systeminfo:computer:openHABianPi:cpu#load5” }
Number CPU_Load15 { channel=“systeminfo:computer:openHABianPi:cpu#load15” }
Number CPU_Threads { channel=“systeminfo:computer:openHABianPi:cpu#threads” }
Number CPU_Uptime { channel=“systeminfo:computer:openHABianPi:cpu#uptime” }
Number System_CPU_Uptime “Uptime server [JS(duration.js):%s]” (gSystem) { channel=“systeminfo:computer:openHABianPi:cpu#uptime” }
String System_openHAB_Uptime_output “Uptime openHAB [%s]” (gSystem) { channel=“exec:command:uptime:output” }
Number System_openHAB_Uptime “Uptime openHAB [JS(duration.js):%s]” (gSystem) // updated in exec.rules

/* Drive information*/
String Drive_Name { channel=“systeminfo:computer:openHABianPi:drive#name” }
String Drive_Model { channel=“systeminfo:computer:openHABianPi:drive#model” }
String Drive_Serial { channel=“systeminfo:computer:openHABianPi:drive#serial” }

/* Storage information*/
String Storage_Name { channel=“systeminfo:computer:openHABianPi:storage#name” }
String Storage_Type { channel=“systeminfo:computer:openHABianPi:storage#type” }
String Storage_Description { channel=“systeminfo:computer:openHABianPi:storage#description” }
Number Storage_Available { channel=“systeminfo:computer:openHABianPi:storage#available” }
Number Storage_Used { channel=“systeminfo:computer:openHABianPi:storage#used” }
Number Storage_Total { channel=“systeminfo:computer:openHABianPi:storage#total” }
Number Storage_Available_Percent { channel=“systeminfo:computer:openHABianPi:storage#availablePercent” }
Number Storage_Used_Percent { channel=“systeminfo:computer:openHABianPi:storage#usedPercent” }

/* Memory information*/
Number Memory_Available { channel=“systeminfo:computer:openHABianPi:memory#available” }
Number Memory_Used { channel=“systeminfo:computer:openHABianPi:memory#used” }
Number Memory_Total { channel=“systeminfo:computer:openHABianPi:memory#total” }
Number Memory_Available_Percent { channel=“systeminfo:computer:openHABianPi:memory#availablePercent” }
Number Memory_Used_Percent { channel=“systeminfo:computer:openHABianPi:memory#usedPercent” }

/* Swap memory information*/
Number Swap_Available { channel=“systeminfo:computer:openHABianPi:swap#available” }
Number Swap_Used { channel=“systeminfo:computer:openHABianPi:swap#used” }
Number Swap_Total { channel=“systeminfo:computer:openHABianPi:swap#total” }
Number Swap_Available_Percent { channel=“systeminfo:computer:openHABianPi:swap#availablePercent” }
Number Swap_Used_Percent { channel=“systeminfo:computer:openHABianPi:swap#usedPercent” }

/* Battery information*/
String Battery_Name { channel=“systeminfo:computer:work:battery#name” }
Number Battery_RemainingCapacity { channel=“systeminfo:computer:work:battery#remainingCapacity” }
Number Battery_RemainingTime { channel=“systeminfo:computer:work:battery#remainingTime” }

/* Display information*/
String Display_Description { channel=“systeminfo:computer:work:display#information” }

/* Sensors information*/
Number Sensor_CPUTemp { channel=“systeminfo:computer:openHABianPi:sensors#cpuTemp” }
Number Sensor_CPUVoltage { channel=“systeminfo:computer:openHABianPi:sensors#cpuVoltage” }
Number Sensor_FanSpeed { channel=“systeminfo:computer:openHABianPi:sensors#fanSpeed” }

/* Process information*/
Number Process_load { channel=“systeminfo:computer:openHABianPi:process#load” }
Number Process_used { channel=“systeminfo:computer:openHABianPi:process#used” }
String Process_name { channel=“systeminfo:computer:openHABianPi:process#name” }
Number Process_threads { channel=“systeminfo:computer:openHABianPi:process#threads” }
String Process_path { channel=“systeminfo:computer:openHABianPi:process#path” }

My .sitemap:
sitemap our_home label=“Vårt hem” {

Frame label="Datum" {
    Text item=CurrentDate
}
Frame {  

    Group item=Datarum icon="office"
    Group item=Sovrum icon="bedroom"
}

Frame {
    
    Group item=Vardagsrum
    Group item=Kok label="Kök" icon="kitchen"

}

Frame {
    
    Group item=Hall icon="corridor"
    Group item=Badrum icon="bath"
}

Frame {
    
    Group item=Kladkammare label="Klädkammare" icon="wardrobe"
    Group item=Balkong
}

   
Frame label="Vädret" {

        Text label="Solen" icon="sun"{
        Text item=Sunrise_Time icon="sunrise"
	    Text item=Sunset_Time icon="sunset"
        
}

    Text label="Vädret" icon="sun"{

        Text item=Temperature icon="temperature"
        Text item=Temp_Min icon="temperature"
        Text item=Temp_Max icon="temperature"
        Text item=Temp_Feel icon="temperature"
        Text item=Temp_Dewpoint icon="temperature"
        Text item=Humidity icon="humidity"
        Text item=Pressure icon="pressure"
        Text item=Clouds icon="sun_clouds"
        Text item=Condition
        Text item=ObservationTime
        Text item=LastUpdate
        Text item=CommonId
        Text item=Rain icon="rain"
        Text item=Snow icon="snow"
        Text item=Precip_Probability
        Text item=Wind_Speed icon="wind"
        Text item=Wind_Speed_Mps icon="wind"
        Text item=Temp_MinF icon="temperature"
        Text item=Temp_MaxF icon="temperature"
        
    }
}
Frame label="System information" icon="pie" {

    Group item=RaspberryPI {
        
        Text item=Network_IP label="IP" icon="network"
        Text item=Network_DataSent label="Data sänt" icon="network"
        Text item=Network_DataRecevied label="Data mottaget" icon="network"
                  
        Text item=CPU_Load1 icon="processor"
        Text item=CPU_Load5 icon="processor"
        Text item=System_CPU_Uptime icon="time"
        Text item=System_openHAB_Uptime_output
        Text item=System_openHAB_Uptime icon="time"

        Text item=Storage_Total icon="hard_drive"
        Text item=Storage_Available_Percent icon="hard_drive"

        Text item=Memory_Total label="Minne Totalt" icon="ram_memory"
        Text item=Memory_Available label="Minne tillgängligt" icon="ram_memory"
        Text item=Memory_Used label="Minne använt" icon="ram_memory"
        Text item=Memory_Used_Percent label="Minne använt %" icon="ram_memory"        
        
        }
        
    
    Group item=Energi label="Energiförbrukning" icon="solarplant"

    }
}

My .rulefile:
val String _logger = “rules.exec”

// This rule is used to update the Number out of the returned string from the command line.
// Only Works since openhab 2.2.
rule “Convert String to Item Type”
when
Item System_openHAB_Uptime_output changed
then

// Get name of Number Item by removing "_output" from the name of the String Item
val toUpdate = triggeringItem.name.toString.split("_output").get(0)

// post the new value to the Number Item
postUpdate( toUpdate.toString , triggeringItem.state.toString )

logDebug(_logger, "Item '" + toUpdate + "' state: " + triggeringItem.state) 

end

You should mention that one also needs the regex binding installed :wink:

I just implemented @johfeu’s solution and noticed that it triggers when I add an item using Paper UI. (OH 2.4)
Have not tested other use cases yet, but my system might behave the same as yours. So I might switch to your solution.

Edit: Just tried to reproduce. Still working fine for me. No change when manually adding items via paper UI. took some time but now it changed also for me…
Does it mean, the system fires “System started” rule trigger on item changes via paper UI? sounds strange to me

Looks like it.

As I migrate all my rules to JavaScript, I might just put the code directly in my rule file without even using the system start trigger.
Because with JS rules, this code is executed when the script is loaded and this I saw only at system start or when I change the script itself.

This probably works for all jsr223 scripting languages. Maybe it works for the classic rules as well.

Just gave it a quick test: Does not work for classic rules. postUpdate does not work outside the rule block.

Maybe it can be done with different commands. Otherwise we could check if the value is still null/undefined and only then update it, as it means the values have never been set and therefore it has to be the actual first call after the system start. Should be quite easy.

As I persist all item values, so I do not have to bother with null/undefined, this is a little bit more effort in my setup. So I guess I will not bother and just move it to the next-gen rules.

Me once more: I now built the JS “rule” and it works quite well.
I make use of the openHAB Helper Libraries. They also have instruction on how to enable the next-gen rule engine on the website.

JS-Code:

'use strict';

var OPENHAB_CONF = Java.type("java.lang.System").getenv("OPENHAB_CONF");
load(OPENHAB_CONF+'/automation/lib/javascript/core/utils.js');

try {
    postUpdate("OH_StartTime",now());
} catch (err) {
    console.error(err);
}

Note: This is not the actual code I use. I simplified it a bit, as I also send a notification at start to me and use a logger library I wrote, which is not mandatory to use.

Items file:

DateTime OH_StartTime "Openhab start time" <time>

I am not interested in the uptime, so I do not calculate it. But it would be just a matter of making a time triggered rule which is called every minute or so and calculates the duration back to OH_StartTime.

And for completion, the sitemap entry:

Text item=OH_StartTime  label="openHAB start time [%1$tA %1$tR]"

I currently restart openHAB daily, so I just display the weekday and time, but you can also show the full date, if preferred.

Hi,

I was wondering why it doesn’t work, but it has something do with the exec.whitelist:

/etc/openhab2/things/uptime.things

Thing exec:command:uptime [command="/etc/openhab2/scripts/uptime.sh", interval=60, timeout=2]
Thing systeminfo:computer:local [interval_high=2, interval_medium=60]

/etc/openhab2/misc/exec.whitelist

# For security reasons all commands that are used by the exec binding or transformation need to be whitelisted.
# Every command needs to be listed on a separate line below.
/etc/openhab2/scripts/uptime.sh

@rtvb I hope you can update your tutorial.
@Gargam3L0 this should solve your problem

Is the $OPENHAB_CONF/scripts/uptime.sh path really a good solution? Because openHAB tries to convert each file within the scripts folder. It works but maybe it was smarter to use another location. If you look inside the karaf console you get something similar like this:

09:14:37.388 [DEBUG] [pse.smarthome.model.script.rules.exec] - Item 'System_openHAB_Uptime' state: 1442
09:15:05.732 [WARN ] [arthome.model.script.actions.BusEvent] - Cannot convert 'sh: 1: /etc/openhab2/scripts/uptime.sh: Permission denied
sh: 1: /etc/openhab2/scripts/uptime.sh: Permission denied' to a state type which item 'System_openHAB_Uptime' accepts: [DecimalType, QuantityType, UnDefType].
09:15:05.742 [DEBUG] [pse.smarthome.model.script.rules.exec] - Item 'System_openHAB_Uptime' state: sh: 1: /etc/openhab2/scripts/uptime.sh: Permission denied
sh: 1: /etc/openhab2/scripts/uptime.sh: Permission denied

The permission denied error occurs because an .rules file was expected in this folder and he tries to convert or read it. Well the exec binding can read it but not the “system reader” from openHAB. (Sorry for my bad english. I hope you can understand what I mean. I have no idea what it’s called, which ultimately reads the files.)

I hope I was able to impart a little more knowledge to the whole thing here.

Here’s the code change to make this OH 2.x uptime rule work on post (Show openHAB uptime - #4 by johfeu) with OH 3.x.

			var tmpNow = new DateTimeType(now().plusDays(0))
			logInfo("OHUpTime", "tmpNow variable is " + tmpNow)
			
			val Number item_millis = (tmpNow as DateTimeType).zonedDateTime.toInstant.toEpochMilli
			logInfo("OHUpTime", "item_millis variable is " + item_millis)
			
			val Number now_millis = now.toInstant.toEpochMilli
			logInfo("OHUpTime", "now_millis variable is " + now_millis)
			
			var Number diff = (now_millis - item_millis)/60000
			logInfo("OHUpTime", "diff variable is " + diff)

Best, Jay