For who want to have some functions that can be activated only by digiting a PIN code, here what I have done.
keypad.items
//KeyPad Items
Number KP_PinDigit
String KP_Status "Status [%s]"
Number KP_Result
Switch KP_TriggerOK
Switch KP_TriggerKO
// Function Example Items
Switch X_AlarmStatus "[%s]" <siren>
keypad.rules
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.openhab.core.types.State
import org.openhab.core.types.*
import java.util.concurrent.locks.ReentrantLock
import java.util.HashMap
import java.util.LinkedHashMap
import java.util.ArrayList
import java.util.Map
var java.util.concurrent.locks.ReentrantLock lock = new java.util.concurrent.locks.ReentrantLock()
var String MSG_PIN_OK = "PIN OK!"
var String MSG_PIN_KO = "WRONG PIN!"
var String MSG_STANDBY = "-"
var String MY_PIN01 = "1234"
var integer MAX_DELAY = 4
var Timer timerCodeReset = null
var Timer timerStatusReset = null
var String sCodeInserted = ""
rule "Activation with PIN"
when
Item KP_PinDigit received command
then
try {
lock.lock()
if (KP_PinDigit.state!=-1) {
if (sCodeInserted=="") {
// 1° Digit
sCodeInserted = KP_PinDigit.state.toString
KP_Status.postUpdate(sCodeInserted)
logInfo("KEYPAD","Code insterted: (" + sCodeInserted + ")")
timerCodeReset = createTimer(now.plusSeconds(MAX_DELAY)) [|
logInfo("KEYPAD","Timeout, resetting..")
KP_PinDigit.postUpdate(-1)
KP_Status.postUpdate(MSG_STANDBY)
sCodeInserted = ""
timerCodeReset = null
]
}
else if (sCodeInserted.length()>=1) {
// Digit > 1st
if (timerCodeReset!=null) {
timerCodeReset.reschedule(now.plusSeconds(4))
} else {
sCodeInserted = ""
}
sCodeInserted = sCodeInserted + KP_PinDigit.state.toString
logInfo("KEYPAD","Code insterted: (" + sCodeInserted + ")")
KP_Status.postUpdate(sCodeInserted)
if (sCodeInserted.length()>=MY_PIN01.length()) {
logInfo("KEYPAD","Pin complete")
if (sCodeInserted.matches(MY_PIN01)) {
// Pin OK
logInfo("KEYPAD","Pin complete, OK")
KP_Status.postUpdate(MSG_PIN_OK)
KP_TriggerOK.sendCommand(ON)
KP_Result.postUpdate(2)
} else {
// Pin NOT OK
logInfo("KEYPAD","Pin complete, WRONG!")
KP_TriggerKO.sendCommand(ON)
KP_Result.postUpdate(1)
KP_Status.postUpdate(MSG_PIN_KO)
}
sCodeInserted = ""
timerCodeReset = null
}
}
KP_PinDigit.postUpdate(-1)
if (KP_Result.state>0) {
timerCodeReset = createTimer(now.plusSeconds(5)) [|
KP_Result.postUpdate(0)
KP_Status.postUpdate(MSG_STANDBY)
timerCodeReset = null
]
}
}
}
finally {
lock.unlock()
}
end
rule "Activation with PIN OK"
when
Item KP_TriggerOK received command ON
then
// Do something
if (X_AlarmStatus.state==OFF) {
X_AlarmStatus.sendCommand(ON)
else {
X_AlarmStatus.sendCommand(OFF)
}
KP_TriggerOK.postUpdate(OFF)
end
rule "Activation with PIN KO"
when
Item KP_TriggerKO received command ON
then
// Do something
KP_TriggerKO.postUpdate(OFF)
end
keypad.sitemap
sitemap keypad label="Keypad"
{
Text item=X_AlarmStatus
Text item=KP_Status icon="graph11" valuecolor=[KP_Result==1="red", KP_Result==2="green"]
Switch item=KP_PinDigit label="" mappings=[1=" 1 ", 2=" 2 ", 3=" 3 "]
Switch item=KP_PinDigit label="" mappings=[4=" 4 ", 5=" 5 ", 6=" 6 "]
Switch item=KP_PinDigit label="" mappings=[7=" 7 ", 8=" 8 ", 9=" 9 "]
Switch item=KP_PinDigit label="" mappings=[11=" ", 0=" 0 ", 11=" "]
}
keypad.map
OFF=NOT ACTIVE
ON=ACTIVE
-=NOT ACTIVE
undefined=NOT ACTIVE
And then the result
During digiting PIN
PIN Ok
Wrong PIN
The only problem is that keypad is not rendered very well on web UI…
Enjoy!