Hello community,
my current task is to realize a rule-template for one LCN-key and a HUE-light/group. The key should offer the with the following functions:
- pressed short → toggle light On/Off
- pressed long → dim light Up or Down
- release long pressed → stop dimming
- pressed short + long → change the color of a HUE lamp
- double pressed short → now specified yet
LCN offers for one switch the values HIT (short) / MAKE (long) / BREAK (release). I used this to set some virtual releais with the LCN software:
- HIT(short) → toggle Relais7
- MAKE (long) → set Relais8 to ON
- BREAK(release) → set Relais8 to OFF
The idear is to measure the time between to key hits. If this time is within an defind threshold (doublePressedTime) the second action will be performed (4. or 5.) otherwise the normal action (1.-3.) will be performed. So the first detection of a short pressed key (Relais7 changes it’s state) should start timer. If the timer terminates the normal action for this key (1. pressed short) should take action. But If a second trigger occurs, while the timer is running, the timer should be canceled and the second trigger action while be performed (4. or 5.).
Okay that’s the problem and the idear to solve this. This leads to the following code … without the actions to control the HUE lamp.
var keyPressedShort = "Module11KGStef_Relais7";
var keyPressedLongOrRelease = "Module11KGStef_Relais8";
var doublePressedTime = 600 ; // Unit = ms
var triggerTime = Java.type('java.time.Instant') ;
var triggerItemName;
var lastActionTime, currentActionTime, deltaActionTime ;
var actionState
var scriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution');
var zdt = Java.type('java.time.ZonedDateTime');
if (typeof this.timers === 'undefined') {
this.timers = [];
}
// estimate the time between to trigger-events
if (lastActionTime == NaN) lastActionTime = 0;
currentActionTime = triggerTime.now().toEpochMilli() ;
deltaActionTime = currentActionTime - lastActionTime ;
lastActionTime = currentActionTime ;
if ((triggerItemName = event.itemName) == keyPressedShort) {
if (deltaActionTime < doublePressedTime){
// Timer is running/defined --> second time pressed within the doublePressedTime
if (typeof this.timers['KeyTimer'] !== 'undefined') {
this.timers['KeyTimer'].cancel();
this.timers['KeyTimer'] = undefined;
actionState = 'ShortTwice' ;
}
} else {
// Not running Timer --> first hit ... so start a timer for doublePressedTime
if (typeof this.timers['KeyTimer'] === 'undefined' || (this.timers['KeyTimer'].hasTerminated())) {
actionState = 'FirstAction';
this.timers['KeyTimer'] = scriptExecution.createTimer(zdt.now().plusNanos(doublePressedTime*1000), function () {
if (typeof this.timers['KeyTimer'] !== 'undefined') {
this.timers['KeyTimer'].cancel();
this.timers['KeyTimer'] = undefined;
actionState = 'ShortOnce' ;
print (actionState) ;
}
})
} else {
this.timers['KeyTimer'].cancel();
this.timers['KeyTimer'] = undefined;
actionState = 'TimerProblems' ;
}
}
} else {
// keyPressedLongOrRelease was hit ...
if ((typeof this.timers['KeyTimer'] !== 'undefined') && ((this.timers['KeyTimer'].isRunning()) || this.timers['KeyTimer'].hasTerminated())) {
this.timers['KeyTimer'].cancel();
this.timers['KeyTimer'] = undefined;
actionState = 'ShortPlus' ;
}
if (itemRegistry.getItem(keyPressedLongOrRelease).getState() == 'ON') {
if (actionState == 'ShortPlus') {
actionState = 'ShortPlusLong' ;
} else {
actionState = 'Long' ;
}
} else {
actionState = 'Released' ;
}
};
print ('-----------------------------')
print (triggerItemName);
print(deltaActionTime) ;
print(actionState) ;
From my point of view the js script above should to what I want … but I can’t get a “ShortPlusLong” or a “ShortTwice” actionState alltough I pressed the key within the “doublePressedTime” a second time.
This relates to some questions:
- Is there a possibility to add MilliSecond directly at “createTimer(zdt.now().plusxxx” (I can’t find a hint for that and NanoSeconds will realy make no sence)?
- What exactly happends, when I start a timer?
** Will the script stop and will be continuied when the timer expires?
** Will only the code within scriptExecution.createTimer ( … ) backets executed, or this code plus the rest of the script?
** Will the scripped triggered a second time, while the timer is running (this is what I expect)? - Can someone see a logical ot syntaktical mistake within the script?
I would be greate, if someone can help me to fix this behavior.
Thanks an best regards
Stef