What I would love is to have a unified text-based and UI-based configuration.
Why?
First of all, I am a big fan of text-based configuration as I find it better to maintain, to overview, and to version-control. (e.g. I use a SVN repository to store my text-based config so that I can track changes).
But I also start finding advantages of the UI based configuration, especially the remote editing over the UI when you are not at home and do not have a VPN connecting to your home and your own file servers.
So the idea is to have a synchronized text file that is translated to the internal config, if you change it, but also translated back into text if you change the config in the UI. Could be a checkmark to set once if you want to have a synchronized text file of the e.g. rule/item/thing or if you are happy with UI based config only. Of course if you start configuring by text, this checkmark would be set by default.
Perhaps there is already this functionality…I recall a “last state” property. But if not, I can imagine it very useful to have a Push and Pop for item state, similar to Linux pushd/popd.
Imagine you have an active scene, and you wish to override that temporarily (push the state onto a stack, if you will). Then, you wish to revert to the previous state (pop the state off of the stack).
You can implement this in a rule right now using storeStates and restoreStates. It’s also easy enough to implement this in any rule yourself since a stack is a standard data structure that is easy to implement.
Beyond that there is a PR to add a lastState to the Item itself that does not require access to persistence.
Finally, persistence has access to the last state and all states since a given timestamp.
You can open a new thread for help implementing this in what ever rules language is your choice.
store_states Item1, Item2 do
# Do stuff here
# You can even nest it
store_states Item1, Item2 do
# Do more stuff here
end
end
# Item1 and Item2's states are restored after the do..end block automatically.
# Or for a manual restoration:
# Save the states into a variable named `states`
states = store_states Item1, Item2
# Do stuff here
# The states object has a #restore method
states.restore
# This means you can store the states in an array and do push/pop if you want to store multiple levels of state.
Another suggestion for OH5:
Priovide some variables/items which show a) the currently installed OH-version and b) if there is a newer (stable) version available.
The idea is to integrate this information into your gui/sitemap and to display it to the user. Rules etc can be used for notifications (if wanted)
var sysinfo = actions.HTTP.sendHttpGetRequest('http://localhost:8080/rest/');
var parsed = JSON.parse(sysinfo)
var currVersion = parsed.runtimeInfo.version;
console.info(currVersion);
Replace the url if you are running on a non-standard port and the log statement with an update to your Item.
var releasePage = actions.HTTP.sendHttpGetRequest('https://api.github.com/repos/openhab/openhab-distro/releases/latest');
var parsed = JSON.parse(releasePage);
var latestVersion = parsed.tag_name;
console.info(latestVersion);
Again, replace the log with an update to the Item you care about.
I might make this into a rule template if there’s demand for it.
Full script:
var sysinfo = actions.HTTP.sendHttpGetRequest('http://localhost:8080/rest/');
var parsed = JSON.parse(sysinfo)
var currVersion = parsed.runtimeInfo.version;
console.info(currVersion);
var releasePage = actions.HTTP.sendHttpGetRequest('https://api.github.com/repos/openhab/openhab-distro/releases/latest');
parsed = JSON.parse(releasePage);
var latestVersion = parsed.tag_name;
console.info(latestVersion);
I made it a little longer than necessary so everyone can see the steps clearly. But hopefully you can see this is pretty easy. It should be translatable to any rules language that supports JSON (sorry Rules DSL, you’ll have to come up with a regex) almost line for line.
Note, you have access to the current running version in Help & About on MainUI already.
That wasn’t documented anywhere (at least not in the places I usually look). Good to know.
So the full code becomes:
// Current Version
console.info(org.openhab.core.OpenHAB.version);
// Latest Release
var releasePage = actions.HTTP.sendHttpGetRequest('https://api.github.com/repos/openhab/openhab-distro/releases/latest');
parsed = JSON.parse(releasePage);
var latestVersion = parsed.tag_name;
console.info(latestVersion);
Can “org.openhab.core.OpenHAB.version” be used in a DSL rule? I’m getting an error.
var currVersion = org.openhab.core.OpenHAB.version
Script execution of rule with UID 'CheckForUpdate-1' failed: The name 'org' cannot be resolved to an item or type; line 7, column 21, length 3 in CheckForUpdate
Just to share - this rule will send a daily reminder when a new version is available.
rule CheckForUpdate
when Time cron "0 0 8 * * ? *"
then // Get the installed version
var rc = ""
rc = sendHttpGetRequest("http://localhost:8080/rest/")
var currVersion = transform("JSONPATH", "runtimeInfo.version", rc)
// Get the latest version
rc = sendHttpGetRequest("https://api.github.com/repos/openhab/openhab-distro/releases/latest")
var latestVersion = transform("JSONPATH", "tag_name", rc)
// Only check major version and minor version
var currMajorVersion = currVersion.split("\\.").get(0)
var currMinorVersion = currVersion.split("\\.").get(1)
var latestMajorVersion = latestVersion.split("\\.").get(0)
var latestMinorVersion = latestVersion.split("\\.").get(1)
// Nothing to do if the installed version is newer that the latest version or
// the installed version is the latest version
if ((currMajorVersion > latestMajorVersion) ||
(currMajorVersion == latestMajorVersion && currMinorVersion >= latestMinorVersion)) {
logInfo("CheckForUpdate","openHAB update not required. Installed version is {}, latest version is {}",
currMajorVersion + "." + currMinorVersion, latestMajorVersion + "." + latestMinorVersion)
return
}
// Send a notification to update openHAB
var msg = "<font face=\"Calibri\" size=\"+1\">" +
"There is a new openHAB version available for update.<br><br>"
msg += "Installed version: " + currVersion + "<br>"
msg += "Available version: " + latestVersion + "<br></font>"
val mailActions = getActions("mail","mail:smtp:myemail")
mailActions.sendHtmlMail("someone@example.com", "New openHAB Version Available", msg)
logInfo("CheckForUpdate","Email notification sent for update from openHAB version {} to version {}", currVersion, latestVersion)
end
with “some kind” I mean, in javascript it is recommended to use the new “Java.type” syntax. In the documentation they talk about “Backwards-compatible syntax”. So it would not be a surprise if they fully deprecate it some days…
in python you have to enable a jython compatibility mode to have this behavior and the recommended way is
I wasn’t specifying a specific syntax. I’m surprised that it works as is in javascript. It was merely a pointer for where to look. That syntax is perfectly fine for jruby and it’s available in the jruby helper library as
The add-on and JSR223 injects the Java stuff already. So there shouldn’t need to be a need to Java.type it in a rule. Perhaps it’s cleaner to use:
var runtime = require("@runtime");
console.log(runtime.org.openhab.core.OpenHAB.version)
To aid in UI rules development a bunch of stuff gets injected to the script automatically. If that didn’t happen roughly 20%+ of all the code written in the UI would be require and Java.type statements (based on my own code).
In short, the class has already been Java.type()'d.
I like the idea of wrapping this into some kind of LookupWrapper Class without enabling a backward compatible mode.
Will do something similar in pythonscripting.
All the JSR223 objects are already available in pythonscripting too, but the “@require” statement seams to be a special wrapper class in the javascript binding which makes this available.
I’m not entirely certain of the specifics, but the helper library completely hides and in some cases replaces the standard JSR223 stuff (e.g. items is your entry to all things Items whereas in JSR223 items is a map of Item name and current state). The helper library should be the only stuff you use unless you are in the very rare case where the helper library doesn’t provide some capability. That way you are always and ever only using JavaScript classes and Objects.
In those rare cases where you need to do something not provided by the helper library as JS, you can import the JSR223 runtime like a NPM library using require and access all the Java stuff and OH API stuff that’s part of the JSR223 runtime. If it’s not there, you can use Java.type to pull in other Java classes, though it’ll often be easier to find an npm library to do what you need rather than pulling in Java stuff to do it.
There is a setting on the add-on to automatically inject the helper library or not. If that’s disabled, you need to import the helper library to use it. Using var runtime = require('@runtime') is a way to get to the JSR223 stuff without blowing away the helper library, assuming it’s already injected.