Tp-Link Tapo C210 camera without internet

Posted on December 07, 2021 in Misc • 3 min read

It is quite challenging today to find a “security camera” (IP camera) which offers cloudless features, decent price and standard RTSP feeds. The only one I could come across is the Tp-Link Tapo C210 with this setup.

Tp-Link Tapo C210 camera is a cheap security camera, having 360 degrees rotation (which in my case is useful to physically ensure the camera is not filming when set to confidentiality mode) and exposing a basic API on the local network which can be used in Python script.

Installation

It can be configured in a cloud-less (without internet connection) environment with the following steps:

  • Install the “Tp-Link Tapo” app on your smartphone and create a cloud account. This is counterintuitive for this scenario, but required. We will never use an internet connection from now on.
  • Switch your smartphone to airplane mode and install the camera as usual (connect your smartphone to the camera wifi, set up the real wifi to use). The real wifi to use does not need to have access to Internet (it is fully firewalled in my case).
  • Connect to your firewalled wifi, camera should be working locally through the app.

From this point, you can use the “Tp-Link Tapo” app to control your camera on your local network.

Note: The app does not work when using a VPN interface to connect remotely (typically your mobile phone on LTE network + Wireguard link). You can however control the Tapo camera over such a link through RTSP feed and the next sections.

Controlling PTZ (Pan/Tilt/Zoom) and switching privacy mode programmatically

Provided you are fluent with scripting, you can also discard completely the “Tp-Link Tapo” app from now on:

  • The camera can expose standards RTSP feeds (which VLC supports for instance). You just need to set up a local camera account by going to “Advanced settings” > “Camera Account” in the “Tp-Link Tapo” app. You can then connect to rtsp://<YOUR_TAPO_IP>/stream1 in VLC and provide these credentials.
  • The camera itself can be fully controlled outside of the app through its API. In Python, pytapo library will help you a lot. You need to provide it the IP of your Tapo camera, admin as username and your Tp-Link cloud password as password. Although we do provide it our cloud credentials, everything works fully locally in this setup (no internet access required, neither from the script nor from the camera).

Out of the box, the Tapo C210 camera does not have a physical protection when confidentiality mode is on. With a bit of scripting, you can leverage its ability to rotate 360 degrees to make it turn against a wall when confidentiality mode is set:

import time
import pytapo


MAX_ITERATIONS=25


def get_privacy_mode(tapo):
    return tapo.getPrivacyMode().get('enabled', 'off') == 'on'


def toggle_privacy(tapo):
    current_privacy = get_privacy_mode(tapo)
    # Note: moving is disabled when in privacy mode.
    if current_privacy:
        tapo.setPrivacyMode(False)
        # Wait for privacy mode to be off, while avoiding infinite loop is the camera is stuck for some reason.
        for i in range(MAX_ITERATIONS):
            current_privacy = get_privacy_mode(tapo)
            if not current_privacy:
                break
            time.sleep(0.2)
            raise Exception('Tapo stuck in privacy mode!')
        tapo.moveMotor(-180, 0)
    else:
        tapo.moveMotor(180, 0)
        time.sleep(10)
        tapo.setPrivacyMode(True)

Ensuring correct date/time without NTP

As the Tapo C210 does not have internet access, it cannot rely on NTP to get correct date and time. Fortunately, setting up date / time manually can be easily done through the ONVIF interface:

from onvif import ONVIFCamera
mycam = ONVIFCamera('<YOUR_TAPO_IP>', 2020, '<YOUR_TAPO_USERNAME>', '<YOUR_TAPO_PASSWORD>', '/etc/onvif/wsdl/')

time_params = mycam.devicemgmt.create_type('SetSystemDateAndTime')
time_params.DateTimeType = 'Manual'
time_params.DaylightSavings = False
time_params.TimeZone = 'GMT+01:00'  # Edit according to your timezone
time_params.UTCDateTime = mycam.devicemgmt.GetSystemDateAndTime().UTCDateTime
# Adjust UTCDateTime if required
# time_params.UTCDateTime.Date.{Day,Month,Year} = ...
# time_params.UTCDateTime.Time.{Hour,Minute,Second} = ...
mycam.devicemgmt.SetSystemDateAndTime(time_params)

where <YOUR_TAPO_USERNAME>/<YOUR_TAPO_PASSWORD> are the credentials for the local account set up in the Tapo app (not the admin / Tp-Link cloud credentials!).

Left to explore

  • [ ] Motion detection, either through Tapo itself or through Motion/ML/ZoneMinder
  • [ ] Position presets
  • [ ] Local rolling archive with a Raspberry Pi