Tapo C310 person detection sensor

Hello.
Can someone help me how to get binary sensor person detection in Tapo c310 integration.
The motion sensor works great but detects everything. Thank you

This request is also outstanding in the HACS-based Tapo integration
awaiting for someone to spend time on it.

hey guys, I recently started using Home assistant and connected my C310 ending at the point you guys at.
But I’m slightly confused as they already implemented the “Person Detection” mode but there is no sensors for this to also push a notifcation to the Logbook

Am I missing something to add the sensor? Been trying to manipulate the Motion Entity ID to Person detection but it seems to have no affect.

Hope anyone found a work around.

Regards

This is motion detection
there is an added feature of ‘person’ detection

There is a settings option for “motion” and “person” detection. But sadly on the settings option you can receive on your phone Tapo app then.

Anyways, has anyone of you a work around to save the record on your Server once the motion sensor was triggered? Since the person detection isn’t available as alert yet I assume its only doable for motion.

Would highly appreciate.

Using Home assistant on Proxmox

1 Like

Same here with C320WS and C110 cams: person detection works like a charm in Tapo app, but I have a LOT of false alarms in HASS - based on the standard motion detection onvif event.

Shadows in the daytime, tiny bugs at night
 completely unuseable for automation.

  • I also started the trial period of Tap Care service to check if they have any kind of notification (e-mail or something), but I can’t see any.

  • I tried to use my Synology NVR’s person detection feature, but it needs at least a 25fps stream to work - what a shame that tapo cameras are maximized in 15


So it doesn’t work either :frowning:

I’m not in app development and packet capturing techniques, but what if one just installs Tapo app in an android emulator and monitors the communication between Tapo app and the cameras/servers?

Anyone tried this?
Or is this kind of reverse engineering a completely bad direction?

Any help appreciated!

Hi all. For what it’s worth, here’s my apporach to getting HA alerts when a person is detected (I have a TP-Link Tapo C320W camerag). My camera only tells me about motion detections, not any other detections. This approach is a bit bare, but it works:

High level overview:
I use a python script to poll my camera for all events that occured, filter for the “person detected” event and send a message to HA using MQTT.

The approach:

  • Make sure you have a MQTT broker running
  • Here’s a nifty method (from the pytapo library, bless their souls) that allows you to read all events from your Tapo Camera that occured between two timeframes.
  • Use a python script to poll the camera events and match on the “person detection” alarm type
  • Use AppDaemon to run the python script (or another way if you have one, but just make sure that the script can access your network)
  • Send a MQTT message whenever the “person detected” event happened.

The code

Be sure to to install the pytapo and paho-mqtt libraries.

here’s the code:

import appdaemon.plugins.hass.hassapi as hass
from paho.mqtt import client as mqtt
from pytapo import Tapo
from datetime import datetime
import time
import json

TRANSPORT = "tcp"
BROKER_ADDRESS = "your-broker-ip"
BROKER_PORT = 1883
BROKER_USERNAME = "broker-username"
BROKER_PASSWORD = "broker-password"
PERSON_DETECTED_ALARM_TYPE = 6
# See https://github.com/JurajNyiri/pytapo/blob/2a28236dfd885947d93f6a98ac1b10cdb0b731d4/pytapo/__init__.py#L677
# To check that `6` is also your camera's `person detected` alarm type, open a python shell, run the code to
# instantiate a tapo client (see code below), let your camera detect a person, call the
# tapo_client.getEvents(startTime=now - 60*10) to see the events for the past 10 minutes and check the last
# event's alarm type ID

ENTITY_ID = "tap_camera" # Give your entity a name
TOPIC= "tapo/person_detected" # change this to your liking
DISCOVERY_TOPIC = f"homeassistant/binary_sensor/{ENTITY_ID}/config"

CAMERA_IP = "camera ip" # make sure this is static
CAMERA_USERNAME = "camera-username"
CAMERA_PASSWORD = "the-camera-password"
INTERVAL_SEC = 5

BIRTH_TOPIC = f"homeassistant/binary_sensor/{ENTITY_ID}/status"
BIRTH_PAYLOAD = "online"
WILL_TOPIC = f"homeassistant/binary_sensor/{ENTITY_ID}/status"
WILL_PAYLOAD = "offline"
UNIQUE_ID = "3e73ef97-470b-5555-6666-f0b59d0552ce" # You can use another unique id here as well, just make sure is
# doesn't change

class TapoEventListener(hass.Hass):

    def initialize(self):
        self.mqtt_client = None
        self.tapo_client = None
        self._setup_clients()
        self._enter_loop()

    def _send_message(self, client, message):
        client.publish(TOPIC, message)

    def _publish_discovery(self, client):
        discovery_payload = {
            "name": "Person Detected",
            "state_topic": TOPIC,
            "payload_on": "detected",
            "payload_off": "clear",
            "device_class": "motion",
            "unique_id": UNIQUE_ID,
            "object_id": UNIQUE_ID,
        }
        # Publish the discovery message to the discovery topic
        client.publish(DISCOVERY_TOPIC, json.dumps(discovery_payload), retain=True)

    def _setup_clients(self):
        # MQTT
        self.log("Creating MQTT client...")
        self.mqtt_client = mqtt.Client()
        self.mqtt_client.username_pw_set(BROKER_USERNAME, BROKER_PASSWORD)
        self.log("Setting will message...")
        self.mqtt_client.will_set(WILL_TOPIC, WILL_PAYLOAD, qos=1, retain=True)
        self.log("Connecting...")
        self.mqtt_client.connect(BROKER_ADDRESS, BROKER_PORT)
        self.log("Publishing discovery payload...")
        self._publish_discovery(self.mqtt_client)
        self.log("Sending birth message...")
        self.mqtt_client.publish(BIRTH_TOPIC, BIRTH_PAYLOAD, qos=1, retain=True)

        # Camera
        self.log("Creating Tapo Camera client...")
        self.tapo_client = Tapo(CAMERA_IP, user=CAMERA_USERNAME, password=CAMERA_PASSWORD)


    def _enter_loop(self):
        self.log("Entering loop...")
        now = int(datetime.timestamp(datetime.now()))
        self.tapo_client.getEvents(startTime=now - INTERVAL_SEC)
        try:
            while True:
                person_detected = False
                events = self.tapo_client.getEvents(startTime=now - INTERVAL_SEC)
                self.mqtt_client.reconnect()
                for event in events:
                    alarm_type = event["alarm_type"]
                    if alarm_type == PERSON_DETECTED_ALARM_TYPE:
                        self.log(f"Person detected!")
                        person_detected = True
                        self._send_message(self.mqtt_client, message="detected")
                        break
                if not person_detected:
                    self._send_message(self.mqtt_client, message="clear")

                time.sleep(INTERVAL_SEC)
                now = int(datetime.timestamp(datetime.now()))
        except Exception as e:
            self.log(f"An error occured:\nError:{e}.\nExiting")
            exit(1)

A few notes:

  • I do not know if the Tapo Camera’s API has a rate limit, but I guess there is one. Have no idea what it is, so be careful with the INTERVAL_SEC variable.
  • This script was not tested rigorously. Any suggested improvements are super welcome.
  • Notifications through HA is obviously not as snappy as those from the Tapo app, but there’s max INTERVAL_SEC ± 1 sec delay from detection to notification.

P.S
If you want to make this robust against camera reboots, you’ll have to update the loop by swapping the while and try-except blocks. Something like:

while True:
    try:
        person_detected = False
        events = self.tapo_client.getEvents(startTime=now - INTERVAL_SEC)
        self.log(f"Events: {events}")
        self.mqtt_client.reconnect()
        for event in events:
            alarm_type = event["alarm_type"]
            if alarm_type == PERSON_DETECTED_ALARM_TYPE:
                self.log(f"Person detected!")
                person_detected = True
                self._send_message(self.mqtt_client, message="detected")
                break
        if not person_detected:
            self._send_message(self.mqtt_client, message="clear")
    except Exception as e:
        self.log(f"An error occured:\nError:{e}")
1 Like

Is there a solution for this?