Sharing Code - Function activation with PIN

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!

8 Likes