2021-05-06 09:08:47 +02:00
# JavaScript Scripting
This add-on provides support for JavaScript (ECMAScript 2021+) that can be used as a scripting language within automation rules.
2021-11-29 09:44:26 +01:00
2021-12-17 08:00:44 +01:00
Also included is [openhab-js ](https://github.com/openhab/openhab-js/ ), a fairly high-level ES6 library to support automation in openHAB. It provides convenient access
to common openHAB functionality within rules including items, things, actions, logging and more.
2021-05-06 09:08:47 +02:00
2021-12-17 08:00:44 +01:00
- [Configuration ](#configuration )
2022-09-13 21:57:09 +02:00
- [UI Based Rules ](#ui-based-rules )
2022-01-30 18:28:58 +01:00
- [Adding Triggers ](#adding-triggers )
- [Adding Actions ](#adding-actions )
2022-09-13 21:57:09 +02:00
- [UI Event Object ](#ui-event-object )
2021-12-17 08:00:44 +01:00
- [Scripting Basics ](#scripting-basics )
2022-01-30 18:28:58 +01:00
- [Require ](#require )
- [Console ](#console )
2022-06-18 13:24:05 +02:00
- [Timers ](#timers )
2022-01-30 18:28:58 +01:00
- [Paths ](#paths )
2021-12-17 08:00:44 +01:00
- [Standard Library ](#standard-library )
2022-01-30 18:28:58 +01:00
- [Items ](#items )
2022-06-18 13:24:05 +02:00
- [Things ](#things )
2022-01-30 18:28:58 +01:00
- [Actions ](#actions )
- [Cache ](#cache )
- [Log ](#log )
- [Time ](#time )
- [Utils ](#utils )
2021-12-17 08:00:44 +01:00
- [File Based Rules ](#file-based-rules )
- [JSRule ](#jsrule )
- [Rule Builder ](#rule-builder )
2022-09-13 21:57:09 +02:00
- [Event Object ](#event-object )
2022-06-18 13:24:05 +02:00
- [Initialization hook: scriptLoaded ](#initialization-hook-scriptloaded )
- [Deinitialization hook: scriptUnloaded ](#deinitialization-hook-scriptunloaded )
- [Advanced Scripting ](#advanced-scripting )
- [@runtime ](#runtime )
2021-05-06 09:08:47 +02:00
2021-12-17 08:00:44 +01:00
## Configuration
2021-05-06 09:08:47 +02:00
2022-09-13 21:57:09 +02:00
This add-on includes by default the [openhab-js ](https://github.com/openhab/openhab-js/ ) NPM library and exports its namespaces onto the global namespace.
2022-06-18 13:24:05 +02:00
This allows the use of `items` , `actions` , `cache` and other objects without the need to explicitly import using `require()` .
2022-09-13 21:57:09 +02:00
This functionality can be disabled for users who prefer to manage their own imports via the add-on configuration options.
2021-12-17 08:00:44 +01:00
2022-04-09 16:56:13 +02:00
![openHAB Rule Configuration ](doc/settings.png )
2021-12-17 08:00:44 +01:00
2022-09-13 21:57:09 +02:00
<!-- Paste the copied docs from openhab - js under this comment. -->
### UI Based Rules
2021-12-17 08:00:44 +01:00
The quickest way to add rules is through the openHAB Web UI.
Advanced users, or users migrating scripts from existing systems may want to use [File Based Rules ](#file-based-rules ) for managing rules using files in the user configuration directory.
### Adding Triggers
2022-09-13 21:57:09 +02:00
2022-06-18 13:24:05 +02:00
Using the openHAB UI, first create a new rule and set a trigger condition.
2021-12-17 08:00:44 +01:00
2022-04-09 16:56:13 +02:00
![openHAB Rule Configuration ](doc/rule-config.png )
2021-12-17 08:00:44 +01:00
2022-01-30 18:28:58 +01:00
### Adding Actions
2022-09-13 21:57:09 +02:00
2022-06-18 13:24:05 +02:00
Select "Add Action" and then select "Run Script" with "ECMAScript 262 Edition 11".
It’ s important this is "Edition 11" or higher, earlier versions will not work.
2022-09-13 21:57:09 +02:00
This will bring up an empty script editor where you can enter your JavaScript.
2021-12-17 08:00:44 +01:00
2022-04-09 16:56:13 +02:00
![openHAB Rule Engines ](doc/rule-engines.png )
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
You can now write rules using standard ES6 JavaScript along with the included openHAB [standard library ](#standard-library ).
2021-12-17 08:00:44 +01:00
2022-04-09 16:56:13 +02:00
![openHAB Rule Script ](doc/rule-script.png )
2021-12-17 08:00:44 +01:00
For example, turning a light on:
2022-09-13 21:57:09 +02:00
2021-12-17 08:00:44 +01:00
```javascript
items.getItem("KitchenLight").sendCommand("ON");
console.log("Kitchen Light State", items.getItem("KitchenLight").state);
```
Sending a notification
2022-09-13 21:57:09 +02:00
2021-12-17 08:00:44 +01:00
```javascript
actions.NotificationAction.sendNotification("romeo@montague.org", "Balcony door is open");
2021-05-06 09:08:47 +02:00
```
2021-12-17 08:00:44 +01:00
Querying the status of a thing
2022-09-13 21:57:09 +02:00
2021-12-17 08:00:44 +01:00
```javascript
const thingStatusInfo = actions.Things.getThingStatusInfo("zwave:serial_zstick:512");
console.log("Thing status",thingStatusInfo.getStatus());
```
2022-06-18 13:24:05 +02:00
See [openhab-js ](https://openhab.github.io/openhab-js ) for a complete list of functionality.
2022-09-13 21:57:09 +02:00
### UI Event Object
2022-06-18 13:24:05 +02:00
2022-09-13 21:57:09 +02:00
**NOTE**: Note that `event` object is different in UI based rules and file based rules! This section is only valid for UI based rules. If you use file based rules, refer to [file based rules event object documentation ](#event-object ).
2022-06-18 13:24:05 +02:00
When you use "Item event" as trigger (i.e. "[item] received a command", "[item] was updated", "[item] changed"), there is additional context available for the action in a variable called `event` .
This tables gives an overview over the `event` object for most common trigger types:
| Property Name | Type | Trigger Types | Description | Rules DSL Equivalent |
2022-09-13 21:57:09 +02:00
|----------------|----------------------------------------------------------------------------------------------------------------------|----------------------------------------|---------------------------------------------------------------------------------------------------------------|------------------------|
2022-06-18 13:24:05 +02:00
| `itemState` | sub-class of [org.openhab.core.types.State ](https://www.openhab.org/javadoc/latest/org/openhab/core/types/state ) | `[item] changed` , `[item] was updated` | State that triggered event | `triggeringItem.state` |
| `oldItemState` | sub-class of [org.openhab.core.types.State ](https://www.openhab.org/javadoc/latest/org/openhab/core/types/state ) | `[item] changed` | Previous state of Item or Group that triggered event | `previousState` |
| `itemCommand` | sub-class of [org.openhab.core.types.Command ](https://www.openhab.org/javadoc/latest/org/openhab/core/types/command ) | `[item] received a command` | Command that triggered event | `receivedCommand` |
| `itemName` | string | all | Name of Item that triggered event | `triggeringItem.name` |
| `type` | string | all | Type of event that triggered event (`"ItemStateEvent"`, `"ItemStateChangedEvent"` , `"ItemCommandEvent"` , ...) | N/A |
Note that in UI based rules `event.itemState` , `event.oldItemState` , and `event.itemCommand` are Java types (not JavaScript), and care must be taken when comparing these with JavaScript types:
```javascript
var { ON } = require("@runtime")
console.log(event.itemState == "ON") // WRONG. Java type does not equal with string, not even with "relaxed" equals (==) comparison
console.log(event.itemState.toString() == "ON") // OK. Comparing strings
console.log(event.itemState == ON) // OK. Comparing Java types
```
**NOTE**: Even with `String` items, simple comparison with `==` is not working as one would expect! See below example:
```javascript
// Example assumes String item trigger
console.log(event.itemState == "test") // WRONG. Will always log "false"
console.log(event.itemState.toString() == "test") // OK
```
2021-12-17 08:00:44 +01:00
## Scripting Basics
The openHAB JSScripting runtime attempts to provide a familiar environment to Javascript developers.
### Require
2022-06-18 13:24:05 +02:00
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.
2021-12-17 08:00:44 +01:00
### Console
2022-06-18 13:24:05 +02:00
The JS Scripting binding supports the standard `console` object for logging.
2022-09-13 21:57:09 +02:00
Script debug logging is enabled by default at the `INFO` level, but can be configured using the console logging commands.
2021-05-06 09:08:47 +02:00
```text
2021-12-17 08:00:44 +01:00
log:set DEBUG org.openhab.automation.script
2021-05-06 09:08:47 +02:00
```
2022-06-18 13:24:05 +02:00
The default logger name prefix is `org.openhab.automation.script` , this can be changed by assigning a new prefix to the `loggerName` property of the console.
```javascript
console.loggerName = "custom"
```
2021-12-17 08:00:44 +01:00
Supported logging functions include:
2022-09-13 21:57:09 +02:00
2021-12-17 08:00:44 +01:00
- `console.log(obj1 [, obj2, ..., objN])`
- `console.info(obj1 [, obj2, ..., objN])`
- `console.warn(obj1 [, obj2, ..., objN])`
- `console.error(obj1 [, obj2, ..., objN])`
- `console.debug(obj1 [, obj2, ..., objN])`
- `console.trace(obj1 [, obj2, ..., objN])`
2021-05-06 09:08:47 +02:00
2022-06-18 13:24:05 +02:00
Where `obj1 ... objN` is a list of JavaScript objects to output.
2022-01-30 18:28:58 +01:00
The string representations of each of these objects are appended together in the order listed and output.
2021-11-29 09:44:26 +01:00
2022-09-13 21:57:09 +02:00
See < https: / / developer . mozilla . org / en-US / docs / Web / API / console > for more information about console logging.
2021-05-06 09:08:47 +02:00
2022-06-18 13:24:05 +02:00
### Timers
2021-05-06 09:08:47 +02:00
2022-06-18 13:24:05 +02:00
#### SetTimeout
The global `setTimeout()` method sets a timer which executes a function or specified piece of code once the timer expires.
2022-09-13 21:57:09 +02:00
2021-11-29 09:44:26 +01:00
```javascript
2022-09-13 21:57:09 +02:00
var ohTimer = setTimeout(callbackFunction, delay);
2021-05-06 09:08:47 +02:00
```
2021-12-17 08:00:44 +01:00
The global `clearTimeout()` method cancels a timeout previously established by calling `setTimeout()` .
2021-05-06 09:08:47 +02:00
2022-09-13 21:57:09 +02:00
The openHAB implementation of `setTimeout()` differs from the [HTML DOM API's `setTimeout()` ](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout ).
2022-06-18 13:24:05 +02:00
openHAB does not return the integer timeoutID as standard JS does, instead it returns an instance of [openHAB Timer ](#openhab-timer ).
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
#### SetInterval
2021-12-17 08:00:44 +01:00
The setInterval() method repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.
```javascript
2022-09-13 21:57:09 +02:00
var ohIntervalTimer = setInterval(callbackFunction, delay);
2021-12-17 08:00:44 +01:00
```
The global `clearInterval()` method cancels a timed, repeating action which was previously established by a call to `setInterval()` .
2022-09-13 21:57:09 +02:00
NOTE: Timers will not be canceled if a script is deleted or modified, it is up to the user to manage timers.
See using the [cache ](#cache ) namespace as well as [ScriptLoaded ](#initialization-hook-scriptloaded ) and [ScriptUnLoaded ](#deinitialization-hook-scriptunloaded ) for a convenient way of managing persisted objects, such as timers between reloads or deletions of scripts.
2021-12-17 08:00:44 +01:00
2022-09-13 21:57:09 +02:00
The openHAB implementation of `setInterval()` differs from the [HTML DOM API's `setInterval()` ](https://developer.mozilla.org/en-US/docs/Web/API/setInterval ).
2022-06-18 13:24:05 +02:00
openHAB does not return the integer timeoutID as standard JS does, instead it returns an instance of [openHAB Timer ](#openhab-timer ).
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
#### openHAB Timer
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
A native openHAB Timer instance has the following methods:
2022-09-13 21:57:09 +02:00
- `cancel()` : Cancels the timer. ⇒ `boolean` : true, if cancellation was successful
- `getExecutionTime()` : The scheduled execution time or null if timer was cancelled. ⇒ `time.ZonedDateTime` or `null`
- `isActive()` : Whether the scheduled execution is yet to happen. ⇒ `boolean`
- `isCancelled()` : Whether the timer has been cancelled. ⇒ `boolean`
- `isRunning()` : Whether the scheduled code is currently executed. ⇒ `boolean`
- `hasTerminated()` : Whether the scheduled execution has already terminated. ⇒ `boolean`
- `reschedule(time.ZonedDateTime)` : Reschedules a timer to a new starting time. This can also be called after a timer has terminated, which will result in another execution of the same code. ⇒ `boolean` : true, if rescheduling was successful
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
Examples:
2022-09-13 21:57:09 +02:00
2021-12-17 08:00:44 +01:00
```javascript
2022-06-18 13:24:05 +02:00
var timer = setTimeout(() => { console.log('Timer expired.'); }, 10000); // Would log 'Timer expired.' in 10s.
if (timer.isActive()) console.log('Timer is waiting to execute.');
timer.cancel();
if (timer.isCancelled()) console.log('Timer has been cancelled.');
timer.reschedule(time.ZonedDateTime.now().plusSeconds(2)); // Logs 'Timer expired.' in 2s.
2021-11-29 09:44:26 +01:00
```
2022-06-18 13:24:05 +02:00
See [openHAB JavaDoc - Timer ](https://www.openhab.org/javadoc/latest/org/openhab/core/model/script/actions/timer ) for full API documentation.
2021-12-17 08:00:44 +01:00
### Paths
For [file based rules ](#file-based-rules ), scripts will be loaded from `automation/js` in the user configuration directory.
NPM libraries will be loaded from `automation/js/node_modules` in the user configuration directory.
## Standard Library
2022-06-18 13:24:05 +02:00
Full documentation for the openHAB JavaScript library can be found at [openhab-js ](https://openhab.github.io/openhab-js ).
2021-12-17 08:00:44 +01:00
### Items
2022-01-30 18:28:58 +01:00
The items namespace allows interactions with openHAB items.
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
See [openhab-js : items ](https://openhab.github.io/openhab-js/items.html ) for full API documentation.
2021-11-29 09:44:26 +01:00
2022-09-13 21:57:09 +02:00
- items : < code > object</ code >
- .getItem(name, nullIfMissing) ⇒ < code > Item</ code >
- .getItems() ⇒ < code > Array.< Item> </ code >
- .getItemsByTag(...tagNames) ⇒ < code > Array.< Item> </ code >
- .addItem([itemConfig](#itemconfig))
- .removeItem(itemOrItemName) ⇒ < code > Boolean</ code >
- .replaceItem([itemConfig](#itemconfig))
- .safeItemName(s) ⇒ < code > String</ code >
2021-11-29 09:44:26 +01:00
2021-12-17 08:00:44 +01:00
```javascript
const item = items.getItem("KitchenLight");
console.log("Kitchen Light State", item.state);
```
2022-06-18 13:24:05 +02:00
#### `getItem(name, nullIfMissing)`
2021-12-17 08:00:44 +01:00
Calling `getItem(...)` returns an `Item` object with the following properties:
2022-09-13 21:57:09 +02:00
- Item : < code > object</ code >
- .type ⇒ < code > String</ code >
- .name ⇒ < code > String</ code >
- .label ⇒ < code > String</ code >
- .history ⇒ [`ItemHistory` ](#itemhistory )
- .state ⇒ < code > String</ code >
- .rawState ⇒ < code > HostState</ code >
- .members ⇒ < code > Array.< Item> </ code >
- .descendents ⇒ < code > Array.< Item> </ code >
- .isUninitialized ⇒ < code > Boolean</ code >
- .groupNames ⇒ < code > Array.< String> </ code >
- .tags ⇒ < code > Array.< String> </ code >
- .getMetadataValue(namespace) ⇒ < code > String</ code >
- .updateMetadataValue(namespace, value) ⇒ < code > String</ code >
- .upsertMetadataValue(namespace, value) ⇒ < code > Boolean</ code >
- .updateMetadataValues(namespaceToValues)
- .sendCommand(value)
- .sendCommandIfDifferent(value) ⇒ < code > Boolean</ code >
- .postUpdate(value)
- .addGroups(...groupNamesOrItems)
- .removeGroups(...groupNamesOrItems)
- .addTags(...tagNames)
- .removeTags(...tagNames)
2021-11-29 09:44:26 +01:00
```javascript
2021-12-17 08:00:44 +01:00
const item = items.getItem("KitchenLight");
//send a ON command
item.sendCommand("ON");
//Post an update
item.postUpdate("OFF");
//Get state
console.log("KitchenLight state", item.state)
2021-11-29 09:44:26 +01:00
```
2022-06-18 13:24:05 +02:00
#### `itemConfig`
2022-09-13 21:57:09 +02:00
2022-06-18 13:24:05 +02:00
Calling `addItem(itemConfig)` or `replaceItem(itemConfig)` requires the `itemConfig` object with the following properties:
2022-09-13 21:57:09 +02:00
- itemConfig : < code > object</ code >
- .type ⇒ < code > String</ code >
- .name ⇒ < code > String</ code >
- .label ⇒ < code > String</ code >
- .category (icon) ⇒ < code > String</ code >
- .groups ⇒ < code > Array.< String> </ code >
- .tags ⇒ < code > Array.< String> </ code >
- .channels ⇒ < code > String|Object { channeluid: { config } }</ code >
- .metadata ⇒ < code > Object { namespace: value }|Object { namespace: { value: value , config: { config } } }</ code >
- .giBaseType ⇒ < code > String</ code >
- .groupFunction ⇒ < code > String</ code >
2022-06-18 13:24:05 +02:00
Note: `.type` and `.name` are required.
Basic UI and the mobile apps need `metadata.stateDescription.config.pattern` to render the state of an Item.
Example:
2022-09-13 21:57:09 +02:00
2022-06-18 13:24:05 +02:00
```javascript
// more advanced example
items.replaceItem({
type: 'String',
name: 'Hallway_Light',
label: 'Hallway Light',
category: 'light',
groups: ['Hallway', 'Light'],
tags: ['Lightbulb'],
channels: {
'binding:thing:device:hallway#light': {},
'binding:thing:device:livingroom#light': {
profile: 'system:follow'
}
},
metadata: {
expire: '10m,command=1',
stateDescription: {
config: {
pattern: '%d%%',
options: '1=Red, 2=Green, 3=Blue'
}
}
}
});
// minimal example
items.replaceItem({
type: 'Switch',
name: 'MySwitch',
metadata: {
stateDescription: {
config: {
pattern: '%s'
}
}
}
});
```
2022-09-13 21:57:09 +02:00
See [openhab-js : ItemConfig ](https://openhab.github.io/openhab-js/global.html#ItemConfig ) for full API documentation.
#### `ItemHistory`
Calling `Item.history` returns a `ItemHistory` object with the following functions:
- ItemHistory :`object`
- .averageBetween(begin, end, serviceId) ⇒ `number | null`
- .averageSince(timestamp, serviceId) ⇒ `number | null`
- .changedBetween(begin, end, serviceId) ⇒ `boolean`
- .changedSince(timestamp, serviceId) ⇒ `boolean`
- .deltaBetween(begin, end, serviceId) ⇒ `number | null`
- .deltaSince(timestamp, serviceId) ⇒ `number | null`
- .deviationBetween(begin, end, serviceId) ⇒ `number | null`
- .deviationSince(timestamp, serviceId) ⇒ `number | null`
- .evolutionRateBetween(begin, end, serviceId) ⇒ `number | null`
- .evolutionRateSince(timestamp, serviceId) ⇒ `number | null`
- .historicState(timestamp, serviceId) ⇒ `string | null`
- .lastUpdate(serviceId) ⇒ `ZonedDateTime | null`
- .latestState(serviceId) ⇒ `string | null`
- .maximumBetween(begin, end, serviceId) ⇒ `string | null`
- .maximumSince(timestamp,serviceId) ⇒ `string | null`
- .minimumSince(begin, end, serviceId) ⇒ `string | null`
- .minimumSince(timestamp, serviceId) ⇒ `string | null`
- .persist(serviceId)
- .previousState(skipEqual, serviceId) ⇒ `string | null`
- .sumBetween(begin, end, serviceId) ⇒ `number | null`
- .sumSince(timestamp, serviceId) ⇒ `number | null`
- .updatedBetween(begin, end, serviceId) ⇒ `boolean`
- .updatedSince(timestamp, serviceId) ⇒ `boolean`
- .varianceBetween(begin, end, serviceId) ⇒ `number | null`
- .varianceSince(timestamp, serviceId) ⇒ `number | null`
Note: `serviceId` is optional, if omitted, the default persistence service will be used.
2022-06-18 13:24:05 +02:00
2021-11-29 09:44:26 +01:00
```javascript
2021-12-17 08:00:44 +01:00
var yesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));
2022-09-13 21:57:09 +02:00
var item = items.getItem('KitchenDimmer');
console.log('KitchenDimmer averageSince', item.history.averageSince(yesterday));
2021-11-29 09:44:26 +01:00
```
2022-09-13 21:57:09 +02:00
See [openhab-js : ItemHistory ](https://openhab.github.io/openhab-js/items.ItemHistory.html ) for full API documentation.
2022-06-18 13:24:05 +02:00
### Things
The Things namespace allows to interact with openHAB Things.
See [openhab-js : things ](https://openhab.github.io/openhab-js/things.html ) for full API documentation.
2022-09-13 21:57:09 +02:00
- things : < code > object</ code >
- .getThing(uid, nullIfMissing) ⇒ < code > Thing</ code >
- .getThings() ⇒ < code > Array.< Thing> </ code >
2022-06-18 13:24:05 +02:00
#### `getThing(uid, nullIfMissing)`
Calling `getThing(...)` returns a `Thing` object with the following properties:
2022-09-13 21:57:09 +02:00
- Thing : < code > object</ code >
- .bridgeUID ⇒ < code > String</ code >
- .label ⇒ < code > String</ code >
- .location ⇒ < code > String</ code >
- .status ⇒ < code > String</ code >
- .statusInfo ⇒ < code > String</ code >
- .thingTypeUID ⇒ < code > String</ code >
- .uid ⇒ < code > String</ code >
- .isEnabled ⇒ < code > Boolean</ code >
- .setLabel(label)
- .setLocation(location)
- .setProperty(name, value)
- .setEnabled(enabled)
2022-06-18 13:24:05 +02:00
```javascript
const thing = things.getThing('astro:moon:home');
console.log('Thing label: ' + thing.label);
// Set Thing location
thing.setLocation('living room');
// Disable Thing
thing.setEnabled(false);
```
2021-12-17 08:00:44 +01:00
### Actions
2022-01-30 18:28:58 +01:00
The actions namespace allows interactions with openHAB actions.
The following are a list of standard actions.
2021-12-17 08:00:44 +01:00
Additional actions provided by user installed addons can be accessed using their common name on the actions name space
(example: `actions.Pushsafer.pushsafer(...)` )
2022-01-30 18:28:58 +01:00
See [openhab-js : actions ](https://openhab.github.io/openhab-js/actions.html ) for full API documentation and additional actions.
2021-12-17 08:00:44 +01:00
#### Audio Actions
2022-06-18 13:24:05 +02:00
See [openhab-js : actions.Audio ](https://openhab.github.io/openhab-js/actions.html#.Audio ) for complete documentation.
2021-12-17 08:00:44 +01:00
2022-01-30 18:28:58 +01:00
#### BusEvent
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
See [openhab-js : actions.BusEvent ](https://openhab.github.io/openhab-js/actions.html#.BusEvent ) for complete documentation.
2021-12-17 08:00:44 +01:00
2022-01-30 18:28:58 +01:00
#### Ephemeris Actions
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
See [openhab-js : actions.Ephemeris ](https://openhab.github.io/openhab-js/actions.html#.Ephemeris ) for complete documentation.
2021-12-17 08:00:44 +01:00
Ephemeris is a way to determine what type of day today or a number of days before or after today is. For example, a way to determine if today is a weekend, a bank holiday, someone’ s birthday, trash day, etc.
2022-01-30 18:28:58 +01:00
Additional information can be found on the [Ephemeris Actions Docs ](https://www.openhab.org/docs/configuration/actions.html#ephemeris ) as well as the [Ephemeris JavaDoc ](https://www.openhab.org/javadoc/latest/org/openhab/core/model/script/actions/ephemeris ).
2021-11-29 09:44:26 +01:00
```javascript
2021-12-17 08:00:44 +01:00
// Example
let weekend = actions.Ephemeris.isWeekend();
2021-11-29 09:44:26 +01:00
```
2021-12-17 08:00:44 +01:00
#### Exec Actions
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
See [openhab-js : actions.Exec ](https://openhab.github.io/openhab-js/actions.html#.Exec ) for complete documentation.
2021-11-29 09:44:26 +01:00
Execute a command line.
```javascript
// Execute command line.
2021-12-17 08:00:44 +01:00
actions.Exec.executeCommandLine('echo', 'Hello World!');
2021-11-29 09:44:26 +01:00
// Execute command line with timeout.
2021-12-17 08:00:44 +01:00
let Duration = Java.type('java.time.Duration');
actions.Exec.executeCommandLine(Duration.ofSeconds(20), 'echo', 'Hello World!');
2021-11-29 09:44:26 +01:00
// Get response from command line.
2021-12-17 08:00:44 +01:00
let response = actions.Exec.executeCommandLine('echo', 'Hello World!');
2021-11-29 09:44:26 +01:00
// Get response from command line with timeout.
2021-12-17 08:00:44 +01:00
response = actions.Exec.executeCommandLine(Duration.ofSeconds(20), 'echo', 'Hello World!');
2021-11-29 09:44:26 +01:00
```
2022-01-30 18:28:58 +01:00
#### HTTP Actions
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
See [openhab-js : actions.HTTP ](https://openhab.github.io/openhab-js/actions.html#.HTTP ) for complete documentation.
2021-11-29 09:44:26 +01:00
```javascript
// Example GET Request
2021-12-17 08:00:44 +01:00
var response = actions.HTTP.sendHttpGetRequest('< url > ');
2021-11-29 09:44:26 +01:00
```
Replace `<url>` with the request url.
2022-01-30 18:28:58 +01:00
#### ScriptExecution Actions
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
See [openhab-js : actions.ScriptExecution ](https://openhab.github.io/openhab-js/actions.html#.ScriptExecution ) for complete documentation.
2021-12-17 08:00:44 +01:00
2021-11-29 09:44:26 +01:00
```javascript
2021-12-17 08:00:44 +01:00
let now = time.ZonedDateTime.now();
2021-11-29 09:44:26 +01:00
// Function to run when the timer goes off.
function timerOver () {
2022-09-13 21:57:09 +02:00
console.info('The timer is over.');
2021-11-29 09:44:26 +01:00
}
// Create the Timer.
2022-09-13 21:57:09 +02:00
this.myTimer = actions.ScriptExecution.createTimer('My Timer', now.plusSeconds(10), timerOver);
2021-11-29 09:44:26 +01:00
// Cancel the timer.
this.myTimer.cancel();
// Check whether the timer is active. Returns true if the timer is active and will be executed as scheduled.
let active = this.myTimer.isActive();
// Reschedule the timer.
this.myTimer.reschedule(now.plusSeconds(5));
```
2022-09-13 21:57:09 +02:00
2022-01-30 18:28:58 +01:00
#### Semantics Actions
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
See [openhab-js : actions.Semantics ](https://openhab.github.io/openhab-js/actions.html#.Semantics ) for complete documentation.
2021-11-29 09:44:26 +01:00
2022-01-30 18:28:58 +01:00
#### Things Actions
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
See [openhab-js : actions.Things ](https://openhab.github.io/openhab-js/actions.html#.Things ) for complete documentation.
2021-11-29 09:44:26 +01:00
2022-01-30 18:28:58 +01:00
#### Voice Actions
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
See [openhab-js : actions.Voice ](https://openhab.github.io/openhab-js/actions.html#.Voice ) for complete documentation.
2021-11-29 09:44:26 +01:00
2022-01-30 18:28:58 +01:00
#### Cloud Notification Actions
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
Note: Optional action if [openHAB Cloud Connector ](https://www.openhab.org/addons/integrations/openhabcloud/ ) is installed.
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
Notification actions may be placed in rules to send alerts to mobile devices registered with an [openHAB Cloud instance ](https://github.com/openhab/openhab-cloud ) such as [myopenHAB.org ](https://myopenhab.org/ ).
2021-11-29 09:44:26 +01:00
For available actions have a look at the [Cloud Notification Actions Docs ](https://www.openhab.org/docs/configuration/actions.html#cloud-notification-actions ).
```javascript
// Example
2021-12-17 08:00:44 +01:00
actions.NotificationAction.sendNotification('< email > ', '< message > '); // to a single myopenHAB user identified by e-mail
actions.NotificationAction.sendBroadcastNotification('< message > '); // to all myopenHAB users
2021-11-29 09:44:26 +01:00
```
Replace `<email>` with the e-mail address of the user.
Replace `<message>` with the notification text.
2021-12-17 08:00:44 +01:00
### Cache
2022-06-18 13:24:05 +02:00
The cache namespace provides a default cache that can be used to set and retrieve objects that will be persisted between reloads of scripts.
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
See [openhab-js : cache ](https://openhab.github.io/openhab-js/cache.html ) for full API documentation.
2021-12-17 08:00:44 +01:00
2022-09-13 21:57:09 +02:00
- cache : < code > object</ code >
- .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 >
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
The `defaultSupplier` provided function will return a default value if a specified key is not already associated with a value.
2021-11-29 09:44:26 +01:00
2022-01-30 18:28:58 +01:00
**Example** *(Get a previously set value with a default value (times = 0))*
2022-09-13 21:57:09 +02:00
2021-12-17 08:00:44 +01:00
```js
let counter = cache.get("counter", () => ({ "times": 0 }));
console.log("Count",counter.times++);
```
2022-01-30 18:28:58 +01:00
**Example** *(Get a previously set object)*
2022-09-13 21:57:09 +02:00
2021-12-17 08:00:44 +01:00
```js
let counter = cache.get("counter");
if(counter == null){
counter = {times: 0};
cache.put("counter", counter);
}
console.log("Count",counter.times++);
```
2022-09-13 21:57:09 +02:00
2021-12-17 08:00:44 +01:00
### Log
2022-09-13 21:57:09 +02:00
By default, the JS Scripting binding supports console logging like `console.log()` and `console.debug()` to the openHAB default log.
Additionally, scripts may create their own native openHAB logger using the log namespace.
2021-11-29 09:44:26 +01:00
```javascript
2021-12-17 08:00:44 +01:00
let logger = log('my_logger');
2021-11-29 09:44:26 +01:00
2021-12-17 08:00:44 +01:00
//prints "Hello World!"
logger.debug("Hello {}!", "world");
2021-05-06 09:08:47 +02:00
```
2021-11-29 09:44:26 +01:00
2021-12-17 08:00:44 +01:00
### Time
2021-11-29 09:44:26 +01:00
2022-01-30 18:28:58 +01:00
openHAB internally makes extensive use of the `java.time` package.
2022-09-13 21:57:09 +02:00
openHAB-JS exports the excellent [JS-Joda ](https://js-joda.github.io/js-joda/ ) library via the `time` namespace, which is a native JavaScript port of the same API standard used in Java for `java.time` .
2022-01-30 18:28:58 +01:00
Anywhere that a native Java `ZonedDateTime` or `Duration` is required, the runtime will automatically convert a JS-Joda `ZonedDateTime` or `Duration` to its Java counterpart.
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
The exported JS-Joda library is also extended with convenient functions relevant to openHAB usage.
2021-12-17 08:00:44 +01:00
Examples:
2022-09-13 21:57:09 +02:00
2021-12-17 08:00:44 +01:00
```javascript
var now = time.ZonedDateTime.now();
var yesterday = time.ZonedDateTime.now().minusHours(24);
var item = items.getItem("Kitchen");
console.log("averageSince", item.history.averageSince(yesterday));
```
2022-09-13 21:57:09 +02:00
2021-12-17 08:00:44 +01:00
```javascript
actions.Exec.executeCommandLine(time.Duration.ofSeconds(20), 'echo', 'Hello World!');
```
2022-09-13 21:57:09 +02:00
2022-01-03 13:52:05 +01:00
See [JS-Joda ](https://js-joda.github.io/js-joda/ ) for more examples and complete API usage.
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
#### `time.toZDT()`
2022-09-13 21:57:09 +02:00
There will be times when this automatic conversion is not available (for example when working with date times within a rule).
2022-06-18 13:24:05 +02:00
To ease having to deal with these cases a `time.toZDT()` function will accept almost any type that can be converted to a `time.ZonedDateTime` .
The following rules are used during the conversion:
| Argument Type | Rule | Examples |
|------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------|
| `null` or `undefined` | `time.ZonedDateTime.now()` | `time.toZDT();` |
| `time.ZonedDateTime` | passed through unmodified | |
| `java.time.ZonedDateTime` | converted to the `time.ZonedDateTime` equivalent | |
| JavaScript native `Date` | converted to the equivalent `time.ZonedDateTime` using `SYSTEM` as the timezone | |
| `number` , `bingint` , `java.lang.Number` , `DecimalType` | rounded to the nearest integer and added to `now` as milliseconds | `time.toZDT(1000);` |
| `QuantityType` | if the units are `Time` , that time is added to `now` | `time.toZDT(item.getItem('MyTimeItem').rawState);` |
| `items.Item` or `org.openhab.core.types.Item` | if the state is supported (see the `Type` rules in this table, e.g. `DecimalType` ), the state is converted | `time.toZDT(items.getItem('MyItem'));` |
| `String` , `java.lang.String` , `StringType` | parsed based on the following rules | |
| RFC String (output from a Java `ZonedDateTime.toString()` ) | parsed | `time.toZDT(new DateTimeType().getZonedDateTime().toString());` |
| `"HH:MM[:ss]"` (24 hour time) | today's date with the time indicated, seconds is optional | `time.toZDT('13:45:12');` |
| `"kk:mm[:ss][ ]a"` (12 hour time) | today's date with the time indicated, the space between the time and am/pm and seconds are optional | `time.toZDT('1:23:45 PM');` |
| Duration String | any duration string supported by `time.Duration` added to `now()` , see [the docs ](https://js-joda.github.io/js-joda/class/packages/core/src/Duration.js~Duration.html#static-method-parse ) for details | `time.toZDT('PT1H4M6.789S');` |
When a type or string that cannot be handled is encountered, an error is thrown.
#### `toToday()`
When you have a `time.ZonedDateTime` , a new `toToday()` method was added which will return a new `time.ZonedDateTime` with today's date but the original's time, accounting for DST changes.
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
const alarm = items.getItem('Alarm');
alarm.postUpdate(time.toZDT(alarm).toToday());
```
2022-09-13 21:57:09 +02:00
#### `isBetweenTimes(start, end)`
2022-06-18 13:24:05 +02:00
Tests whether this `time.ZonedDateTime` is between the passed in `start` and `end` .
However, the function only compares the time portion of the three, ignoring the date portion.
The function takes into account times that span midnight.
`start` and `end` can be anything supported by `time.toZDT()` .
Examples:
```javascript
2022-09-13 21:57:09 +02:00
time.toZDT().isBetweenTimes('22:00', '05:00') // currently between 11:00 pm and 5:00 am
time.toZDT().isBetweenTimes(items.getItem('Sunset'), '11:30 PM') // is now between sunset and 11:30 PM?
time.toZDT(items.getItem('StartTime')).isBetweenTimes(time.toZDT(), 'PT1H'); // is the state of StartTime between now and one hour from now
2022-06-18 13:24:05 +02:00
```
#### `isClose(zdt, maxDur)`
Tests to see if the delta between the `time.ZonedDateTime` and the passed in `time.ZonedDateTime` is within the passed in `time.Duration` .
```javascript
const timestamp = time.toZDT();
// do some stuff
2022-09-13 21:57:09 +02:00
if(timestamp.isClose(time.toZDT(), time.Duration.ofMillis(100))) {
// did "do some stuff" take longer than 100 msecs to run?
}
2022-06-18 13:24:05 +02:00
```
#### `getMillisFromNow`
This method on `time.ZonedDateTime` returns the milliseconds from now to the passed in `time.ZonedDateTime` .
```javascript
const timestamp = time.ZonedDateTime.now().plusMinutes(5);
console.log(timestamp.getMillisFromNow());
```
2022-01-30 18:28:58 +01:00
### Utils
2022-09-13 21:57:09 +02:00
openHAB internally is a Java program.
2022-01-30 18:28:58 +01:00
openHAB-JS converts between Java and JavaScript data types and reverse.
2022-06-18 13:24:05 +02:00
See [openhab-js : utils ](https://openhab.github.io/openhab-js/utils.html ) for full API documentation.
2022-01-30 18:28:58 +01:00
2021-12-17 08:00:44 +01:00
## File Based Rules
2022-06-18 13:24:05 +02:00
The JS Scripting binding will load scripts from `automation/js` in the user configuration directory.
2022-01-30 18:28:58 +01:00
The system will automatically reload scripts when changes are detected to files.
2022-04-22 15:28:10 +02:00
Local variable state is not persisted among reloads, see using the [cache ](#cache ) for a convenient way to persist objects.
2021-12-17 08:00:44 +01:00
File based rules can be created in 2 different ways: using [JSRule ](#jsrule ) or the [Rule Builder ](#rule-builder ).
2022-09-13 21:57:09 +02:00
See [openhab-js : rules ](https://openhab.github.io/openhab-js/rules.html ) for full API documentation.
2021-11-29 09:44:26 +01:00
2021-12-17 08:00:44 +01:00
### JSRule
JSRules provides a simple, declarative syntax for defining rules that will be executed based on a trigger condition
2021-11-29 09:44:26 +01:00
```javascript
2021-12-17 08:00:44 +01:00
const email = "juliet@capulet.org"
rules.JSRule({
name: "Balcony Lights ON at 5pm",
description: "Light will turn on when it's 5:00pm",
triggers: [triggers.GenericCronTrigger("0 0 17 * * ?")],
2022-06-18 13:24:05 +02:00
execute: (event) => {
2021-12-17 08:00:44 +01:00
items.getItem("BalconyLights").sendCommand("ON");
actions.NotificationAction.sendNotification(email, "Balcony lights are ON");
2022-01-30 18:28:58 +01:00
},
tags: ["Balcony", "Lights"],
id: "BalconyLightsOn"
2021-12-17 08:00:44 +01:00
});
```
2022-01-30 18:28:58 +01:00
Note: `description` , `tags` and `id` are optional.
2022-06-18 13:24:05 +02:00
Note: You can use the passed `event` object to get information about the trigger that triggered the rule.
See [Event Object ](#event-object ) for documentation.
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
Multiple triggers can be added, some example triggers include:
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
```javascript
triggers.ChannelEventTrigger('astro:sun:local:rise#event', 'START');
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.ItemStateChangeTrigger('my_item', 'OFF', 'ON');
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.ItemStateUpdateTrigger('my_item', 'OFF');
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.ItemCommandTrigger('my_item', 'OFF');
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.GroupStateChangeTrigger('my_group', 'OFF', 'ON');
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.GroupStateUpdateTrigger('my_group', 'OFF');
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.GroupCommandTrigger('my_group', 'OFF');
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.ThingStatusUpdateTrigger('some:thing:uuid','OFFLINE');
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.ThingStatusChangeTrigger('some:thing:uuid','ONLINE','OFFLINE');
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.SystemStartlevelTrigger(40) // Rules loaded
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.SystemStartlevelTrigger(50) // Rule engine started
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.SystemStartlevelTrigger(70) // User interfaces started
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.SystemStartlevelTrigger(80) // Things initialized
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.SystemStartlevelTrigger(100) // Startup Complete
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
triggers.GenericCronTrigger('0 30 16 * * ? *');
2021-11-29 09:44:26 +01:00
2022-06-18 13:24:05 +02:00
triggers.TimeOfDayTrigger('19:00');
2022-09-13 21:57:09 +02:00
triggers.DateTimeTrigger('MyDateTimeItem');
2021-11-29 09:44:26 +01:00
```
2022-09-13 21:57:09 +02:00
You can use `null` for a trigger parameter to skip its configuration.
See [openhab-js : triggers ](https://openhab.github.io/openhab-js/triggers.html ) in the API documentation for a full list of all triggers.
2021-12-17 08:00:44 +01:00
### Rule Builder
The Rule Builder provides a convenient API to write rules in a high-level, readable style using a builder pattern.
2021-11-29 09:44:26 +01:00
2021-12-17 08:00:44 +01:00
Rules are started by calling `rules.when()` and can chain together [triggers ](#rule-builder-triggers ),
[conditions ](#rule-builder-conditions ) and [operations ](#rule-builder-operations ) in the following pattern:
2021-11-29 09:44:26 +01:00
```javascript
2022-01-30 18:28:58 +01:00
rules.when().triggerType()...if().conditionType().then().operationType()...build(name, description, tags, id);
2021-12-17 08:00:44 +01:00
```
2021-11-29 09:44:26 +01:00
2022-09-13 21:57:09 +02:00
Rule are completed by calling `.build(name, description, tags, id)` , all parameters are optional and reasonable defaults will be used if omitted.
2022-01-30 18:28:58 +01:00
- `name` String rule name - defaults generated name
- `description` String Rule description - defaults generated description
- `tags` Array of string tag names - defaults empty array
2022-09-13 21:57:09 +02:00
- `id` String id - defaults random UUID
2021-12-17 08:00:44 +01:00
A simple example of this would look like:
```javascript
rules.when().item("F1_Light").changed().then().send("changed").toItem("F2_Light").build("My Rule", "My First Rule");
```
Operations and conditions can also optionally take functions:
```javascript
rules.when().item("F1_light").changed().then(event => {
console.log(event);
}).build("Test Rule", "My Test Rule");
```
2022-09-13 21:57:09 +02:00
2022-06-18 13:24:05 +02:00
See [Examples ](#rule-builder-examples ) for further patterns.
2021-12-17 08:00:44 +01:00
#### Rule Builder Triggers
2022-09-13 21:57:09 +02:00
- `when()`
- `or()`
- `.channel(channelName)` Specifies a channel event as a source for the rule to fire.
- `.triggered(event)` Trigger on a specific event name
- `.cron(cronExpression)` Specifies a cron schedule for the rule to fire.
- `.item(itemName)` Specifies an item as the source of changes to trigger a rule.
- `.for(duration)`
- `.from(state)`
- `.to(state)`
- `.fromOff()`
- `.toOn()`
- `.receivedCommand()`
- `.receivedUpdate()`
- `.memberOf(groupName)`
- `.for(duration)`
- `.from(state)`
- `.to(state)`
- `.fromOff()`
- `.toOn()`
- `.receivedCommand()`
- `.receivedUpdate()`
- `.system()`
- `.ruleEngineStarted()`
- `.rulesLoaded()`
- `.startupComplete()`
- `.thingsInitialized()`
- `.userInterfacesStarted()`
- `.startLevel(level)`
- `.thing(thingName)`
- `changed()`
- `updated()`
- `from(state)`
- `to(state)`
2021-12-17 08:00:44 +01:00
Additionally all the above triggers have the following functions:
2022-09-13 21:57:09 +02:00
- `.if()` or `.if(fn)` -> a [rule condition ](#rule-builder-conditions )
- `.then()` or `.then(fn)` -> a [rule operation ](#rule-builder-operations )
- `.or()` -> a [rule trigger ](#rule-builder-triggers ) (chain additional triggers)
2021-12-17 08:00:44 +01:00
#### Rule Builder Conditions
2022-09-13 21:57:09 +02:00
- `if(optionalFunction)`
- `.stateOfItem(itemName)`
- `is(state)`
- `in(state...)`
2021-12-17 08:00:44 +01:00
#### Rule Builder Operations
2022-09-13 21:57:09 +02:00
- `then(optionalFunction)`
- `.build(name, description, tags, id)`
- `.copyAndSendState()`
- `.copyState()`
- `.inGroup(groupName)`
- `.postIt()`
- `.postUpdate(state)`
- `.send(command)`
- `.sendIt()`
- `.sendOff()`
- `.sendOn()`
- `.sendToggle()`
2021-12-17 08:00:44 +01:00
#### Rule Builder Examples
```javascript
2022-06-18 13:24:05 +02:00
// Basic rule, when the BedroomLight1 is changed, run a custom function
2021-12-17 08:00:44 +01:00
rules.when().item('BedroomLight1').changed().then(e => {
console.log("BedroomLight1 state", e.newState)
2022-09-13 21:57:09 +02:00
}).build();
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
// Turn on the kitchen light at SUNSET
rules.when().timeOfDay("SUNSET").then().sendOn().toItem("KitchenLight").build("Sunset Rule","turn on the kitchen light at SUNSET");
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
// Turn off the kitchen light at 9PM and tag rule
rules.when().cron("0 0 21 * * ?").then().sendOff().toItem("KitchenLight").build("9PM Rule", "turn off the kitchen light at 9PM", ["Tag1", "Tag2"]);
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
// Set the colour of the hall light to pink at 9PM, tag rule and use a custom ID
rules.when().cron("0 0 21 * * ?").then().send("300,100,100").toItem("HallLight").build("Pink Rule", "set the colour of the hall light to pink at 9PM", ["Tag1", "Tag2"], "MyCustomID");
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
// When the switch S1 status changes to ON, then turn on the HallLight
2021-12-17 08:00:44 +01:00
rules.when().item('S1').changed().toOn().then(sendOn().toItem('HallLight')).build("S1 Rule");
2022-06-18 13:24:05 +02:00
// When the HallLight colour changes pink, if the function fn returns true, then toggle the state of the OutsideLight
2021-12-17 08:00:44 +01:00
rules.when().item('HallLight').changed().to("300,100,100").if(fn).then().sendToggle().toItem('OutsideLight').build();
2022-06-18 13:24:05 +02:00
// And some rules which can be toggled by the items created in the 'gRules' Group:
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
// When the HallLight receives a command, send the same command to the KitchenLight
2021-12-17 08:00:44 +01:00
rules.when().item('HallLight').receivedCommand().then().sendIt().toItem('KitchenLight').build("Hall Light", "");
2022-06-18 13:24:05 +02:00
// When the HallLight is updated to ON, make sure that BedroomLight1 is set to the same state as the BedroomLight2
2021-12-17 08:00:44 +01:00
rules.when().item('HallLight').receivedUpdate().then().copyState().fromItem('BedroomLight1').toItem('BedroomLight2').build();
2022-06-18 13:24:05 +02:00
```
### Event Object
**NOTE**: The `event` object is different in UI Based Rules and File Based Rules!
This section is only valid for File Based Rules.
2022-09-13 21:57:09 +02:00
If you use UI Based Rules, refer to [UI based rules event object documentation ](#ui-event-object ).
2022-06-18 13:24:05 +02:00
When a rule is triggered, the script is provided the event instance that triggered it.
The specific data depends on the event type.
2022-09-13 21:57:09 +02:00
The `event` object provides some information about that trigger.
2022-06-18 13:24:05 +02:00
This tables gives an overview over the `event` object:
2022-09-13 21:57:09 +02:00
| Property Name | Trigger Types | Description | Rules DSL Equivalent |
|-------------------|------------------------------------------------------|-------------------------------------------------------------------------------------|------------------------|
| `oldState` | `ItemStateChangeTrigger` , `GroupStateChangeTrigger` | Previous state of Item or Group that triggered event | `previousState` |
| `newState` | `ItemStateChangeTrigger` , `GroupStateChangeTrigger` | New state of Item or Group that triggered event | N/A |
| `receivedState` | `ItemStateUpdateTrigger` , `GroupStateUpdateTrigger` | State of Item that triggered event | `triggeringItem.state` |
| `receivedCommand` | `ItemCommandTrigger` , `GroupCommandTrigger` | Command that triggered event | `receivedCommand` |
| `itemName` | `Item****Trigger` | Name of Item that triggered event | `triggeringItem.name` |
| `receivedEvent` | `ChannelEventTrigger` | Channel event that triggered event | N/A |
| `channelUID` | `ChannelEventTrigger` | UID of channel that triggered event | N/A |
| `oldStatus` | `ThingStatusChangeTrigger` | Previous state of Thing that triggered event | N/A |
| `newStatus` | `ThingStatusChangeTrigger` | New state of Thing that triggered event | N/A |
| `status` | `ThingStatusUpdateTrigger` | State of Thing that triggered event | N/A |
| `thingUID` | `Thing****Trigger` | UID of Thing that triggered event | N/A |
| `eventType` | all except `PWMTrigger` , `PIDTrigger` , time triggers | Type of event that triggered event (change, command, triggered, update) | N/A |
| `triggerType` | all except `PWMTrigger` , `PIDTrigger` , time triggers | Type of trigger that triggered event | N/A |
2022-06-18 13:24:05 +02:00
All properties are typeof `string` .
**NOTE:**
`Group****Trigger` s use the equivalent `Item****Trigger` as trigger for each member.
2022-09-13 21:57:09 +02:00
Time triggers do not provide any event instance, therefore no property is populated.
2022-06-18 13:24:05 +02:00
See [openhab-js : EventObject ](https://openhab.github.io/openhab-js/rules.html#.EventObject ) for full API documentation.
2021-12-17 08:00:44 +01:00
2022-06-18 13:24:05 +02:00
### Initialization hook: scriptLoaded
For file based scripts, this function will be called if found when the script is loaded.
```javascript
scriptLoaded = function () {
2022-09-13 21:57:09 +02:00
console.log("script loaded");
loadedDate = Date.now();
2022-06-18 13:24:05 +02:00
};
2021-12-17 08:00:44 +01:00
```
2022-06-18 13:24:05 +02:00
### Deinitialization hook: scriptUnloaded
For file based scripts, this function will be called if found when the script is unloaded.
```javascript
scriptUnloaded = function () {
2022-09-13 21:57:09 +02:00
console.log("script unloaded");
// clean up rouge timers
clearInterval(timer);
2022-06-18 13:24:05 +02:00
};
```
## Advanced Scripting
### @runtime
One can access many useful utilities and types using `require("@runtime")` , e.g.
```javascript
var { ON, OFF, QuantityType } = require("@runtime");
// Alternative, more verbose way to achieve the same:
//
// var runtime = require("@runtime");
//
// var ON = runtime.ON;
// var OFF = runtime.OFF;
// var QuantityType = runtime.QuantityType;
```
| Variable | Description |
2022-09-13 21:57:09 +02:00
|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
2022-06-18 13:24:05 +02:00
| `State` | [`org.openhab.core.types.State` ](https://www.openhab.org/javadoc/latest/org/openhab/core/types/state ) |
| `Command` | [`org.openhab.core.types.Command` ](https://www.openhab.org/javadoc/latest/org/openhab/core/types/command ) |
| `URLEncoder` | [`java.net.URLEncoder` ](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLEncoder.html ) |
| `File` | [`java.io.File` ](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/File.html ) |
| `Files` | [`java.nio.file.Files` ](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/Files.html ) |
| `Path` | [`java.nio.file.Path` ](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/Path.html ) |
| `Paths` | [`java.nio.file.Paths` ](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/Paths.html ) |
| `IncreaseDecreaseType` | [`org.openhab.core.library.types.IncreaseDecreaseType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/increasedecreasetype ) |
| `DECREASE` | `IncreaseDecreaseType` enum item |
| `INCREASE` | `IncreaseDecreaseType` enum item |
| `OnOffType` | [`org.openhab.core.library.types.OnOffType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/onofftype ) |
| `ON` | `OnOffType` enum item |
| `OFF` | `OnOffType` enum item |
| `OpenClosedType` | [`org.openhab.core.library.types.OpenClosedType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/openclosedtype ) |
| `OPEN` | `OpenClosedType` enum item |
| `CLOSED` | `OpenClosedType` enum item |
| `StopMoveType` | [`org.openhab.core.library.types.StopMoveType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/stopmovetype ) |
| `STOP` | `StopMoveType` enum item |
| `MOVE` | `StopMoveType` enum item |
| `UpDownType` | [`org.openhab.core.library.types.UpDownType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/updowntype ) |
| `UP` | `UpDownType` enum item |
| `DOWN` | `UpDownType` enum item |
| `UnDefType` | [`org.openhab.core.library.types.UnDefType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/types/undeftype ) |
| `NULL` | `UnDefType` enum item |
| `UNDEF` | `UnDefType` enum item |
| `RefreshType` | [`org.openhab.core.library.types.RefreshType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/types/refreshtype ) |
| `REFRESH` | `RefreshType` enum item |
| `NextPreviousType` | [`org.openhab.core.library.types.NextPreviusType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/nextprevioustype ) |
| `NEXT` | `NextPreviousType` enum item |
| `PREVIOUS` | `NextPreviousType` enum item |
| `PlayPauseType` | [`org.openhab.core.library.types.PlayPauseType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/playpausetype ) |
| `PLAY` | `PlayPauseType` enum item |
| `PAUSE` | `PlayPauseType` enum item |
| `RewindFastforwardType` | [`org.openhab.core.library.types.RewindFastforwardType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/rewindfastforwardtype ) |
| `REWIND` | `RewindFastforwardType` enum item |
| `FASTFORWARD` | `RewindFastforwardType` enum item |
| `QuantityType` | [`org.openhab.core.library.types.QuantityType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/quantitytype ) |
| `StringListType` | [`org.openhab.core.library.types.StringListType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/stringlisttype ) |
| `RawType` | [`org.openhab.core.library.types.RawType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/rawtype ) |
| `DateTimeType` | [`org.openhab.core.library.types.DateTimeType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/datetimetype ) |
| `DecimalType` | [`org.openhab.core.library.types.DecimalType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/decimaltype ) |
| `HSBType` | [`org.openhab.core.library.types.HSBType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/hsbtype ) |
| `PercentType` | [`org.openhab.core.library.types.PercentType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/percenttype ) |
| `PointType` | [`org.openhab.core.library.types.PointType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/pointtype ) |
| `StringType` | [`org.openhab.core.library.types.StringType` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/stringtype ) |
| `SIUnits` | [`org.openhab.core.library.unit.SIUnits` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/unit/siunits ) |
| `ImperialUnits` | [`org.openhab.core.library.unit.ImperialUnits` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/unit/imperialunits ) |
| `MetricPrefix` | [`org.openhab.core.library.unit.MetricPrefix` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/unit/metricprefix ) |
| `Units` | [`org.openhab.core.library.unit.Units` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/unit/units ) |
| `BinaryPrefix` | [`org.openhab.core.library.unit.BinaryPrefix` ](https://www.openhab.org/javadoc/latest/org/openhab/core/library/unit/binaryprefix ) |
| `ChronoUnit` | [`java.time.temporal.ChronoUnit` ](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/temporal/ChronoUnit.html ) |
| `Duration` | [`java.time.Duration` ](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/Duration.html ) |
| `ZoneId` | [`java.time.ZoneId` ](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/ZoneId.html ) |
| `ZonedDateTime` | [`java.time.ZonedDateTime` ](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/ZonedDateTime.html ) |
`require("@runtime")` also defines "services" such as `items` , `things` , `rules` , `events` , `actions` , `ir` , `itemRegistry` .
You can use these services for backwards compatibility purposes or ease migration from JSR223 scripts.
Generally speaking, you should prefer to use [Standard Library ](#standard-library ) provided by this library instead.