Dahua VTO custom integration

Hi,

I have de Dahua VTO4202FB-P.
When I add the sensor, HA sees the type and serial number. However, the status remains unchanged at OK.

deviceType: DHI-VTO4202FB-P
serialNumber: 8E035A4P******0E
friendly_name: intercom-door

Are there people with this type of intercom with experience?

Thank you,
Michiel

Hello, if status is OK and you see the serialNumber than everything works as expected and your device is supported. Now you should build your logic as explained here in examples.

Hi,

Thank you for your response.

But when I search for the sensor via ‘Develper Tools’, the ‘State’ only stays on ‘OK’. Whether the intercom rings or not. This remains unchanged.

I added the indoor station (VTH2421F-P) and the outdoor station (DHI-VTO4202FB-P).
Both return a deviceType and serialNumber returned.

Thanks,
Michiel

I try it with this code, modifying only the entity_id for the one of my light, and when trying to save the automation, it shows me the following error:
Message malformed: extra keys not allowed @ data[‘0’]

Why it happens?

It’s can be anything, post here the full code of your automation.
You use a code from my previous post where I post the changes for this example.

This integration doesn’t expose any sensors like intercom rings, door unlock, etc, instead sensors you should use events received from device and fired by integration. You can use this example as starting point, add this automation’s into your yaml configuration and you will get notification for different events, than modify this automation’s according your needs.

If you are not familiar with HA yaml programming you can use rroller integration which exposes these sensors and you can use GUI configuration and regular HA automation editor.

Hi “myhomeiot”

Thank you very much for the response. I’m going to work on this, but then I’ll know which direction to go.

regards
Michiel

Hi,

The integration catches well the events but I wonder how to get the RFID card number in the event ? It seems that I don’t have all the variables.

Here is an example of the content I get when an enrolled rfid tag is passed on the doorbell.

event_type: dahua_vto
data:
  Action: Pulse
  Code: DoorStatus
  Data:
    LocaleTime: '2023-01-25 21:08:29'
    Relay: true
    Status: Close
    UTC: 1674680909
  Index: 0
  entity_id: sensor.dahua_vto

Hello,

Just tested with my VTO2111D, when I pass defined and enabled RFID card I get following events:

{'Action': 'Pulse', 'Code': 'BackKeyLight', 'Data': {'LocaleTime': '2023-01-26 12:58:50', 'State': 8, 'UTC': 1674730730.0}, 'Index': -1, 'entity_id': 'sensor.dahua_vto'}
{'Action': 'Pulse', 'Code': 'AccessControl', 'Data': {'CardNo': '18749234', 'CardType': None, 'LocaleTime': '2023-01-26 12:58:51', 'Method': 1, 'Name': 'OpenDoor', 'Password': '', 'ReaderID': '1', 'RecNo': 1484, 'SnapURL': '', 'Status': 1, 'Type': 'Entry', 'UTC': 1674730731.0, 'UserID': '9901'}, 'Index': 0, 'entity_id': 'sensor.dahua_vto'}
{'Action': 'Pulse', 'Code': 'DoorCard', 'Data': {'Check': [0, 0], 'LocaleTime': '2023-01-26 12:58:51', 'Number': '18749234', 'Type': 0, 'UTC': 1674730731.0}, 'Index': 0, 'entity_id': 'sensor.dahua_vto'}

For blocked card (lost mode) I get:

{'Action': 'Pulse', 'Code': 'BackKeyLight', 'Data': {'LocaleTime': '2023-01-26 13:06:17', 'State': 9, 'UTC': 1674731177.0}, 'Index': -1, 'entity_id': 'sensor.dahua_vto'}
{'Action': 'Pulse', 'Code': 'AccessControl', 'Data': {'CardNo': '18749234', 'CardType': None, 'LocaleTime': '2023-01-26 13:06:17', 'Method': 1, 'Name': 'OpenDoor', 'Password': '', 'ReaderID': '1', 'RecNo': 1488, 'SnapURL': '', 'Status': 0, 'Type': 'Entry', 'UTC': 1674731177.0, 'UserID': ''}, 'Index': 0, 'entity_id': 'sensor.dahua_vto'}
{'Action': 'Pulse', 'Code': 'DoorCard', 'Data': {'Check': [0, 0], 'LocaleTime': '2023-01-26 13:06:17', 'Number': '18749234', 'Type': 0, 'UTC': 1674731177.0}, 'Index': 0, 'entity_id': 'sensor.dahua_vto'}

The integration is running but for triggering the doorbell there is also the docker container DahuaVTO2mqtt. Do you think the other events are catched by the dokcker container ?

My firmware version : 2022-05-23 V4.511.0000000.0.R

I don’t know if DahuaVTO2mqtt send all events from device. If you have VTH as well you should see lot of annoying events like:

{'Action': 'Pulse', 'Code': 'SIPRegisterResult', 'Data': {'Date': '26-01-2023 13:17:24', 'LocaleTime': '2023-01-26 13:17:24', 'Success': True, 'UTC': 1674731844.0}, 'Index': 0, 'entity_id': 'sensor.dahua_vto'}

Yes, I see these events.
My question was moslty : do you suggest that I stop dahuavto2mqtt container to test that the integration catch all events ?

Both integration should work simultaneously without any problems, but for clean test, yes, I suggest you to stop dahuavto2mqtt container and make sure that your card is defined and opens the door then you pass it.

PS: I’m not sure why you use both integration (this and DahuaVTO2mqtt) because it’s more or less same and you can use just one.

Update: For catch all events I use this automation

Thank you for your answer.
I use the dahuavto2mqtt since ages to ring a bell. I plan to remove it as soon as I can catch the button event with the integration.

Here you can find the example.

Thank you, it is perfect, I get all events and nfc IDs.

Hi, this is the setup I’m using for my system if anyone finds it useful.

I’m using the VIP Vision INTIPRDSDB and INTIPMONDW, which are basically rebranded versions of the Dahua VTO2111D and VTH5221D. They work perfectly with this integration.
They were acting weird until I updated the firmware on them to 4.300.0000006.0.T,build:2019-03-20 first though.

As well as setting up this integration I added the intercom camera using the Generic Camera integration using the following URLs and digest auth with the same admin and the password for the intercom.
I used Connect to Dahua cameras to figure out which camera urls to use, and ended up using:
http://<ip_address>/cgi-bin/snapshot.cgi?1
rtsp://admin:<password>@<ip_address>:554/cam/realmonitor?channel=1&subtype=1
This gives the sub/second stream, set "subtype=0" instead for the main stream.

Sensors and locks defined in configuration.yaml:
The main things that will need changing are:

  • The VTO name, I named mine “Intercom” so replace the "sensor.intercom" with yours
  • Auto_off times depending on your settings on the intercom
  • Access card IDs and names
  • Remove the entries for the second gate if you only have one connected
  • And potentially the names of all the created entities
    (the unique_ids probably should all be random UUIDs, but I made these before I knew that (UUIDs can be generated in the cog menu of the File Editor addon))
template:
  # Tamper sensor for the camera being covered
  - trigger:
      platform: event
      event_type: dahua_vto
      event_data:
        Code: VideoBlind
    binary_sensor:
      - name: VTO Camera Covered
        unique_id: "vto_camera_covered"
        state: "{{ trigger.event.data.Action | string == 'Start' }}"
        device_class: tamper

  # Sensors for the gate connected to the first intercom relay
  - trigger:
      platform: event
      event_type: dahua_vto
      event_data:
        Code: AccessControl
        Index: 0
    binary_sensor:
      # State of the relay
      #  Use the timer set in the intercom web interface for the unlock time as the auto_off time
      - name: Front Gate State
        unique_id: "front_gate_state"
        auto_off: 5
        state: >
          {{ trigger.event.data.Data.Name | string == "OpenDoor"
          and
          trigger.event.data.Data.Status | int == 1 }}
        device_class: lock
    sensor:
      # The last access method used to unlock the gate
      #  The state will be set according to which one of the following trigged the unlock:
      #   Access card ID 
      #   Short_number value of the dahua_vto.open_door service (HA is from the template lock set below, HA_Notif is from an automation)
      #   Room number of the Dahua tablet (9901)
      #  The attributes:
      #   Successful unlock?
      #   Which method was used to unlock (Mine only supports Access Card or by Network)
      #   The full event data
      - name: Front Gate Access
        unique_id: "front_gate_access"
        state: >
          {% if trigger.event.data.Data.Method | int == 1 %}
              {% set cards = {
                "12345671": "Card 1",
                "12345672": "Card 2",
                "12345673": "Card 3",
                "12345674": "Card 4",
              } %}
              {% if trigger.event.data.Data.CardNo in cards %}
                {{ cards[trigger.event.data.Data.CardNo] }}
              {% else %}
                Unrecognised card: {{ trigger.event.data.Data.CardNo }}
              {% endif %}
          {% elif trigger.event.data.Data.UserID | string == "HA" %}
            Home Assistant
          {% elif trigger.event.data.Data.UserID | string == "HA_Notif" %}
            Notification
          {% elif trigger.event.data.Data.UserID | string == "9901" %}
            Intercom Tablet
          {% else %}
            Other Unlock: {{ trigger.event.data.Data.Method | int }}
          {% endif %}
        attributes:
            Successful: "{{ trigger.event.data.Data.Status | int == 1 }}"
            Method: >
              {% if trigger.event.data.Data.Method | int == 1 %}
                Card 
              {% elif trigger.event.data.Data.Method | int == 4 %}
                Remote
              {% else %}
                Other: {{ trigger.event.data.Data.Method | int }}
              {% endif %}
            Data: "{{ trigger.event.data }}"

  # Sensors for the gate connected to the second intercom relay
  #  Use the timer set in the intercom web interface for the unlock time as the auto_off time
  - trigger:
      platform: event
      event_type: dahua_vto
      event_data:
        Code: AccessControl
        Index: 1
    binary_sensor:
      - name: Car Gate State
        unique_id: "car_gate_state"
        auto_off: 30
        state: >
          {{ trigger.event.data.Data.Name | string == "OpenDoor"
          and
          trigger.event.data.Data.Status | int == 1 }}

  # Whether the doorbell is ringing
  #  Used to trigger the doorbell automation
  #  Use the ringing time from the intercom as the auto_off time
  - trigger:
      platform: event
      event_type: dahua_vto
      event_data:
        Code: BackKeyLight
    binary_sensor:
      - name: Doorbell Ringing
        unique_id: "doorbell_ringing"
        auto_off: 60
        state: >
          {% if trigger.event.data.Data.State | int == 1 %}
            on
          {% elif trigger.event.data.Data.State | int == 0 %}
            off
          {% else %}
            {{ states("binary_sensor.doorbell_ringing") }}
          {% endif %}
        device_class: sound

# Uses the above gate sensors to define locks that allow opening the gates
#  The short_number sets the UserID for the unlock event
lock:
  # Gate connected to relay 1
  - platform: template
    name: Front Gate
    unique_id: "front_gate"
    value_template: "{{ not is_state('binary_sensor.front_gate_state', 'on') }}"
    lock:
    unlock:
      service: dahua_vto.open_door
      data_template:
        entity_id: sensor.intercom
        channel: 1
        short_number: HA

  # Gate connected to relay 2
  - platform: template
    name: Car Gate
    unique_id: "car_gate"
    value_template: "{{ not is_state('binary_sensor.car_gate_state', 'on') }}"
    lock:
    unlock:
      service: dahua_vto.open_door
      data:
        entity_id: sensor.intercom
        channel: 2
        short_number: HA

If I had a magnetic sensor (Dahua VTO custom integration - #115 by myhomeiot) I’d probably combine it with the relay for the status of the lock.




Notification automations:

The sensor, camera, intercom, and notify entity names will need changing

# Sends a notification when an invalid card is used on the intercom.
#  I assume this would also work similarly with an invalid keypad code if supported by the intercom.

alias: Notify Dahua VTO Invalid Card
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.front_gate_access
    attribute: Successful
    to: false
condition: []
action:
  - service: notify.notify_all_phones
    data:
      message: >-
        Invalid card: "{{ trigger.to_state.attributes.Data.Data.CardNo }}" used
        on intercom
      data:
        push:
          interruption-level: time-sensitive
mode: single
# Sends a notification to the notification group I created when the intercom's button is pressed.
# It allows the camera to be shown when you long press on the notification (on iOS, probably similar on Android)
# It waits for the CANCEL_CALL action for the time the intercom rings for then cancels the call if received in that time.
# There is then a separate automation to receive the OPEN_GATE action which opens the gate and cancels the call.
#  They could be merged into the same automation, but I wanted the open gate action to work at any time and I didn't really want it waiting in this automation forever.

alias: Notify Dahua VTO Doorbell
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.doorbell_ringing
    to: "on"
    from: "off"
condition: []
action:
  - service: notify.notify_all_phones
    data:
      title: Someone's at the gate
      message: Open to see camera
      data:
        tag: intercom
        entity_id: camera.intercom_sub
        actions:
          - action: OPEN_GATE
            title: Open gate
          - action: CANCEL_CALL
            title: Cancel Call
        push:
          interruption-level: time-sensitive
  - wait_for_trigger:
      - platform: event
        event_type: mobile_app_notification_action
        event_data:
          action: CANCEL_CALL
    continue_on_timeout: false
    timeout:
      hours: 0
      minutes: 1
      seconds: 0
      milliseconds: 0
  - service: dahua_vto.send_command
    data:
      entity_id: sensor.intercom
      method: console.runCmd
      params:
        command: hc
      event: true
    alias: "Dahua VTO: Send command: Cancel Call"
mode: restart
# Listens for the notification action, opening the gate and stopping the ringing
alias: Notify_Action Event Intercom Open Gate
description: ""
trigger:
  - platform: event
    event_type: mobile_app_notification_action
    event_data:
      action: OPEN_GATE
    context: {}
condition: []
action:
  - service: dahua_vto.open_door
    data:
      entity_id: sensor.intercom
      channel: 1
      short_number: HA_Notif
  - service: dahua_vto.send_command
    data:
      entity_id: sensor.intercom
      method: console.runCmd
      params:
        command: hc
      event: true
mode: single




And here’s a list of the useful identifying parts of events that are generated for various things:

VTO Events:
  "event_type": "dahua_vto"
  Valid card used to unlock door:
    Card swiped:
      "Code": "DoorCard",
      "Data": {
        "Number": "1234567c",
    Card successfully used:
      "Code": "AccessControl",
      "Data": {
        "CardNo": "1234567c",
        "Name": "OpenDoor",
        "Status": 1,
    Door unlocked:
      "Code": "BackKeyLight",
      "Data": {
        "State": 8,
  Invalid card attempt to unlock door:
    Card swiped:
      "Code": "DoorCard",
      "Data": {
        "Number": "a8765432",
    Card unsuccessfully used:
      "Code": "AccessControl",
      "Data": {
        "CardNo": "a8765432",
        "Name": "OpenDoor",
        "Status": 0,
    Failed door unlocked:
      "Code": "BackKeyLight",
      "Data": {
        "State": 9,
  Camera Covered:
    Beginning:
      "Action": "Start",
      "Code": "VideoBlind",
    End:
      "Action": "Stop",
      "Code": "VideoBlind",
  Doorbell Rang:
    Button pressed:
      "Code": "BackKeyLight",
      "Data": {
        "State": 1,
    Ringing:
      "Code": "BackKeyLight",
      "Data": {
        "State": 2,
  Call not answered:
    Call timeout:
      "Code": "BackKeyLight",
      "Data": {
        "State": 6,
    > 8 seconds
    Back to normal state:
      "Code": "BackKeyLight",
      "Data": {
        "State": 0,
  Call answered by VTH:
    Call answered:
      "Code": "BackKeyLight",
      "Data": {
        "State": 5,
    > After call
    Back to normal state:
      "Code": "BackKeyLight",
      "Data": {
        "State": 0,
  Ringing cancelled by notification:
    Command response:
      'result': True,
      'method': 'console.runCmd',
      'entity_id': 'sensor.intercom'
    Back to normal state:
      "Code": "BackKeyLight",
      "Data": {
        "State": 0,
  Ringing cancelled by VTH:
    "Code": "BackKeyLight",
    "Data": {
      "State": 0,
3 Likes

Thank you for sharing! Very nice configuration example!

1 Like

Just an update:
Thanks to the right help, the integration with the Dahua intercom was successful!

My hardware:
Outpost: DHI-VTO4202FB-P
Indoor station: VTH2421F-P

3 Likes

Hi,

I also have the DHI-VTO4202 with 5 doorbells.
The integration is working very well.

But sadly i cant differentiate between the 5 different buttons.
I want to ring the analog bell with a relay. But for this I first need to know which bell rings.
In the Log every button has the same output.

Thank you in advance.