[OH3] Main UI - main_widget - Part 6a - The Security Keypad [3.3.0;3.4.9)

[:crayon: Add a primary screenshot or a logo here. The first image of the post will be promoted seen in the add-on list in the UI.]

[:crayon: Replace with your description.]

Screenshots

[:crayon: Upload other screenshots if necessary or remove the section.]

Changelog

Version 0.1

  • initial release

Resources

uid: main_widget_Security_Keypad
tags: []
props:
  parameters:
    - context: item
      description: Item holding the security mode
      label: Security Mode Item
      name: securityMode
      required: true
      type: TEXT
    - context: item
      description: Item holding the reference PIN
      label: Pin Item
      name: referencePIN
      required: true
      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
    - context: text
      description: Target Security Mode
      name: targetMode
      required: true
      type: TEXT
  parameterGroups: []
component: f7-block
config:
  style:
    background: =(themeOptions.dark=="light") ? ("white"):("black")
    --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: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "1"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "1" : "1"'
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "2"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "2" : "2"'
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "3"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "3" : "3"'
    - component: f7-row
      config:
        class:
          - margin
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "4"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "4" : "4"'
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "5"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "5" : "5"'
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "6"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "6" : "6"'
    - component: f7-row
      config:
        class:
          - margin
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "7"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "7" : "7"'
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "8"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "8" : "8"'
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "9"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "9" : "9"'
    - component: f7-row
      config:
        class:
          - margin
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "*"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "*" : "*"'
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "0"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "0" : "0"'
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: "#"
                    raised: true
                    large: true
                    action: variable
                    actionVariable: pincode
                    actionVariableValue: '=(vars.pincode) ? vars.pincode + "#" : "#"'
    - 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:
                    text: Enter
                    fill: true
                    large: true
                    action: command
                    disabled: =!vars.pincode
                    actionItem: =props.securityMode
                    actionCommand: '=(items[props.referencePIN].state != vars.pincode) ? "" : props.targetMode'
                    actionFeedback: ='{ "text":"Alarmmodus geändert","position":"center","closeButton":"true" }'
                    clearVariable: pincode
                    popup-close: true
          - 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) : ""'

Hi @hmerk , i was playing with this keypad. At the above line there is a check with reference pin. If the pin is incorrect it still calls the action command. And if the value is empty it gives error as communication error.

Is there is way to not call the action command if pin validation fails?

I tried different things but nothing worked.

Thanks
Amin

Don’t really understand your issue.
If the state of reference PIN item does not match the entered PIN, action command is empty, so nothing happens.

Thank for the quick reply.

here is the error I see if I enter incorrect pin. In App

In Logs

2024-12-28 14:22:16.421 [ERROR] [internal.JSONResponseExceptionMapper] - Unexpected exception occurred while processing REST request.
javax.ws.rs.WebApplicationException: HTTP 415 Unsupported Media Type
	at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1581) ~[bundleFile:3.6.2]
	at org.apache.cxf.jaxrs.utils.JAXRSUtils.processRequestBodyParameter(JAXRSUtils.java:1058) ~[bundleFile:3.6.2]
	at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:989) ~[bundleFile:3.6.2]
	at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:215) ~[bundleFile:3.6.2]
	at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:79) ~[bundleFile:3.6.2]
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307) ~[bundleFile:3.6.2]
	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[bundleFile:3.6.2]
	at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265) ~[bundleFile:3.6.2]
	at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[bundleFile:3.6.2]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[bundleFile:3.6.2]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[bundleFile:3.6.2]
	at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225) ~[bundleFile:3.6.2]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:304) ~[bundleFile:3.6.2]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:217) ~[bundleFile:3.6.2]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:517) ~[bundleFile:4.0.4]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:279) ~[bundleFile:3.6.2]
	at org.ops4j.pax.web.service.spi.servlet.OsgiInitializedServlet.service(OsgiInitializedServlet.java:102) ~[bundleFile:?]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656) ~[bundleFile:9.4.54.v20240208]
	at org.ops4j.pax.web.service.spi.servlet.OsgiFilterChain.doFilter(OsgiFilterChain.java:113) ~[bundleFile:?]
	at org.ops4j.pax.web.service.jetty.internal.PaxWebServletHandler.doHandle(PaxWebServletHandler.java:334) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:234) ~[bundleFile:9.4.54.v20240208]
	at org.ops4j.pax.web.service.jetty.internal.PrioritizedHandlerCollection.handle(PrioritizedHandlerCollection.java:96) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:722) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) ~[bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [bundleFile:9.4.54.v20240208]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [bundleFile:9.4.54.v20240208]
	at java.lang.Thread.run(Thread.java:840) [?:?]
your code goes here

I m using a switch item for control here. What I m understanding is if the pin is incorrect, it tries to assign empty state to switch item which gives above error. When I assign it proper ON or OFF state then no error is thrown.

But ideally, there should be no update to item if pin validation fails. Hope this clarifies the issue.

Did you change the pinpad widget?
Our code does not call an action if pin is not matching. This is working since implemented also working in the original pinpad on the marketplace.

Hi ,

Nothing changed. Used as is. I just removed the Action confirmation line. let me try with that too.

Now used the above code as is no change. but getting same error.

Settings details.

widget config

Ok, you are trying to control a Switch Item with the keypad. This is not what it is designed for. We are sending a predefined string to a String (mode) item.

Ok, got it. Thanks!