System Uptime Info and an Automatic Reboot

When using the 4 files from Robert I get the message :

2017-09-10 21:51:02.554 [WARN ] [.core.transform.TransformationHelper] - Cannot get service reference for transformation service of type REGEX
2017-09-10 21:51:02.555 [WARN ] [hab.binding.exec.handler.ExecHandler] - Couldn’t transform response because transformationService of type ‘REGEX’ is unavailable

in the logs…

Okay, my mistake; the RegEx Transformation was missing… But I only see the uptime in seconds :frowning:

-> Update: The JS must be placed in folder ‘transform’ and not in ‘scripts’. Now its working

1 Like

Thanks for this, nice and simple. Although your cron format is wrong. Unsure what time of the day 50 o’clock is :slight_smile:

...cron "0 50 3 * * ?"...

I also get this when saving the rules file. Still seems to work though.

2018-01-31 11:16:44.982 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model ‘home.rules’, using it anyway:
Assignment to final field
Constant condition is always false.

THe Validation error can be fixed by changing

val Boolean RebootDue = false

to this

var Boolean RebootDue = false

I had this rule by @kevin and it was working great until I added dbmap Persistence and now on every reboot the system maintains the original “OHStartedAt” value…there for I would get in to a constant reboot scenario if I hadnt commented out the final part of the rule that does the reboot… Anyone know why or how to reset the “OHStartedAt” value on a reboot?

My version of the Rule is here:

var Long Uptime
var Boolean RebootDue = false

rule "Calculate Uptime"
when Time cron "0 * * * * ?" then
if (OHStartedAt.state == NULL)
{	var DateTime StartedTime = (now)
OHStartedAt.sendCommand(StartedTime.toString)
logInfo("Testing", "OHStartedAt " +OHStartedAt.state)
}	
else	
{
var DateTime BegunAt = parse(OHStartedAt.state.toString)
Uptime = (now.getMillis() - BegunAt.getMillis())/60000
//	logInfo("Testing", "Uptime in minutes is " +Uptime)
if (Uptime > 10080)	{	RebootDue = true	}
var String UT
var days = Uptime/1440
Uptime = Uptime - days*1440
var hour = Uptime/60
Uptime = Uptime - hour*60
var min = Uptime
UT = days+ "d "+ hour + "h "+ min + "m"
OHFriendlyUptime.sendCommand(UT)
}
logInfo("Is a Reboot Due?", "RebootDue Status Flag = " +RebootDue)
logInfo("OHStartedAt", "Last Rebooted on " +OHStartedAt.state)
end
// rule "Reboot PiServer"
// when RebootDue = true 
// then executeCommandLine("sudo /sbin/reboot", 60000)
// end

Thanx for any advice.

Don’t persist the item OHStartedAt, this does not make any sense.

Hi job,

I have not added any grouping for that String, my items file entry looks like this:

String   OHStartedAt
String   OHFriendlyUptime
Switch   openhabBackup                       "RaspberryPi Image Back-up"   <floppy>           { expire="3s, command=OFF" }
Switch   system_PIRESTART_sw                 "Restart openHabian Server"   <switch>
Switch   Alarm_Fire                          "Fire Alarm Monitoring (On/Off)"       <switch>
Switch   GF_Dining_Light1                    "Dining Room Ceiling"         <light>            (GF_Dining, gLights, sPersist)           [ "Lighting"   ]

It looks like you are persisting every item.

Create some groups for your persistence strategy e.g.:

  • gRestoreOnStartup
  • gEvery5Minutes
  • gEveryChange

And push the items to persist in these groups according.

Don’t put OHStartedAt in the restore on startup strategy

Another possibility would be to create a System started triggered rule which resets the OHStartedAt date.

Thanx job,

I added in false (gGroups) after each of the string and other items that did not have them previously but this did not change anything and after a reboot the OHStartedAt string still persisted.

String   OHStartedAt                                                                          (gOhstartedat)
String   OHFriendlyUptime                                                                     (gOhfriendlyuptime)
Switch   openhabBackup                       "RaspberryPi Image Back-up"   <floppy>           (gOhbackup)                              { expire="3s, command=OFF" }
Switch   system_PIRESTART_sw                 "Restart openHabian Server"   <switch>           (gPirestart)
Switch   Alarm_Fire                          "Fire Alarm Monitoring (On/Off)"       <switch>  (gFirealarmsw)

I have been playing with additional rule entry to reset the String each restart…that appears to be working and I will monitor the output for a week to see if it works longer term.

 rule "Reset Clock"
 when
   System started
 then
{	var DateTime StartedTime = (now)
OHStartedAt.sendCommand(StartedTime.toString)
logInfo("Testing", "OHStartedAt " +OHStartedAt.state)
}
 end

I would still like to know how to over ride the dbmap persistence on those items not requiring that, as I had done it for another default.items and that works OK:

Switch   FF_Hallway_Light12                  "Hall Ceiling"                <light>            (FF_Hallway, gLights)                    [ "Lighting"   ]   { mqtt=">[broker:cmnd/kitchen/power2:command:*:default], <[broker:stat/kitchen/POWER2:state:default]", expire="2s,command=OFF" }

EDIT:

I dont think that i have set up my dbmap.persist file correctly and presently it is maintaining all items:

// mapdb.persistence

Strategies {
	default = everyChange
}
Items {
	* : strategy = everyChange, restoreOnStartup
}

Am’I allowed to enter multiple lines to the mapdb.persist file like this?

// mapdb persistence

Strategies {
	default = everyChange
}
Items {
	sPersist* : strategy = everyChange, restoreOnStartup
	gLights* : strategy = everyChange, restoreOnStartup
	gPower* : strategy = everyChange, restoreOnStartup
}

I’m not sure, but i think so.

I’m using the persistence groups as kind of tags for items. Every item that gets persisted, is in the gPersist group. Every item which should be restored on startup is in gRestoreOnStartup. I do not use gLights or gPower in persistence, a persisted lights item is in both groups.

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

This is great
Could you post this into its own topic in the tutorial and examples category, please?

Hi
The first code window, is this done by putty or should i past that into a file? If so what kind of file and where.?

Best regards Jerry

It’s a rules file

Ahh, ok then. Thanks alot :slight_smile:

Uptime openHAB aN:aN whats wrong when i get aN:aN instead of the time?

Dear All

I applied the logic described above, tried different syntax/format, added notification to make the code was executed
but the Rasp is never rebooting, the line below does not move anything
executeCommandLine(’“sudo” “reboot”’, 5000)

Has anyone been successful with reboot from openhab rule ?
Thank you

Im not using the rule here, but would assume, that the rule can only reboot OpenHab, when the Openhab user is member of sudoers. Only than the Openhab user can trigger a reboot.

Have a look at this article, this might help you:

What does the logs tell you?

I do not think it is possible to reboot the machine that OH is running on from OH itself. Here is the sequence of events.

  1. OH creates a shell
  2. OH calls reboot
  3. reboot sends out the “we’re going down!” signal to all running processes.
  4. OH receives the “we’re going down!” signal
  5. OH abruptly kills the shell it create to call the reboot command
  6. The reboot command get’s killed because the shell it was running in, it’s parent process, was killed
  7. The machine stops rebooting.

This seems to be the behavior when ever someone tries to do it. I do think this is a side effect from the fact that the reboot command’s parentage is something like:

systemd -> java -> shell -> reboot

Perhaps the reboot command can’t survive it’s grandparent process being killed the same way it can it’s parent process.

Thank you mdnx, I managed to get the reboot working by following your instruction

Regards
David

1 Like