[RELEASE] Virtual Keypad

Got these working. Thought I'd share incase others are interested.


1 Like

Hello, thanks for all the work on this. I am relatively new to Hubitat. I am lost on getting the status count down in the button. The button flashes but the text still has the default button name.

The count down displays on the 'input display' child device. Replace your chime device on the dashboard with the input display. Then add another dashboard tile for the chime. You can make that smaller and in the position desired.

Hey @mbarone, I've just got the time to mess around with the arming delays and the chimes, Is there any way to implement a Countdown when HSM Alerts Intrusion? I'm not sure if it's possible. I currently have a Variable number tile and Rule Machine to do this but If I could get it to somehow use the Input device to have a countdown (like the arming count down) It would be one less tile I need on the Dashboard. I understand if you don't want to implement this feature, If that is the case do you have any Ideas how this could be done within Virtual Keypad?

Is there any chance to be able to get more complete lock functionality with this? I want to use it in Notifications app and it doesn't show up as a lock but all the attributes seem to be there.

@scubamikejax904 sorry for the delayed response.. ive had this response saved as a draft for over a month..

This was pretty much where i hit a wall when i was actively developing this project. At the time (on version 2.2.x) there was limited ability to hook into the hsm intrusion and create a delay style entry.

if i were to try again i would likely use something like nyckelharpa: [Release] Nyckelharpa, an HSM Extension

where you can better control hsm arming/etc and have a custom entry delay. There would still need to be some work for it to display properly on the keypad,

unfortunately, using the keypad input display is limited currently, as there are inherent issues if other apps are attempting to display content on the input display, and you hit a key on the keypad, the keypad will take priority and wipe out the previous message, or in the case of a countdown, they might fight over the text input and it will flash between the 2 messages. There is definitely room for improvement of the keypad input display, that may include a 2nd line of text that can persist for a period of time or something. Definitely a lot of room for improvement.. unfortunately, I just dont have the free time to continue developing right now. I am happy to review pull requests, and can add other contributors to the github repo if someone wants to take on continued development of the project.

This currently wont work as expected, because the keypad has no concept of locked or unlocked. it doesnt keep the state for anything like that.

The keypad only controls the triggers to other systems, like hsm or rule machine. this is why it allows you to run the disarm command 10 times in a row if you wanted instead of skipping the extra commands and giving you a status message.. because the keypad doenst know if the system is armed or not, it just passes on commands, and can easily password protect desired commands.

for this to work as you would expect, the keypad would need to manage its own state of the system (lock/unlock), but due to other ways of locking/unlocking, the keypad lock state may become out of sync with the main system (hsm/etc) and would not operate as expected in this scenario. this is 1 reason i kept them separated for the current version, with the hopes of tying them together better as hubitat matured and allowed for more hooks/control into hsm from apps.

Unfortunately (for this community), in the past 2 years, my first kid was born, and got a new, more demanding job, which really limits my time for extra curricular projects like this for now. I am hopeful to gain back some project time as my son is getting older and work becomes more structured, so please keep the requests coming, but it may take a bit for me to get to them.

1 Like

@mbarone no worries I've got 2 kids (one 4 and one 9 months both are great and I wouldn't trade it for anything) you don't have to tell me about no free time. Your app has been rock solid.

2 Likes

Have the Virtual Keypad running and functioning correctly. Having trouble when inserting it (as iframe keypad) into a main dashboard in that the fonts don't scale with the buttons and are too big.

Is there a way to adjust the font style and font size?

I'm also trying to get this working on a fireHD8, and new to this, but know someone has already figured out an optimum size and font scale.

Anyone willing to share their setup for Fire HD 8 (grid, font, etc) and how they set up the virtual keypad to fit and any changes needed to basic install?

Thanks for any help you can provide.

(I have a very basic understanding/learning of CSS, and have experimented with Simple CSS editor but can not get the adjustments to work on the stock Virtual Keypad buttons and iframe scaling.)

  1. How did you adjust the font size being too big? I'm looking for a simpler way than editing every tile button which I got to work.
  2. After Adjusting font the text is vertically just below center. did you find a way to center vertically?
  3. Did you find a way to get rid of the gray edge on the right of the tile.
  4. Iframe displays fine in browser and on Fire HD, but won't show on ipad/ios. Did you encounter this and if so find a fix?

Thanks

Hey Ghunts,

Sorry for the delay, I dont have much time to review and respond to this thread currently.

I have my setup on several fireHD8 tablets. So my CSS in the main thread, should get you pretty close.

That being said, I created this and did the original config on the old version of the dashboards, and have not yet migrated to the new dashboard framework (that was introduced a year+ ago). This difference may be causing the issues you are seeing with scaling.. Im not sure what if any changes on the new dashboards may affect the CSS, but this could be the issue.

Also, to help, possibly, the way i got this working, was to create my keypad dashboard (full screen) with all the buttons i wanted.
Then i created the fireHD8 dashboard, and added the keypad iframe, as well as the other tiles i wanted there. It took a while to get that dashboard properly sized for the fireHD8, modifying row and column values and adjusting the default tile size to make it work.

If it helps, here are my dashboard setting (not the keypad, but the fireHD8 that the keypad is included on). also note, i am using the iframe version of the keypad so it only takes up 1 tile/button instead of the whole keypad.. but it should be good both ways.


again, take a look at the css and config files in the first post, they should get you pretty close.

1 Like

Thanks @mbarone. After lots of trial and error and tweaking CSS, I’ve got the layout on Fire HD 8 close to where I need it. I really appreciate the work you put in on this and sharing the above. It will help me finish this off.

Gary

Hey guys I am a newbie to Hubitat and want to get the full version of virtual keyboard loaded. By trade I am a network engineer so I can get my way around things but not a programmer by any means. I figured out how to get the Hubitat Package manager installed. I then downloaded all the apps and files from the list of instructions from the beginning of this thread.
I just can't seem to figure out using the HPM, how to install those apps and drivers for the complete Virtual Keyboard App. I tried using url's from the site where those files are at and I tied local path as well. I know it probably something very simple and stupid that I am missing but any help would be much appreciated. Then I am assuming the instructions above will get the Keyboard setup and I can put a count beep for the delay when arming away.

Below is my current setup that I will be trying to get working:
I am going to use the Hubitat for my base alarm system and monitoring for the garage, shop and shed. I purchased a Konnected Pro board 12 zone panel. I have have 10 contact wired sensors, 2 motions sensors, 3 Sirens for each location, 3 chimes for each entry local and will be adding 3 Fire 8 Tablets to Arm/Disarm with touch screen and pin access.

I went with Hubitat since it's a local hub and can still work fine on the local network even if the internet was down. I really like to build out a Virtual keyboard like markbellkosel84 has shown is looks awesome. But at this point I just want to get something functions to stand up my alarm system. Once I get comfortable I will migrate this to do a complete Home Automation for my house I am building.

Any help here will be much appreciated. Thanks for time and sorry for the long winded post.

1 Like

Hey @racer2fast, here is the dashboard layout I use, I have a couple extra device/variables on it for my functionality that you can remove if you want. you will need to copy and paste the below into the layout tab (replacing the existing layout) of a new dashboard that you create. Tile ID 16, is an HSM status tile, Tile ID 17 is a Visual Countdown (variable that starts when HSM goes into Intrusion Delay and just gives a visual cue that the alarm is activated), Tile ID 19 is an invisible Panic Button that goes on top of Tiles 16 & 17. Let me know if you need any other help setting anything up

Layout

{
"localization": "English",
"roundedCorners": 0,
"dateFormat": "MM/DD/YYYY",
"hideLabels": true,
"customColors": [
{
"template": "hsm",
"bgColor": "rgb(158,0,0)",
"iconColor": "",
"state": "disarmed",
"customIcon": ""
},
{
"template": "hsm",
"bgColor": "rgb(1,161,9)",
"iconColor": "",
"state": "armedhome",
"customIcon": ""
},
{
"template": "hsm",
"bgColor": "rgb(1,161,9)",
"iconColor": "",
"state": "armedaway",
"customIcon": ""
},
{
"template": "hsm",
"bgColor": "rgb(1,161,9)",
"iconColor": "",
"state": "armednight",
"customIcon": ""
}
],
"colWidth": "",
"cloudRefresh": 1,
"hsmPin": "",
"hide3dot": false,
"clockMode": true,
"gridGap": 8,
"tiles": [
{
"rowSpan": 1,
"template": "buttons",
"col": 2,
"colSpan": 1,
"id": 0,
"row": 5,
"device": "2306",
"templateExtra": "0"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 1,
"colSpan": 1,
"id": 1,
"row": 2,
"device": "2306",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 2,
"colSpan": 1,
"id": 2,
"row": 2,
"device": "2306",
"templateExtra": "2"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 3,
"colSpan": 1,
"id": 3,
"row": 2,
"device": "2306",
"templateExtra": "3"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 1,
"colSpan": 1,
"id": 4,
"row": 3,
"device": "2306",
"templateExtra": "4"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 2,
"colSpan": 1,
"id": 5,
"row": 3,
"device": "2306",
"templateExtra": "5"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 3,
"colSpan": 1,
"id": 6,
"row": 3,
"device": "2306",
"templateExtra": "6"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 1,
"colSpan": 1,
"id": 7,
"row": 4,
"device": "2306",
"templateExtra": "7"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 2,
"colSpan": 1,
"id": 8,
"row": 4,
"device": "2306",
"templateExtra": "8"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 3,
"colSpan": 1,
"id": 9,
"row": 4,
"device": "2306",
"templateExtra": "9"
},
{
"rowSpan": 1,
"template": "attribute",
"col": 1,
"colSpan": 3,
"id": 10,
"row": 1,
"device": "2308",
"templateExtra": "InputDisplay"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 3,
"colSpan": 1,
"id": 11,
"row": 5,
"device": "2302",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 4,
"colSpan": 2,
"id": 12,
"row": 2,
"device": "2293",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 4,
"colSpan": 2,
"id": 13,
"row": 3,
"device": "2294",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 4,
"colSpan": 2,
"id": 14,
"row": 4,
"device": "2295",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 4,
"colSpan": 2,
"id": 15,
"row": 5,
"device": "2503",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "hsm",
"col": 4,
"colSpan": 1,
"id": 16,
"row": 1,
"device": "-3",
"templateExtra": " "
},
{
"rowSpan": 1,
"template": "buttons",
"col": 4,
"colSpan": 2,
"id": 19,
"row": 1,
"device": "2307",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "variable-number",
"col": 5,
"colSpan": 1,
"id": 17,
"row": 1,
"device": "3598"
}
],
"goBack": false,
"modePin": "",
"bgColor": "#ffffff00",
"lanRefresh": 1,
"iconSize": "40",
"cols": 5,
"rowHeight": "",
"customCSS": ".header.flex {\npadding:0 !important;\n}\n\n.wrapper {\noverflow: hidden;\npadding-right: 15px;\n}\n\n.dashBack.flex, .dashName.flex {\ndisplay:none;\n}\n\n.he-tap:before {\ncontent: none;\n}\n\n.tile.button .tile-title, .tile.attribute .tile-title {\nvisibility: hidden;\ndisplay: none;\n}\n\n.tile.button .tile-contents, .tile.attribute .tile-contents {\nheight: calc(100%);\n}\n\n.tile.attribute .tile-primary, .tile.button .tile-primary {\npadding:0;\n}\n\n#tile-1 .tile-primary :before {\ncontent: "1";\n}\n\n#tile-2 .tile-primary :before {\ncontent: "2";\n}\n\n#tile-3 .tile-primary :before {\ncontent: "3";\n}\n\n#tile-4 .tile-primary :before {\ncontent: "4";\n}\n\n#tile-5 .tile-primary :before {\ncontent: "5";\n}\n\n#tile-6 .tile-primary :before {\ncontent: "6";\n}\n\n#tile-7 .tile-primary :before {\ncontent: "7";\n}\n\n#tile-8 .tile-primary :before {\ncontent: "8";\n}\n\n#tile-9 .tile-primary :before {\ncontent: "9";\n}\n\n#tile-0 .tile-primary :before {\ncontent: "0";\n}\n\n#tile-11 .tile-primary :before {\ncontent: "Clear";\n}\n\n#tile-13 .tile-primary :before {\ncontent: "Home";\n}\n\n#tile-14 .tile-primary :before {\ncontent: "Night";\n}\n\n#tile-15 .tile-primary :before {\ncontent: "Disarm";\n}\n\n#tile-12 .tile-primary :before {\ncontent: "Away";\n}\n\n#tile-16 .tile-primary :before {\ncontent: " ";\n}\n#tile-19 {background-color: rgba(0,0,0,0);}\n#tile-10 .tile-primary {font-size: 30px !important;}\n#tile-11 .tile-contents{-moz-transform:scale(.5);zoom:.5}\n#tile-12 .tile-contents{-moz-transform:scale(.75);zoom:.75}\n#tile-13 .tile-contents{-moz-transform:scale(.75);zoom:.75}\n#tile-14 .tile-contents{-moz-transform:scale(.75);zoom:.75}\n#tile-15 .tile-contents{-moz-transform:scale(.75);zoom:.75}\n#tile-16 .tile-title{visibility:hidden}\n#tile-17 .tile-title:after{content:" ";left:0;padding:.5em .5em 3px .5em;position:absolute;top:0;visibility:visible;width:100%}\n#tile-17 .tile-title{visibility:hidden}\n#tile-17 .tile-contents{-moz-transform:scale(1.75);zoom:1.75}",
"hideEvents": false,
"tempScale": "F",
"noColors": false,
"readOnly": false,
"rows": 5,
"hideIconText": true,
"hideTextShadow": true,
"name": "Keypad - Main",
"fontSize": 11
}

1 Like

Hey scubamikejax904, I appreciate the help and sharing your layout. I been busy at work and now just getting back to my little project here. I will reach out if I have any further questions. Thanks again for replying to my questions.

I've been using this for a couple years now and it was working great. However, I've noticed that when I access my main dashboard from a remote network, virtual keypad won't render. It does fine if I'm on my LAN, but when I'm away from home I need to load up just the keypad dashboard and not the main dashboard as I get this:

I haven't really updated this app in a couple years or paid much attention to it. I did look at the install directions and redid them, but I get the same result. I suspect it has something to do with how the Main Keypad device gets set as the iFrame preference. I really don't understand how this works, I just followed the direction in the main post. Any suggestions how to debug this?

Ok, I was dumb and figured it out. I was using the "local" link to the Keypad dashboard instead of the cloud based one, so obviously it wouldn't work. Once I changed that it works fine.

1 Like

Hi, I have just moved to Hubitat and am setting up my Konnected alarm, loving this app, thanks to @mbarone for creating this excellent app.

I am trying to look at different layouts etc and love the work you have done. I tried your CSS and JSON code you dropped in the chat here, CSS goes in fine but wen I drop the JSON in the layout I always get an error when I try and save and the layout is a little wrong with the icons being at the top of the buttons. Screen shots below. I also dropped the code into a validator to see if I can understand where it is throwing the error, see screen shot of that as well. i am sure I am missing something obvious as a newbie to this. Any help appreciated (I know this is quite an old thread)

Without re-entering the JSON and parsing it item by item to verify, I believe that the issue you are seeing is that the JSON is missing a comma somewhere and therefore is failing to parse correctly.

1 Like

Hey @Stickman Try this one, I just copied it fresh from my dashboard, I'm not sure what happened to that last one (if this doesn't work I can DM it to you)

fresh Json

{
"localization": "English",
"roundedCorners": 0,
"dateFormat": "MM/DD/YYYY",
"hideLabels": true,
"customColors": [
{
"template": "hsm",
"bgColor": "rgb(158,0,0)",
"iconColor": "",
"state": "disarmed",
"customIcon": ""
},
{
"template": "hsm",
"bgColor": "rgb(1,161,9)",
"iconColor": "",
"state": "armedhome",
"customIcon": ""
},
{
"template": "hsm",
"bgColor": "rgb(1,161,9)",
"iconColor": "",
"state": "armedaway",
"customIcon": ""
},
{
"template": "hsm",
"bgColor": "rgb(1,161,9)",
"iconColor": "",
"state": "armednight",
"customIcon": ""
}
],
"colWidth": "",
"cloudRefresh": 1,
"hsmPin": "",
"hide3dot": false,
"clockMode": true,
"gridGap": 8,
"tiles": [
{
"rowSpan": 1,
"template": "buttons",
"col": 2,
"colSpan": 1,
"id": 0,
"row": 5,
"device": "2306",
"templateExtra": "0"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 1,
"colSpan": 1,
"id": 1,
"row": 2,
"device": "2306",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 2,
"colSpan": 1,
"id": 2,
"row": 2,
"device": "2306",
"templateExtra": "2"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 3,
"colSpan": 1,
"id": 3,
"row": 2,
"device": "2306",
"templateExtra": "3"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 1,
"colSpan": 1,
"id": 4,
"row": 3,
"device": "2306",
"templateExtra": "4"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 2,
"colSpan": 1,
"id": 5,
"row": 3,
"device": "2306",
"templateExtra": "5"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 3,
"colSpan": 1,
"id": 6,
"row": 3,
"device": "2306",
"templateExtra": "6"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 1,
"colSpan": 1,
"id": 7,
"row": 4,
"device": "2306",
"templateExtra": "7"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 2,
"colSpan": 1,
"id": 8,
"row": 4,
"device": "2306",
"templateExtra": "8"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 3,
"colSpan": 1,
"id": 9,
"row": 4,
"device": "2306",
"templateExtra": "9"
},
{
"rowSpan": 1,
"template": "attribute",
"col": 1,
"colSpan": 3,
"id": 10,
"row": 1,
"device": "2308",
"templateExtra": "InputDisplay"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 3,
"colSpan": 1,
"id": 11,
"row": 5,
"device": "2302",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 4,
"colSpan": 2,
"id": 12,
"row": 2,
"device": "2293",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 4,
"colSpan": 2,
"id": 13,
"row": 3,
"device": "2294",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 4,
"colSpan": 2,
"id": 14,
"row": 4,
"device": "2295",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "buttons",
"col": 4,
"colSpan": 2,
"id": 15,
"row": 5,
"device": "2503",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "hsm",
"col": 4,
"colSpan": 1,
"id": 16,
"row": 1,
"device": "-3",
"templateExtra": " "
},
{
"rowSpan": 1,
"template": "buttons",
"col": 4,
"colSpan": 2,
"id": 19,
"row": 1,
"device": "2307",
"templateExtra": "1"
},
{
"rowSpan": 1,
"template": "variable-number",
"col": 5,
"colSpan": 1,
"id": 17,
"row": 1,
"device": "3598"
}
],
"goBack": false,
"modePin": "",
"bgColor": "#ffffff00",
"lanRefresh": 2,
"iconSize": "40",
"cols": 5,
"rowHeight": "",
"customCSS": ".header.flex {\npadding:0 !important;\n}\n\n.wrapper {\noverflow: hidden;\npadding-right: 15px;\n}\n\n.dashBack.flex, .dashName.flex {\ndisplay:none;\n}\n\n.he-tap:before {\ncontent: none;\n}\n\n.tile.button .tile-title, .tile.attribute .tile-title {\nvisibility: hidden;\ndisplay: none;\n}\n\n.tile.button .tile-contents, .tile.attribute .tile-contents {\nheight: calc(100%);\n}\n\n.tile.attribute .tile-primary, .tile.button .tile-primary {\npadding:0;\n}\n\n#tile-1 .tile-primary :before {\ncontent: "1";\n}\n\n#tile-2 .tile-primary :before {\ncontent: "2";\n}\n\n#tile-3 .tile-primary :before {\ncontent: "3";\n}\n\n#tile-4 .tile-primary :before {\ncontent: "4";\n}\n\n#tile-5 .tile-primary :before {\ncontent: "5";\n}\n\n#tile-6 .tile-primary :before {\ncontent: "6";\n}\n\n#tile-7 .tile-primary :before {\ncontent: "7";\n}\n\n#tile-8 .tile-primary :before {\ncontent: "8";\n}\n\n#tile-9 .tile-primary :before {\ncontent: "9";\n}\n\n#tile-0 .tile-primary :before {\ncontent: "0";\n}\n\n#tile-11 .tile-primary :before {\ncontent: "Clear";\n}\n\n#tile-13 .tile-primary :before {\ncontent: "Home";\n}\n\n#tile-14 .tile-primary :before {\ncontent: "Night";\n}\n\n#tile-15 .tile-primary :before {\ncontent: "Disarm";\n}\n\n#tile-12 .tile-primary :before {\ncontent: "Away";\n}\n\n#tile-16 .tile-primary :before {\ncontent: " ";\n}\n//#tile-19 {background-color: rgba(0,0,0,0);}\n#tile-10 .tile-primary {font-size: 30px !important;}\n#tile-11 .tile-contents{-moz-transform:scale(.5);zoom:.5}\n#tile-12 .tile-contents{-moz-transform:scale(.75);zoom:.75}\n#tile-13 .tile-contents{-moz-transform:scale(.75);zoom:.75}\n#tile-14 .tile-contents{-moz-transform:scale(.75);zoom:.75}\n#tile-15 .tile-contents{-moz-transform:scale(.75);zoom:.75}\n#tile-16 .tile-title{visibility:hidden}\n#tile-17 .tile-title:after{content:" ";left:0;padding:.5em .5em 3px .5em;position:absolute;top:0;visibility:visible;width:100%}\n#tile-17 .tile-title{visibility:hidden}\n#tile-17 .tile-contents{-moz-transform:scale(1.75);zoom:1.75}",
"hideEvents": false,
"tempScale": "F",
"noColors": false,
"readOnly": null,
"rows": 5,
"hideIconText": true,
"hideTextShadow": true,
"name": "Z Dashboard",
"fontSize": 11
}