JanK
(Jan K)
January 8, 2023, 1:00pm
1
Hi everyone,
the REST endpoint /rules/{ruleUID}/runnow
includes in the API explorer by default a payload.
What is the payload for? Is it possible to use the data inside the rule?
Thank you for reading this and helping me!
Kind regards
Jan
More details:
I tried this demo rule:
rules.JSRule({
name: "Test",
id:"Test",
triggers: [
triggers.ItemStateChangeTrigger("no-item", "ON", "OFF"),
],
description: "Regel schreibt nur einen Log-Eintrag",
execute: (data) => {
logger.info('Test: ' + JSON.stringify(data));
}
});
and send this request:
curl -X 'POST' \
'http://<openhab>/rest/rules/Test/runnow' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
}'
The result is
2023-01-08 13:48:09.751 [INFO ] [.openhab.automation.openhab-js.rules] - Adding rule: Test
2023-01-08 13:48:09.758 [WARN ] [dule.handler.ItemStateTriggerHandler] - Item 'no-item' needed for rule 'Test' is missing. Trigger 'c9d744a8-dc24-49ea-a070-6f389793b375' will not work.
2023-01-08 13:48:23.472 [INFO ] [tomation.openhab-js.rules_nachtlicht] - Test: {}
Notes:
I only tried JS rules here, but if required I can use another Rule engine.
Triggering the rule with a ItemChange Trigger sets some data to the rule parameter.
The trigger in this JS rule is another hack to create rule without trigger. Creating no trigger, prevents the creation of a rule.
Using a valid trigger does not change the result regarding this question.
Platform information:
Hardware: RPi4
OS: OpenHABian
openHAB version: 3.4
rlkoshak
(Rich Koshak)
January 9, 2023, 2:29pm
2
Are you referring to the context (i.e. the request body)?
That is a way to pass name/value pairs to the called rule. In the UI for JS Scripting, they are made available under context
. In other rule languages it appears differently (e.g. Nashorn they appear under this
, in Rules DSL they just appear as variables).
See also rules - Documentation
You should be able to use triggers: [],
. If that doesn’t work, please file an issue on the openhab-js repo.
JanK
(Jan K)
January 9, 2023, 6:15pm
3
Thank you @rlkoshak for your help.
I try to use the payload of the POST request. In my example it is the object:
{
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
}
But I cannot figure out how to get the context of the rule. this.ctx
seems empty and context
does not exist.
I also tried a UI based rule with no success.
configuration: {}
triggers: []
conditions: []
actions:
- inputs: {}
id: "1"
configuration:
type: application/javascript;version=ECMAScript-2021
script: |-
var logger = log('rules_demo');
logger.info('Empty: ' + JSON.stringify( Object.keys(this.ctx.values)));
logger.info('Doe not exist: ' + JSON.stringify(context));
type: script.ScriptAction
I will do that after some tests with a fresh OH installation.
rlkoshak
(Rich Koshak)
January 9, 2023, 6:56pm
4
I’m not sure whether/how the data is accessible from text based JS Scripting rules.
And I was remembering incorrectly. In Nashorn JS the variables are under context
. In JS Scripting the variables are just there. So you would access the value of “additionalProp1” just using additionalProp1
in the rule. That definitely works in UI scripts.
NOTE: There’s no JSON. There’s no parsing. You don’t get a long String. Each name/value pair becomes a separate variable. This is the REST API interface to a standard mechanism built into core.
Here’s a JS Scripting script I’m working on that triggers when a Thing changes status in a predefined way and calls another rule to process it.
console.loggerName = 'org.openhab.automation.rules_tools.Thing Status';
console.debug('ThingStatusInfoChangedEvent:' + event.toString());
var parsed = JSON.parse(event.payload);
var data = {};
data['thingID'] = event.topic.split('/')[2];;
data['thing'] = things.getThing(data['thingID']);
data['oldStatus'] = parsed[1].status;
data['oldDetail'] = parsed[1].statusDetail;
data['newStatus'] = parsed[0].status;
data['newDetail'] = parsed[0].statusDetail;
rules.runRule("thing_status_handler_new", data, true);
The script in the thing_status_handler
rule:
console.log('Thing ID: ' + thingID);
console.log('Old Status: ' + oldStatus + '(' + oldDetail + ')');
console.log('New Status: ' + newStatus + '(' + newDetail + ')');
console.log('Thing: ' + thing.toString());
console.log('Thing Status : ' + thing.status);
console.log('Raw Thing from JS Thing: ' + thing.rawThing.getUID());
JanK
(Jan K)
January 9, 2023, 9:24pm
5
Hi @rlkoshak
Thank you very much!
That works with the REST request as well and I can write my rules using the UI.
Having all rules in the same place/as files would be nice but it is a good solution.
For someone else who is trying the same, my last test rule was:
configuration: {}
triggers: []
conditions: []
actions:
- inputs: {}
id: "1"
configuration:
type: application/javascript;version=ECMAScript-2021
script: |-
var logger = log('rules_demo');
logger.info('additionalProp1: ' + JSON.stringify(additionalProp1));
type: script.ScriptAction
and my REST request is
curl -X 'POST' \
'http://<openhab>/rest/rules/008a6dc2cd/runnow' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"additionalProp1": "Demo Text"
}'
This will print
[INFO ] [hab.automation.openhab-js.rules_demo] - additionalProp1: "Demo Text""
rlkoshak
(Rich Koshak)
January 9, 2023, 9:34pm
6
I think the JSON.stringify
is redundant. You should be able to just use
logger.info('additionalProp1: ' + additionalProp1)