Number System_CPU_Uptime "Uptime [JS(duration.js):%s]" <clock> (System) { channel="systeminfo:computer:local:cpu#uptime" }
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;
if (d == 1) {
result = d + " day";
} else {
result = d + " days";
}
}
// hours
if (h > 0) {
if (result != '') {
result = result + ', ';
}
result = result + h;
if (h == 1) {
result = result + ' hour';
} else {
result = result + ' hours';
}
}
// minutes
if (m > 0) {
if (result != '') {
result = result + ', ';
}
result = result + m;
if (m == 1) {
result = result + ' minute';
} else {
result = result + ' minutes';
}
}
return result;
})(input)
There must be something about what you are doing that I don’t understand because I still don’t see how implementing this in JS is any better or worse, lets you do anything or prevents you from doing anything that you also couldn’t do in a rule.
Not that it matters. There are lots of ways to do what you want in OH.
That is probably a false assumption. Both the JS transform and the Rules DSL require spinning up an interpreter but the actual calculation is trivial so they are probably the same CPU wise.
Secondly, in this case I dint see how putting it into a JS transform is any more generic than using a rule. You will need to edit/change something somewhere to change language anyway so putting it in a transform just moved where you need to make the edits, it didn’t really make them generic or easier to make.
I can see some arguments fit why you would want to do this in a transform. It is a good place to centralize your internationalization changes and I do like separating stuff like that. So from an organizational perspective I totally see advantages. But from a performance and genericization perspective I see no advantage.
Finally, even on a Pi, once per second is forever. I wouldn’t worry about optimizing such a set of rules until you actually see a performance problem.
At a high level, the full text gets set to a String Item. There is a Rule that triggers when this String Item changes. In this rule parse out the data needed and postUpdate those values to the Items that represent that value.
Assuming there is a javascript that does the conversion, the .widget file will have to change to show the item’s string, but I don’t know how to do that…
I tried changing the .item file to the line below but the uptime is still reported in minutes
updated .item file
Number CPU_Uptime "Uptime [JS(duration.js):%s]" <clock> (gSystem) { channel="systeminfo:computer:work:cpu#uptime" }
Should I place the javascript file in /etc/openhab2/transform or /etc/openhab2/scripts or …
What will be the settings in the .items .widget files?
Thanks @rlkoshak and @rtvb . I am not seeing any difference when using the js script (I’m still seeing the upstart in minutes) @rtvb I don’t have a rule for displaying the upstart. It basically refreshes every e.g. 30 secs based on systeminfo.things
Would itemValue(‘CPU_Uptime’) in the widget, trigger the item state (i.e. “Uptime [JS(duration.js):%s]”) that will trigger the js script?
@rlkoshak, I saw your recommendation to use designer to flush out any syntax errors in rules. I’ll start using it when I have first chance (I haven’t used it before and I don;t want to open another front here)
I’m trying to add log statements within it to see what is going on there but I don’t see anything in openhab.log…
I did the following:
Turned on DEBUG logging for package org.openhab.io.net.exec in karaf (per the guidelines for openhab1 here (I’m using openhab2 but did not find documentation for openhab2))
You don’t need too. My code was just an example how to use it when needed. I use this to send myself a daily email with some general system statistics.
I dont’t have any experience with HABpanel, so I can’t help you with this one.
In general, if you use the duration javascript, the actual item value is still kept as a Number by opennHAB but only transformed at runtime when displayed in the sitemap.
In a karaf console you could use smarthome:status CPU_Uptime to show the actual value.
A dummy rule to test your javascript could be (untested):
rule "Test Duration Script"
when
Item CPU_Uptime received update
then
val String duration = '' + transform("JS", "duration.js", CPU_Uptime.state.toString)
logInfo('Test', 'Number ==> ' + CPU_Uptime.state.toString)
logInfo('Test', 'String ==> ' + duration)
end
Your example rule helped me solve the problem. The conversion showed ok in openhab.log.
I ended up updating habpanel from a string item, which is updated automatically via the rule every time the uptime number item is updated (thanks @rlkoshak for your advice).
See my solution here
rule "format uptime"
when
Time cron "32 0/5 * * * ?"
then
var int days = (uptime.state as DecimalType).intValue / (24 * 60)
var int hours = ((uptime.state as DecimalType).intValue / 60) - (24 * days)
var int minutes = ((uptime.state as DecimalType).intValue - 60 * (24 * days + hours))
var String result = ""
// days
if (days > 0) {
result = result + days + " Tage / "
}
// hours
if (hours > 0) {
result = result + hours + " Std. / "
}
// minutes
if (minutes > 0) {
result = result + minutes + " Min."
} uptimeFormatted.postUpdate(result)
logInfo("system.rules", "Uptime updated to " + uptimeFormatted.state)
end