Dahua Door Intercom Widget

DahuaDoor Widget

this widget is meant for the DahuaDoor binding and provides a practical MainUI intercom popup:

  • WebRTC video playback
  • Answer / hangup buttons
  • door opener buttons
  • optional SIP state handling for popup visibility

It is designed for users who already have a working DahuaDoor thing with WebRTC/SIP enabled.

Prerequisites:

  • DahuaDoor binding configured and online
    (please see Dahua Door Binding for installation)

  • Items for:

    • webrtc-url
    • sip-call-state (optional but recommended)
    • sip-registered (optional but recommended)
    • door opener item(s)
    • session trigger item for popup open/close logic

Example required item mapping:

  • item_webrtcUrl → String item linked to channel webrtc-url
  • item_sipCallState → String item linked to channel sip-call-state
  • item_sipRegistered → Switch item linked to channel sip-registered
  • item_doorOpen → Switch item for relay 1
  • item_doorOpen2 → Switch item for relay 2 (optional)
  • item_doorbellSession → Switch item used to control popup open/close

How to use

Since MainUI does not provide an automatic popup feature, I placed the widget in a separate layer on the Overview page and used the visible property to toggle its visibility (this requires the Overview page to be active when you want to receive a call).

The start of my overview page looks as follows:

config:
  label: Übersicht
blocks:
  - component: oh-block
    config:
      visible: =items.DahuaDoor_Doorbell.state === "ON"
      style:
        position: fixed
        top: "0"
        left: "0"
        width: 100vw
        height: 100vh
        z-index: "9999"
        margin: "0"
        padding: "0"
    slots:
      default:
        - component: oh-grid-cells
          config:
            cols: 1
          slots:
            default:
              - component: widget:dahua-webrtc-video
                config:
                  thingUid: dahuadoor:vto2202:frontdoor
                  item_webrtcUrl: DahuaDoor_WebRTC_URL
                  item_doorOpen: DoorOpener
                  item_doorOpen2: DoorOpener_GarageTrigger
                  item_doorbellSession: DahuaDoor_Doorbell
                  item_sipCallState: DahuaDoor_SIP_CallState
                  item_sipRegistered: DahuaDoor_SIP_Registered

for the dahua-webrtc-video widget you should adjust the item/thing definition you are using.

Screenshots

Changelog

Version 0.1

  • initial release

Version 0.2

  • bug fix: mic did not turn on when call was accepted

Resources

uid: dahua-webrtc-video
tags:
  - dahuadoor
props:
  parameters:
    - context: item
      label: WebRTC URL Item
      name: item_webrtcUrl
      required: true
      type: TEXT
    - context: item
      label: Door Open Item
      name: item_doorOpen
      required: false
      type: TEXT
    - context: item
      label: Door Open Item 2
      name: item_doorOpen2
      required: false
      type: TEXT
    - context: item
      label: Doorbell Session Item
      name: item_doorbellSession
      required: true
      type: TEXT
    - context: text
      label: Thing UID
      name: thingUid
      required: true
      type: TEXT
    - context: item
      label: SIP Call State Item (optional)
      name: item_sipCallState
      required: false
      type: TEXT
    - context: item
      label: SIP Registered Item (optional)
      name: item_sipRegistered
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Apr 6, 2026, 4:27:24 PM
component: f7-popup
config:
  opened: =props.item_doorbellSession && items[props.item_doorbellSession].state
    === "ON" && (!props.item_sipCallState || !items[props.item_sipCallState] ||
    (items[props.item_sipCallState].state !== "HUNGUP" &&
    items[props.item_sipCallState].state !== "IDLE" &&
    items[props.item_sipCallState].state !== "TERMINATING")) &&
    (!props.item_sipRegistered || !items[props.item_sipRegistered] ||
    items[props.item_sipRegistered].state === "ON")
  style:
    background: black
    height: 440px
slots:
  default:
    - component: oh-context
      config:
        variables:
          localMicEnabled: false
          localMuteEnabled: false
      slots:
        default:
          - component: oh-video
            config:
              playerType: webrtc
              sendAudio: =vars.localMicEnabled && (!props.item_sipCallState || !items[props.item_sipCallState] || items[props.item_sipCallState].state === "ANSWERING" || items[props.item_sipCallState].state === "ACTIVE")
              micActive: =vars.localMicEnabled && (!props.item_sipCallState || !items[props.item_sipCallState] || items[props.item_sipCallState].state === "ANSWERING" || items[props.item_sipCallState].state === "ACTIVE")
              muteActive: =vars.localMuteEnabled
              startMuted: =vars.localMuteEnabled
              hideControls: false
              visible: '=items[props.item_webrtcUrl] && items[props.item_webrtcUrl].state && items[props.item_webrtcUrl].state !== "-" && items[props.item_webrtcUrl].state !== "NULL" && items[props.item_webrtcUrl].state !== "UNDEF"'
              url: '=items[props.item_webrtcUrl] && items[props.item_webrtcUrl].state && items[props.item_webrtcUrl].state !== "-" && items[props.item_webrtcUrl].state !== "NULL" && items[props.item_webrtcUrl].state !== "UNDEF" ? items[props.item_webrtcUrl].state : ""'
          - component: f7-block
            config:
              style:
                margin-left: 20px
                margin-right: 20px
                background: rgba(0,0,0,0.7)
                display: flex
                z-index: "10"
                justify-content: space-between
            slots:
              default:
                - component: oh-button
                  config:
                    iconF7: '=vars.localMuteEnabled ? "speaker_slash_fill" : "speaker_2_fill"'
                    iconSize: "28"
                    iconColor: '=vars.localMuteEnabled ? "white" : "green"'
                    action: variable
                    actionVariable: localMuteEnabled
                    actionVariableValue: =!vars.localMuteEnabled
                - component: oh-button
                  config:
                    iconF7: '=vars.localMicEnabled ? "mic_fill" : "mic_slash_fill"'
                    iconSize: "28"
                    iconColor: '=vars.localMicEnabled ? "red" : "white"'
                    action: variable
                    actionVariable: localMicEnabled
                    actionVariableValue: =!vars.localMicEnabled
                - component: oh-button
                  config:
                    iconF7: phone_fill_arrow_up_right
                    iconSize: "28"
                    iconColor: green
                    visible: =!!props.thingUid
                    action: http
                    actionHttpMethod: POST
                    actionUrl: ='/dahuadoor/sip/answer?thing=' + props.thingUid
                    actionVariable: localMicEnabled
                    actionVariableValue: true
                - component: oh-button
                  config:
                    iconF7: phone_down_fill
                    iconSize: "28"
                    iconColor: red
                    visible: =!!props.thingUid
                    action: http
                    actionHttpMethod: POST
                    actionUrl: ='/dahuadoor/sip/hangup?thing=' + props.thingUid
                    actionVariable: localMicEnabled
                    actionVariableValue: false
                - component: oh-button
                  config:
                    iconF7: lock_open_fill
                    iconSize: "28"
                    iconColor: green
                    visible: =!!props.item_doorOpen
                    action: command
                    actionCommand: ON
                    actionItem: =props.item_doorOpen
                - component: oh-button
                  config:
                    iconF7: square_arrow_up
                    iconSize: "28"
                    iconColor: green
                    visible: =!!props.item_doorOpen2
                    action: command
                    actionCommand: ON
                    actionItem: =props.item_doorOpen2

@Armadillo nice - will look to test in coming weeks at one site. A quick addition in the openHAB settings (Help & About) there is an options “Listen for UI Commands to” and you could have a rule that sets the changes the page to your required page and this would make it the active page and then on those devices that you want to respond you set the relevant setting to that string field

Thanks a lot for the tip, that is a very good idea.

I will test the “Listen for UI Commands to” approach so the target page can be activated automatically on selected devices before the popup condition is evaluated. That should make the widget much more practical in daily use.