[Custom Component] Tapo: Cameras Control

HomeAssistant - Tapo: Cameras Control

Custom component - Tapo: Cameras Control - to add Tapo cameras into Home Assistant

Installation

Copy contents of custom_components/tapo_control/ to custom_components/tapo_control/ in your Home Assistant config folder.

Installation using HACS

HACS is a community store for Home Assistant. You can install HACS and then install Tapo: Camera Control from the HACS store.

Requirements

Network

Following target TCP (v)LAN ports must be open in firewall for the camera to access your Tapo Camera from Home Assistant:

  • 443 - HTTPS for control of the camera (services)
  • 554 - RTSP to fetch video stream from the camera
  • 2020 - ONVIF to track detected movement via a binary sensor

These are not WAN ports, DO NOT OPEN WAN PORTS VIA PORT FORWARDING. You might need to open (v)lan ports only if you know what all of this means.

Usage

Add cameras via Integrations (search for Tapo) in Home Assistant UI. You can also simply click the button below if you have MyHomeAssistant redirects set up.

Open your Home Assistant instance and start setting up a new integration.

Cameras are also automatically discovered when they are (re)connected to WIFI.

To add multiple cameras, add integration multiple times.

See examples for lovelace cards.

Quick Start

This custom component creates:

  • Camera entities, one for HD and one for SD stream
  • Binary sensor for motion after the motion is detected for the first time
  • Light entity, if the camera supports a floodlight switch
  • Buttons for Calibrate, Format, Manual Alarm start & stop, Moving the camera, Reboot and syncing time
  • Switch entities for auto track, Flip setting, LED Indicator, Lens Distortion Correction and Privacy mode
  • Select entities for Automatic Alarm, Light Frequency, Motion Detection, Night Vision and Move to Preset
  • Number entity for Movement Angle
  • And finally 2 tapo_control.* services to control a camera

Use these services in following service calls.

tapo_control.save_preset

Saves the current PTZ position to a preset

  • name Required: Name of the preset. Cannot be empty or a number
tapo_control.delete_preset

Deletes a preset

  • preset Required: PTZ preset ID or a Name. See possible presets in entity attributes

Sound Detection

Integration is capable of analysing sound from camera microphone and expose noise detected via binary_sensor.

You need to enable this feature in integration options by checking “Enable sound threshold detection”. After enabling it, you can also set any other options starting with [Sound Detection]. You will need to restart Home Asssistant after doing any changes.

For more information and troubleshooting see Home Assistant ffmpeg documentation on which this feature is based on.

Troubleshooting | FAQ

Binary sensor for motion doesn't show up or work

Motion sensor is added only after a motion is detected for the first time.

  • Make sure the camera has motion detection turned on
  • Make sure the camera has privacy mode turned off
  • Make sure the camera can see you and your movement
  • Try walking in front of the camera
  • If above didn’t work, restart the camera and try again

Also make sure that:

  • binary sensor is not disabled via entity, check .storage/core.entity_registry for disabled entities, look for “disabled_by”: “user” on platform “tapo_control”. If it is, remove the whole entity or change to “disabled_by”: null, and restart HASS.
  • binary sensor is enabled in tapo integration options
  • onvif port 2020 on camera is opened
Big delay in camera stream

This is a known issue of Home Assistant.

There is an ability to disable usage of Home Assistant Stream component for the camera, which might lower the delay very significantly at cost of higher CPU usage.

You can choose to disable stream component when adding the camera, or via Options when camera has already been added. This change requires a restart of Home Assistant.

There might be some disadvantages to doing this, like losing option to control playback and a higher CPU usage.
Results depend on your hardware and future Home Assistant updates.

If you disable stream and your hardware is not up to the task, you will get artifacts, bigger delay and freezes.

If you wish, try it out and see what works best for you.

Another possibility is using WebRTC Camera by AlexxIT.

Example working configuration:

type: custom:webrtc-camera
entity: camera.bedroom_hd
No audio in camera stream

Supported audio codecs in Home Assistant are “aac”, “ac3” and “mp3”.

Tapo Cameras use PCM ALAW (alaw) which is not supported.

More details here.

You can get sound working using WebRTC Camera by AlexxIT.

Example working configuration:

type: custom:webrtc-camera
entity: camera.bedroom_hd
Supported models

Users reported full functionality with following Tapo Cameras:

  • TC60
  • TC70
  • C100
  • C110
  • C200
  • C210
  • C310
  • C320WS

The integration should work with any other non-battery Tapo Cameras.

Battery cameras controlled via HUB are working only for control:

  • C420S2

If you had success with some other model, please report it via a new issue.

Have a comment or a suggestion?

Please open a new issue, or discuss on Home Assistant: Community Forum.

Join discussion on Discord.

Thank you

Buy Me A Coffee

Disclaimer

This integration is using python module Pytapo which is an unofficial module for achieving interoperability with Tapo cameras.

Author is in no way affiliated with Tp-Link or Tapo.

All the api requests used within the pytapo library are available and published on the internet (examples linked above) and the pytapo module is purely just a wrapper around those https requests.

Author does not guarantee functionality of this integration and is not responsible for any damage.

All product names, trademarks and registered trademarks in this repository, are property of their respective owners.

23 Likes

Spectacular - I have 3 Tapo camera’s (c100, 2 x c200) I’ll be trying this out on tonight. New to this HA lark but will do what I can to help out :slight_smile:

Some help for further development:

This is a Tp-Link C200, basic_info, info, and module_spec:

{

    "device_info": {

        "basic_info": {

            "device_type": "SMART.IPCAMERA",

            "device_model": "C200",

            "device_name": "C200 1.0",

            "device_info": "C200 1.0",

            "hw_version": "1.0",

            "sw_version": "1.0.14 Build 200720 Rel.38552n(4555)",

            "device_alias": "Tapo_Camera_XXXX",

            "features": "3",

            "barcode": "",

            "mac": "AA-BB-CC-DD-EE-00",

            "dev_id": "XXXXXXXXXXXXXXXXX",

            "oem_id": "XXXXXXXXXXXXXXXXXX",

            "hw_desc": "XXXXXXXXXXXXXXXXXXXXXX"

        }

    },

    "error_code": 0

}
{
    "device_info": {
        "info": {
            ".name": "info",
            ".type": "info",
            "device_model": "C200",
            "hw_version": "1.0",
            "fw_description": "C200 1.0",
            "product_id": "00c20000",
            "device_name": "C200 1.0",
            "device_info": "C200 1.0",
            "cur_isp_version": "14",
            "sensor": "SC2335",
            "sw_version": "1.0.14 Build 200720 Rel.38552n(4555)",
            "sys_software_revision": "0x500a0100",
            "sys_software_revision_minor": "0x000e",
            "device_type": "SMART.IPCAMERA",
            "features": "3",
            "domain_name": "tplogin.cn",
            "language": "EN",
            "enable_dns": "1",
            "manufacturer_name": "TP-LINK",
            "friendly_name": "IPC",
            "model_description": "IPC",
            "manufacturer_url": "http://www.tp-link.com",
            "vendor_id": "0x00000001",
            "zone_code": "0x0",
            "roi_reg_num": "1",
            "cover_reg_num": "4",
            "md_reg_num": "32",
            "td_reg_num": "1",
            "plugin_obtain_way": "web",
            "product_type": "ipc",
            "up_fw_shared_prefix": "Tapo_C200v1",
            "unify_firmware_support": "1",
            "isp_version": "14"
        }
    },
    "error_code": 0
}
{

    "function": {

        "module_spec": {

            ".name": "module_spec",

            ".type": "module-spec",

            "app_version": "1.0.0",

            "led": "1",

            "change_password": "1",

            "local_storage": "1",

            "timing_reboot": "1",

            "motor": "1",

            "ota_upgrade": "1",

            "msg_push": "1",

            "msg_alarm": "1",

            "network": [

                "wifi"

            ],

            "events": [

                "motion",

                "tamper"

            ],

            "playback": [

                "local",

                "p2p",

                "relay"

            ],

            "preview": [

                "local",

                "p2p",

                "relay"

            ],

            "video_codec": [

                "h264"

            ],

            "audio": [

                "speaker",

                "microphone"

            ],

            "download": [

                "video"

            ],

            "record_type": [

                "timing",

                "motion"

            ],

            "record_max_slot_cnt": "10",

            "stream_max_sessions": "10",

            "streaming_support_versions": [

                "1.0"

            ],

            "relay_support_versions": [

                "1.3"

            ],

            "p2p_support_versions": [

                "1.1"

            ],

            "device_share": [

                "preview",

                "playback",

                "motor",

                "voice"

            ],

            "msg_alarm_list": [

                "sound",

                "light"

            ],

            "storage_api_version": "2.2",

            "playback_scale": "1",

            "lens_mask": "1",

            "target_track": "1",

            "wireless_hotspot": "1",

            "wifi_connection_info": "1",

            "video_detection_digital_sensitivity": "1",

            "client_info": "1",

            "ssl_cer_version": "1.0",

            "media_encrypt": "1",

            "multi_user": "0",

            "auth_encrypt": "1"

        }

    },

    "error_code": 0

}

This is a Tp-Link C100, basic_info , info , and module_spec :

{

    "device_info": {

        "basic_info": {

            "device_type": "SMART.IPCAMERA",

            "device_model": "C100",

            "device_name": "C100 1.0",

            "device_info": "C100 1.0",

            "hw_version": "1.0",

            "sw_version": "1.0.2 Build 200306 Rel.41295n(4555)",

            "device_alias": "Tapo_Camera_XXXX",

            "features": "3",

            "barcode": "",

            "mac": "AA-BB-CC-DD-EE-00",

            "dev_id": "XXXXXXXXXXXXXXXXX",

            "oem_id": "XXXXXXXXXXXXXXXXXX",

            "hw_desc": "XXXXXXXXXXXXXXXXXXXXXX"

        }

    },

    "error_code": 0

}
{

    "device_info": {

        "info": {

            ".name": "info",

            ".type": "info",

            "device_model": "C100",

            "hw_version": "1.0",

            "fw_description": "C100 1.0",

            "product_id": "00c10000",

            "device_name": "C100 1.0",

            "device_info": "C100 1.0",

            "cur_isp_version": "5",

            "sw_version": "1.0.2 Build 200306 Rel.41295n(4555)",

            "sys_software_revision": "0x500a0100",

            "sys_software_revision_minor": "0x0002",

            "device_type": "SMART.IPCAMERA",

            "features": "3",

            "domain_name": "tplogin.cn",

            "language": "EN",

            "enable_dns": "1",

            "manufacturer_name": "TP-LINK",

            "friendly_name": "IPC",

            "model_description": "IPC",

            "manufacturer_url": "http://www.tp-link.com",

            "vendor_id": "0x00000001",

            "zone_code": "0x0",

            "roi_reg_num": "1",

            "cover_reg_num": "4",

            "md_reg_num": "32",

            "td_reg_num": "1",

            "plugin_obtain_way": "web",

            "product_type": "ipc",

            "up_fw_shared_prefix": "Tapo_C100v1",

            "unify_firmware_support": "1",

            "isp_version": "5"

        }

    },

    "error_code": 0

}
{

    "function": {

        "module_spec": {

            ".name": "module_spec",

            ".type": "module-spec",

            "app_version": "1.0.0",

            "led": "1",

            "change_password": "1",

            "local_storage": "1",

            "timing_reboot": "1",

            "ota_upgrade": "1",

            "msg_push": "1",

            "msg_alarm": "1",

            "network": [

                "wifi"

            ],

            "events": [

                "motion",

                "tamper"

            ],

            "playback": [

                "local",

                "p2p",

                "relay"

            ],

            "preview": [

                "local",

                "p2p",

                "relay"

            ],

            "video_codec": [

                "h264"

            ],

            "audio": [

                "speaker",

                "microphone"

            ],

            "download": [

                "video"

            ],

            "record_type": [

                "timing",

                "motion"

            ],

            "record_max_slot_cnt": "10",

            "stream_max_sessions": "10",

            "streaming_support_versions": [

                "1.0"

            ],

            "relay_support_versions": [

                "1.3"

            ],

            "p2p_support_versions": [

                "1.1"

            ],

            "device_share": [

                "preview",

                "playback",

                "voice"

            ],

            "msg_alarm_list": [

                "sound",

                "light"

            ],

            "storage_api_version": "2.2",

            "playback_scale": "1",

            "lens_mask": "1",

            "wireless_hotspot": "1",

            "wifi_connection_info": "1",

            "video_detection_digital_sensitivity": "1",

            "client_info": "1",

            "ssl_cer_version": "1.0",

            "media_encrypt": "1",

            "multi_user": "0",

            "auth_encrypt": "1"

        }

    },

    "error_code": 0

}

(I haven’t updated the firmware on this one yet.)

1 Like

Version 1.0 has been released!

Initial release of Tapo: Cameras Control

New Features

  • Support for multiple cameras
  • Internal authentication does not expire and works even after reboot of a camera
  • Automatic update of all camera entities
  • Main attributes of camera for every entity, along with preset list
  • Full HACS compatibility

New services

  • tapo_control.ptz
  • tapo_control.set_privacy_mode
  • tapo_control.set_alarm_mode
  • tapo_control.set_led_mode
  • tapo_control.set_motion_detection_mode
  • tapo_control.set_auto_track_mode
  • tapo_control.reboot
  • tapo_control.save_preset
  • tapo_control.delete_preset

Details for services in readme.

Questions? Feedback? Bugs?

If you have any suggestions, questions or bug reports please open a new issue, or discuss on Home Assistant: Community Forum.

3 Likes

WOW! This works great, thank you for your good work!

1 Like

Brilliant work. Thank you

1 Like

VERSION 2.0 :tada:

It has been a few days since the first release, and I feel its a time for version 2.0 which is packed with a lot of awesome new features.

I would like to say special thank you to everyone who reported bugs or joined discussion on Home Assistant: Community Forum

New Features

  • Completely refactored the whole integration. Code is now a lot easier to read, simpler and up to current HASS standards.
  • Set up via Home Assistant Integrations UI, which also means, setup via configuration.yaml is no longer supported.
  • Automatically creates a new device in Home Assistant with its information like firmware, brand, model etc
  • Each device automatically creates 2 entities - HD and SD streams of camera platform
  • Camera stream is now available
  • Ability to format SD card of a camera
  • Better error handling and validation of service calls before they get executed

Minor updates

  • Integration now has an icon, brand and model
  • Added motion_detection and motion_detection_sensitivity attributes
  • Added privacy_mode attribute
  • Added alarm and alarm_mode attributes
  • Added led attribute
  • Added auto_track attribute

Breaking Changes

  • Integration is now set up via UI. You will need to remove tapo_control from configuration.yaml and set up integration using Home Assistant -> Configuration -> Integrations. Just search for tapo and add the cameras.
  • Entities of platform tapo_control are no longer created, camera platform is used instead.
  • Entity names now include _hd or _sd in the name. This does not affect services.
5 Likes

Great work! :pray:
Need to dig up my C200 from the junk again and try this!

Great work! Thank you!:+1:

Thanks for your great work!
How do you view and control your cameras inside the dashboard?

I created switches to use with a picture glance, but maybe there is are ways to optimize this, for example using some kind of joystick instead of switches for ptz.

Here are my switches:

  - platform: template
    switches:
      camera_preset_default:
        value_template: "on"
        unique_id: cam1_preset_default
        turn_on:
          service: tapo_control.ptz
          data_template:
            preset: 1
            entity_id: camera.cam1_hd
        turn_off:
          service: tapo_control.ptz
          data_template:
            preset: 1
            entity_id: camera.cam1_hd

  - platform: template
    switches:
      camera_preset_down:
        value_template: "on"
        unique_id: cam1_preset_down
        turn_on:
          service: tapo_control.ptz
          data_template:
            preset: 2
            entity_id: camera.cam1_hd
        turn_off:
          service: tapo_control.ptz
          data_template:
            preset: 2
            entity_id: camera.cam1_hd
            
  - platform: template
    switches:
      camera_preset_up:
        value_template: "on"
        unique_id: cam1_preset_up
        turn_on:
          service: tapo_control.ptz
          data_template:
            preset: 3
            entity_id: camera.cam1_hd
        turn_off:
          service: tapo_control.ptz
          data_template:
            preset: 3
            entity_id: camera.cam1_hd
            
  - platform: template
    switches:
      camera_up:
        value_template: "on"
        unique_id: cam1_up
        turn_on:
          service: tapo_control.ptz
          data_template:
            tilt: UP
            distance: 0.1
            entity_id: camera.cam1_hd
        turn_off:
          service: tapo_control.ptz
          data_template:
            tilt: UP
            distance: 0.1
            entity_id: camera.cam1_hd
            
  - platform: template           
    switches:
      camera_down:
        value_template: "on"
        unique_id: cam1_down
        turn_on:
          service: tapo_control.ptz
          data_template:
            tilt: DOWN
            distance: 0.1
            entity_id: camera.cam1_hd
        turn_off:
          service: tapo_control.ptz
          data_template:
            tilt: DOWN
            distance: 0.1
            entity_id: camera.cam1_hd
            
  - platform: template                    
    switches:
      camera_left:
        value_template: "on"
        unique_id: cam1_left
        turn_on:
          service: tapo_control.ptz
          data_template:
            pan: LEFT
            distance: 0.1
            entity_id: camera.cam1_hd
        turn_off:
          service: tapo_control.ptz
          data_template:
            pan: LEFT
            distance: 0.1
            entity_id: camera.cam1_hd
   
  - platform: template                  
    switches:
      camera_right:
        unique_id: cam1_right
        value_template: "on"
        turn_on:
          service: tapo_control.ptz
          data_template:
            pan: RIGHT
            distance: 0.1
            entity_id: camera.cam1_hd
        turn_off:
          service: tapo_control.ptz
          data_template:
            pan: RIGHT
            distance: 0.1
            entity_id: camera.cam1_hd
            
            
  - platform: template                  
    switches:
      camera_privacy:
        value_template: "{{ is_state_attr('camera.cam1_hd','privacy_mode' ,'on') }}"
        unique_id: cam1_privacy
        turn_on:
          service: tapo_control.set_privacy_mode
          data_template:
            entity_id: camera.cam1_hd
            privacy_mode: 'on'
        turn_off:
          service: tapo_control.set_privacy_mode
          data_template:
            entity_id: camera.cam1_hd
            privacy_mode: 'off'

I have tried to use the service to toggle privacy mode on and off but can only get it to toggle on
The command for toggle off doesn´t seem to work ?

Trying this via the Developer tools

How are you testing this? The app is buggy, you need to restart it, or not use at all (watch stream in hass instead). See this discussion, maybe you are dealing with the same thing.

1 Like

You can also use something like this:

camera_image: camera.bedroom_hd
camera_view: live
entities:
  - entity: camera.bedroom_hd
    icon: 'mdi:palm-tree'
    tap_action:
      action: call-service
      service: script.set_bedroom_camera_away
  - entity: camera.bedroom_hd
    icon: 'mdi:home'
    tap_action:
      action: call-service
      service: script.set_bedroom_camera_home
hold_action:
  action: call-service
  service: python_script.set_camera
  service_data:
    entity_id: sensor.show_camera
    state: '70'
tap_action:
  action: more-info
title: Bedroom
type: picture-glance

Until someone creates a new lovelace component I think solution like these are the best we can get.

1 Like

You where right. I was watching in the Tapo app and when restarting the app all was good.

Also checked in Hass and it workes great

1 Like

am I correct in thinking that motion sensing state is not currently supported but camera feeds are? I assume I can combine T:CC with ONVIF to get both. If so what would people recomend as the preferred video source, stream via ONVIF or stream via T:CC?

@JurajNyiri - superb work sir :slight_smile:

Thank you :slight_smile:

Yes you are correct. It is planned for 2.1 as onvif is able to get the status, I should be able to replicate the logic inside this integration.

I have created many more feature requests I plan to implement in the future, I need help with this one specifically.

As in which stream to use, I have just checked onvif integration and internal code works exactly the same.

1 Like

Version 2.1 has been released! :running_man:

New Features

Motion sensor

The first time your camera detects a motion it creates a new binary sensor. This sensor is updated in real time whenever there is a motion to on or off state.
After the next Home Assistant reboot, this sensor is restored with unavailable state until it detects motion again.

Motion sensor should recover from any reboots or disconnects of the camera automatically.

See the new troubleshooting section in readme if you have any questions regarding motion sensor before creating a new issue.

Camera image

Component now also provides an image of the current stream.

It generates it from the current stream on Home Assistant. While this is a common practice in other integrations too, we could do better and get the image directly from the camera instead. See this feature request if you would like to help.

New update coordinator

This release includes a rewrite of how updates are handled, resulting in 2 times reduction of number of requests outgoing camera while not affecting update speed.

Other minor updates

  • support for services camera.disable_motion_detection and camera.enable_motion_detection
  • support for services camera.turn_on camera.turn_off

Final remarks

If you need help…

Please open a new issue or a feature request, or discuss and ask for help on Home Assistant: Community Forum.

If you would like to help…

Join the discussion or see issues marked with help wanted.

There are already some examples going around with requests for more.

I would love to see what people already created with this camera on lovelace, so please open a PR and let’s share!

4 Likes

Created Discord server for support, research and discussion. Feel free to join! :slight_smile:

Would be possible to have those services implemented as entities where possible? Like motion detection being on or off could be a switch and the value would be updated by polling.