OH3: Scripts do not work

I have one question on which I can’t find answer. I use OH 3.0.0M1 and I like it more than 2.0 …
Im new to rules on OH but Im not sure if I really understand how rules work on OH3…
Im try create one simple rule which must triger if item value(dimmer) change to 50 or more and then as action set that item to 0.

This Rule do not work(Is not triggered, if I run it manualy from eb it turn off dimmer):

triggers:

  • id: “1”
    configuration:
    itemName: ZWave_Floor1_Office_Dimmer_TableLight_Dimmer
    state: “50”
    operator: “>=
    type: core.ItemStateChangeTrigger
    conditions: []
    actions:
  • inputs: {}
    id: “2”
    configuration:
    itemName: ZWave_Floor1_Office_Dimmer_TableLight_Dimmer
    command: “0”
    type: core.ItemCommandAction

If I create rule which have fixed value like this one then it normaly trigger:

triggers:

  • id: “1”
    configuration:
    itemName: ZWave_Floor1_Office_Dimmer_TableLight_Dimmer
    state: “100
    operator: “=
    type: core.ItemStateChangeTrigger
    conditions: []
    actions:
  • inputs: {}
    id: “2”
    configuration:
    itemName: ZWave_Floor1_Office_Dimmer_TableLight_Dimmer
    command: “0”
    type: core.ItemCommandAction

What exactly I do wrong? Or is there some bug in rules and do not work as must?
This is ony test rule but in reality I need trigger which will triger when battery on battery powered devices change from >=30 to <=29 and send notification that I need charge batteries… Is “previousstate” availible in OH3 rules?
Thanks for any help.

Try the latest snapshot. I have been testing OH3 off & on starting around Milestone 1 & I thought rules did not work. I had a rule work with a later snapshot. Perhaps something was fixed in between the Milestone & snapshots.

1 Like

“operator” is not a valid option of the core.ItemStateChangeTrigger. You only have the options that are presented by the UI.
In your case you should remove operator and state so the rule will be triggered every time the item changes, and add a condition “[but only if] an item has a given state”, in the condition you can use the operator.

2 Likes

ysc it do not work or maybe Im again do something wrong…

Log:

2020-11-02 19:47:23.282 [INFO ] [marthome.event.ItemStateChangedEvent] - Item ‘ZWave_Floor1_Office_Dimmer_TableLight_Dimmer’ changed from 0 to 100

New Triger:

triggers:

  • id: “1”
    configuration:
    itemName: ZWave_Floor1_Office_Dimmer_TableLight_Dimmer
    type: core.ItemStateChangeTrigger
    conditions:
  • id: “3”
    configuration:
    itemName: ZWave_Floor1_Office_Dimmer_TableLight_Dimmer
    operator: “>=”
    state: “50”
    type: core.ItemStateCondition
    actions:
  • inputs: {}
    id: “2”
    configuration:
    itemName: ZWave_Floor1_Office_Dimmer_TableLight_Dimmer
    command: “0”
    type: core.ItemCommandAction

Do you maybe know how I can get previousstate in new trigger? Because in near future I will need triger which will send me low battery notification only once when battery will change from example 30->29 and previous state is I think good way to do it. Then I will also need another notification when I will recharge batteries and it will go from 99->100 that I get notification that bateries are recharged…

I believe OH does not save states. That is why there are persistence options.

There i an implicit variable oldState, but that only exists when the rule i triggered by a Changed trigger. So only if the rule is triggered by id: 1. If the rule is triggered by the other two there won’t be an old state and you will need to use persistence, which requires additional configuration.

2 Likes

Ok thanks so if I understand right ith that “next-gen rules system” I can’t create simple rules for low battery notifications with GUI because:
1.) core.ItemStateChangeTrigger do not allow to use operators
2.) oldState can be used only in core.ItemStateChangeTrigger

So as I understand for simple triger which will trigger for example(code is not walid OH script code is just “pseudocode”):

if (ZWave_Floor2_Kitchen_Thermostat_BatteryLevel.oldState>=30 AND ZWave_Floor2_Kitchen_Thermostat_BatteryLevel.state<=29) then
SendNotification(“Battery low”)

So this can’t be done with simple GUI and need to use scripting in trigers? Which of two option is recommended to do in long term support and are any limitations in each of them?

If you add another trigers ho do they react as AND or as OR ? For example if I add 3 items into when ItemStateChangeTrigger …

It has never been possible to have AND in a rule trigger. Rules are triggered based on events. You will never have the case where two events occur at exactly the same time.

Changed triggers only allow static operators. You can say changed to X or changed from Y or even changed from X to Y, but you can’t say changed to > 30.

oldState cannot be used with the trigger, it can only be used in the conditional (but only if…) or action scripts.

You can’t use scripting in triggers. But you can in the conditional and the action. Trigger the rule when ever the battery level changes. Then in the but only if… section check the states of the Item. Only if the Item passes that check will the action run. But I don’t know if you have access to oldState in the GUI so you might have to use a “if a script evaluates to true” and code the if statement yourself.

It’s always OR because the triggers are based on events, not states.

1 Like

Thanks for answers. Right now I have several new questions :slight_smile:
1.) What about “But only if” what is here used OR or AND? Because there usually we will need both options… We can do something if (item1 = 0 AND item2 = 0) or we can do something if (item1 = 0 OR item2=0) …
2.) If Im understand right I will need to make triger which triget on every “ZWave_Floor2_Kitchen_Thermostat_BatteryLevel” state change and run as action(Then) script in which I will check state of item and action which I would like to do?
3.) Which scripting language is preffered to use in long term support or offer more options “Rule DSL (v1)” or “ECMAScript (ECMA - 262 Edition 5.1)” ? So I don’t want spend learning one of them because is added as legacy support and ill be terminated in some next versions…
4.) Is in OH3 option to make triggers outside GUI?

Thanks for answers, help and time.

The new rules engine allows triggers with “but only” conditions …
But it is still important to understand that the primary trigger is an event, not a condition.

You cannot trigger on item = x, it’s just not an event. Item changing to x is an event.

Previously, we might trigger a rule by door opening, then in the body of the rule test if was dark before turning on the light.

Now we have a little shorthand, we can trigger on door-opening BUT ONLY IF state = dark.
It’s the same event driven structure.

1 Like

I understand that trigger is event. Im try right now my way and looks like with ay which Im describe in second question in last post Im get what I need.
Im create Rule with ItemStateChangeTrigger on one test item without previous state and state value. Im as Then action set to run ECMAScript and in script do small demo example:

var logger = Java.type(“org.slf4j.LoggerFactory”).getLogger(“org.openhab.core.model.script.LowBatteryTrigger”);
logger.debug(“Trigger Started”);
var from = parseFloat(oldState.toString().split(’ ‘)[0]);
var to = parseFloat(newState.toString().split(’ ')[0]);
logger.debug("From: " + from);
logger.debug("To: " + to);
if (from <= 50 && to >= 51) {
events.sendCommand(‘ZWave_Floor1_Office_Dimmer_TableLight_Dimmer’, ‘0’);
logger.debug(“Triger OK”);
}
logger.debug(“Trigger Finished”);

18:00:11.572 [DEBUG] [b.core.model.script.LowBatteryTrigger] - Trigger Started
18:00:11.623 [DEBUG] [b.core.model.script.LowBatteryTrigger] - From: 0
18:00:11.627 [DEBUG] [b.core.model.script.LowBatteryTrigger] - To: 100
18:00:11.669 [DEBUG] [b.core.model.script.LowBatteryTrigger] - Triger OK
18:00:11.673 [DEBUG] [b.core.model.script.LowBatteryTrigger] - Trigger Finished
18:00:11.720 [DEBUG] [b.core.model.script.LowBatteryTrigger] - Trigger Started
18:00:11.739 [DEBUG] [b.core.model.script.LowBatteryTrigger] - From: 100
18:00:11.743 [DEBUG] [b.core.model.script.LowBatteryTrigger] - To: 0
18:00:11.746 [DEBUG] [b.core.model.script.LowBatteryTrigger] - Trigger Finished

By quick test it work as must. When I turn on test dimmer it meet requirements and turn it off… That way I can make script for Low Battery event…

You can define the conditional how ever you want. If the UI doesn’t support what you want you can even write your own script to handle the condition. For HestiaPi I even put corrective actions into the condition. For example, if one ties to set an Item to a state that isn’t allowed, it prevents the rule from running and resets the Item back to it’s previous state

But as rossko57 says, the rule triggers on events. Once triggered you can check the states of Items and time and anything else relevant to see if the rule needs to run or not.

That’s one way to do it. But what I’ve been describing is you trigger the rule for all state changes to that Item. The conditional checks to see if the Item has changed from and to a state where an alert is required. Only if that evaluates to true does the action run where the alert is sent.

I think it’s safe to use either. I don’t see either going anywhere any time soon. There are more examples of Rules DSL on the forum and the docs. But ECMA (i.e. JavaScript), being a popular language outside of openHAB, will have more resources in the wider world to help you learn it. Groovy is also an option (install-able as an addon in OH 3 M2) and Python will become available someday.

I don’t know what this means. If you mean you want to write rules without using MainUI than yes, you can write rules outside of the GUI just like you can do any other configuration outside of the GUI.

1 Like

Is there some documentation/references what “modules”, “classes” are availible in scripting and how to use it?
I can’t find anything usefull and Im new at openhab “ECMA scripting” Im develop apps in Delphi, Java, C#.

Im sucessfully add loging option in script:

var logger = Java.type(“org.slf4j.LoggerFactory”).getLogger(“org.openhab.core.model.script.LowBatteryTrigger”);
logger.debug(“DEMO Log”);

Now I would like to know how can I use external actions for example send Push notification trough OpenHAB Cloud addon…
Im try add it like:

var push_notification = Java.type(“org.eclipse.smarthome.io.openhabcloud.internal.CloudService”);

or

var push_notification = Java.type(“io.openhabcloud.internal.CloudService”);

But it crash at that line…

I still cant get simple sendNotification() to work… All time I get “java.lang.ClassNotFoundException” errors…
Im try several way to use openhab cloud sendnotification function like:

var openhab_notification = Java.type(“org.openhab.io.openhabcloud.NotificationAction”);
openhab_notification.sendNotification(“email”, “This is notification”);

var openhab_notification = org.openhab.io.openhabcloud.NotificationAction;
openhab_notification.sendNotification(“email”, “This is notification”);

How we can send notification in OH3?

I strongly encourage the use of the Helper Libraries. They are documented at https://openhab-scripters.github.io/openhab-helper-libraries/index.html. In particular pay attention to the “But how do I…” page. Also look at the library source code which is informative.

I’ve posted some further examples at openHAB 3.0 my getting started notes: Rules (I return and update this periodically so check back often) and much older examples at Experimental Next-Gen Rules Engine Documentation 1 of : Introduction which have a lot of stuff that is no longer correct but is still largely useful. Full docs for ECMA Script have not been built yet.

I’ve not tried to send a notification yet so I cannot say for sure. But org.openhab.io.openhabCloud.NotificationAction is the correct path according to the code on github.

Hi,
Im already try helper libraries with javascript but didn’t work. I will try them again with carefully reading instructions…
As Im try a lot of things I can’t find way to run anything usefull from scripts… Everything fail with ClassNotFoundException …

What didn’t work?

Also, did you install the openHAB Cloud Connector add-on?

I don’t have the cloud connector installed in OH3 so I can’t test it myself at this time because one can only have one OH instance connected to the myopenhab.org server at a time.

Nothing didn’t work :slight_smile:
Now Im do everything as written in tutorial but they do not work also HelloWorld.js do not write into log every 10 seconds…
First Im enable logging:
jsr223 │ DEBUG
org.openhab.core.automation │ DEBUG

Then Im shutdown openhab and copy files.

Im copy content of Core folder into openhab:
automation_folder

Then Im rename configuration file:

configuration

And copy demo script to personal folder:

personal

Then Im start openhab and log:tail

19:01:09.577 [INFO ] [b.core.internal.i18n.I18nProviderImpl] - Time zone set to 'Europe/Ljubljana'.
19:01:09.610 [INFO ] [b.core.internal.i18n.I18nProviderImpl] - Location set to 'REMOVED'.
19:01:09.620 [INFO ] [b.core.internal.i18n.I18nProviderImpl] - Locale set to 'sl_SI'.
19:01:11.028 [DEBUG] [ript.internal.ScriptEngineManagerImpl] - Initialized a generic ScriptEngineFactory for Oracle Nashorn (11.0.9): supports ECMAScript (ECMA - 262 Edition 5.1) with file extensions [js], names [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript], and mimetypes [application/javascript, application/ecmascript, text/javascript, text/ecmascript]
19:01:11.038 [DEBUG] [ript.internal.ScriptEngineManagerImpl] - Initialized a custom ScriptEngineFactory for Oracle Nashorn (11.0.9): supports ECMAScript (ECMA - 262 Edition 5.1) with file extensions [js], names [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript], and mimetypes [application/javascript, application/ecmascript, text/javascript, text/ecmascript]
19:01:16.938 [WARN ] [org.openhab.core.net.NetUtil         ] - Found multiple local interfaces - ignoring REMOVED
19:01:25.739 [DEBUG] [ovider.AbstractResourceBundleProvider] - Parse rules from bundle 'org.openhab.core.automation' 
19:01:25.739 [DEBUG] [ovider.AbstractResourceBundleProvider] - Parse rules from bundle 'org.openhab.core.automation.module.script.rulesupport' 
19:01:25.870 [DEBUG] [re.automation.internal.RuleEngineImpl] - ModuleHandlerFactory added CoreModuleHandlerFactory
19:01:25.870 [DEBUG] [re.automation.internal.RuleEngineImpl] - ModuleHandlerFactory added TimerModuleHandlerFactory
19:01:25.878 [DEBUG] [re.automation.internal.RuleEngineImpl] - ModuleHandlerFactory added ScriptModuleHandlerFactory
19:01:25.880 [DEBUG] [re.automation.internal.RuleEngineImpl] - ModuleHandlerFactory added ScriptedCustomModuleHandlerFactory
19:01:25.880 [DEBUG] [re.automation.internal.RuleEngineImpl] - ModuleHandlerFactory added ScriptedPrivateModuleHandlerFactory
19:01:25.880 [DEBUG] [re.automation.internal.RuleEngineImpl] - ModuleHandlerFactory added AnnotatedActionModuleTypeProvider
19:01:25.880 [DEBUG] [re.automation.internal.RuleEngineImpl] - ModuleHandlerFactory added AnnotatedThingActionModuleTypeProvider
19:01:25.880 [DEBUG] [re.automation.internal.RuleEngineImpl] - ModuleHandlerFactory added EphemerisModuleHandlerFactory
19:01:28.624 [DEBUG] [ript.internal.ScriptEngineManagerImpl] - Initialized a custom ScriptEngineFactory for null (null): supports Rule DSL (v1) with file extensions null, names null, and mimetypes [application/vnd.openhab.dsl.rule]
19:01:28.635 [INFO ] [b.core.model.lsp.internal.ModelServer] - Started Language Server Protocol (LSP) service on port 5007
19:01:31.389 [DEBUG] [re.automation.internal.RuleEngineImpl] - ModuleHandlerFactory added MediaModuleHandlerFactory
19:01:31.481 [INFO ] [org.openhab.ui.internal.UIService    ] - Started UI on port 8080
19:01:31.974 [INFO ] [hab.ui.habpanel.internal.HABPanelTile] - Started HABPanel at /habpanel
19:01:32.148 [DEBUG] [io.openhabcloud.internal.CloudService] - openHAB Cloud connector activated
19:01:32.148 [DEBUG] [io.openhabcloud.internal.CloudService] - remoteAccessEnabled is not set, keeping value 'true'
19:01:32.157 [DEBUG] [io.openhabcloud.internal.CloudService] - API Token = REMOVED
19:01:32.167 [DEBUG] [io.openhabcloud.internal.CloudService] - Using secret at 'c:\openhab\userdata\openhabcloud\secret' with content 'REMOVED'
19:01:32.167 [DEBUG] [io.openhabcloud.internal.CloudService] - UUID = REMOVED, secret = REMOVED
19:01:32.179 [DEBUG] [io.openhabcloud.internal.CloudService] - Using secret at 'c:\openhab\userdata\openhabcloud\secret' with content 'REMOVED'
19:01:33.378 [DEBUG] [.io.openhabcloud.internal.CloudClient] - Socket.IO connected
19:01:33.378 [INFO ] [.io.openhabcloud.internal.CloudClient] - Connected to the openHAB Cloud service (UUID = REMOVED, base URL = http://localhost:8080)

If I create simple Script in UI and run it:

var OPENHAB_CONF = Java.type('java.lang.System').getenv('OPENHAB_CONF');
load(OPENHAB_CONF + '/automation/lib/javascript/core/actions.js');

if (Ping.checkVitality("10.5.5.5", 0, 5000)) {
    LogAction.logInfo("Rules", "Server is online");
} else {
    LogAction.logInfo("Rules", "Server is offline");
}

It still crash:

19:16:16.416 [INFO ] [smarthome.event.RuleUpdatedEvent     ] - Rule '71a2abce18' has been updated.
19:16:23.261 [DEBUG] [ript.internal.ScriptEngineManagerImpl] - Added ScriptEngine for language 'application/javascript' with identifier: 9f0e7e1f-6265-444d-98c0-eeb15f4de628
19:16:23.715 [WARN ] [re.automation.internal.RuleEngineImpl] - Fail to execute action: script
java.lang.RuntimeException: java.lang.ClassNotFoundException: org.eclipse.smarthome.model.script.actions.Exec cannot be found by org.apache.aries.jax.rs.whiteboard_1.0.9
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:531) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.Context.evaluateSource(Context.java:1438) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.Context.load(Context.java:962) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.objects.Global.load(Global.java:1720) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.scripts.Script$Recompilation$37$\^eval\_$cu1$restOf/0x00000007c0dfd040.:program(<eval>:2) ~[?:?]
        at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:655) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:527) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:456) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:413) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:409) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:162) ~[jdk.scripting.nashorn:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) ~[java.scripting:?]
        at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:62) ~[?:?]
        at java.util.Optional.ifPresent(Optional.java:183) ~[?:?]
        at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:59) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1179) [bundleFile:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.runNow(RuleEngineImpl.java:1031) [bundleFile:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.runNow(RuleEngineImpl.java:1047) [bundleFile:?]
        at org.openhab.core.automation.rest.internal.RuleResource.runNow(RuleResource.java:305) [bundleFile:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) [bundleFile:1.0.9]
        at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) [bundleFile:1.0.9]
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201) [bundleFile:1.0.9]
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104) [bundleFile:1.0.9]
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) [bundleFile:1.0.9]
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) [bundleFile:1.0.9]
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) [bundleFile:1.0.9]
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [bundleFile:1.0.9]
        at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267) [bundleFile:1.0.9]
        at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) [bundleFile:1.0.9]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) [bundleFile:1.0.9]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) [bundleFile:1.0.9]
        at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:216) [bundleFile:1.0.9]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301) [bundleFile:1.0.9]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:220) [bundleFile:1.0.9]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) [bundleFile:3.1.0]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:276) [bundleFile:1.0.9]
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:852) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:544) [bundleFile:9.4.20.v20190813]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) [bundleFile:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:536) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1581) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1307) [bundleFile:9.4.20.v20190813]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:293) [bundleFile:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:482) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1549) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1204) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [bundleFile:9.4.20.v20190813]
        at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80) [bundleFile:?]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.Server.handle(Server.java:494) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:374) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:268) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:367) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:782) [bundleFile:9.4.20.v20190813]
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:918) [bundleFile:9.4.20.v20190813]
        at java.lang.Thread.run(Thread.java:834) [?:?]
Caused by: java.lang.ClassNotFoundException: org.eclipse.smarthome.model.script.actions.Exec cannot be found by org.apache.aries.jax.rs.whiteboard_1.0.9
        at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:484) ~[org.eclipse.osgi-3.12.100.jar:?]
        at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:395) ~[org.eclipse.osgi-3.12.100.jar:?]
        at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:387) ~[org.eclipse.osgi-3.12.100.jar:?]
        at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:150) ~[org.eclipse.osgi-3.12.100.jar:?]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[?:?]
        at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:564) ~[org.eclipse.osgi-3.12.100.jar:?]
        at org.ops4j.pax.swissbox.core.BundleClassLoader.findClass(BundleClassLoader.java:176) ~[bundleFile:?]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:588) ~[?:?]
        at org.ops4j.pax.swissbox.core.BundleClassLoader.loadClass(BundleClassLoader.java:192) ~[bundleFile:?]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[?:?]
        at java.lang.Class.forName0(Native Method) ~[?:?]
        at java.lang.Class.forName(Class.java:398) ~[?:?]
        at jdk.nashorn.internal.runtime.Context.findClass(Context.java:1180) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.objects.NativeJava.simpleType(NativeJava.java:546) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.objects.NativeJava.type(NativeJava.java:326) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.objects.NativeJava.type(NativeJava.java:318) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.objects.NativeJava.type(NativeJava.java:314) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.scripts.Script$Recompilation$41$16A$actions$cu1$restOf.L:3(file:/c:/openhab/conf/automation/lib/javascript/core/actions.js:23) ~[?:?]
        at jdk.nashorn.internal.scripts.Script$Recompilation$39$actions.:program(file:/c:/openhab/conf/automation/lib/javascript/core/actions.js:3) ~[?:?]
        at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:655) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:527) ~[jdk.scripting.nashorn:?]
        ... 73 more
19:16:24.465 [DEBUG] [re.automation.internal.RuleEngineImpl] - The rule '71a2abce18' is executed.

This is my developing Windows 10 computer but same happen on linux openhab server…

Im try sendNotification with official 3.0.0M2(Installed from UI) and 3.0.0.SNAPSHOT(Installed manualy) on linux server and on windows pc and it crash wirh ClassNotFoundException …

Im also myself modify and build openhabcloud addon from sources and make it simple for debuging only and make it by new RuleAction way like in Mail or other addons but still didn’t work…
NotificationAction.java:

/**
 * Copyright (c) 2010-2020 Contributors to the openHAB project
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package org.openhab.io.openhabcloud;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.annotation.ActionInput;
import org.openhab.core.automation.annotation.ActionOutput;
import org.openhab.core.automation.annotation.RuleAction;
import org.openhab.core.thing.binding.ThingActions;
import org.openhab.core.thing.binding.ThingActionsScope;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.io.openhabcloud.internal.CloudHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class provides static methods that can be used in automation rules
 * for sending notifications to the native apps.
 *
 * @author Victor Belov - Initial contribution
 * @author Kai Kreuzer - migrated code to ESH APIs
 *
 */

@ThingActionsScope(name = "openhabcloud")
@NonNullByDefault
public class NotificationAction implements ThingActions {

    private static final Logger logger = LoggerFactory.getLogger(NotificationAction.class);

    private @Nullable CloudHandler handler;

    @RuleAction(label = "send a push message", description = "Sends a push message.")
    public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendNotification(
            @ActionInput(name = "userId") @Nullable String userId,
            @ActionInput(name = "message") @Nullable String message) {
        return sendNotification(userId, message, null, null);
    }

    @RuleAction(label = "send a push message", description = "Sends a push message.")
    public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendNotification(
            @ActionInput(name = "userId") @Nullable String userId,
            @ActionInput(name = "message") @Nullable String message, @ActionInput(name = "icon") @Nullable String icon,
            @ActionInput(name = "severity") @Nullable String severity) {

        if (userId == null) {
            logger.warn("Cannot send push message as userId is missing.");
            return false;
        }

        if (message == null) {
            logger.warn("Cannot send push message as message is missing.");
            return false;
        }

        try {

            final CloudHandler handler = this.handler;
            if (handler == null) {
                logger.info("Handler is null, cannot send push message.");
                return false;
            } else {
                logger.info("Push Message is send.");
                return true; // handler.sendMail(builder.build());
            }
        } catch (Exception e) {
            logger.warn("Could not send notification: {}", e.getMessage());
            return false;
        }
    }

    @Override
    public void setThingHandler(@Nullable ThingHandler handler) {
        if (handler instanceof CloudHandler) {
            this.handler = (CloudHandler) handler;
        }
    }

    @Override
    public @Nullable ThingHandler getThingHandler() {
        return handler;
    }
}

CloudHandler.java

package org.openhab.io.openhabcloud.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@NonNullByDefault
public class CloudHandler extends BaseThingHandler {

    private final Logger logger = LoggerFactory.getLogger(CloudHandler.class);

    public CloudHandler(Thing thing) {
        super(thing);
    }

    @Override
    public void handleCommand(ChannelUID channelUID, Command command) {
    }

    @Override
    public void initialize() {

        updateStatus(ThingStatus.ONLINE);
    }
}

Hmmm, I thought there was an update to the libraries for that. The LogAction changed names to Log. You can get past this error by editing actions.js and change LogAction to Log.

Does the notify action work if you write a Script Action using Rule DSL? I think sending a notification should be one of the options for choosing an Action for the rule which would not involve writing any code. Is it there? Does it work when you select it?

There is nothing to type or import and the like to use it in Rules DSL. If it doesn’t even work there then something else outside of the rules is the source of the problem.

Im on middle updating windows openhab server to latest snapshot to test if there has been some problem with M1 and M2 version and ECMA scripts and already fixed…
Im try Rule DSL on my linux openhab server and it work.

Sending script:

sendNotification("EMAIL", "This is a directed notification");

Log:

2020-11-09 18:48:46.939 [DEBUG] [b.io.openhabcloud.NotificationAction] - sending notification 'This is a directed notification' to user EMAIL
2020-11-09 18:48:46.940 [DEBUG] [o.openhabcloud.internal.CloudService] - Sending message 'This is a directed notification' to user id EMAIL

Script run normaly and I receive notification on mobile phone…