Skip to content

Commit

Permalink
Merge pull request #107 from rkoshak/oh4Updates
Browse files Browse the repository at this point in the history
Updates to library for OH 4
  • Loading branch information
rkoshak authored Aug 18, 2023
2 parents 4400d39 + a3894f7 commit 31285c4
Show file tree
Hide file tree
Showing 23 changed files with 369 additions and 330 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ New to OH 3.4 release, a system wide cache has been added where variables can be
On can pull, and if it doesn't exist instantiate a Object in one line inside your rule.

```
var timers = cache.shared.get('timers', () new timerMgr.TimerMgr());
var timers = cache.shared.get('timers', () TimerMgr());
```

It is important to use unique keys across all your rules to avoid collisions.
Expand Down
30 changes: 22 additions & 8 deletions countdownTimer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { loopingTimer } = require('openhab_rules_tools');
const { LoopingTimer } = require('openhab_rules_tools');
const { time, items } = require('openhab');

/**
Expand Down Expand Up @@ -27,16 +27,16 @@ class CountdownTimer {

// Start the countdown timer
this.countItem = countItem;
this.countdownTimer = new loopingTimer.LoopingTimer();
this.countdownTimer.loop(this._iterateGenerator(this), 0, name); // start now
this.countdownTimer = LoopingTimer();
this.countdownTimer.loop(this.#iterateGenerator(this), 0, name); // start now
}

/**
* Determines the number of seconds left and updates the count Item. If the
* time left is less than a second, 0 is the value posted.
* @param {CountdownTimer} ctx Context to access the timer information from inside the countdown Timer's lambda
*/
_updateItem(ctx) {
#updateItem(ctx) {
let left = (ctx.timeLeft.compareTo(ctx.ONE_SEC) < 0) ? 0 : ctx.timeLeft.seconds();
items.getItem(ctx.countItem).postUpdate(left);
}
Expand All @@ -46,9 +46,9 @@ class CountdownTimer {
* the time has run out, calling updateItem each time.
* @param {CountdownTimer} ctx Context to access the timer information from inside the looping timer
*/
_iterateGenerator(ctx) {
#iterateGenerator(ctx) {
return () => {
ctx._updateItem(ctx);
ctx.#updateItem(ctx);
if (!ctx.timeLeft.isZero()) {
let sleepTime = (ctx.timeLeft.compareTo(ctx.ONE_SEC) < 0) ? ctx.timeLeft : ctx.ONE_SEC;
ctx.timeLeft = ctx.timeLeft.minusDuration(sleepTime);
Expand All @@ -73,12 +73,26 @@ class CountdownTimer {
*/
cancel() {
this.timeLeft = time.Duration.ofSeconds(0);
this._updateItem(this);
this.#updateItem(this);
this.countDownTimer?.cancel();
return this.timer.cancel();
}
}

/**
* A countdown timer updates an Item with the number of seconds left in the timer
* once a second.
* @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
* @returns a new CountdownTimer
*/
function getCountdownTimer(when, func, countItem, name) {
return new CountdownTimer(when, func, countItem, name);
}

module.exports = {
CountdownTimer
CountdownTimer,
getCountdownTimer
}
24 changes: 17 additions & 7 deletions deferred.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { timerMgr } = require('openhab_rules_tools');
const { TimerMgr } = require('openhab_rules_tools');
const { time, items } = require('openhab');

/**
Expand All @@ -10,7 +10,7 @@ class Deferred {
* Constructor
*/
constructor() {
this.timers = new timerMgr.TimerMgr();
this.timers = TimerMgr();
}

/**
Expand All @@ -19,7 +19,7 @@ class Deferred {
* @param {string} value command or update to send
* @param {boolean} isCommand when true, value will be sent as a command, otherwise posted as an update
*/
_timerBodyGenerator(target, value, isCommand) {
#timerBodyGenerator(target, value, isCommand) {
const item = items.getItem(target);
return () => (isCommand) ? item.sendCommand(value) : item.postUpdate(value);
}
Expand All @@ -34,11 +34,11 @@ class Deferred {
*/
defer(target, value, when, isCommand) {
const triggerTime = time.toZDT(when);
if (triggerTime.isBefore(time.ZonedDateTime.now())) {
triggerTime = time.ZonedDateTime.now();
if (triggerTime.isBefore(time.toZDT())) {
triggerTime = time.toZDT();
}
this.timers.cancel(target);
this.timers.check(target, triggerTime, this._timerBodyGenerator(target, value, isCommand, when), false);
this.timers.check(target, triggerTime, this.#timerBodyGenerator(target, value, isCommand, when), false);
}

/**
Expand All @@ -57,6 +57,16 @@ class Deferred {
}
}

/**
* Deferred is a way to schedule a simple command sometime in the future.
*
* @returns a new instance of Deferred
*/
function getDeferred() {
return new Deferred();
}

module.exports = {
Deferred
Deferred,
getDeferred
}
23 changes: 17 additions & 6 deletions gatekeeper.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Gatekeeper {
* @parm {*} ctx pointer to the Gatekeeper OPbject.
* @returns {function} function called by the timer to process the next command.
*/
_procCommandGenerator(ctx) {
#procCommandGenerator(ctx) {
return () => {

// no more commands
Expand All @@ -38,15 +38,15 @@ class Gatekeeper {
else {
const command = ctx.commands.pop();
const func = command[1];
const before = time.ZonedDateTime.now();
const before = time.toZDT();
func();
const after = time.ZonedDateTime.now();
const after = time.toZDT();

const delta = time.Duration.between(before, after);
const pause = time.toZDT(command[0]);
const triggerTime = pause.minus(delta);

ctx.timer = helpers.createTimer(triggerTime, ctx._procCommandGenerator(ctx), this.name, 'gatekeeper');
ctx.timer = helpers.createTimer(triggerTime, ctx.#procCommandGenerator(ctx), this.name, 'gatekeeper');
}

};
Expand All @@ -61,7 +61,7 @@ class Gatekeeper {
addCommand(pause, command) {
this.commands.add([pause, command]);
if (this.timer === null || this.timer.hasTerminated()) {
this._procCommandGenerator(this)();
this.#procCommandGenerator(this)();
}
}

Expand All @@ -76,6 +76,17 @@ class Gatekeeper {
}
}

/**
* The Gatekeeper will ensure that a certain amount of time passes between
* commands.
* @param {String} name optional and used in error messages
* @returns a new Gatekeeper instance
*/
function getGatekeeper(name) {
return new Gatekeeper(name);
}

module.exports = {
Gatekeeper
Gatekeeper,
getGatekeeper
}
6 changes: 3 additions & 3 deletions helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ const createTimer = (when, func, name, key) => {
* @returns {boolean} true if validation passes, false if there's a problem
**/
const checkGrpAndMetadata = (namespace, grp, validateFunc, usage) => {
let isGood = true;
let badItems = [];
const isGood = true;
const badItems = [];

// Get all the Item with NAMESPACE metadata
// Get all the Items with NAMESPACE metadata
const allItems = items.getItems();
const filtered = allItems.filter(item => item.getMetadata(namespace));

Expand Down
36 changes: 30 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
module.exports = {
get timeUtils() { return require('./timeUtils.js') },
get timerMgr() { return require('./timerMgr.js') },
get loopingTimer() { return require('./loopingTimer.js') },
get rateLimit() { return require('./rateLimit.js') },
get timerMgr() {
console.warn('require TimerMgr instead of timerMgr and use TimerMgr() instead of new timerMgr.TimerMgr().');
return require('./timerMgr.js')
},
get TimerMgr() { return require('./timerMgr.js').getTimerMgr; },
get loopingTimer() {
console.warn('require LoopingTimer instead of loopingTimer and use LoopingTimer() instead of new loopingTimer.LoopingTimer().');
return require('./loopingTimer.js')
},
get LoopingTimer() { return require('./loopingTimer.js').getLoopingTimer; },
get rateLimit() {
console.warn('require RateLimit instead of rateLimit and use RateLimit() instead of new rateLimit.RateLimit().');
return require('./rateLimit.js')
},
get RateLimit() { return require('./rateLimit.js').getRateLimit; },
get testUtils() { return require('./testUtils.js') },
get gatekeeper() { return require('./gatekeeper.js') },
get deferred() { return require('./deferred.js') },
get countdownTimer() { return require('./countdownTimer.js') },
get gatekeeper() {
console.warn('require Gatekeeper instead of gatekeeper and use Gatekeeper() instead of new gatekeeper.Gatekeeper().');
return require('./gatekeeper.js');
},
get Gatekeeper() { return require('./gatekeeper.js').getGatekeeper; },
get deferred() {
console.warn('require Deferred instead of deferred and use Deferred() instead of new deferred.Deferred().');
return require('./deferred.js');
},
get Deferred() { return require('./deferred.js').getDeferred; },
get countdownTimer() {
console.warn('require CountdownTimer instead of countdownTimer and use CountdownTimer() instead of new countdownTimer.CountdownTimer().');
return require('./countdownTimer.js');
},
get CountdownTimer() { return require('./countdownTimer.js').getCountdownTimer; },
get groupUtils() { return require('./groupUtils.js') },
get rulesUtils() { return require('./rulesUtils.js') },
get helpers() { return require('./helpers.js') }
Expand Down
11 changes: 10 additions & 1 deletion loopingTimer.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ class LoopingTimer {
}
}

/**
* @returns a timer that resheduels itself until the passed in looping function
* return null
*/
function getLoopingTimer() {
return new LoopingTimer();
}

module.exports = {
LoopingTimer
LoopingTimer,
getLoopingTimer
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openhab_rules_tools",
"version": "2.0.2",
"version": "2.0.3",
"description": "Functions and classes to make writing openHAB rules in JS Scripting easier.",
"private": false,
"license": "EPL-2.0",
Expand All @@ -21,6 +21,6 @@
"url": "https://github.com/rkoshak/openhab-rules-tools/issues"
},
"devDependencies": {
"openhab": "^4.1.0"
"openhab": "^4.5.1"
}
}
}
13 changes: 11 additions & 2 deletions rateLimit.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ class RateLimit {
}
}

/**
* The RateLimit class keeps track of when the last `run` was called and throws
* away subsequent calls to run that occur before the passed in `when`.
*/
function getRateLimit() {
return new RateLimit();
}

module.exports = {
RateLimit
}
RateLimit,
getRateLimit
}
10 changes: 5 additions & 5 deletions rule-templates/debounce/debounce2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,16 @@ actions:
configuration:
type: application/javascript
script: >
// Version 0.2
// Version 0.3
var {timerMgr, helpers} = require('openhab_rules_tools');
var {TimerMgr, helpers} = require('openhab_rules_tools');
console.loggerName = 'org.openhab.automation.rules_tools.Debounce';
//osgi.getService('org.apache.karaf.log.core.LogService').setLevel(console.loggerName, 'DEBUG');
helpers.validateLibraries('4.1.0', '2.0.1');
helpers.validateLibraries('4.1.0', '2.0.3');
var USAGE = "Debounce metadata should follow this format:\n"
Expand All @@ -93,7 +93,7 @@ actions:
*/
var getConfig = (itemName) => {
const md = items[itemName].getMetadata()['{{namespace}}'];
const md = items[itemName].getMetadata()['{{namespace}}'];
if(!md) {
throw itemName + ' does not have {{namespace}} metadata!\n' + USAGE;
}
Expand Down Expand Up @@ -159,7 +159,7 @@ actions:
console.debug('Debounce:', event.type, 'item:', event.itemName);
// Initialize the timers, config and end debounce function
const timers = cache.private.get('timerMgr', () => new timerMgr.TimerMgr());
const timers = cache.private.get('timerMgr', () => TimerMgr());
const cfg = getConfig(event.itemName);
const endDebounce = endDebounceGenerator(event.itemName, event.itemState, cfg.proxy, cfg.command);
Expand Down
8 changes: 4 additions & 4 deletions rule-templates/ephemToD/time_state_machine.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@ actions:
configuration:
type: application/javascript
script: >
// Version 0.2
// Version 0.3
var {timerMgr, helpers} = require('openhab_rules_tools');
var {TimerMgr, helpers} = require('openhab_rules_tools');
console.loggerName = 'org.openhab.automation.rules_tools.TimeStateMachine';
//osgi.getService('org.apache.karaf.log.core.LogService').setLevel(console.loggerName, 'DEBUG');
helpers.validateLibraries('4.2.0', '2.0.1');
helpers.validateLibraries('4.2.0', '2.0.3');
console.debug('Starting state machine in ten seconds...');
Expand Down Expand Up @@ -316,7 +316,7 @@ actions:
};
var timers = cache.private.get('timers', () => new timerMgr.TimerMgr());
var timers = cache.private.get('timers', () => TimerMgr());
// Wait a minute after the last time the rule is triggered to make sure all Items are done changing (e.g.
Expand Down
Loading

0 comments on commit 31285c4

Please sign in to comment.