diff --git a/bundles/org.openhab.automation.jsscripting/README.md b/bundles/org.openhab.automation.jsscripting/README.md
index af642e521..a9749d482 100644
--- a/bundles/org.openhab.automation.jsscripting/README.md
+++ b/bundles/org.openhab.automation.jsscripting/README.md
@@ -73,8 +73,8 @@ You can now write rules using standard ES6 JavaScript along with the included op
For example, turning a light on:
```javascript
-items.getItem("KitchenLight").sendCommand("ON");
-console.log("Kitchen Light State", items.getItem("KitchenLight").state);
+items.KitchenLight.sendCommand("ON");
+console.log("Kitchen Light State", items.KitchenLight.state);
```
Sending a notification
@@ -147,7 +147,8 @@ 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 consists of the prefix `org.openhab.automation.script` and the script’s individual part `.file.filename` or `.ui.ruleUID`.
+This logger name can be changed by assigning a new string to the `loggerName` property of the console:
```javascript
console.loggerName = 'org.openhab.custom';
@@ -291,16 +292,18 @@ Use the `SCRIPT` transformation with JavaScript Scripting by:
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.
+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), and import the used namespaces with `const { rules, triggers, items } = require('openhab');` (adjust this to your needs).
+If an API does not provide type definitions and therefore autocompletion won't work, the documentation will include a note.
### Items
-The items namespace allows interactions with openHAB items.
+The `items` namespace allows interactions with openHAB Items.
+Anywhere that a native openHAB `Item` is required, the runtime will automatically convert the JS-`Item` to its Java counterpart.
See [openhab-js : items](https://openhab.github.io/openhab-js/items.html) for full API documentation.
- items : `object`
+ - .NAME ⇒ `Item`
- .getItem(name, nullIfMissing) ⇒ `Item`
- .getItems() ⇒ `Array[Item]`
- .getItemsByTag(...tagNames) ⇒ `Array[Item]`
@@ -310,13 +313,13 @@ See [openhab-js : items](https://openhab.github.io/openhab-js/items.html) for fu
- .safeItemName(s) ⇒ `string`
```javascript
-var item = items.getItem("KitchenLight");
+var item = items.KitchenLight;
console.log("Kitchen Light State", item.state);
```
#### `getItem(name, nullIfMissing)`
-Calling `getItem(...)` returns an `Item` object with the following properties:
+Calling `getItem(...)` or `...` returns an `Item` object with the following properties:
- Item : `object`
- .rawItem ⇒ `HostItem`
@@ -326,34 +329,38 @@ Calling `getItem(...)` returns an `Item` object with the following properties:
- .name ⇒ `string`
- .label ⇒ `string`
- .state ⇒ `string`
+ - .numericState ⇒ `number|null`: State as number, if state can be represented as number, or `null` if that's not the case
+ - .quantityState ⇒ [`Quantity|null`](#quantity): Item state as Quantity or `null` if state is not Quantity-compatible
- .rawState ⇒ `HostState`
- .members ⇒ `Array[Item]`
- .descendents ⇒ `Array[Item]`
- .isUninitialized ⇒ `boolean`
- .groupNames ⇒ `Array[string]`
- .tags ⇒ `Array[string]`
- - .getMetadataValue(namespace) ⇒ `string`
- - .updateMetadataValue(namespace, value) ⇒ `string`
- - .upsertMetadataValue(namespace, value) ⇒ `boolean`
- - .updateMetadataValues(namespaceToValues)
- - .sendCommand(value)
- - .sendCommandIfDifferent(value) ⇒ `boolean`
- - .postUpdate(value)
+ - .getMetadata(namespace) ⇒ `object|null`
+ - .replaceMetadata(namespace, value, configuration) ⇒ `object`
+ - .removeMetadata(namespace) ⇒ `object|null`
+ - .sendCommand(value): `value` can be a string or a [`time.ZonedDateTime`](#time)
+ - .sendCommandIfDifferent(value) ⇒ `boolean`: `value` can be a string or a [`time.ZonedDateTime`](#time)
+ - .postUpdate(value): `value` can be a string or a [`time.ZonedDateTime`](#time)
- .addGroups(...groupNamesOrItems)
- .removeGroups(...groupNamesOrItems)
- .addTags(...tagNames)
- .removeTags(...tagNames)
```javascript
+// Equivalent to items.KitchenLight
var item = items.getItem("KitchenLight");
// Send an ON command
item.sendCommand("ON");
// Post an update
item.postUpdate("OFF");
// Get state
-console.log("KitchenLight state", item.state)
+console.log("KitchenLight state", item.state);
```
+See [openhab-js : Item](https://openhab.github.io/openhab-js/items.Item.html) for full API documentation.
+
#### `itemConfig`
Calling `addItem(itemConfig)` or `replaceItem(itemConfig)` requires the `itemConfig` object with the following properties:
@@ -431,15 +438,15 @@ Calling `Item.history` returns a `ItemHistory` object with the following functio
- .deviationSince(timestamp, serviceId) ⇒ `number | null`
- .evolutionRateBetween(begin, end, serviceId) ⇒ `number | null`
- .evolutionRateSince(timestamp, serviceId) ⇒ `number | null`
- - .historicState(timestamp, serviceId) ⇒ `string | null`
+ - .historicState(timestamp, serviceId) ⇒ `HistoricItem | 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`
+ - .maximumBetween(begin, end, serviceId) ⇒ `HistoricItem | null`
+ - .maximumSince(timestamp,serviceId) ⇒ `HistoricItem | null`
+ - .minimumSince(begin, end, serviceId) ⇒ `HistoricItem | null`
+ - .minimumSince(timestamp, serviceId) ⇒ `HistoricItem | null`
- .persist(serviceId)
- - .previousState(skipEqual, serviceId) ⇒ `string | null`
+ - .previousState(skipEqual, serviceId) ⇒ `HistoricItem | null`
- .sumBetween(begin, end, serviceId) ⇒ `number | null`
- .sumSince(timestamp, serviceId) ⇒ `number | null`
- .updatedBetween(begin, end, serviceId) ⇒ `boolean`
@@ -451,10 +458,24 @@ Note: `serviceId` is optional, if omitted, the default persistence service will
```javascript
var yesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));
-var item = items.getItem('KitchenDimmer');
+var item = items.KitchenDimmer;
console.log('KitchenDimmer averageSince', item.history.averageSince(yesterday));
```
+The `HistoricItem` object contains the following properties, representing Item state and the respective timestamp:
+
+- `state`: State as string
+- `numericState`: State as number, if state can be represented as number, or `null` if that's not the case
+- `quantityState`: Item state as [`Quantity`](#quantity) or `null` if state is not Quantity-compatible
+- `rawState`: State as Java `State` object
+- `timestamp`: Timestamp as [`time.ZonedDateTime`](#time)
+
+```javascript
+var midnight = time.toZDT('00:00');
+var historic = items.KitchenDimmer.history.maximumSince(midnight);
+console.log('KitchenDimmer maximum was ', historic.state, ' at ', historic.timestamp);
+```
+
See [openhab-js : ItemHistory](https://openhab.github.io/openhab-js/items.ItemHistory.html) for full API documentation.
### Things
@@ -531,19 +552,14 @@ See [openhab-js : actions.Exec](https://openhab.github.io/openhab-js/actions.htm
Execute a command line.
```javascript
-
// Execute command line.
actions.Exec.executeCommandLine('echo', 'Hello World!');
// Execute command line with timeout.
-var Duration = Java.type('java.time.Duration');
-actions.Exec.executeCommandLine(Duration.ofSeconds(20), 'echo', 'Hello World!');
-
-// Get response from command line.
-var response = actions.Exec.executeCommandLine('echo', 'Hello World!');
+actions.Exec.executeCommandLine(time.Duration.ofSeconds(20), 'echo', 'Hello World!');
// Get response from command line with timeout.
-response = actions.Exec.executeCommandLine(Duration.ofSeconds(20), 'echo', 'Hello World!');
+var response = actions.Exec.executeCommandLine(time.Duration.ofSeconds(20), 'echo', 'Hello World!');
```
#### HTTP Actions
@@ -564,7 +580,7 @@ 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.
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.
+Keep in mind that you should somehow manage the timers you create using `createTimer`, otherwise you could end up with unmanageable 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`
@@ -703,18 +719,6 @@ if (counter === null) {
console.log('Count', counter.times++);
```
-### Log
-
-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.
-
-```javascript
-var logger = log('my_logger');
-
-//prints "Hello World!"
-logger.debug("Hello {}!", "world");
-```
-
### Time
openHAB internally makes extensive use of the `java.time` package.
@@ -728,7 +732,7 @@ Examples:
```javascript
var now = time.ZonedDateTime.now();
var yesterday = time.ZonedDateTime.now().minusHours(24);
-var item = items.getItem("Kitchen");
+var item = items.Kitchen;
console.log("averageSince", item.history.averageSince(yesterday));
```
@@ -744,20 +748,20 @@ There will be times when this automatic conversion is not available (for example
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');` |
+| 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);` |
+| [`Quantity`](#quantity) or `QuantityType` | if the units are `Time`, that time is added to `now` | `time.toZDT(item.getItem('MyTimeItem').rawState);`, `time.toZDT(Quantity('10 min'));` |
+| `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 | |
+| [ISO8601 Date/Time](https://en.wikipedia.org/wiki/ISO_8601) String | parsed, depending on the provided data: if no date is passed, today's date; if no time is passed, midnight time | `time.toZDT('00:00');`, `time.toZDT('2022-12-24');`, `time.toZDT('2022-12-24T18:30');` |
+| RFC String (output from a Java `ZonedDateTime.toString()`) | parsed | `time.toZDT('2019-10-12T07:20:50.52Z');` |
+| `"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');` |
+| [ISO 8601 Duration](https://en.wikipedia.org/wiki/ISO_8601#Durations) String | added to `now` | `time.toZDT('PT1H4M6.789S');` |
When a type or string that cannot be handled is encountered, an error is thrown.
@@ -768,10 +772,43 @@ 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.
```javascript
-var alarm = items.getItem('Alarm');
+var alarm = items.Alarm;
alarm.postUpdate(time.toZDT(alarm).toToday());
```
+#### `isBeforeTime(timestamp)`, `isBeforeDate(timestamp)`, `isBeforeDateTime(timestamp)`
+
+Tests whether this `time.ZonedDateTime` is before the time passed in `timestamp`, tested in various ways:
+
+- `isBeforeTime` only compares the time portion of both, ignoring the date portion
+- `isBeforeDate` only compares the date portion of both, ignoring the time portion
+- `isBeforeDateTime` compares both date and time portions
+
+`timestamp` can be anything supported by `time.toZDT()`.
+
+Examples:
+
+```javascript
+time.toZDT('22:00').isBeforeTime('23:00')
+time.toZDT('2022-12-01T12:00Z').isBeforeDateTime('2022-12-02T13:00Z')
+```
+
+#### `isAfterTime(timestamp)`, `isAfterDate(timestamp)`, `isAfterDateTime(timestamp)`
+
+Tests whether this `time.ZonedDateTime` is after the time passed in `timestamp`, tested in various ways:
+
+- `isAfterTime` only compares the time portion of both, ignoring the date portion
+- `isAfterDate` only compares the date portion of both, ignoring the time portion
+- `isAfterDateTime` compares both date and time portions
+
+`timestamp` can be anything supported by `time.toZDT()`.
+
+```javascript
+// Equivalent to items.Sunset
+time.toZDT().isAfterTime(items.getItem('Sunset')) // is now after sunset?
+time.toZDT().isAfterDateTime('2022-12-01T12:00Z') // is now after 2022-12-01 noon?
+```
+
#### `isBetweenTimes(start, end)`
Tests whether this `time.ZonedDateTime` is between the passed in `start` and `end`.
@@ -783,10 +820,35 @@ Examples:
```javascript
time.toZDT().isBetweenTimes('22:00', '05:00') // currently between 11:00 pm and 5:00 am
+// Equivalent to items.Sunset
time.toZDT().isBetweenTimes(items.getItem('Sunset'), '11:30 PM') // is now between sunset and 11:30 PM?
+// Equivalent to items.StartTime
time.toZDT(items.getItem('StartTime')).isBetweenTimes(time.toZDT(), 'PT1H'); // is the state of StartTime between now and one hour from now
```
+#### `isBetweenDates(start, end)`
+
+Tests whether this `time.ZonedDateTime` is between the passed in `start` and `end`.
+However, the function only compares the date portion of the three, ignoring the time portion.
+`start` and `end` can be anything supported by `time.toZDT()`.
+
+Examples:
+
+```javascript
+time.toZDT().isBetweenDates('2022-06-18', '2023-12-24') // currently between 2022-06-18 and 2023-12-24
+```
+
+#### `isBetweenDateTimes(start, end)`
+
+Tests whether this `time.ZonedDateTime` is between the passed in `start` and `end`.
+`start` and `end` can be anything supported by `time.toZDT()`.
+
+Examples:
+
+```javascript
+time.toZDT().isBetweenDateTimes('2022-06-18T22:00Z', '2023-12-24T05:00Z') // currently between 2022-06-18 22:00 and 2023-12-24 05: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`.
@@ -808,6 +870,100 @@ var timestamp = time.ZonedDateTime.now().plusMinutes(5);
console.log(timestamp.getMillisFromNow());
```
+### Quantity
+
+The `Quantity` class greatly simplifies Quantity handling by providing unit conversion, comparisons and mathematical operations.
+A Quantity consists of a measurement and its [Unit of Measurement (UoM)](https://www.openhab.org/docs/concepts/units-of-measurement.html#list-of-units), e.g. `5.7 m` (the measurement is `5.7`, the unit is `m` meters).
+
+Internally using the openHAB `QuantityType`, which relies on [`javax.measure`](https://unitsofmeasurement.github.io/unit-api/), it supports all units and dimensions that openHAB supports.
+If your unit is not listed in the UoM docs, it is very likely that it is still supported, e.g. the Angstrom Å for very small lengths (1 Å = 10 nm).
+Anywhere that a native openHAB `QuantityType` is required, the runtime will automatically convert the JS-`Quantity` to its Java counterpart.
+
+#### Creation
+
+`Quantity(value)` is used without new (it's a factory, not a constructor), pass an amount **and** a unit to it to create a new `Quantity` object:
+
+The argument `value` can be a string, a `Quantity` instance or an openHAB Java [`QuantityType`](https://www.openhab.org/javadoc/latest/org/openhab/core/library/types/quantitytype).
+
+`value` strings have the `$amount $unit` format and must follow these rules:
+
+- `$amount` is required with a number provided as string
+- `$unit` is optional (unitless quantities are possible) and can have a prefix like `m` (milli) or `M` (mega)
+- `$unit` does not allow whitespaces.
+- `$unit` does allow superscript, e.g. `²` instead of `^2`.
+- `$unit` requires the `*` between two units to be present, although you usually omit it (which is mathematically seen allowed, but openHAB needs the `*`).
+
+Generally, you can expect a unit consisting of two (or more) units to need a `*`, e.g. `Nm` is `N*m`,
+
+Nearly all [Units of Measurement (UoM)](https://www.openhab.org/docs/concepts/units-of-measurement.html#list-of-units) are expected to work with `Quantity`.
+`ɡₙ` (standard gravity) is known to not work.
+
+```javascript
+// Allowed:
+var qty = Quantity('5.75 m');
+qty = Quantity('1 N*m');
+qty = Quantity('1 m/s');
+qty = Quantity('1 m^2/s^2');
+qty = Quantity('1 m^2/s^-2'); // negative powers
+qty = Quantity('1'); // unitless quantity
+
+// Not allowed:
+qty = Quantity('m');
+qty = Quantity('1 Nm'); // * is required
+qty = Quantity('1 m^2 / s^2'); // whitespaces are not allowed
+qty = Quantity('1 m^2 s^2'); // / is required
+qty = Quantity('1 m2/s2'); // ^ is required
+```
+
+#### Conversion
+
+It is possible to convert a `Quantity` to a new `Quantity` with a different unit or to get a `Quantity`'s amount as integer or float:
+
+```javascript
+var qty = Quantity('10.2 °C');
+
+qty = qty.toUnit('°F');
+var intValue = qty.int;
+var floatValue = qty.float;
+```
+
+`toUnit` returns a new Quantity with the given unit or `null`, if conversion to that unit is not possible.
+
+#### Comparison
+
+`Quantity` provides the following methods for comparison:
+
+- `equal(value)` ⇒ `boolean`: this `Quantity` equals to `value`
+- `greaterThan(value)` ⇒ `boolean`: this `Quantity` is greater than `value`
+- `greaterThanOrEqual(value)` ⇒ `boolean`: this `Quantity` is greater than or equal to `value`
+- `lessThan(value)` ⇒ `boolean`: this `Quantity` is less than `value`
+- `lessThanOrEqual(value)` ⇒ `boolean`: this `Quantity` is less than or equal to `value`
+
+`value` can be a string or a `Quantity`, for the string the same rules apply as described above.
+
+#### Mathematical Operators
+
+- `add(value)` ⇒ `Quantity`: `value` can be a string or a `Quantity`
+- `divide(value)` ⇒ `Quantity`: `value` can be a number, a string or a `Quantity`
+- `multiply(value)` ⇒ `Quantity`: `value` can be a number, a string or a `Quantity`
+- `subtract(value)` ⇒ `Quantity`: `value` can be a string or a `Quantity`
+
+For the string the same rules apply as described above.
+
+See [openhab-js : Quantity](https://openhab.github.io/openhab-js/Quantity.html) for full API documentation.
+
+### Log
+
+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.
+
+```javascript
+var logger = log('my_logger');
+
+//prints "Hello World!"
+logger.debug("Hello {}!", "world");
+```
+
### Utils
openHAB internally is a Java program.
@@ -837,6 +993,7 @@ rules.JSRule({
description: "Light will turn on when it's 5:00pm",
triggers: [triggers.GenericCronTrigger("0 0 17 * * ?")],
execute: (event) => {
+ // Equivalent to items.BalconyLights.sendCommand("ON")
items.getItem("BalconyLights").sendCommand("ON");
actions.NotificationAction.sendNotification(email, "Balcony lights are ON");
},
diff --git a/bundles/org.openhab.automation.jsscripting/pom.xml b/bundles/org.openhab.automation.jsscripting/pom.xml
index 4817609df..f54bdb3e6 100644
--- a/bundles/org.openhab.automation.jsscripting/pom.xml
+++ b/bundles/org.openhab.automation.jsscripting/pom.xml
@@ -24,7 +24,7 @@
22.0.0.2${project.version}
- openhab@3.2.4
+ openhab@4.0.0
diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java
deleted file mode 100644
index 1661eb1ad..000000000
--- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Copyright (c) 2010-2023 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.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.function.Consumer;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Allows scripts to register for lifecycle events
- *
- * @author Jonathan Gilbert - Initial contribution
- */
-public class Lifecycle implements ScriptDisposalAware {
- private static final Logger logger = LoggerFactory.getLogger(Lifecycle.class);
- public static final int DEFAULT_PRIORITY = 50;
- private List listeners = new ArrayList<>();
-
- public void addDisposeHook(Consumer