[jsscripting] Upgrade openhab-js & Remove SharedCache (#13908)
Upgrades the included openhab-js version to 3.1.0, which uses the new caches from core (introduced in https://github.com/openhab/openhab-core/pull/2887) and provides many doc improvements. Removes the SharedCache from the addon because this functionality is now provided by core (see https://github.com/openhab/openhab-core/pull/2887). Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
This commit is contained in:
parent
506c7387c5
commit
438552d485
@ -82,7 +82,7 @@ actions.NotificationAction.sendNotification("romeo@montague.org", "Balcony door
|
|||||||
Querying the status of a thing
|
Querying the status of a thing
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const thingStatusInfo = actions.Things.getThingStatusInfo("zwave:serial_zstick:512");
|
var thingStatusInfo = actions.Things.getThingStatusInfo("zwave:serial_zstick:512");
|
||||||
console.log("Thing status",thingStatusInfo.getStatus());
|
console.log("Thing status",thingStatusInfo.getStatus());
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -124,32 +124,34 @@ console.log(event.itemState.toString() == "test") // OK
|
|||||||
|
|
||||||
## Scripting Basics
|
## Scripting Basics
|
||||||
|
|
||||||
The openHAB JSScripting runtime attempts to provide a familiar environment to Javascript developers.
|
The openHAB JavaScript Scripting runtime attempts to provide a familiar environment to JavaScript developers.
|
||||||
|
|
||||||
### Require
|
### Require
|
||||||
|
|
||||||
Scripts may include standard NPM based libraries by using CommonJS `require`.
|
Scripts may include standard NPM based libraries by using CommonJS `require`.
|
||||||
The library search will look in the path `automation/js/node_modules` in the user configuration directory.
|
The library search will look in the path `automation/js/node_modules` in the user configuration directory.
|
||||||
|
See [libraries](#libraries) for more information.
|
||||||
|
|
||||||
### Console
|
### Console
|
||||||
|
|
||||||
The JS Scripting binding supports the standard `console` object for logging.
|
The JS Scripting binding supports the standard `console` object for logging.
|
||||||
Script debug logging is enabled by default at the `INFO` level, but can be configured using the console logging commands.
|
Script logging is enabled by default at the `INFO` level (messages from `console.debug` and `console.trace` won't be displayed), but can be configured using the [openHAB console](https://www.openhab.org/docs/administration/console.html):
|
||||||
|
|
||||||
```text
|
```text
|
||||||
log:set DEBUG org.openhab.automation.script
|
log:set DEBUG org.openhab.automation.script
|
||||||
|
log:set TRACE org.openhab.automation.script
|
||||||
|
log:set DEFAULT org.openhab.automation.script
|
||||||
```
|
```
|
||||||
|
|
||||||
The default logger name prefix is `org.openhab.automation.script`, this can be changed by assigning a new string to the `loggerName` property of the console.
|
The default logger name prefix is `org.openhab.automation.script`, this can be changed by assigning a new string to the `loggerName` property of the console:
|
||||||
|
|
||||||
Please be aware that messages might not appear in the logs if the logger name does not start with `org.openhab`.
|
|
||||||
This behaviour is due to [log4j2](https://logging.apache.org/log4j/2.x/) requiring definition for each logger prefix.
|
|
||||||
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
console.loggerName = "org.openhab.custom"
|
console.loggerName = 'org.openhab.custom';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Please be aware that messages do not appear in the logs if the logger name does not start with `org.openhab`.
|
||||||
|
This behaviour is due to [log4j2](https://logging.apache.org/log4j/2.x/) requiring a setting for each logger prefix in `$OPENHAB_USERDATA/etc/log4j2.xml` (on openHABian: `/srv/openhab-userdata/etc/log4j2.xml`).
|
||||||
|
|
||||||
Supported logging functions include:
|
Supported logging functions include:
|
||||||
|
|
||||||
- `console.log(obj1 [, obj2, ..., objN])`
|
- `console.log(obj1 [, obj2, ..., objN])`
|
||||||
@ -164,11 +166,13 @@ The string representations of each of these objects are appended together in the
|
|||||||
|
|
||||||
See <https://developer.mozilla.org/en-US/docs/Web/API/console> for more information about console logging.
|
See <https://developer.mozilla.org/en-US/docs/Web/API/console> for more information about console logging.
|
||||||
|
|
||||||
|
Note: [openhab-js](https://github.com/openhab/openhab-js/) is logging to `org.openhab.automation.openhab-js`.
|
||||||
|
|
||||||
### Timers
|
### Timers
|
||||||
|
|
||||||
JS Scripting provides access to the global `setTimeout`, `setInterval`, `clearTimeout` and `clearInterval` methods specified in the [Web APIs](https://developer.mozilla.org/en-US/docs/Web/API).
|
JS Scripting provides access to the global `setTimeout`, `setInterval`, `clearTimeout` and `clearInterval` methods specified in the [Web APIs](https://developer.mozilla.org/en-US/docs/Web/API).
|
||||||
|
|
||||||
When a script is unloaded, all created timers and intervals are automatically cancelled.
|
When a script is unloaded, all created timeouts and intervals are automatically cancelled.
|
||||||
|
|
||||||
#### SetTimeout
|
#### SetTimeout
|
||||||
|
|
||||||
@ -243,10 +247,49 @@ For [file based rules](#file-based-rules), scripts will be loaded from `automati
|
|||||||
|
|
||||||
NPM libraries will be loaded from `automation/js/node_modules` in the user configuration directory.
|
NPM libraries will be loaded from `automation/js/node_modules` in the user configuration directory.
|
||||||
|
|
||||||
|
### Deinitialization Hook
|
||||||
|
|
||||||
|
It is possible to hook into unloading of a script and register a function that is called when the script is unloaded.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
require('@runtime').lifecycleTracker.addDisposeHook(() => functionToCall());
|
||||||
|
|
||||||
|
// Example
|
||||||
|
require('@runtime').lifecycleTracker.addDisposeHook(() => {
|
||||||
|
console.log("Deinitialization hook runs...")
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## `SCRIPT` Transformation
|
||||||
|
|
||||||
|
openHAB provides several [data transformation services](https://www.openhab.org/addons/#transform) as well as the `SCRIPT` transformation, that is available from the framework and needs no additional installation.
|
||||||
|
It allows transforming values using any of the available scripting languages, which means JavaScript Scripting is supported as well.
|
||||||
|
See the [transformation docs](https://openhab.org/docs/configuration/transformations.html#script-transformation) for more general information on the usage of `SCRIPT` transformation.
|
||||||
|
|
||||||
|
Use the `SCRIPT` transformation with JavaScript Scripting by:
|
||||||
|
|
||||||
|
1. Creating a script in the `$OPENHAB_CONF/transform` folder with the `.script` extension.
|
||||||
|
The script should take one argument `input` and return a value that supports `toString()` or `null`:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
(function(data) {
|
||||||
|
// Do some data transformation here
|
||||||
|
return data;
|
||||||
|
})(input);
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Using `SCRIPT(graaljs:<scriptname>.script):%s` as the transformation profile, e.g. on an Item.
|
||||||
|
3. Passing parameters is also possible by using a URL like syntax: `SCRIPT(graaljs:<scriptname>.script?arg=value):%s`.
|
||||||
|
Parameters are injected into the script and can be referenced like variables.
|
||||||
|
|
||||||
## Standard Library
|
## Standard Library
|
||||||
|
|
||||||
Full documentation for the openHAB JavaScript library can be found at [openhab-js](https://openhab.github.io/openhab-js).
|
Full documentation for the openHAB JavaScript library can be found at [openhab-js](https://openhab.github.io/openhab-js).
|
||||||
|
|
||||||
|
The openHAB JavaScript library provides type definitions for most of its APIs to enable code completion is IDEs like [VS Code](https://code.visualstudio.com).
|
||||||
|
To use the type definitions, install the [`openhab` npm package](https://npmjs.com/openhab) (read the [installation guide](https://github.com/openhab/openhab-js#custom-installation) for more information).
|
||||||
|
If an API does not provide type definitions and therefore autocompletion won‘t work, the documentation will include a note.
|
||||||
|
|
||||||
### Items
|
### Items
|
||||||
|
|
||||||
The items namespace allows interactions with openHAB items.
|
The items namespace allows interactions with openHAB items.
|
||||||
@ -263,7 +306,7 @@ See [openhab-js : items](https://openhab.github.io/openhab-js/items.html) for fu
|
|||||||
- .safeItemName(s) ⇒ `string`
|
- .safeItemName(s) ⇒ `string`
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const item = items.getItem("KitchenLight");
|
var item = items.getItem("KitchenLight");
|
||||||
console.log("Kitchen Light State", item.state);
|
console.log("Kitchen Light State", item.state);
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -298,12 +341,12 @@ Calling `getItem(...)` returns an `Item` object with the following properties:
|
|||||||
- .removeTags(...tagNames)
|
- .removeTags(...tagNames)
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const item = items.getItem("KitchenLight");
|
var item = items.getItem("KitchenLight");
|
||||||
//send an ON command
|
// Send an ON command
|
||||||
item.sendCommand("ON");
|
item.sendCommand("ON");
|
||||||
//Post an update
|
// Post an update
|
||||||
item.postUpdate("OFF");
|
item.postUpdate("OFF");
|
||||||
//Get state
|
// Get state
|
||||||
console.log("KitchenLight state", item.state)
|
console.log("KitchenLight state", item.state)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -439,7 +482,7 @@ Calling `getThing(...)` returns a `Thing` object with the following properties:
|
|||||||
- .setEnabled(enabled)
|
- .setEnabled(enabled)
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const thing = things.getThing('astro:moon:home');
|
var thing = things.getThing('astro:moon:home');
|
||||||
console.log('Thing label: ' + thing.label);
|
console.log('Thing label: ' + thing.label);
|
||||||
// Set Thing location
|
// Set Thing location
|
||||||
thing.setLocation('living room');
|
thing.setLocation('living room');
|
||||||
@ -452,6 +495,8 @@ thing.setEnabled(false);
|
|||||||
The actions namespace allows interactions with openHAB actions.
|
The actions namespace allows interactions with openHAB actions.
|
||||||
The following are a list of standard actions.
|
The following are a list of standard actions.
|
||||||
|
|
||||||
|
Note that most of the actions currently do **not** provide type definitions and therefore auto-completion does not work.
|
||||||
|
|
||||||
See [openhab-js : actions](https://openhab.github.io/openhab-js/actions.html) for full API documentation and additional actions.
|
See [openhab-js : actions](https://openhab.github.io/openhab-js/actions.html) for full API documentation and additional actions.
|
||||||
|
|
||||||
#### Audio Actions
|
#### Audio Actions
|
||||||
@ -472,7 +517,7 @@ Additional information can be found on the [Ephemeris Actions Docs](https://www
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// Example
|
// Example
|
||||||
let weekend = actions.Ephemeris.isWeekend();
|
var weekend = actions.Ephemeris.isWeekend();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Exec Actions
|
#### Exec Actions
|
||||||
@ -487,11 +532,11 @@ Execute a command line.
|
|||||||
actions.Exec.executeCommandLine('echo', 'Hello World!');
|
actions.Exec.executeCommandLine('echo', 'Hello World!');
|
||||||
|
|
||||||
// Execute command line with timeout.
|
// Execute command line with timeout.
|
||||||
let Duration = Java.type('java.time.Duration');
|
var Duration = Java.type('java.time.Duration');
|
||||||
actions.Exec.executeCommandLine(Duration.ofSeconds(20), 'echo', 'Hello World!');
|
actions.Exec.executeCommandLine(Duration.ofSeconds(20), 'echo', 'Hello World!');
|
||||||
|
|
||||||
// Get response from command line.
|
// Get response from command line.
|
||||||
let response = actions.Exec.executeCommandLine('echo', 'Hello World!');
|
var response = actions.Exec.executeCommandLine('echo', 'Hello World!');
|
||||||
|
|
||||||
// Get response from command line with timeout.
|
// Get response from command line with timeout.
|
||||||
response = actions.Exec.executeCommandLine(Duration.ofSeconds(20), 'echo', 'Hello World!');
|
response = actions.Exec.executeCommandLine(Duration.ofSeconds(20), 'echo', 'Hello World!');
|
||||||
@ -515,6 +560,9 @@ The `ScriptExecution` actions provide the `callScript(string scriptName)` method
|
|||||||
You can also create timers using the [native JS methods for timer creation](#timers), your choice depends on the versatility you need.
|
You can also create timers using the [native JS methods for timer creation](#timers), your choice depends on the versatility you need.
|
||||||
Sometimes, using `setTimer` is much faster and easier, but other times, you need the versatility that `createTimer` provides.
|
Sometimes, using `setTimer` is much faster and easier, but other times, you need the versatility that `createTimer` provides.
|
||||||
|
|
||||||
|
Keep in mind that you should somehow manage the timers you create using `createTimer`, otherwise you could end up with unmanagable timers running until you restart openHAB.
|
||||||
|
A possible solution is to store all timers in an array and cancel all timers in the [Deinitialization Hook](#deinitialization-hook).
|
||||||
|
|
||||||
##### `createTimer`
|
##### `createTimer`
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -566,12 +614,24 @@ See [openhab-js : actions.ScriptExecution](https://openhab.github.io/openhab-js/
|
|||||||
|
|
||||||
See [openhab-js : actions.Semantics](https://openhab.github.io/openhab-js/actions.html#.Semantics) for complete documentation.
|
See [openhab-js : actions.Semantics](https://openhab.github.io/openhab-js/actions.html#.Semantics) for complete documentation.
|
||||||
|
|
||||||
#### Things Actions
|
#### Thing Actions
|
||||||
|
|
||||||
It is possible to get the actions for a Thing using `actions.Things.getActions(bindingId, thingUid)`, e.g. `actions.Things.getActions('network', 'network:pingdevice:pc')`.
|
It is possible to get the actions for a Thing using `actions.Things.getActions(bindingId, thingUid)`, e.g. `actions.Things.getActions('network', 'network:pingdevice:pc')`.
|
||||||
|
|
||||||
See [openhab-js : actions.Things](https://openhab.github.io/openhab-js/actions.html#.Things) for complete documentation.
|
See [openhab-js : actions.Things](https://openhab.github.io/openhab-js/actions.html#.Things) for complete documentation.
|
||||||
|
|
||||||
|
#### Transformation Actions
|
||||||
|
|
||||||
|
openHAB provides various [data transformation services](https://www.openhab.org/addons/#transform) which can translate between technical and human-readable values.
|
||||||
|
Usually, they are used directly on Items, but it is also possible to access them from scripts.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
console.log(actions.Transformation.transform('MAP', 'en.map', 'OPEN')); // open
|
||||||
|
console.log(actions.Transformation.transform('MAP', 'de.map', 'OPEN')); // offen
|
||||||
|
```
|
||||||
|
|
||||||
|
See [openhab-js : actions.Transformation](https://openhab.github.io/openhab-js/actions.Transformation.html) for complete documentation.
|
||||||
|
|
||||||
#### Voice Actions
|
#### Voice Actions
|
||||||
|
|
||||||
See [openhab-js : actions.Voice](https://openhab.github.io/openhab-js/actions.html#.Voice) for complete documentation.
|
See [openhab-js : actions.Voice](https://openhab.github.io/openhab-js/actions.html#.Voice) for complete documentation.
|
||||||
@ -595,11 +655,25 @@ Replace `<message>` with the notification text.
|
|||||||
|
|
||||||
### Cache
|
### Cache
|
||||||
|
|
||||||
The cache namespace provides a default cache that can be used to set and retrieve objects that will be persisted between reloads of scripts.
|
The cache namespace provides both a private and a shared cache that can be used to set and retrieve objects that will be persisted between subsequent runs of the same or between scripts.
|
||||||
|
|
||||||
|
The private cache can only be accessed by the same script and is cleared when the script is unloaded.
|
||||||
|
You can use it to e.g. store timers or counters between subsequent runs of that script.
|
||||||
|
When a script is unloaded and its cache is cleared, all timers (see [ScriptExecution Actions](#scriptexecution-actions)) stored in its private cache are cancelled.
|
||||||
|
|
||||||
|
The shared cache is shared across all rules and scripts, it can therefore be accessed from any automation language.
|
||||||
|
The access to every key is tracked and the key is removed when all scripts that ever accessed that key are unloaded.
|
||||||
|
If that key stored a timer, the timer is cancelled.
|
||||||
|
|
||||||
See [openhab-js : cache](https://openhab.github.io/openhab-js/cache.html) for full API documentation.
|
See [openhab-js : cache](https://openhab.github.io/openhab-js/cache.html) for full API documentation.
|
||||||
|
|
||||||
- cache : <code>object</code>
|
- cache : <code>object</code>
|
||||||
|
- .private
|
||||||
|
- .get(key, defaultSupplier) ⇒ <code>Object | null</code>
|
||||||
|
- .put(key, value) ⇒ <code>Previous Object | null</code>
|
||||||
|
- .remove(key) ⇒ <code>Previous Object | null</code>
|
||||||
|
- .exists(key) ⇒ <code>boolean</code>
|
||||||
|
- .shared
|
||||||
- .get(key, defaultSupplier) ⇒ <code>Object | null</code>
|
- .get(key, defaultSupplier) ⇒ <code>Object | null</code>
|
||||||
- .put(key, value) ⇒ <code>Previous Object | null</code>
|
- .put(key, value) ⇒ <code>Previous Object | null</code>
|
||||||
- .remove(key) ⇒ <code>Previous Object | null</code>
|
- .remove(key) ⇒ <code>Previous Object | null</code>
|
||||||
@ -607,22 +681,22 @@ See [openhab-js : cache](https://openhab.github.io/openhab-js/cache.html) for fu
|
|||||||
|
|
||||||
The `defaultSupplier` provided function will return a default value if a specified key is not already associated with a value.
|
The `defaultSupplier` provided function will return a default value if a specified key is not already associated with a value.
|
||||||
|
|
||||||
**Example** *(Get a previously set value with a default value (times = 0))*
|
**Example** *(Get a previously set value with a default value (times = 0))*
|
||||||
|
|
||||||
```js
|
```js
|
||||||
let counter = cache.get("counter", () => ({ "times": 0 }));
|
var counter = cache.private.get('counter', () => ({ 'times': 0 }));
|
||||||
console.log("Count",counter.times++);
|
console.log('Count', counter.times++);
|
||||||
```
|
```
|
||||||
|
|
||||||
**Example** *(Get a previously set object)*
|
**Example** *(Get a previously set object)*
|
||||||
|
|
||||||
```js
|
```js
|
||||||
let counter = cache.get("counter");
|
var counter = cache.private.get('counter');
|
||||||
if(counter == null){
|
if (counter === null) {
|
||||||
counter = {times: 0};
|
counter = { times: 0 };
|
||||||
cache.put("counter", counter);
|
cache.private.put('counter', counter);
|
||||||
}
|
}
|
||||||
console.log("Count",counter.times++);
|
console.log('Count', counter.times++);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Log
|
### Log
|
||||||
@ -631,7 +705,7 @@ By default, the JS Scripting binding supports console logging like `console.log(
|
|||||||
Additionally, scripts may create their own native openHAB logger using the log namespace.
|
Additionally, scripts may create their own native openHAB logger using the log namespace.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
let logger = log('my_logger');
|
var logger = log('my_logger');
|
||||||
|
|
||||||
//prints "Hello World!"
|
//prints "Hello World!"
|
||||||
logger.debug("Hello {}!", "world");
|
logger.debug("Hello {}!", "world");
|
||||||
@ -690,7 +764,7 @@ When you have a `time.ZonedDateTime`, a new `toToday()` method was added which w
|
|||||||
For example, if the time was 13:45 and today was a DST changeover, the time will still be 13:45 instead of one hour off.
|
For example, if the time was 13:45 and today was a DST changeover, the time will still be 13:45 instead of one hour off.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const alarm = items.getItem('Alarm');
|
var alarm = items.getItem('Alarm');
|
||||||
alarm.postUpdate(time.toZDT(alarm).toToday());
|
alarm.postUpdate(time.toZDT(alarm).toToday());
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -714,7 +788,7 @@ time.toZDT(items.getItem('StartTime')).isBetweenTimes(time.toZDT(), 'PT1H'); //
|
|||||||
Tests to see if the delta between the `time.ZonedDateTime` and the passed in `time.ZonedDateTime` is within the passed in `time.Duration`.
|
Tests to see if the delta between the `time.ZonedDateTime` and the passed in `time.ZonedDateTime` is within the passed in `time.Duration`.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const timestamp = time.toZDT();
|
var timestamp = time.toZDT();
|
||||||
// do some stuff
|
// do some stuff
|
||||||
if(timestamp.isClose(time.toZDT(), time.Duration.ofMillis(100))) {
|
if(timestamp.isClose(time.toZDT(), time.Duration.ofMillis(100))) {
|
||||||
// did "do some stuff" take longer than 100 msecs to run?
|
// did "do some stuff" take longer than 100 msecs to run?
|
||||||
@ -726,7 +800,7 @@ if(timestamp.isClose(time.toZDT(), time.Duration.ofMillis(100))) {
|
|||||||
This method on `time.ZonedDateTime` returns the milliseconds from now to the passed in `time.ZonedDateTime`.
|
This method on `time.ZonedDateTime` returns the milliseconds from now to the passed in `time.ZonedDateTime`.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const timestamp = time.ZonedDateTime.now().plusMinutes(5);
|
var timestamp = time.ZonedDateTime.now().plusMinutes(5);
|
||||||
console.log(timestamp.getMillisFromNow());
|
console.log(timestamp.getMillisFromNow());
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -752,7 +826,7 @@ See [openhab-js : rules](https://openhab.github.io/openhab-js/rules.html) for fu
|
|||||||
JSRules provides a simple, declarative syntax for defining rules that will be executed based on a trigger condition
|
JSRules provides a simple, declarative syntax for defining rules that will be executed based on a trigger condition
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const email = "juliet@capulet.org"
|
var email = "juliet@capulet.org"
|
||||||
|
|
||||||
rules.JSRule({
|
rules.JSRule({
|
||||||
name: "Balcony Lights ON at 5pm",
|
name: "Balcony Lights ON at 5pm",
|
||||||
@ -846,6 +920,8 @@ rules.when().item("F1_light").changed().then(event => {
|
|||||||
}).build("Test Rule", "My Test Rule");
|
}).build("Test Rule", "My Test Rule");
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note that the Rule Builder currently does **not** provide type definitions and therefore auto-completion does not work.
|
||||||
|
|
||||||
See [Examples](#rule-builder-examples) for further patterns.
|
See [Examples](#rule-builder-examples) for further patterns.
|
||||||
|
|
||||||
#### Rule Builder Triggers
|
#### Rule Builder Triggers
|
||||||
@ -884,7 +960,7 @@ See [Examples](#rule-builder-examples) for further patterns.
|
|||||||
- `from(state)`
|
- `from(state)`
|
||||||
- `to(state)`
|
- `to(state)`
|
||||||
|
|
||||||
Additionally all the above triggers have the following functions:
|
Additionally, all the above triggers have the following functions:
|
||||||
|
|
||||||
- `.if()` or `.if(fn)` -> a [rule condition](#rule-builder-conditions)
|
- `.if()` or `.if(fn)` -> a [rule condition](#rule-builder-conditions)
|
||||||
- `.then()` or `.then(fn)` -> a [rule operation](#rule-builder-operations)
|
- `.then()` or `.then(fn)` -> a [rule operation](#rule-builder-operations)
|
||||||
@ -979,31 +1055,56 @@ Time triggers do not provide any event instance, therefore no property is popula
|
|||||||
|
|
||||||
See [openhab-js : EventObject](https://openhab.github.io/openhab-js/rules.html#.EventObject) for full API documentation.
|
See [openhab-js : EventObject](https://openhab.github.io/openhab-js/rules.html#.EventObject) for full API documentation.
|
||||||
|
|
||||||
### Initialization hook: scriptLoaded
|
|
||||||
|
|
||||||
For file based scripts, this function will be called if found when the script is loaded.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
scriptLoaded = function () {
|
|
||||||
console.log("script loaded");
|
|
||||||
loadedDate = Date.now();
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### Deinitialization hook: scriptUnloaded
|
|
||||||
|
|
||||||
For file based scripts, this function will be called if found when the script is unloaded.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
scriptUnloaded = function () {
|
|
||||||
console.log("script unloaded");
|
|
||||||
// clean up rouge timers
|
|
||||||
clearInterval(timer);
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Advanced Scripting
|
## Advanced Scripting
|
||||||
|
|
||||||
|
### Libraries
|
||||||
|
|
||||||
|
#### Third Party Libraries
|
||||||
|
|
||||||
|
Loading of third party libraries is supported the same way as loading the openHAB JavaScript library:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var myLibrary = require('my-library');
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: Only CommonJS `require` is supported, ES module loading using `import` is not supported.
|
||||||
|
|
||||||
|
Run the `npm` command from the `automation/js` folder to install third party libraries, e.g. from [npm](https://www.npmjs.com/search?q=openhab).
|
||||||
|
This will create a `node_modules` folder (if it doesn't already exist) and install the library and it's dependencies there.
|
||||||
|
|
||||||
|
There are already some openHAB specific libraries available on [npm](https://www.npmjs.com/search?q=openhab), you may also search the forum for details.
|
||||||
|
|
||||||
|
#### Creating Your Own Library
|
||||||
|
|
||||||
|
You can also create your own personal JavaScript library for openHAB, but you can not just create a folder in `node_modules` and put your library code in it!
|
||||||
|
When it is run, `npm` will remove everything from `node_modules` that has not been properly installed.
|
||||||
|
|
||||||
|
Follow these steps to create your own library (it's called a CommonJS module):
|
||||||
|
|
||||||
|
1. Create a separate folder for your library outside of `automation/js`, you may also initialize a Git repository.
|
||||||
|
2. Run `npm init` from your newly created folder; at least provide responses for the `name`, `version` and `main` (e.g. `index.js`) fields.
|
||||||
|
3. Create the main file of your library (`index.js`) and add some exports:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var someProperty = 'Hello world!';
|
||||||
|
function someFunction () {
|
||||||
|
console.log('Hello from your personal library!');
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
someProperty,
|
||||||
|
someFunction
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Tar it up by running `npm pack` from your library's folder.
|
||||||
|
5. Install it by running `npm install <name>-<version>.tgz` from the `automation/js` folder.
|
||||||
|
6. After you've installed it with `npm`, you can continue development of the library inside `node_modules`.
|
||||||
|
|
||||||
|
It is also possible to upload your library to [npm](https://npmjs.com) to share it with other users.
|
||||||
|
|
||||||
|
If you want to get some advanced information, you can read [this blog post](https://bugfender.com/blog/how-to-create-an-npm-package/) or just google it.
|
||||||
|
|
||||||
### @runtime
|
### @runtime
|
||||||
|
|
||||||
One can access many useful utilities and types using `require("@runtime")`, e.g.
|
One can access many useful utilities and types using `require("@runtime")`, e.g.
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
<graal.version>22.0.0.2</graal.version> <!-- DO NOT UPGRADE: 22.0.0.2 is the latest version working on armv7l / OpenJDK 11.0.16 -->
|
<graal.version>22.0.0.2</graal.version> <!-- DO NOT UPGRADE: 22.0.0.2 is the latest version working on armv7l / OpenJDK 11.0.16 -->
|
||||||
<asm.version>6.2.1</asm.version>
|
<asm.version>6.2.1</asm.version>
|
||||||
<oh.version>${project.version}</oh.version>
|
<oh.version>${project.version}</oh.version>
|
||||||
<ohjs.version>openhab@2.1.1</ohjs.version>
|
<ohjs.version>openhab@3.1.2</ohjs.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@ -1,101 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2010-2022 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.automation.jsscripting.internal.scope;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
import org.openhab.core.automation.module.script.ScriptExtensionProvider;
|
|
||||||
import org.osgi.service.component.annotations.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shared Cache implementation for JS scripting.
|
|
||||||
*
|
|
||||||
* @author Jonathan Gilbert - Initial contribution
|
|
||||||
*/
|
|
||||||
@Component(immediate = true)
|
|
||||||
@NonNullByDefault
|
|
||||||
public class SharedCache implements ScriptExtensionProvider {
|
|
||||||
|
|
||||||
private static final String PRESET_NAME = "cache";
|
|
||||||
private static final String OBJECT_NAME = "sharedcache";
|
|
||||||
|
|
||||||
private JSCache cache = new JSCache();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<String> getDefaultPresets() {
|
|
||||||
return Set.of(PRESET_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<String> getPresets() {
|
|
||||||
return Set.of(PRESET_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<String> getTypes() {
|
|
||||||
return Set.of(OBJECT_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable Object get(String scriptIdentifier, String type) throws IllegalArgumentException {
|
|
||||||
if (OBJECT_NAME.equals(type)) {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> importPreset(String scriptIdentifier, String preset) {
|
|
||||||
if (PRESET_NAME.equals(preset)) {
|
|
||||||
final Object requestedType = get(scriptIdentifier, OBJECT_NAME);
|
|
||||||
if (requestedType != null) {
|
|
||||||
return Map.of(OBJECT_NAME, requestedType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unload(String scriptIdentifier) {
|
|
||||||
// ignore for now
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class JSCache {
|
|
||||||
private Map<String, Object> backingMap = new HashMap<>();
|
|
||||||
|
|
||||||
public void put(String k, Object v) {
|
|
||||||
backingMap.put(k, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable Object remove(String k) {
|
|
||||||
return backingMap.remove(k);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable Object get(String k) {
|
|
||||||
return backingMap.get(k);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable Object get(String k, Supplier<Object> supplier) {
|
|
||||||
return backingMap.computeIfAbsent(k, (unused_key) -> supplier.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user