Vivint Doorbell Integration

Hey Wmaker,

The model number for the doorbell camer i have is VS-DBC250-110. Hope it helps

Thanks @James_Y for this. I managed to acquire a VS-DBC250-110 model (aka V-DBC2S) and have spent the last several days playing around with it.

Couple of things I can add to this thread:

  1. I was able to solve the problem concerning having to re-mount after a reboot/restart.
    I will say I looked for other ways to detect the doorbell button being pressed. I thought for sure that there was a configurable parameter somewhere that said what to do when the doorbell button was pressed. It appears that the play_sound script is called from the init daemon, but nowhere could I find a parameter in the daemon’s config to tell it to do this. I next investigated whether or not the Vivotek software could detect a button push as an event. If it could, then one could also create actions (using the GUI) such as sending http notifications to a destination of your choice. I found where there was actually an event being defined in one of Vivotek’s xml files for a button press, but apparently it was not integrated in with the rest of the Vivotek software. So in the end, I came back to the solution everyone else uses, that is to mount the play_sound script on a writable filesystem so that it could be modified.

  2. http client - the camera has an http client, so it is possible to send an http based webhook directly to HA. To be honest, I’m surprised the telnet solution worked, as from my understanding HA only has a single socket and its configured to run either http or https, but anyway glad it worked out.

  3. http to https (essentially a proxy) - The camera also has a SSL Tunnel client/server that in theory could be used for carrying http, but I could not get it to work with my Home Assistant setup. As I use https (secured), I had to come up with another way to send a webhook to HA, and I ended up writing some simple python code that receives http GETs from the vivint doorbell, and relays a POST to HA using https.

  4. HA Vivotek Integration - If you weren’t aware, there is a vivotek camera integration for HA. I managed to get it working with the doorbell camera for streaming video (unfortunately there is no audio, and as I understand it, audio has yet to be incorporated in to HA streaming) and have gotten the snap shot to work so that you can actually take a picture of whoever presses the doorbell button…

Remounting after reboot
I first tried the normal way which is to add an entry in /etc/fstab. However after a reboot, what I found out was that the device blows away any changes that were made. In fact several files and directories in /etc/ are blown away and re-written. What I managed to figure out was that after the device reboots, Linux/Busybox calls a few init scripts, and one in particular is /etc/init.d/rcS. Towards the end of it, it in turn calls all the scripts in /etc/rcS.d/. Luckily this directory actually resides in /mnt/flash/etc/rcS.d/ which is writable and does not get blown away after reboot.

So in /mnt/flash/etc/rcS.d, add a file named say mount_doorbell that will do the mount. Here is what is in mine::

#!/bin/sh
mount --bind /mnt/flash2/play_sound /usr/bin/play_sound

You can modify it if you put your play_sound script somewhere else. I put mine in the flash2 filesystem since it has lots of empty space.

HTTP Client
Within the play_sound script I added the following to it (within the else statement):

        if [ $1 == $DOORBELL_CHIME ] ; then
               #httpclient -M POST -m ' ' -S HA_IPADDRESS 8123 "" "" -U /api/webhook/XXXX
                httpclient -M GET -r "./temp" -S HA_IPADDRESS 8080 "" "" -U /api/webhook/XXXX
        fi

The commented out httpclient does a POST and the one you would need to send directly to HA. I’ve not been able to test this completely so it may not work exactly. The other httpclient is the one I use to send to my python code.

Python Code
Its a work in progress, but I do have a working version I can share later. It will be standalone code that will need to be started using the method of your choice.

EDIT: Finally getting around to posting the http to https relay code.

This code will take the URL received from the vivint camera’s http GET, which contains ‘/api/webhook/XXXX’ (where XXXX is the webhook) and relay it to HA using http POST and passing the ‘/api/webhook/XXXX’ to HA.

#!/usr/bin/python3
from http.server import BaseHTTPRequestHandler,HTTPServer
import requests
import logging
import logging.handlers #Needed for Syslog
import sys

#Change the following to fit your needs:
HA_URL1 = "https://<IPADDRESS_OR_DNS_OF_HA>:<HA_PORT>"
PORT_NUMBER = <PORT_TO_LISTEN_TO_FROM_VIVINT>

# Setup Logger for this server.
#   If you want to see output to the Console, set CONSOLE = 1
#     Otherwise logs go to local syslog server.
#   If you want debug level output, then change the last two lines
#      _LOGGER.setLevel from NOTSET to DEBUG.
CONSOLE = 0
_LOGGER = logging.getLogger(__name__)
if CONSOLE:
    formatter = \
        logging.Formatter('%(message)s')
    handler1 = logging.StreamHandler(sys.stdout)
    handler1.setFormatter(formatter)
    handler1.setLevel(logging.NOTSET)
    _LOGGER.addHandler(handler1)
else:
    formatter2 = \
        logging.Formatter('%(levelname)s %(asctime)s %(filename)s - %(message)s')
    handler2 = logging.handlers.SysLogHandler(address = '/dev/log')
    handler2.setFormatter(formatter2)
    handler2.setLevel(logging.NOTSET)
    _LOGGER.addHandler(handler2)

#_LOGGER.setLevel(logging.DEBUG)
_LOGGER.setLevel(logging.NOTSET)

def HAPost(url, path):
    """Send http/https POST to home assistant with api """
    url = url + path
    try:
        response = requests.post(url)
       #print(url, response)
        _LOGGER.debug("Sending URL: %s", url)
        _LOGGER.debug("Response: %s", response)
        if str(response) == '<Response [201]>':
            return 1
    except(requests.exceptions.Timeout):
        #HA is slow, just keep retrying
       #print('requests.exceptions.Timeout')
        _LOGGER.error("REQUESTS.TIMEOUT")
        pass #do nothing
    except(requests.exceptions.ConnectionError):
       #print('REQUESTS.CONNECTION_ERROR to ',url)
        _LOGGER.error("REQUESTS.CONNECTION_ERROR to %s",url)
        return 1


#Handle an incoming request
class myHandler(BaseHTTPRequestHandler):
    """Handle the incoming HTTP GET or POST Request."""

    def process_incoming(self):
        """Process the incoming request."""
       #print("Path ", self.path)
       #print("Headers: ", self.headers)
        _LOGGER.debug("Received Path: %s", self.path)
        _LOGGER.debug("Received Headers: %s", self.headers)
        sendReply = False
        position = self.path.find("/api/webhook/")
        if position == -1:
           #print("api/webhook/ portion of URL Not Found")
            _LOGGER.warning("/api/webhook/ portion of URL Not Found")
        else:
            sendReply = True
            url = HA_URL1
            HAPost(url, self.path)

        if sendReply == True:
           #self.send_response(204) #Vivent doesn't like
            self.send_response(200)
            #Must return something to vivint even if null.
            mimetype='text/html'
            self.send_header('Content-type',mimetype)
            self.end_headers()
            self.wfile.write(str.encode('')) #encode string to bytes

        else:
            self.send_error(404,'The requested URL was not found: %s' % self.path)
        return

    def do_GET(self):
        """Process incoming GET requests."""
        return self.process_incoming()

    def do_POST(self):
        """Process incoming POST requests."""
        return self.process_incoming()
    def log_message(self, format, *args):
        """
        Remove this method if you want to see
        normal http.server output, otherwise
        override the http.server output with
        your own logger.
        """
        _LOGGER.debug("%s - - [%s] %s\n" %
                       (self.client_address[0],
                        self.log_date_time_string(),
                        format%args))
        return

try:
    #Create and startup the server and define the handler to manage
    #  the incoming http requests.
    server = HTTPServer(('', PORT_NUMBER), myHandler)
   #print('Started httpserver on port ',  PORT_NUMBER)
    _LOGGER.info("Started http server on port: %s", PORT_NUMBER)

    #Run forever
    server.serve_forever()

except KeyboardInterrupt:
   #print(' received, shutting down the server')
    _LOGGER.info(' received, shutting down the server')
   #print( '^C received, shutting down the server')
finally:
   #print("Closing the socket.  We're Done!")
    _LOGGER.info("Closing the socket.  We're Done!")
    server.socket.close()



2 Likes

Good finds!
I was unable to use any httpClient as my doorbell firmware was so old… It didn’t seem to have anything I could use. I am definitely going to investigate getting the mount script functional on mine

Hey Tommy,

Im trying to configure that when motion is detected, the camera will notify HA, but im having trouble finding the script which activates when motion is detected (Im assuming there is a script that is being called similar to play_sound for when the button is being pressed). Any help is appreciated.

Cheers

I haven’t searched around to see if there is a similar script but there is likely not one.

However since Motion Detection is done by the Vivotek software and in general you have to setup Motion detection using the Vivotek GUI (Goto “Configuration” tab and Applications->Motion Detection), you can also configure the Vivotek software for an “Event” using the GUI (Goto Event->Event Settings).
For an “Event”, you would use the motion detection as a trigger, and one of the actions you can define for an event is “Server” (with some “server-name”).

Configure a “Server” with your “server-name” and configure it with an HTTP URL. I just tried this by setting the URL to http://HA_IP_ADDRESS:PORT/api/webhook/DoorbellMotion and when the trigger occurred (I used a manual trigger to test out), Vivotek sent an HTTP POST with the /api/webhook/DoorbellMotion to that address and port.

Hope this helps.

Hi all,
I wanted to share a project that I have have been working on that allow you to establish a two-way audio call with the Vivint/Vivotek Doorbell from a web browser. The project is made up of 3 parts:

  • DoorVivint Card - A Lovelace card that can view your Vivint/Vivotek Doorbell video, and with the push of a button, establish a two-way call with the doorbell. It uses JSSIP and relies on the webbrowser’s support for WebRTC to work properly and as I found out, not all do :frowning: ). As WebRTC uses secure websocket’s, you really need to have a public SSL certificate (duckdns will do).
  • app_rtsp_sip - An Asterisk application that handles the split audio streams of the Vivint/Vivotek Doorbell (audio from the doorbell is setup using RTSP, and audio to the doorbell is setup using SIP). It is a companion project to DoorVivint Card.
  • Asterisk - Asterisk is a free opensource IP PBX. It connects to the DoorVivint card directly (using a websocket), and to Vivint/Vivotek doorbell via the app_rtsp_sip application. It is the brains that lets the DoorVivint Card call the Vivint/Vivotek doorbell. To get app_rtsp_sip working with Asterisk, both need to be compiled from scratch and subsequently installed.

It is a rather involved task to get all this setup and running, but I have done my best to provide instructions to do just that.

Currently I have this working on Chrome running on Windows 10. My ultimate goal was to get this working on my Home Assistant iOS App, but thus far I have been unsuccessful getting this part of the project working. Similarly, depending on your browser’s support for WebRTC and JSSIP, it may or may not work for you.

Best Regards.

4 Likes

Wow Tommy,

That’s amazing. I am trying to get this working on my vivint camera too I believe i have the same model as James_Y. I’m at the step of adding the card, however without luck. Any Tips?

Maybe i did not add the correct resources? I installed via manuel and HACS both method yeilded failed result. May I see how you added your resources?

Please Advise/?

Add via HACS.

Check this thread to see if this helps:

I think what you have was what use to be the old way of configuring resources into ui-lovelace.yaml. This has since moved into configuration.yaml.

Also another thing to look into, the card config you show may need to be shifted to the right by two spaces.

Hi all,

I’ve been working with HA for about a month now, and have recently followed the advice of this thread to get my Vivint doorbell onto my local network. It is a DB8332-SW Version 0200m, if that matters. Originally using the default password and now with a revised password I have both http and telnet access.

The additions to configuration.yaml seem very straightforward, I’ve just used items from https://www.home-assistant.io/integrations/vivotek/ and the config passes all checks. For completeness, my config is:

camera:
  - platform: vivotek
    name: 'Front Door Camera'
    ip_address: 192.168.1.5
    ssl: false
    verify_ssl: false
    username: root
    password: 
    security_level: admin
    framerate: 5
    stream_path: live2.sdp

In which the password (not shown) is my actual root password. However, when I restart to include the new integration, I get (the final line is)…

libpyvivotek.vivotek.VivotekCameraError: Unauthorized. Credentials may be invalid.

…this seems to have been a common error that happened last year moving from 0.99 to 0.100 (that was fixed?). Please, if it’s obvious to you, what stupid thing am I missing?

Yeah I’ve run into this before…Your config looks fine, but for comparison of what you have versus what I have, the only difference is I have live2.sdp in double-quotes, and I don’t have the security_level set, but its suppose to be admin by default anyway. If that doesn’t work, my only other suggestion would be to double-check the passwords…maybe change them in the vivotek web gui (and of course in this HA config) just to see.

@wmaker, thanks. I will give your suggestions a shot. I just successfully got the vivotek to mount a samba share (but not from the web interface - from telnet! argh!) so progress continues. Hopefully I can get HA to see the darn thing.

Looks like to get my SMB mount permanent I’ll need to follow your steps in post #16, so thanks in advance for blazing this trail!

Best,
Kendall

Just some random updates that may hopefully help others… (I still can’t get HA to recognize the darn thing)…

  • The root filesystem can be remounted read/write using the “standard technique”… if you want to add changes to various scripts without having to perform the bind mounts mentioned in the first post (unless these are overwritten at reboot? donno)… Not sure what convinced me of this but I can’t repeat it…
  • Using the web interface you can set up network storage, but the current scripts in cgi-bin won’t correctly test mount a Samba share… however
  • mount.cifs will mount a Samba share if you remove the arg sec=ntlm and replace it with vers=3.0 (force a SMB version 3 mount)… at least this worked for me. I read that one shouldn’t use vers and sec (security) options at the same time, so I removed the sec option.
  • This has to be corrected in /mnt/flash/etc/auto.conf, so that automount can mount the SMB share when asked.
  • With this correction in place and the right event settings, the Vivotek is saving tarfiles (containing a snapshot and clip) to the Samba share…

Looks like I need to lower the sensitivity as 6 tarfiles have appeared in the last 10 minutes hahahahah!

Progress, I guess.

Fixed… If you are having trouble with the “Credentials may be invalid.” error, try changing your (http) authentication from basic to digest:

authentication: digest

All is well now.

Wow great additions from a lot of people! Just out of curiosity, does the vivotek integration perform better than just setting up an RTSP stream from the camera?

Before the Vivotek integration came along I did setup my Vivotek cameras using RTSP stream. The other thing I do with the Vivotek integration is to use some of service calls it provides.

Is the video streaming performance about the same between the two? I don’t really use the call functionality

Good question… I seem to recall when I first setup the Vivotek integration, it was setting up an rtsp stream to the camera just like a regular camera would do, so I think the performance is the same.

1 Like

Hi Tommy,
did you maybe updated your plugin recently or the version available on the github is the latest one?
I finally managed to run it with my Dahua VTO2000A doorbell. It is great idea to run the communication as designed here and I believe it will run reliable.
I’m now thinking about some customizations however would like to avoid making mistakes I’ll do while learning :-).

Hi,
The version on my github is still the latest one.