diff --git a/README.md b/README.md index 3783c04a2..f7784a137 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ binding](https://www.openhab.org/addons/automation/jsscripting/). - [Paths](#paths) - [Standard Library](#standard-library) - [Items](#items) + - [Things](#things) - [Actions](#actions) - [Cache](#cache) - [Log](#log) @@ -393,6 +394,43 @@ var item = items.getItem("KitchenDimmer"); console.log("KitchenDimmer averageSince", item.history.averageSince(yesterday)); ``` +### 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. + +* things : object + * .getItem(uid, nullIfMissing) ⇒ Thing + * .Things() ⇒ Array.<Thing> + +#### `getThing(uid, nullIfMissing)` + +Calling `getThing(...)` returns a `Thing` object with the following properties: + +* Thing : object + * .bridgeUID ⇒ String + * .label ⇒ String + * .location ⇒ String + * .status ⇒ String + * .statusInfo ⇒ String + * .thingTypeUID ⇒ String + * .uid ⇒ String + * .isEnabled ⇒ Boolean + * .setLabel(label) + * .setLocation(location) + * .setProperty(name, value) + * .setEnabled(enabled) + +```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); +``` + ### Actions The actions namespace allows interactions with openHAB actions. diff --git a/index.js b/index.js index a607bf053..2c75087b2 100644 --- a/index.js +++ b/index.js @@ -13,6 +13,9 @@ /** * @typedef {Object} HostTrigger Native Jave openHAB Trigger (instance of {@link https://www.openhab.org/javadoc/latest/org/openhab/core/automation/trigger org.openhab.core.automation.Trigger}) */ +/** + * @typedef {Object} HostThing Native Java openHAB Thing (instance of {@link https://www.openhab.org/javadoc/latest/org/openhab/core/thing/thing org.openhab.core.thing.Thing}) + */ // lazy getters to avoid any reference loading all submodules module.exports = { diff --git a/things/things.js b/things/things.js index 2154ff80c..2a74ffcc7 100644 --- a/things/things.js +++ b/things/things.js @@ -1,3 +1,10 @@ +const osgi = require('../osgi'); +const utils = require('../utils'); +const log = require('../log')('things'); // eslint-disable-line no-unused-vars + +const thingRegistry = osgi.getService('org.openhab.core.thing.ThingRegistry'); +const thingMgr = osgi.getService('org.openhab.core.thing.ThingManager'); + const JavaThingBuilder = Java.type('org.openhab.core.thing.binding.builder.ThingBuilder'); const ThingTypeUID = Java.type('org.openhab.core.thing.ThingTypeUID'); const JavaChannelBuilder = Java.type('org.openhab.core.thing.binding.builder.ChannelBuilder'); @@ -7,6 +14,13 @@ const ChannelKind = Java.type('org.openhab.core.thing.type.ChannelKind'); const ChannelTypeUID = Java.type('org.openhab.core.thing.type.ChannelTypeUID'); const Configuration = Java.type('org.openhab.core.config.core.Configuration'); +/** + * Things namespace. + * This namespace handles querying and editing openHAB Things. + * + * @namespace things + */ + class OHThing { constructor (rawThing) { this.rawThing = rawThing; @@ -95,7 +109,154 @@ class ChannelBuilder { } } +/** + * Class representing an openHAB Thing + * + * @memberof things + */ +class Thing { + /** + * Create an Thing, wrapping a native Java openHAB Thing. Don't use this constructor, instead call {@link getThing}. + * @param {HostThing} rawThing Java Thing from Host + * @hideconstructor + */ + constructor (rawThing) { + if (typeof rawThing === 'undefined') { + throw Error('Supplied Thing is undefined'); + } + this.rawThing = rawThing; + } + + /** + * Thing's bridge UID as `String` + */ + get bridgeUID () { + try { + return this.rawThing.getBridgeUID().getID(); + } catch (error) { + // Thing has no bridge + } + } + + /** + * label as `String` + */ + get label () { + return this.rawThing.getLabel(); + } + + /** + * physical location as `String` + */ + get location () { + return this.rawThing.getLocation(); + } + + /** + * status as `String` + */ + get status () { + return this.rawThing.getStatus().toString(); + } + + /** + * status info (more detailed status text) as `String` + */ + get statusInfo () { + return this.rawThing.getStatusInfo().toString(); + } + + /** + * Thing type UID as `String` + */ + get thingTypeUID () { + return this.rawThing.getThingTypeUID().toString(); + } + + /** + * Thing UID as `String` + */ + get uid () { + return this.rawThing.getUID().toString(); + } + + /** + * whether the Thing is enabled or not (`Boolean`) + */ + get isEnabled () { + return this.rawThing.isEnabled(); + } + + /** + * Set the label. + * @param {String} label Thing label + */ + setLabel (label) { + this.rawThing.setLabel(label); + } + + /** + * Sets the physical location. + * @param {String} location physical location of the Thing + */ + setLocation (location) { + this.rawThing.setLocation(location); + } + + /** + * Sets the property value for the property identified by the given name. + * @param {String} name name of the property + * @param {String} value value for the property + */ + setProperty (name, value) { + this.rawThing.setProperty(name, value); + } + + /** + * Sets the enabled status of the Thing. + * @param {Boolean} enabled whether the Thing is enabled or not + */ + setEnabled (enabled) { + thingMgr.setEnabled(this.rawThing.getUID(), enabled); + } +} + +/** + * Gets an openHAB Thing. + * + * @memberof things + * @param {String} uid UID of the thing + * @param {Boolean} [nullIfMissing] whether to return null if the Thing cannot be found (default is to throw an exception) + * @returns {things.Thing} the Thing + */ +const getThing = function (uid, nullIfMissing) { + try { + if (typeof uid === 'string' || uid instanceof String) { + return new Thing(thingRegistry.get(new ThingUID(uid))); + } + } catch (e) { + if (nullIfMissing) { + return null; + } else { + throw e; + } + } +}; + +/** + * Gets all openHAB Things. + * + * @memberof things + * @returns {things.Thing[]} all Things + */ +const getThings = function () { + return utils.javaSetToJsArray(thingRegistry.getAll()).map(i => new Thing(i)); +}; + module.exports = { newThingBuilder: (thingTypeUID, id, bridgeUID) => new ThingBuilder(thingTypeUID, id, bridgeUID), - newChannelBuilder: (thingUID, channelId, acceptedItemType) => new ChannelBuilder(thingUID, channelId, acceptedItemType) + newChannelBuilder: (thingUID, channelId, acceptedItemType) => new ChannelBuilder(thingUID, channelId, acceptedItemType), + Thing, + getThing, + getThings };