Vivint Doorbell Integration

I am new to this community, but thought I would share this in case anyone else was interested.
This is stemmed from recently purchasing a house that has a vivint system built into it, and having the run around with vivint about services and paying for monitoring.

I decided to do some research and found this post on the openHAB community:

Connect doorbell to wifi
and
Connect to doorbell via telnet

Following these instructions I was able to connect the doorbell to my wifi network instead of the network on the vivint panel.
Once it was connected to my network, I was able to log in via the web portal with the credentials:

root
adcvideo

As well as telnet into the OS (which runs some form of embedded linux), which gave me access to modify the file system. In the web portal there are a ton of settings for motion detection and video quality. To link this up to my Home Assistant setup was a little bit tricky.

First, I had to find the .wav file (since that was the only thing that I knew it had to have when the button is pushed). Once I found this, I was able to find the script that calls it, and ultimately found the script called bellButton in /usr/bin/.

Now I knew that I needed to have a simple webrequest added to the script, problem is the embedded system didn’t have curl or any of the other libraries needed to make a webrequest. That’s when I thought why not try telnet? Sure enough, this works perfect:

{ echo "POST /api/webhook/[trigger_name]"; echo; } | telnet [host name or ip] 8123

Once I was able to determine that I could use telnet, I just need to add it to the bellbutton script, only problem is /usr/bin is readOnly storage. Simple solution for that:

  • Copy the bellbutton script to a writeable directory using this command:
    cp /usr/bin/bellbutton /mnt/flash/bellbutton
  • Modify bellbutton script in /mnt/flash using vi and add your telnet line where it is needed
  • Mount your copied script to temporarily overwrite the existing script using this command:
    mount --bind /mnt/flash/bellbutton /usr/bin.bellbutton

I have yet to add this mount to the init.d so that it gets remounted on reboot, but for now the doorbell works perfect!

Edit: Keep in mind, if you plan on doing this yourself and using SSL front end, you will need to set up duckdns and nginx because telnet does not work over SSL.

2 Likes

I’ve been looking into doing that for a while. I also have 3 Vivint cameras around the house that I want to integrate with HA.
Do you have more detail on how to integrate the doorbell with HA?
Also is it possible to use it with vivant panel and HA at the same time? If not then would it be possible to revert back to vivant panel if needed?

I thought I had posted as much detail as a could (short of making a video on the whole process). What is not working?

Unfortunately you can’t use the vivint panel and HA at the same time, because part of the process is moving the doorbell off of the panel’s wifi network and connecting it to your wifi network so that you can telnet to HA. I haven’t tried reverting back to the panel, but I am pretty sure you just would reset the doorbell and go through the pairing process for adding it to the panel.

Hey HeedfulCrayon,

First of all, thank you so much, I have successfully enabled Telnet, however, I am having some trouble following the rest of the steps after that, could you please provide some more detailed guidance? on how to link the Vivint doorbell to Homeassistant?

Best,

James

Do you have a script called bellButton in /usr/bin/ ?

No, I do not have the script called bellButton,

however I do have a script called play_sound. Are they similar?

It could work. It just depends on if the event of pushing the button called that script. I would gamble that it does call that script, so you could inject a telnet command into that.

Could you please go into a little more detail on how to inject telnet command? Also do I have to set up the telnet component on homeassistant as well? I am unfamiliar with what to put into the script. Can you provide a screen capture of your script?

Just to clarify, are we trying to use the doorbell to Telnet into the home assistant server?

Sorry, I am quite a noob with this.

I am confident that the play_sound script is called when pushing the button after reviewing the script, as it plays Bell.wav

This is what bellbutton looks like

Also, it looks like you may have different firmware, because I don’t even have a play_sound script

Any luck getting it to work?

I just tried putting the code in and setting up the automation for the doorbell. And I got it working.

Thank you for your help HeedfulCrayon

Also I am running Version: 0200i as can be seen in the bottom left corner

Glad I could be of help… Pretty awesome to have that huh? I just want to make sure you know that you will have to add the mounting script into a service for when the doorbell restarts, otherwise it will stop working. I am still trying to figure that part out

Hi, I don’t have Vivent, but I do use Vivotek IP Cameras so was curious about this. Is there a model number for this doorbell camera? Thanks.

I think it is V DBC1, but the connection instructions on the openHab site are for another model, so it might work :man_shrugging:

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