Example: PIN code protect parts of your Sitemap

I had created a way to apply policies to my kids devices on my firewall with this set up

But then needed a way to protect the sitemap from my kids being able to change the policies themselves.

Using this excellent example:

I stripped out what I didnt need and made a simple 4 number PIN access switch that I could drive visibility off of for sitemap items:

Items
Create a single line PIN code entry and a few items to show or store values

Number keypad "PIN" <lock>
Switch resetkeypad "Reset"
Switch keypadpass "PIN Correct"
String key1 "key1: [%s]"
String key2 "key2: [%s]"
String key3 "key3: [%s]"
String key4 "key4: [%s]"
String keycounter "keycounter: [%s]"
String keyentered "Key entered: [%s]"

Sitemap

Frame label="SecurityCode" {
						Switch item=keypad icon="none" mappings=[1="1",2="2",3="3",4="4",5="5"]
						Switch item=resetkeypad
						Switch item=keypadpass
						Text   item=keyentered	
					}

Rule

var int key_digit_1 = 0
var int key_digit_2 = 0
var int key_digit_3 = 0
var int key_digit_4 = 0
var int key_count = 0

//Key Pad Code Comparison 
rule "Key Digit"
when
    Item keypad received command
then
     
    //define correct keypad code here
    var int code_1 = 1
    var int code_2 = 2
    var int code_3 = 3
    var int code_4 = 2

    //counter used for comparison of current keypad digit status to save the value in the correct variable
    //will be reset after 5 digits have been entered - see below
    if(	key_count == 0) {
        //read status of the keypad and write it to the variable
        key_digit_1 = (keypad.state as DecimalType).intValue
        key1.postUpdate(key_digit_1)
            //counter +1 to allow entry of next number into other variable
        key_count = key_count + 1
        keycounter.postUpdate(key_count)
            //display the just entered number in the updated text in the UI
        keyentered.postUpdate(key_digit_1.toString + "-" + key_digit_2.toString + "-" + key_digit_3.toString + "-" + key_digit_4.toString)
        }
    else if (key_count == 1) {
        key_count = key_count + 1
        key_digit_2 = (keypad.state as DecimalType).intValue
        key2.postUpdate(key_digit_2)
        keycounter.postUpdate(key_count)
        keyentered.postUpdate(key_digit_1.toString + "-" + key_digit_2.toString + "-" + key_digit_3.toString + "-" + key_digit_4.toString )
    }
    else if (key_count == 2) {
        key_digit_3 = (keypad.state as DecimalType).intValue
        key3.postUpdate(key_digit_3)
        key_count = key_count + 1
        keycounter.postUpdate(key_count)
        keyentered.postUpdate(key_digit_1.toString + "-" + key_digit_2.toString + "-" + key_digit_3.toString + "-" + key_digit_4.toString )
    }
    else if (key_count == 3) {
        key_digit_4 = (keypad.state as DecimalType).intValue
        key4.postUpdate(key_digit_4)
        key_count = key_count + 1
        keycounter.postUpdate(key_count)
        keyentered.postUpdate(key_digit_1.toString + "-" + key_digit_2.toString + "-" + key_digit_3.toString + "-" + key_digit_4.toString )
    
        //code comparison - if correct, trigger switch, reset variables, counter and displayed code
        if(	key_digit_1 == code_1 &&
            key_digit_2 == code_2 &&
            key_digit_3 == code_3 &&
            key_digit_4 == code_4 )
             {
                keypadpass.sendCommand(ON)
                key_count = 0
                key_digit_1 = 0
                key_digit_2 = 0
                key_digit_3 = 0
                key_digit_4 = 0
                keyentered.postUpdate(key_digit_1.toString + "-" + key_digit_2.toString + "-" + key_digit_3.toString + "-" + key_digit_4.toString )
                key1.postUpdate(key_digit_1)
                key2.postUpdate(key_digit_2)
                key3.postUpdate(key_digit_3)
                key4.postUpdate(key_digit_4)
                keycounter.postUpdate(key_count)	
        }        
            //if one of the code elements does not match, activate alarm system
        else if( 	
            key_digit_1 != code_1 ||
            key_digit_2 != code_2 || 
            key_digit_3 != code_3 ||
            key_digit_4 != code_4) {
            key_count = 0
            key_digit_1 = 0
            key_digit_2 = 0
            key_digit_3 = 0
            key_digit_4 = 0
            keyentered.postUpdate(key_digit_1.toString + "-" + key_digit_2.toString + "-" + key_digit_3.toString + "-" + key_digit_4.toString )
            keypadpass.sendCommand(OFF)
            key1.postUpdate(key_digit_1)
            key2.postUpdate(key_digit_2)
            key3.postUpdate(key_digit_3)
            key4.postUpdate(key_digit_4)
            keycounter.postUpdate(key_count)	
        }
    }
end

//manual switch to reset the keypad
rule "Key reset"
when
    Item resetkeypad received command ON
then
    key_count = 0
    key_digit_1 = 0
    key_digit_2 = 0
    key_digit_3 = 0
    key_digit_4 = 0
    keyentered.postUpdate(key_digit_1.toString + "-" + key_digit_2.toString + "-" + key_digit_3.toString + "-" + key_digit_4.toString)
    keypadpass.sendCommand(OFF)	
    key1.postUpdate(key_digit_1)
    key2.postUpdate(key_digit_2)
    key3.postUpdate(key_digit_3)
    key4.postUpdate(key_digit_4)  
    keycounter.postUpdate(key_count)
    resetkeypad.sendCommand(OFF)	 			
end

All you need to do then is wire up whatever you want “secured” using visibility tags

Frame label="Internet Access" visibility=[keypadpass==ON] {
						Switch item=Policy_Jackson_Surface mappings=[block="Block",p_103="103",p_104="104"]
...
}

From any change of the “secured” items the rule that fires also resets the keypadpass state to OFF and everything is hidden again.

after youve finished testing remove the keypadpass switch from the sitemap

Limitations

  • You cant have a PIN with the two of the same numbers following each other eg 1223
  • The data entry can be sluggish, and sometimes posts the previous value
  • If you flick the reset switch when the last number you have selected is the first number of the PIN (eg 1331) then you cant select the first digit again

Hope this helps someone.

7 Likes

Thank you. But sometimes when I press one digit other digit (that was pressed priviously) is actually displayed. So I can’t type correct password. Do you have newer version of rule when this bug is fixed ?

Update: It seems to me that in rule “Key Digit” instead of “Item keypad received command” type “Item keypad received update” this problem is absent. But if you have better solution please share.