diff --git a/.gitignore b/.gitignore index 600d2d3..7c78742 100755 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.vscode \ No newline at end of file +.vscode +node_modules diff --git a/countdownTimer.js b/countdownTimer.js index e1b4df6..cf549cb 100755 --- a/countdownTimer.js +++ b/countdownTimer.js @@ -14,8 +14,9 @@ class CountdownTimer { * @param {*} when time.toZDT compatible time or duration * @param {function} func function to call at when * @param {string} countItem name of the Item to update with the seconds remaining + * @param {string} [name] countdown name displayed in openHAB */ - constructor(when, func, countItem) { + constructor(when, func, countItem, name) { this.start = time.toZDT(); this.end = time.toZDT(when); this.ONE_SEC = time.Duration.ofSeconds(1); @@ -27,7 +28,7 @@ class CountdownTimer { // Start the countdown timer this.countItem = countItem; this.countdownTimer = new loopingTimer.LoopingTimer(); - this.countdownTimer.loop(this._iterateGenerator(this), 0); // start now + this.countdownTimer.loop(this._iterateGenerator(this), 0, name); // start now } /** diff --git a/gatekeeper.js b/gatekeeper.js index 17043b0..2bc8bdd 100755 --- a/gatekeeper.js +++ b/gatekeeper.js @@ -1,4 +1,6 @@ const { time } = require('openhab'); +const helpers = require('./helpers'); + /** * Class that implements the Gatekeeper design pattern. When the user calls * addCommand, it will queue them up so that a new command is not called until @@ -8,11 +10,14 @@ class Gatekeeper { /** * Creates the Gatekeeper + * + * @param {string} [name] name of the Gatekeeper (used for the timer) */ - constructor() { + constructor(name) { var ArrayDeque = Java.type('java.util.ArrayDeque'); this.commands = new ArrayDeque(); this.timer = null; + this.name = name; } /** @@ -41,7 +46,7 @@ class Gatekeeper { const pause = time.toZDT(command[0]); const triggerTime = pause.minus(delta); - ctx.timer = actions.ScriptExecution.createTimer(triggerTime, ctx._procCommandGenerator(ctx)); + ctx.timer = helpers.createTimer(triggerTime, ctx._procCommandGenerator(ctx), null, this.name, 'gatekeeper'); } }; diff --git a/helpers.js b/helpers.js new file mode 100644 index 0000000..755c139 --- /dev/null +++ b/helpers.js @@ -0,0 +1,29 @@ +const { actions, time } = require('openhab'); + +/** + * Utility function to create a named timer. + * + * The name can be set with the name parameter or is autogenerated from the ruleUID (for UI) or filename and the timer's key (if available). + * + * @param {*} when any representation of time or duration, see {@link https://openhab.github.io/openhab-js/time.html#.toZDT time.toZDT} + * @param {function} func function to call when the timer expires + * @param {*} [arg] argument to pass to the timer + * @param {string} [name] name for the timer + * @param {string} [key] key of the timer to append to the generated name + * @returns openHAB Java {@link https://www.openhab.org/javadoc/latest/org/openhab/core/model/script/actions/timer Timer} + */ +const createTimer = (when, func, arg, name, key) => { + const timeout = time.toZDT(when); + if (name === null || name === undefined) { + if (global.ruleUID !== undefined) { // Use UI ruleUID and key if available + name = 'ui.' + global.ruleUID + ((key !== undefined) ? '.' + key : ''); + } else if (global['javax.script.filename'] !== undefined) { // Use filename and key if available + name = 'file.' + global['javax.script.filename'].replace(/^.*[\\/]/, '') + ((key !== undefined) ? '.' + key : ''); + } + } + return actions.ScriptExecution.createTimerWithArgument(name, timeout, arg, func); +}; + +module.exports = { + createTimer +}; diff --git a/loopingTimer.js b/loopingTimer.js index e1c2a62..617db9a 100755 --- a/loopingTimer.js +++ b/loopingTimer.js @@ -1,4 +1,4 @@ -const { time } = require('openhab'); +const helpers = require('./helpers'); /** * Implements a looping Timer which is passed a function that is expected to return @@ -18,15 +18,15 @@ class LoopingTimer { * Kicks off the timer loop. Schedules a timer to call func at when * @param {function} func function to call at when, must return a when to continue the loop or null to stop * @param {*} when any of the types supported by time.toZDT + * @param {string} [name] timer name displayed in openHAB */ - loop(func, when) { + loop(func, when, name) { this.func = func; + this.name = name; if (!when) this.expired(); else { - this.timer = actions.ScriptExecution.createTimer( - time.toZDT(when), - () => this.expired()); + this.timer = helpers.createTimer(when, () => this.expired(), null, name, 'loopingTimer'); } } @@ -38,9 +38,9 @@ class LoopingTimer { expired() { var when = this.func(); if (when) { - this.timer = actions.ScriptExecution.createTimer( + this.timer = helpers.createTimer( time.toZDT(when), - () => this.expired()); + () => this.expired(), null, this.name, 'loopingTimer'); } } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..f14d5d9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,37 @@ +{ + "name": "openhab_rules_tools", + "version": "1.1.3", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@js-joda/core": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@js-joda/core/-/core-4.3.1.tgz", + "integrity": "sha512-oeaetlodcqVsiZDxnEcqsbs+sXBkASxua0mXs5OXuPQXz3/wdPTMlxwfQ4z2HKcOik3S9voW3QJkp/KLWDhvRQ==", + "dev": true + }, + "@js-joda/timezone": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@js-joda/timezone/-/timezone-2.14.0.tgz", + "integrity": "sha512-P1Ft2yyVdHOrBSGC73NMs8rJEkk8VbDGD3iXcI15jfBC3MxYhorl/0n6pCUG+Vsy8i0GvEudP4ELSGu0mq46MA==", + "dev": true + }, + "openhab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/openhab/-/openhab-2.0.3.tgz", + "integrity": "sha512-Lp1gBhsOi6ff0DRV0TOblbQWlB87OORXLb3VoYn5ZbTp/k8oWxJNAzO/yC5F5iYXVuPUg/FAWSstyJB3cC4XfA==", + "dev": true, + "requires": { + "@js-joda/core": "^4.3.1", + "@js-joda/timezone": "^2.11.1", + "parse-duration": "^0.1.1" + } + }, + "parse-duration": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.3.tgz", + "integrity": "sha512-hMOZHfUmjxO5hMKn7Eft+ckP2M4nV4yzauLXiw3PndpkASnx5r8pDAMcOAiqxoemqWjMWmz4fOHQM6n6WwETXw==", + "dev": true + } + } +} diff --git a/package.json b/package.json index e1caa2a..41d0ff2 100755 --- a/package.json +++ b/package.json @@ -19,5 +19,8 @@ "author": "Richard Koshak", "bugs": { "url": "https://github.com/rkoshak/openhab-rules-tools/issues" + }, + "devDependencies": { + "openhab": "^2.0.3" } -} \ No newline at end of file +} diff --git a/timerMgr.js b/timerMgr.js index 811e32c..ec53fd2 100755 --- a/timerMgr.js +++ b/timerMgr.js @@ -1,4 +1,5 @@ const { time } = require('openhab'); +const helpers = require('./helpers'); /** * Implements a manager for Timers with a simple interface. Once built, call @@ -49,15 +50,15 @@ class TimerMgr { * the timer using when. * If there is a timer already associated with key, if a flappingFunc is * provided, call it. - * @param {*} key usually a String, the "name" of the timer + * @param {string} key the identifier of the timer in the TimerMgr instance * @param {*} when any representation of time of duration, see time.toZDT - * @param {function} func optional function to call when the timer expires - * @param {boolean} reschedule optional flag, when present and true rescheudle the timer if it already exists - * @param {function} flappingFunc optional function to call when the timer already exists + * @param {function} func function to call when the timer expires + * @param {boolean} [reschedule=false] optional flag, when present and true rescheudle the timer if it already exists + * @param {function} [flappingFunc] optional function to call when the timer already exists + * @param {string} [name] timer name displayed in openHAB */ - check(key, when, func, reschedule, flappingFunc) { - - var timeout = time.toZDT(when); + check(key, when, func, reschedule, flappingFunc, name) { + const timeout = time.toZDT(when); // timer exists if (key in this.timers) { @@ -74,9 +75,7 @@ class TimerMgr { // timer doesn't already exist, create a new one else { - var timer = actions.ScriptExecution.createTimerWithArgument(timeout, - this, - this._notFlapping(key)); + var timer = helpers.createTimer(when, this._notFlapping(key), this, name, key); this.timers[key] = { 'timer': timer, 'flapping': flappingFunc,