UI Widget: Keypad

This is the first submission of a widget for the openHAB 3 main UI. For now you can define them by going to Developer Tools > Widgets, creating a new one, and copy-pasting the code below.

This widget will allow users to enter a numerical (plus * and #) PIN code and send a command with the result to a predefined item when pressing the Send button.

image
The widget code:

uid: keypad
tags: []
props:
  parameters:
    - context: item
      description: Item to send the pincode to
      label: Item
      name: item
      required: false
      type: TEXT
    - description: Replace pincode characters with this string, leave blank to show it as-is
      label: Mask character
      name: mask
      required: false
      type: TEXT
    - description: If this widget is shown in a popup, close it after pressing Send
      label: Close Popup on Send
      name: closePopup
      required: false
      type: BOOLEAN
  parameterGroups: []
timestamp: Oct 20, 2020, 10:17:43 PM
component: f7-block
config:
  label: Please Input Pin
  style:
    --f7-button-text-color: var(--f7-text-color)
    --f7-button-bg-color: var(--f7-card-bg-color)
    --f7-theme-color-rgb: var(--f7-color-blue-rgb)
  class:
    - padding
slots:
  default:
    - component: oh-label-card
      config:
        outline: true
        class:
          - margin-bottom
        label: "=(props.mask && vars.pincode) ? props.mask.repeat(vars.pincode.length || 0) : vars.pincode"
    - component: f7-row
      config:
        class:
          - margin
      slots:
        default:
          - component: oh-repeater
            config:
              fragment: true
              for: digit
              in:
                - "1"
                - "2"
                - "3"
                - "4"
                - "5"
                - "6"
                - "7"
                - "8"
                - "9"
                - "*"
                - "0"
                - "#"
            slots:
              default:
                - component: f7-col
                  config:
                    width: "33"
                    class:
                      - margin-vertical-half
                  slots:
                    default:
                      - component: oh-button
                        config:
                          text: =loop.digit
                          raised: true
                          large: true
                          action: variable
                          actionVariable: pincode
                          actionVariableValue: "=(vars.pincode) ? vars.pincode + loop.digit : loop.digit"
    - component: f7-row
      config:
        style:
          --f7-theme-color: var(--f7-color-blue)
          --f7-button-bg-color: transparent
        class:
          - margin
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: Clear
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: ""
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    class: "=(props.closePopup) ? ['popup-close'] : []"
                    style:
                      --f7-button-hover-bg-color: var(--f7-color-blue-tint)
                      --f7-button-pressed-bg-color: var(--f7-color-blue-tint)
                    text: Send
                    fill: true
                    large: true
                    action: command
                    disabled: =!vars.pincode
                    closePopup: =props.closePopup
                    actionItem: =(props.item) || 'TestString'
                    actionCommand: =vars.pincode
                    clearVariable: pincode
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: Back
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode.substring(0, vars.pincode.length - 1) : ""'

You can show it inline in a page if you want but the preferred way to integrate it is with a “Open Popup” action in one of the widgets that support them, like the Label Card in a layout page, or a floor plan marker:

image

image

In YAML definition this translates to:

component: oh-label-card
config:
  label: Unlock
  action: popup
  actionModal: widget:keypad
  actionModalConfig:
    mask: "*"
    item: TestString
    closePopup: true
11 Likes

Replaced a bunch of repeated code for the 12 digit buttons with a repeater, which was not available when this widget was made. Also fixed some color glitches for the Send button when hovered or pressed.

1 Like

Hi. Just brought your widget into my alarm control page. Great for wall mounted tablets that are out in the open where a giant DISARM ME NOW button is a little self-defeating.

The close pop-up on send is not working for me in any browser though. Any suggestions?

There a small typo in the class expression, change:

to

class: "=(props.closePopup) ? ['popup-close'] : []"

That did the trick. Thanks!

:man_facepalming:
Added it without testing, realized it didn’t work in the demo but forgot to correct it here, thanks. Fixed now.

Hi @ysc

Thanks so much for the Widget. I have been looking at using it to replace what I have from my OH 2.5 Sitemaps where I use the following rule to Disarm my alarm, however I cannot get the widget to do the action I need. I can only get it to put the entered PIN_Number into an item. Was hoping that pressing SEND would complete the action.

rule "Partion 3 DISARM"

when
    Item Partition3_Disarm  received command ON
then
if (Partition3_Armed.state == OFF ) {
    logWarn("actions", "Alarm is not armed")
            Alarm_Feedback.postUpdate("Alarm is not armed")
            createTimer(now.plusSeconds(5), [
            Alarm_Feedback.postUpdate("")
        ])
}
else if (Pin_Number.state.toString == "" ) {
    logWarn("actions", "Please enter PIN")
            Alarm_Feedback.postUpdate("Please enter PIN")
            createTimer(now.plusSeconds(5), [
            Alarm_Feedback.postUpdate("")
        ])
}
else {
    val actions = getActions("caddx","caddx:partition:e59e4935:partition3")
    if (null === actions) {
        logWarn("actions", "Actions not found, check thing ID for bridge")
        return
    }
    var EnteredPin = ScriptServiceUtil.getItemRegistry.getItem("Pin_Number")
            logInfo("", "EnteredPin " + EnteredPin.state.toString)
       
    actions.disarm(EnteredPin.state.toString)
    Pin_Number.postUpdate("")
}
end

If I set the “Item to send pincode to” to Pin_Number I see the update. so not sure how I would initiate the actual action to Disarm the alarm?

Sure I am missing something basic. But your assistance would be greatly appreciated.
Thanks
Mark

EDIT: So after sleeping on this I realised what I had wrong. Will use the “Pincode Item” to trigger a rule.

Hi, I would like to hide from the frontail logviewer the status of the inserted pin string.
Should I do it from karaf? If so how?
thank you

1 Like

Have not done filtering in OH3 but it worked in 2.5 guessing same method will work if you adjust the any openhab2 paths or filenames to just openhab.

1 Like

Thanks for the reply, I will try as soon as possible

Hi

Did you come right with your log file filtering question?

I have resolved on my system by making the following changes to my log4j2.xml:

        <!-- Event log appender -->
        <RollingRandomAccessFile fileName="${sys:openhab.logdir}/events.log" filePattern="${sys:openhab.logdir}/events.log.%i" name="EVENT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5.5p] [%-36.36c] - %m%n"/>
        <!-- Filter Pin Number from Logs -->    
        <RegexFilter onMatch="DENY" onMismatch="NEUTRAL" regex=".*(Pin_Number).*"/> 
            <Policies>
                <OnStartupTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="16 MB"/>
            </Policies>
        </RollingRandomAccessFile>



        <Logger additivity="false" level="INFO" name="openhab.event">
            <AppenderRef ref="EVENT"/>
            <AppenderRef ref="OSGI"/>
                    <!-- Filter Pin Number -->
                    <RegexFilter regex=".*(Pin_Number).*" onMatch="DENY" onMismatch="NEUTRAL"/>
        </Logger>

The Pin_Number entries such as:

2021-03-31 09:37:57.354 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'Pin_Number' received command 9999
2021-03-31 09:37:57.354 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Pin_Number' changed from NULL to 9999
2021-03-31 09:38:08.326 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Pin_Number' changed from 9999 to _

Are no longer logged to my events.log file and they also do not appear on the Karaf Console.

Would be nice if you could just REDACT the number - which you probably could as the logging event would still be there.

Anyway - hope it helps.
Mark

1 Like

Hi All,
I want to use a similar widget as popover instead of popup.

The Pop is just to confirm Setting Away status.

I have mish-mashed the above widget and able to send the command to an item, basically click the Send button sends a static string as action command.

My main query is there a way to close the popover like it happens for the popup. Rite now I have to click Send and click outside or back the popover to close the popover.

I tried using the samples popover close action it doesn’t close the popover. The action command is still working though.

Any suggestions.

For some reason the F7 open and close properties between the popup and popover are swapped. Instead of closePopup try:

popoverClose: true
1 Like

Awesome!!

Thanks it worked replaced the closePopup: ... with popoverClose: true it works as expected, once button is pressed the popover closes.