This tutorial post is very out of date and ultimately did not make it into the official docs. Do not use this except for historic purposes. See the Getting Started Tutorial sections on rules for how to get started with rules. Rules - Introduction | openHAB
Other Functions and Actions
OH supports a number of functions which allow one to cause something to occur in a script such as sending an email or scheduling something to occur at a later date. There are a number of built in functions and a number of add-ons called Actions that can be installed and used.
createTimer
Schedules a function to execute sometime in the future.
// Native Quartz version
var ScriptExecution = Java.type("org.eclipse.smarthome.model.script.actions.ScriptExecution");
var DateTime = Java.type("org.joda.time.DateTime");
var runme1 = function(){ logInfo("Native Quartz Timer completed"); }
var timer1 = ScriptExecution.createTimer( DateTime.now().plusSeconds(5), runme1);
...
timer1.cancel();
// Native Java/Nashorn
var Timer = Java.type("java.util.Timer");
var timer2 = new Timer("setTimeout", true);
var runme2 = function() { logInfo("Native Java/Nashorn Timer completed"); };
timer2.schedule( runme2, 2000);
...
timer2.cancel();
// Library version
// NOTE: This does not use the Quartz Scheduler like the above does
var runme3 = function(){ logWarn(logInfo("Library Native Quartz Timer completed"); };
var timer3 = createTimer( now().plusSeconds(2), runme3, "argument");
...
timer3 = timer.cancel();
// setTimeout Library version javascript like, with argument.
var runme4 = function(){ logWarn(logInfo("Library setTimeout completed"); };
var timer4 = setTimeout( runme4, 1000, "argument");
...
timer4.cancel();
Unfortunately, unlike in the Rules DSL where we can have global variables that survive a Ruleās execution methods like cancel
and reschedule
will be less useful in NGRE.
sleep
Pauses execution of the Rule for the given number of milliseconds.
// Native and Library version
java.lang.Thread.sleep(1000);
storeStates/restoreStates
Retrieves a map of Item name and State pairs for the given list of Items. Because PaperUI rules do not support global variables, these may not be as useful. Typically, one will call storeStates
and save those values somewhere, then later call restoreStates
later on to restore those Items to the saved states.
// Native version
var states = events.storeStates(ir.getItem("Test"), ir.getItem("ColorTest"), ir.getItem("DimmerTest"));
...
events.restoreStates(states);
// Library version - Untested as of this writing
var states = events.storeStates(ir.getItem("Test"), ir.getItem("ColorTest"), ir.getItem("DimmerTest"));
...
events.restoreStates(states);
Unfortunately, the utility of these two actions are greatly reduced as there is no way to persist the variable states across multiple runs of the Rule or across multiple Rules. TODO: However, one could parse the Map returned by storeStates into a String and post that to an Item and then parse it back to go the other way. Submit a PR to add this to the library.
logging
Often it is useful to log certain information to the logs for debugging and monitoring. OH supports five levels of logging. Levels are used to limit how much gets saved to the log file. While debugging a problem or developing new Rules one might set the logging level to DEBUG or TRACE to get more information but set the level to INFO or WARN during normal operations. Each level includes the logging from the levels above it in the following table (i.e. WARN level also includes ERROR logs).
Level | Purpose |
---|---|
ERROR | Use to denote a fatal error that prevents a Rule from working. |
WARN | Use to denote something that is wrong or unexpected in a Rule but the Rule is able to manage it. |
INFO | Informational level info needed for general monitoring. |
DEBUG | Additional information that might be useful for writing new Rules or identifying problems. |
TRACE | Highly detailed information. |
By default, the Rules loggers are configured to only output at the INFO level.
// Native
var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.eclipse.smarthome.model.script.Rules");
logger.error("This is an error log");
logger.warn("This is a warning log");
logger.info("This is an info log");
logger.debug("This is a debug log");
logger.trace("This is a trace log");
// Library
logError("This is an error log");
logWarn("This is a warning log");
logInfo("This is an info log");
logDebug("This is a debug log");
logTrace("This is a trace log");
In the Native version above, you can change the string in getLogger
to be the name of where you want your logs to go. So, if for example, you want to put all the logs from one Rule or set of Rules in a separate logger so they can be separately filtered or saved in a separate log file, use a different path.
The library writes to "org.eclipse.smarthome.automation.module.script.rulesupport.internal.shared.SimpleRule"
.
See the logger docs for details on how to format and create the strings that get logged.
executeCommandLine
To execute a shell script or program from a script use executeCommandLine
or executeCommandLineAndWaitResponse
. These functions use the same underlying code to kick off the scripts that the Exec binding does so the same warnings and work arounds apply:
- sometimes it will be required to replace spaces with
@@
- the command will run as the same user that openHAB is running as which is usually
openhab
- the openhab user doesnāt have a full set of environment variables so the full path to the command and files used by the command will need to be supplied.
// Native
var ExecUtil = Java.type("org.eclipse.smarthome.io.net.exec.ExecUtil");
var r1 = ExecUtil.executeCommandLineAndWaitResponse("echo 'wait for result'", 5000);
logInfo(r1);
ExecUtil.executeCommandLine("echo `don't wait for result`");
// Library
var r2 = executeCommandLineAndWaitResponse("echo 'wait for result2'", 5000);
logInfo(r2);
executeCommandLine("echo 'don't wait for result'");
transform
There will be times where one will want to call the transformation service from a script. This can be done with the transform
function.
// Native
var ScriptServiceUtil = Java.type("org.eclipse.smarthome.model.script.ScriptServiceUtil");
var services = ScriptServiceUtil.getActionServices();
var tnsf = services.stream().filter(function(el){ return el.getActionClassName().contains("Transform"); }).findFirst().get();
logInfo(tnsf.getActionClass().static.transform("MAP", "locks.map", "21"));
// Library - TODO didn't work
logInfo(transform("MAP", "locks.map", "21"));
See the Transformation Service Documentation for the available services and how to use them.
HTTP Requests
There are a number of functions built in to OH to make simple HTTP requests to a web server.
var url = "http://demo.openhab.org:8080/rest/";
var timeout = 5000;
// Native Java
var HttpUtilNativ = Java.type("org.eclipse.smarthome.io.net.http.HttpUtil");
var results = HttpUtilNativ.executeUrl("GET", url, timeout);
logInfo("results GET: ", results);
results = HttpUtilNativ.executeUrl("PUT", url, timeout);
logInfo("results PUT: ", results);
results = HttpUtilNativ.executeUrl("POST", url, timeout);
logInfo("results POST: ", results);
// Library
results = sendHttpGetRequest(url, timeout);
logInfo("results sendHttpGetRequest: ", results);
results = sendHttpPutRequest(url, timeout);
logInfo("results sendHttpPutRequest: ", results);
results = sendHttpPostRequest(url, timeout);
logInfo("results sendHttpPostRequest: ", results);
results = sendHttpDeleteRequest(url, timeout);
logInfo("results sendHttpDeleteRequest: ", results);
// Library executeUrlWithContent( httpMethod, url, httpHeaders, content, contentType, timeout)
var header = "application/x-www-form-urlencoded; charset=UTF-8";
var results = executeUrlWithContent("POST", url, null, "", header, timeout);
logInfo("results executeUrlWithContent: ", results);
Thing Status
To obtain the online/offline status of a Thing.
// Native Action
var thingHelper = Java.type("org.eclipse.smarthome.model.script.actions.ThingAction");
var thingStatus = thingHelper.getThingStatusInfo("zwave:device:dongle:node6");
// Using things variable
var ThingUID = Java.type("org.eclipse.smarthome.core.thing.ThingUID");
var tUid = new ThingUID("zwave:device:dongle:node6");
var thing = things.get(tUid);
var status = thing.getStatus();
// There is no library function
TODO add PR to add this action to the library
The possible values from calling toString() on the ThingStatus are:
INITIALIZING
OFFLINE
ONLINE
REMOVED
REMOVING
UNINITIALIZED
UNKNOWN
callScript
This is an action that is available in Rules DSL to call a subscript. Because NGRE has support for libraries this Action is deprecated.
Cloud Notification Actions
Publishes messages to apps connected through myopenhab.org.
// Native JavaScript
var NotificationAction = org.openhab.io.openhabcloud.NotificationAction;
NotificationAction.sendNotification("rlkoshak@gmail.com", "This is a directed notification");
NotificationAction.sendNotification("rlkoshak@gmail.com", "This is a detailed directed notification", "light", "WARN"); // TODO what is severity? "light" is the icon
NotificationAction.sendBroadcastNotification("This is a broadcast test");
NotificationAction.sendBroadcastNotification("This is a detailed brodcast test", "light", "WARN")
NotificationAction.sendLogNotification("This is a log notification");
NotificationAction.sendLogNotification("This is a detailed log notification", "light", "WARN");
// No library helper functions
TODO: Add library helper functions.
Non-core Actions
Actions beyond the the above core set can be installed and called from scripts.
// Native JavaScript
// Library version, a collection of all available Actions are put into a collection that can then be
// called by name.
//To send a Mail:
getAction("Mail").static.sendMail("mail@you.de", "subject", "message");
Iāve not tested the code below this point yet.
TODO: Call an Action
load(Java.type("java.lang.System").getenv("OPENHAB_CONF")+'/automation/jsr223/jslib/JSRule.js');
//Returns actionList like = Voice,Transformation,PersistenceExtensions,ThingAction,Audio,Mail,XMPP,Telegram
logInfo("getActionList:", getActionList());
//To send a Mail:
getAction("Mail").static.sendMail("mail@you.de", "subject", "message");
- third party installed Actions
TODO: Create an Object
- in Rule body
- reusable across multiple Rules
TODO: Migrate JSONDB Rules to Stand Alone .js Files
- how to build up a JSON Rule in a separate file (JSR223 docs for building a Rule)
TODO: Rule Templates
- what are they?
- how do I create them?
- how do I use them?
TODO: Creating Libraries
Will probably be a new posting.
- reusable functions
- reusable Rules
TODO: Comprehensive Examples
- shows multiple rule trigger types
- shows rules enabling/disabling each other
- shows many if not all of the above
- maybe pick one or more DPs as the example
Trouble Shooting
- errors
- where to look
- how to interpret
Previous step: Experimental Next-Gen Rules Engine Documentation 4 of : Writing Scripts
Next step: