Protect a card with a UI keypad (using Custom Button and Node Red)

I’ve seen protected cards that require using a keyboard but that’s a bit fussy on a phone. I wanted to be able to show a card by quickly punching a sequence of UI buttons.

image

The logic is simple. Every time you press a key button, it appends the value of that key to a global variable. If the global variable then equals your password it turns on an input_boolean, and starts a timer to turn off the input_boolean in 30 seconds. Your hidden card is within a Conditional card triggered by that input_boolean.

At the same time, when you press a key button it starts a timer to reset the global variable to null in 5 seconds. That means you must press each required key no more than five seconds apart, and if you press a wrong key you must wait five seconds to start entering your password from the beginning.


Notes:

  • This is designed to stop casual or accidental access but is not ironclad security.
  • Your password can be as many digits as you want. You can also show as many different key buttons as you want including numbers and letters.
  • My timer node is node-red-contrib-stoptimer. You can easily change the length of the timers.
  • And I’m not a pro. Someone could probably replace this using a single line of code with a dozen levels of abstraction conjured up by devilish nested templates. If you do, please share.
# configuration.yaml

input_boolean:
  unlock_card:

input_text:
  unlock_code:
  name: Unlock
# ui-lovelace.yaml
# Keypad to open hidden card
          - type: horizontal-stack
            cards:
              - type: custom:button-card
                template: key_link
                name: 1
                tap_action:
                  action: call-service
                  service: input_text.set_value
                  service_data:
                    entity_id: 'input_text.unlock_code'
                    value: '1'
              - type: custom:button-card
                template: key_link
                name: 2
                tap_action:
                  action: call-service
                  service: input_text.set_value
                  service_data:
                    entity_id: 'input_text.unlock_code'
                    value: '2'
              - type: custom:button-card
                template: key_link
                name: 3
                tap_action:
                  action: call-service
                  service: input_text.set_value
                  service_data:
                    entity_id: 'input_text.unlock_code'
                    value: '3'
              - type: custom:button-card
                template: key_link
                name: 4
                tap_action:
                  action: call-service
                  service: input_text.set_value
                  service_data:
                    entity_id: 'input_text.unlock_code'
                    value: '4'
# your hidden card in ui-lovelace.yaml
          - type: conditional
            conditions:
              - entity: input_boolean.unlock_card
                state: "on"
            card:
                type: 
# ... etc
# Custom Button card templates

  dummy_colors:
    color: &blue_gradient 'linear-gradient( 135deg, rgb(192, 222, 237) 10%, rgb(59, 171, 221) 100%)'  

  key_link:
    color_type: card
    styles:
      card:
        - height: 50px
        #- margin: 5px 5px 5px 5px
        - padding: 5px 15px
        - background-image: *blue_gradient
        - border-radius: 10px
        - -webkit-box-shadow: 0px 5px 5px 0px rgb(3, 150, 255, .4)
        - box-shadow: 2px 5px 5px 0px rgb(3, 150, 255, .4)
        - color: *black_label
# Node Red
[{"id":"8e1f103e.14258","type":"comment","z":"786db0c1.8b55b","name":"Keypad Unlock","info":"","x":120,"y":1340,"wires":[]},{"id":"7debae70.d2b66","type":"server-state-changed","z":"786db0c1.8b55b","name":"input_text.unlock_code","server":"2bcf671a.f2b3c8","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_text.unlock_code","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"x":140,"y":1380,"wires":[["14b51ef9.e3ab41","98c05bef.e2b688"]]},{"id":"7dc5eb1c.e49374","type":"function","z":"786db0c1.8b55b","name":"Update variable","func":"var temp=global.get(\"unlock\")+msg.payload\n\nglobal.set(\"unlock\", temp)\n\nmsg.payload = temp\n\nreturn msg;","outputs":1,"noerr":0,"x":740,"y":1380,"wires":[["71e4d418.a242cc"]]},{"id":"14b51ef9.e3ab41","type":"switch","z":"786db0c1.8b55b","name":"","property":"unlock","propertyType":"global","rules":[{"t":"cont","v":"undefined","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":370,"y":1380,"wires":[["4ca166de.57a858"],["7dc5eb1c.e49374"]]},{"id":"4ca166de.57a858","type":"change","z":"786db0c1.8b55b","name":"","rules":[{"t":"set","p":"unlock","pt":"global","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":530,"y":1340,"wires":[["7dc5eb1c.e49374"]]},{"id":"71e4d418.a242cc","type":"switch","z":"786db0c1.8b55b","name":"Test for PW","property":"unlock","propertyType":"global","rules":[{"t":"eq","v":"1234","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":930,"y":1380,"wires":[["293fedab.8a79b2","ac3de3b1.9711a"],[]]},{"id":"30de7811.a7abc8","type":"stoptimer","z":"786db0c1.8b55b","duration":"5","units":"Second","payloadtype":"str","payloadval":"","name":"5 seconds","x":750,"y":1420,"wires":[["c8aada48.0b7088"],[]]},{"id":"c8aada48.0b7088","type":"change","z":"786db0c1.8b55b","name":"Reset Global","rules":[{"t":"set","p":"unlock","pt":"global","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":930,"y":1420,"wires":[[]]},{"id":"98c05bef.e2b688","type":"api-call-service","z":"786db0c1.8b55b","name":"input_text.unlock_code","server":"2bcf671a.f2b3c8","version":1,"debugenabled":false,"service_domain":"input_text","service":"set_value","entityId":"input_text.unlock_code","data":"{\"value\":\"\" }","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":420,"y":1420,"wires":[["30de7811.a7abc8"]]},{"id":"ac3de3b1.9711a","type":"api-call-service","z":"786db0c1.8b55b","name":"unlock_card ON","server":"2bcf671a.f2b3c8","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.unlock_card ","data":"","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1360,"y":1360,"wires":[[]]},{"id":"293fedab.8a79b2","type":"stoptimer","z":"786db0c1.8b55b","duration":"30","units":"Second","payloadtype":"bool","payloadval":"false","name":"30 seconds","x":1130,"y":1400,"wires":[["6f6d0928.072958"],[]]},{"id":"6f6d0928.072958","type":"api-call-service","z":"786db0c1.8b55b","name":"unlock_card OFF","server":"2bcf671a.f2b3c8","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.unlock_card ","data":"","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1360,"y":1400,"wires":[[]]},{"id":"2bcf671a.f2b3c8","type":"server","z":"","name":"Home Assistant","legacy":false,"hassio":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

I know this was posted a while back, but it was really helpful with learning about conditional cards and putting them behind a pin number.

THANK YOU!!!

1 Like