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
Thanks for this, nice and simple. Although your cron format is wrong. Unsure what time of the day 50 o’clock is
...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.
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
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.
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:
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
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 )
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.
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.
OH creates a shell
OH calls reboot
reboot sends out the “we’re going down!” signal to all running processes.
OH receives the “we’re going down!” signal
OH abruptly kills the shell it create to call the reboot command
The reboot command get’s killed because the shell it was running in, it’s parent process, was killed
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.