Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Add multiple events detections #304

Open
AndreiArdelean1 opened this issue Mar 30, 2023 · 164 comments
Open

Feature Request: Add multiple events detections #304

AndreiArdelean1 opened this issue Mar 30, 2023 · 164 comments
Assignees
Labels
Enhancement New feature or request Help wanted Extra attention is needed

Comments

@AndreiArdelean1
Copy link

AndreiArdelean1 commented Mar 30, 2023

Is your feature request related to a problem? Please describe.
I want to be able to detect multiple event types.
I'm not interested in actually highlighting/retrieving the rectangle where this was detected on the camera, just the detection event.

Describe the solution you'd like
I want to be able to detect and distinguish between:

  • Motion
  • AI: Person, Pet, Vehicle, Baby Crying, Glass Break, Dog Barks, Cat Meows
  • Line-Crossing
  • Camera Tampering

These notifications are sent to the native app.

Describe alternatives you've considered

  1. Create a different sensor for each event type. This has the benefit of also tracking (either now, or maybe in future updates of the camera) the duration that the event was on.
  2. Add attributes to the motion detection sensor binary_sensor that indicate the type of the event

A clear and concise description of any alternative solutions or features you've considered.

Additional context
These features are available on 3MP+ cameras for free, and on 1080p cameras using the paid subscription

Here is the response from GetEventProperties of the ONVIF endpoint on Tapo C225 camera:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsdd="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:chan="http://schemas.microsoft.com/ws/2005/02/duplex" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:xmime="http://tempuri.org/xmime.xsd" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:wsrfr="http://docs.oasis-open.org/wsrf/r-2" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:ter="http://www.onvif.org/ver10/error" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:tdn="http://www.onvif.org/ver10/network/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:trp="http://www.onvif.org/ver10/replay/wsdl" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:hikwsd="http://www.onvifext.com/onvif/ext/ver10/wsdl" xmlns:hikxsd="http://www.onvifext.com/onvif/ext/ver10/schema">
    <SOAP-ENV:Header>
        <wsa5:Action SOAP-ENV:mustUnderstand="true">http://www.onvif.org/ver10/events/wsdl/EventPortType/GetEventPropertiesResponse</wsa5:Action>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <tev:GetEventPropertiesResponse>
            <tev:TopicNamespaceLocation>http://www.onvif.org/onvif/ver10/topics/topicns.xml</tev:TopicNamespaceLocation>
            <wsnt:FixedTopicSet>true</wsnt:FixedTopicSet>
            <wstop:TopicSet>
                <tns1:RuleEngine>
                    <CellMotionDetector>
                        <Motion wstop:topic="true">
                            <tt:MessageDescription IsProperty="true">
                                <tt:Source>
                                    <tt:SimpleItemDescription Type="tt:ReferenceToken" Name="VideoSourceConfigurationToken"></tt:SimpleItemDescription>
                                    <tt:SimpleItemDescription Type="tt:ReferenceToken" Name="VideoAnalyticsConfigurationToken"></tt:SimpleItemDescription>
                                    <tt:SimpleItemDescription Type="xsd:string" Name="Rule"></tt:SimpleItemDescription>
                                </tt:Source>
                                <tt:Data>
                                    <tt:SimpleItemDescription Type="xsd:boolean" Name="IsMotion"></tt:SimpleItemDescription>
                                </tt:Data>
                            </tt:MessageDescription>
                        </Motion>
                    </CellMotionDetector>
                    <TamperDetector>
                        <Tamper wstop:topic="true">
                            <tt:MessageDescription IsProperty="true">
                                <tt:Source>
                                    <tt:SimpleItemDescription Type="tt:ReferenceToken" Name="VideoSourceConfigurationToken"></tt:SimpleItemDescription>
                                    <tt:SimpleItemDescription Type="tt:ReferenceToken" Name="VideoAnalyticsConfigurationToken"></tt:SimpleItemDescription>
                                    <tt:SimpleItemDescription Type="xsd:string" Name="Rule"></tt:SimpleItemDescription>
                                </tt:Source>
                                <tt:Data>
                                    <tt:SimpleItemDescription Type="xsd:boolean" Name="IsTamper"></tt:SimpleItemDescription>
                                </tt:Data>
                            </tt:MessageDescription>
                        </Tamper>
                    </TamperDetector>
                    <LineCrossDetector>
                        <LineCross wstop:topic="true">
                            <tt:MessageDescription IsProperty="true">
                                <tt:Source>
                                    <tt:SimpleItemDescription Type="tt:ReferenceToken" Name="VideoSourceConfigurationToken"></tt:SimpleItemDescription>
                                    <tt:SimpleItemDescription Type="tt:ReferenceToken" Name="VideoAnalyticsConfigurationToken"></tt:SimpleItemDescription>
                                    <tt:SimpleItemDescription Type="xsd:string" Name="Rule"></tt:SimpleItemDescription>
                                </tt:Source>
                                <tt:Data>
                                    <tt:SimpleItemDescription Type="xsd:boolean" Name="IsLineCross"></tt:SimpleItemDescription>
                                </tt:Data>
                            </tt:MessageDescription>
                        </LineCross>
                    </LineCrossDetector>
                    <PeopleDetector>
                        <People wstop:topic="true">
                            <tt:MessageDescription IsProperty="true">
                                <tt:Source>
                                    <tt:SimpleItemDescription Type="tt:ReferenceToken" Name="VideoSourceConfigurationToken"></tt:SimpleItemDescription>
                                    <tt:SimpleItemDescription Type="tt:ReferenceToken" Name="VideoAnalyticsConfigurationToken"></tt:SimpleItemDescription>
                                    <tt:SimpleItemDescription Type="xsd:string" Name="Rule"></tt:SimpleItemDescription>
                                </tt:Source>
                                <tt:Data>
                                    <tt:SimpleItemDescription Type="xsd:boolean" Name="IsPeople"></tt:SimpleItemDescription>
                                </tt:Data>
                            </tt:MessageDescription>
                        </People>
                    </PeopleDetector>
                    <TPSmartEventDetector>
                        <TPSmartEvent wstop:topic="true">
                            <tt:MessageDescription IsProperty="true">
                                <tt:Source>
                                    <tt:SimpleItemDescription Type="tt:ReferenceToken" Name="VideoSourceConfigurationToken"></tt:SimpleItemDescription>
                                    <tt:SimpleItemDescription Type="tt:ReferenceToken" Name="VideoAnalyticsConfigurationToken"></tt:SimpleItemDescription>
                                    <tt:SimpleItemDescription Type="xsd:string" Name="Rule"></tt:SimpleItemDescription>
                                </tt:Source>
                                <tt:Data>
                                    <tt:SimpleItemDescription Type="xsd:boolean" Name="IsTPSmartEvent"></tt:SimpleItemDescription>
                                </tt:Data>
                            </tt:MessageDescription>
                        </TPSmartEvent>
                    </TPSmartEventDetector>
                </tns1:RuleEngine>
            </wstop:TopicSet>
            <wsnt:TopicExpressionDialect>http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet</wsnt:TopicExpressionDialect>
            <wsnt:TopicExpressionDialect>http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete</wsnt:TopicExpressionDialect>
            <tev:MessageContentFilterDialect>http://www.onvif.org/ver10/tev/messageContentFilter/ItemFilter</tev:MessageContentFilterDialect>
            <tev:MessageContentSchemaLocation>http://www.onvif.org/onvif/ver10/schema/onvif.xsd</tev:MessageContentSchemaLocation>
        </tev:GetEventPropertiesResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Currently, motion detection doesn't work on Tapo C225 #303, but this feature would be nice to have once it is working.

@JurajNyiri
Copy link
Owner

This integration reuses onvif from Home Assistant. Adding detectors for these would require to expand on it or handlers to be added into https://github.com/home-assistant/core/blob/dev/homeassistant/components/onvif/parsers.py .

@JurajNyiri
Copy link
Owner

JurajNyiri commented Mar 31, 2023

  1. Install https://github.com/JurajNyiri/HomeAssistant-Tapo-Control/tree/expand_onvif
  2. You should see a lot more warning messages now on onvif events trigger
  3. Unsupported entities should come up as "No registered handler for event from" or "Unable to parse event from"

Please report them here.

I tested on C200 with my Person Detection enabled and I have not received any events...

@NEVdataDyne
Copy link

NEVdataDyne commented Mar 31, 2023

I would like to help as I need my tapo cameras to trigger automations in HA when a person is detected. Until now the only way I could achieve that is to use Alexa between the cameras and HA. With this solution the cameras need to access internet which is not ideal. Using the video stream to detect people on another system is also not a solution because it uses the WiFi so much that it interferes with my Philips Hue remotes.

Could you please tell me how to install https://github.com/JurajNyiri/HomeAssistant-Tapo-Control/tree/expand_onvif ?

@NEVdataDyne
Copy link

NEVdataDyne commented Mar 31, 2023

I downloaded the zip
I updated the Tapo custom component to 5.0
Then I replaced all the files custom_components\tapo_control by the ones from the zip using samba share and restarted HA
I didn't see any new entities so I installed the onvif integration and connected it to one of my C225 camera
I didn't see any new entities either (besides the onvif related entities that I was expecting)
In the logs there doesn't seem to be a message like "No registered handler for event from" or "Unable to parse event from"

I am not sure what I should do?

@JurajNyiri
Copy link
Owner

JurajNyiri commented Mar 31, 2023

The code in the branch above doesnt have any new entities. However, it will catch any previously uncought events with an error message. If you are not seeing any other events then it looks like the camera is not issueing those events. I will do some more testing later with the subscription.

@NEVdataDyne

This comment was marked as off-topic.

@AndreiArdelean1
Copy link
Author

AndreiArdelean1 commented Apr 1, 2023

@NEVdataDyne It looks like you are having the issue #303 (the last error in your comment). Is your motion sensor (classic one) working/triggered in Homeassistant?

@JurajNyiri I'm not seeing any of the errors you mentioned. Could it be that the integration needs to subscribe explicitly for certain events? Something like "on event PERSON_DETECTED post to WEBHOOK".

Also, because of #303 I'm having issues at the moment. I'm changing the file manually inside onvif-zeep-async but it sometimes gets overwritten or some other issue, but the motion detection (classic one) is not very stable for me. This could be the cause I'm not getting any of the new errors.

@NEVdataDyne
Copy link

@AndreiArdelean1 No motion sensor doesn't seem to work. It doesn't seem to work even with my C110 camera so I am not really sure if I am doing somethng wrong. (I have C225, C320WS and one C110 camera)

@AndreiArdelean1
Copy link
Author

I've gotten the integration to work by modifying tapo_control to use a local version of onvif-zeep-async and only motion events are triggered. I've also verified this using Postman and observing the sent events.

Also, the ONVIF integration declares CellMotionDetector, TamperDetector, LineCrossDetector, PeopleDetector, TPSmartEventDetector. All of this should be just boolean values. But, I've only been able to trigger only CellMotionDetector. Since the camera supports other types of detection events/notifications (like pet detection, glass break, vehicle, etc., within the official app) + boundary boxes of the detection inside the video feed, (apparently) are not exposed through ONVIF, I'm guessing the camera uses some Tapo specific API for this. The TamperDetector, LineCrossDetector, and PeopleDetector are most likely discontinued from the ONVIF API or something else is going on.

I'll investigate this further and post updates if I find something else.

@AndreiArdelean1
Copy link
Author

AndreiArdelean1 commented Apr 3, 2023

I didn't manage to find a way of getting the special detection events, but the following will help with integrating the configuration of these events (enabling and sensitivity) into HA and pytapo.

Here is the request the app makes on start:
{"method":"multipleRequest","params":{"requests":[{"method":"getDetectionConfig","params":{"motion_detection":{"name":"motion_det"}}},{"method":"getDetectionRegion","params":{"motion_detection":{"table":["region_info"]}}},{"method":"getBCDConfig","params":{"sound_detection":{"name":["bcd"]}}},{"method":"getPersonDetectionConfig","params":{"people_detection":{"name":["detection"]}}},{"method":"getVehicleDetectionConfig","params":{"vehicle_detection":{"name":["detection"]}}},{"method":"getPetDetectionConfig","params":{"pet_detection":{"name":["detection"]}}},{"method":"getBarkDetectionConfig","params":{"bark_detection":{"name":["detection"]}}},{"method":"getMeowDetectionConfig","params":{"meow_detection":{"name":["detection"]}}},{"method":"getGlassDetectionConfig","params":{"glass_detection":{"name":["detection"]}}},{"method":"getTargetTrackConfig","params":{"target_track":{"name":["target_track_info"]}}},{"method":"getAlertConfig","params":{"msg_alarm":{"name":["chn1_msg_alarm_info","capability"]}}},{"method":"getAlertPlan","params":{"msg_alarm_plan":{"name":"chn1_msg_alarm_plan"}}},{"method":"getAlertTypeList","params":{"msg_alarm":{"name":"alert_type"}}},{"method":"getAlertEventType","params":{"msg_alarm":{"table":["msg_alarm_type"]}}},{"method":"getAlertConfig","params":{"msg_alarm":{"table":["usr_def_audio"]}}},{"method":"getMsgPushConfig","params":{"msg_push":{"name":"chn1_msg_push_info"}}},{"method":"getMsgPushPlan","params":{"msg_push_plan":{"name":"chn1_msg_push_plan"}}},{"method":"getTamperDetectionConfig","params":{"tamper_detection":{"name":"tamper_det"}}},{"method":"getLinecrossingDetectionConfig","params":{"linecrossing_detection":{"name":["detection","arming_schedule"]}}},{"method":"getLinecrossingDetectionRegion","params":{"linecrossing_detection":{"table":["region_info"]}}},{"method":"getMsgPushEventList","params":{"msg_push":{"table":["msg_push_event"]}}}]}}

A few examples of setting detection configs:

  • baby cry
    {"method":"multipleRequest","params":{"requests":[{"method":"setBCDConfig","params":{"sound_detection":{"bcd":{"enabled":"on","sensitivity":"medium"}}}}]}}

  • person
    {"method":"multipleRequest","params":{"requests":[{"method":"setPersonDetectionConfig","params":{"people_detection":{"detection":{"enabled":"off","sensitivity":"60"}}}}]}}

  • pet
    {"method":"multipleRequest","params":{"requests":[{"method":"setPetDetectionConfig","params":{"pet_detection":{"detection":{"enabled":"off","sensitivity":"60"}}}}]}}

  • bark
    {"method":"multipleRequest","params":{"requests":[{"method":"setBarkDetectionConfig","params":{"bark_detection":{"detection":{"enabled":"on","sensitivity":"50"}}}}]}}

  • glass break
    {"method":"multipleRequest","params":{"requests":[{"method":"setGlassDetectionConfig","params":{"glass_detection":{"detection":{"enabled":"on","sensitivity":"60"}}}}]}}

  • tamper
    {"method":"multipleRequest","params":{"requests":[{"method":"setTamperDetectionConfig","params":{"tamper_detection":{"tamper_det":{"enabled":"on","sensitivity":"medium"}}}}]}}

@JurajNyiri
Copy link
Owner

Updated the code in https://github.com/JurajNyiri/HomeAssistant-Tapo-Control/tree/expand_onvif

  1. Download https://github.com/JurajNyiri/HomeAssistant-Tapo-Control/archive/refs/heads/expand_onvif.zip
  2. Follow https://github.com/JurajNyiri/HomeAssistant-Tapo-Control/tree/expand_onvif#installation

You should now see:

  1. Warn message for "async_parse_messages" every time any event is detected
  2. Warn Message Found Event when it found an event it recognizes
  3. Error message "No registered handler for event from" or "Unable to parse event from" when event is found which is not recognized
2023-04-03 08:49:23.920 WARNING (MainThread) [custom_components.tapo_control] async_parse_messages

2023-04-03 08:49:23.921 WARNING (MainThread) [custom_components.tapo_control] Found event ba835a1edb0d0cdf5bcbafab8b732021_tapo_events: {

    'SubscriptionReference': None,

    'Topic': {

        '_value_1': 'tns1:RuleEngine/CellMotionDetector/Motion',

        'Dialect': 'http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet',

        '_attr_1': {

    }

    },

    'ProducerReference': None,

    'Message': {

        '_value_1': {

            'Source': {

                'SimpleItem': [

                    {

                        'Name': 'VideoSourceConfigurationToken',

                        'Value': 'vsconf'

                    },

                    {

                        'Name': 'VideoAnalyticsConfigurationToken',

                        'Value': 'VideoAnalyticsToken'

                    },

                    {

                        'Name': 'Rule',

                        'Value': 'MyMotionDetectorRule'

                    }

                ],

                'ElementItem': [],

                'Extension': None,

                '_attr_1': None

            },

            'Key': None,

            'Data': {

                'SimpleItem': [

                    {

                        'Name': 'IsMotion',

                        'Value': 'true'

                    }

                ],

                'ElementItem': [],

                'Extension': None,

                '_attr_1': None

            },

            'Extension': None,

            'UtcTime': datetime.datetime(1970, 1, 1, 0, 0, tzinfo=<isodate.tzinfo.Utc object at 0x7f663048c580>),

            'PropertyOperation': 'Changed',

            '_attr_1': {

        }

        }

    }

}

@AndreiArdelean1
Copy link
Author

I've already done something similar, but the only thing that changed was the Data.SimpleItem.Value (+ UtcTime). No new event was received by tapo_control, even though the notification was sent to the app. Probably the camera doesn't sent any of the new events using ONVIF.

@JurajNyiri
Copy link
Owner

JurajNyiri commented Apr 3, 2023

I have added to main branch (not yet released to pypi):

  • get/set VehicleDetection
  • get/set Cruise
  • get/set MeowDetection
  • get/set BarkDetection
  • get/set PetDetection
  • get/set BabyCryDetection
  • get/set TamperDetection
  • get/set GlassBreakDetection

I was not able to test:

setBarkDetection
setPetDetection
setGlassBreakDetection
setMeowDetection
setVehicleDetection
getBarkDetection
getPetDetection
getGlassBreakDetection
getMeowDetection
getVehicleDetection
getCruise

@AndreiArdelean1 could you please test above?

Edit: Released as pytapo 3.1.8.

@JurajNyiri
Copy link
Owner

@AndreiArdelean1 now released in https://github.com/JurajNyiri/HomeAssistant-Tapo-Control/releases/tag/5.1.0.beta.1 Please test above, my devices do not support it.

@AndreiArdelean1
Copy link
Author

They all work except for getCruise. getCruise always is {'patrol': {'patrol': {'action': 'idle'}}} regardless if it is idle or doing the cruise. The HA integrations also works. 🎉

@AndreiArdelean1
Copy link
Author

AndreiArdelean1 commented Apr 7, 2023

I've been investigating this issue and here is what I've found so far:

ONVIF:

  • the ONVIF endpoint declares IsMotion, IsTamper, IsLineCross, IsPeople, IsTPSmartEvent
  • for IsTamper, IsLineCross I'm not sure if they are triggered (I don't remember if I tested this), but IsPeople is not triggered
  • Pet, Vehicle, Baby Crying, Glass Break, Dog Barks, Cat Meows, are not even declared in the ONVIF endpoint

UDP:

  • There aren't any multicast packets sent when an event is triggered
  • The app has the option to highlight people, pets, etc. in the live stream. The only place where this could take place (from the network packets received by the app) is inside the video/mp2t in the live stream from port 8800 (https://md.depau.eu/s/r1Ys_oWoP#Live-streaming, https://drmnsamoliu.github.io/video.html). There are no additional application/json received besides the initial ones (informing of the privacy mode overlay). I've not been able to decode the sent JSON packets, only the received ones, as they are encrypted. Most likely the highlighted zones are already included in the video.

API:

  • the App has a feature to view recordings where it also indicates the type of event triggered.
  • when the app enters that screen, here are the calls made:
{"method":"multipleRequest","params":{"requests":[{"method":"searchDateWithVideo","params":{"playback":{"search_year_utility":{"channel":[0],"end_date":"20230431","start_date":"20230401"}}}}]}}
{"method":"multipleRequest","params":{"requests":[{"method":"getSdCardStatus","params":{"harddisk_manage":{"table":["hd_info"]}}},{"method":"getCircularRecordingConfig","params":{"harddisk_manage":{"name":"harddisk"}}}]}}
{"method":"multipleRequest","params":{"requests":[{"method":"getClockStatus","params":{"system":{"name":"clock_status"}}},{"method":"getDstRule","params":{"system":{"name":"dst"}}},{"method":"getTimezone","params":{"system":{"name":["basic"]}}}]}}
{"method":"multipleRequest","params":{"requests":[{"method":"searchDateWithVideo","params":{"playback":{"search_year_utility":{"channel":[0],"end_date":"20230331","start_date":"20230301"}}}}]}}
{"method":"multipleRequest","params":{"requests":[{"method":"searchVideoWithUTC","params":{"playback":{"search_video_with_utc":{"id":1,"start_index":0,"channel":0,"start_time":1680555600,"end_time":1680641999,"end_index":99}}}}]}}
{"method":"multipleRequest","params":{"requests":[{"method":"searchDetectionList","params":{"playback":{"search_detection_list":{"start_index":0,"channel":0,"start_time":1680555600,"end_time":1680641999,"end_index":99}}}}]}}
{"method":"multipleRequest","params":{"requests":[{"method":"searchDateWithVideo","params":{"playback":{"search_year_utility":{"channel":[0],"end_date":"20230231","start_date":"20230201"}}}}]}}

What can be used, for event detection is the call:

{"method":"searchDetectionList","params":{"playback":{"search_detection_list":{"start_index":0,"channel":0,"start_time":1680555600,"end_time":1680641999,"end_index":99}}}}

and returning:

{'playback': {'snapshot_enable': True, 'search_detection_list': [{'start_time': 1680725544, 'end_time': 1680725662, 'alarm_type': 6}, {'start_time': 1680725693, 'end_time': 1680725802, 'alarm_type': 6}, {'start_time': 1680725826, 'end_time': 1680725856, 'alarm_type': 6}, {'start_time': 1680725917, 'end_time': 1680725947, 'alarm_type': 6}], 'total_num': 4}}

A few things to note here:

  • the end time extends if multiple events are triggered in quick succession
  • the alarm type also updates. People, pet detection is preferred over motion events.
  • the start_time and end_time define a range and the camera returns the events that have at least 1s within that range (event.start_time can be before request.start_time, and the same for end_time)

I've written this python script to get the events from the last 10 min to test it:

secondsFrom1970 = tapo.executeFunction(
            "getClockStatus", {"system":{"name":"clock_status"}}
          )["system"]["clock_status"]["seconds_from_1970"]
print(secondsFrom1970)
searchStart = secondsFrom1970 - (10 * 60) # 10 min
searchEnd = secondsFrom1970 + 10
print(tapo.executeFunction(
  "searchDetectionList", {"playback":{"search_detection_list":{"start_index":0,"channel":0,"start_time":searchStart,"end_time":searchEnd,"end_index":99}}}
))

Maybe this method of detection motion could be used to detect motion on #273.
This could be done by:

  1. making the above call every 0.5-1s and getting the last event (named here lastEvent) from the list and later storing it to savedLastEvent.
  2. if the start_time of lastEvent and savedLastEvent are not the same, a new event was triggered
  3. if the alarm_type of lastEvent and savedLastEvent are not the same, a new event was triggered
  4. if savedLastEvent has completed, a new event was triggered
  5. if secondsFrom1970 is within 30s (this is the default/minimum duration of an event) or 10s from the end_time, the event could still be active, otherwise the lastEvent can be marked as completed

Instead of making a call periodically, the ONVIF motion event could be used to trigger the call to searchDetectionList. BUT, the motion event is not triggered if only an AI event is detected. If the motion sensitivity is set high enough, the 2 events would be triggered in close succession and this would probably work.

Probably the best solution would be a combination of making a call periodically and watching for ONVIF motion events.

Other possible methods not yet discovered/implemented on the camera:

  • adding the missing events to ONVIF
  • the camera to emit a multicast broadcast (preferably encrypted) whenever something changes or just on events triggered
  • a way to register a webhook from the camera API for this
  • a way to register a webhook from the Tapo server to HA. Something similar to https://ifttt.com/tplink_tapo/details, but from what I could find, the API is only available to select developers.
  • opening a socket connection to the camera for events (not likely to be done in the future, or to already exist)
  • intercept the calls made by the camera to Tapo servers for notification (if possible, too complicated for the average user for the purpose of this integration)
  • register webhooks with IFTTT (tested and working). The only problem here is that the free plan only allows 5 automations.
  • register webhooks with Alexa

@NEVdataDyne
Copy link

Maybe in "Other possible methods not yet discovered/implemented" you can add "intercept the calls made by the camera to Alexa servers for notification" (for people detection). For some reason Alex seems to be the only service other than Tapo to get notified when a person is detected (and this is the only event Alexa can get).

@AndreiArdelean1
Copy link
Author

I've written this script (attached) to pull events from the camera. It works really well. I'd implement a proof of concept for Tapo-Control, but I'm not very familiar with HomeAssistant integrations. Maybe this method could be used alogside the existing ONVIF events for detecting motion.
Notes: The 2 files need to be under the same directory.
Archive.zip

@JurajNyiri
Copy link
Owner

JurajNyiri commented Apr 13, 2023

Thank you @AndreiArdelean1 . I played with the script, it had a bug where it was calculating incorrect start time for cameras in different timezone to UTC-0. I adjusted a couple of things and released new function getEvents to pytapo 3.1.11.

I am testing with following script:

from pytapo import Tapo
import time
from datetime import datetime
import os

# Camera
user = os.environ.get("user")  # admin user
password = os.environ.get("password")  # cloud password
host = os.environ.get("ip")  # ip of the camera, example: 192.168.1.52

tapo = Tapo(host, user, password, password)

epoch_time = int(time.time())
secondsFrom1970 = epoch_time

minSearchStart = secondsFrom1970 - (60 * 60)

searchStart = minSearchStart # can be used as opt parameter in tapo.getEvents()
searchEnd = secondsFrom1970 + 60  # maybe add a few seconds? # can be used as opt parameter in tapo.getEvents()

while True:
    events = tapo.getEvents()
    if events:
        lastEvent = events[-1]

        newLastEventDictionary = {
            'startTime': lastEvent["start_time"],
            'endTime': lastEvent["end_time"],
            'alarmType': lastEvent["alarm_type"],
        }
        print(datetime.now())
        print(lastEvent)
        print(datetime.fromtimestamp(newLastEventDictionary['startTime']))
        print(datetime.fromtimestamp(newLastEventDictionary['endTime']))
        print("")
    else:
        print("none")
    time.sleep(1)

I tested on 2 C200s. One HW V1.0 and another one 3.0. The 3.0 also has tapo cloud subscription.
I found that:

  • Events are not reported reliably, even if they are visible in the timeline of recordings.
  • Events are reported with start time in the future

I tested also with your script only to verify I haven't made any mistakes when writing the new function.

Could you try it and let me know if it works with your cameras?

@AndreiArdelean1
Copy link
Author

AndreiArdelean1 commented Apr 13, 2023

I get something like:

2023-04-13 15:57:14.501225
{'start_time': 1681390629, 'end_time': 1681390659, 'alarm_type': 2, 'startRelative': 4.0, 'endRelative': -26.0}
2023-04-13 15:57:09
2023-04-13 15:57:39
  • start time is always in the past (startRelative > 0)
  • for me, the events are received reliably. An event being a change in either start_time, end_time, or alarm_type of the last event

What I've noticed, if multiple sources (script and Tapo app) are requesting the events at once, one of them could return an empty list.

@AndreiArdelean1
Copy link
Author

Off-topic, but I'm not sure where I should post this:
All the possible values for alarm_type from searchDetectionList:

allKnownAlarmTypes = {
    1: "Timing",
    2: "Motion",
    3: "TAMPER",
    4: "Line Crossing",
    5: "Area Intrusion", 
    6: "Person",
    7: "Baby Cry",
    8: "Vehicle",
    9: "Pet",
    10: "Ring Alarm",
    11: "Dog Bark",
    12: "Cat Meow",
    13: "Alarm Glass",
    14: "Alarm Smoke",
    15: "Deliver Package",
    16: "Pickup Package",
    17: "Dollbell Ring Missed",
    18: "Dollbell Ring Answered",
    19: "Anti Theft",
}

I'm not sure which work, which don't, or what they mean. I've extracted them from the Android app.
The raw values:

1: TIMING 
2: MOTION 
3: TAMPER 
4: LINECROSS 
5: AREAINTRUSION 
6: HUMAN 
7: BABYCRY 
8: VEHICLE 
9: PET 
10: RINGALARM 
11: ALARMBARK 
12: ALARMMEOW 
13: ALARMGLASS 
14: ALARMSMOKE 
15: DELIVERPACKAGE 
16: PICKUPPACKAGE 
17: DOLLBELLRINGMISSED 
18: DOLLBELLRINGANSWERED 
19: ANTITHEFT 

@JurajNyiri
Copy link
Owner

@AndreiArdelean1 could you please test this script with the pytapo 3.1.13 to verify it still works? I think I managed to fix the timezone issue and it seems to be working fairly well now for me.

@AndreiArdelean1
Copy link
Author

It works!

@fightforlife
Copy link

fightforlife commented May 7, 2023

When I try to run the script above on the latest python docker image I get the following error:
File "/usr/local/lib/python3.11/site-packages/requests/adapters.py", line 517, in send raise SSLError(e, request=request) requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.1.81', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1002)')))

Do you have a tip? Maybe it has something todo with the IP not being a hostname? Is there a way to set the request to insecure?

@rmtrane
Copy link

rmtrane commented Jun 6, 2023

@AndreiArdelean1 Just to clarify, you were able to extract the AI detected events (person, pet, vehicle, baby crying, etc.)? I was playing around for a minute with the getEvents function, but couldn't get it to work. Just wanted to make sure it would be worth the time to actually dive in... Thank you!

@AndreiArdelean1
Copy link
Author

AndreiArdelean1 commented Jun 7, 2023

Hey, yes, it is working. It did work for motion, person, and pet, but it wasn't working for tamper detection (Or I didn't manage to get it in my testing as that type of detection was a bit hard to trigger). Sounds detection (meow, bark, baby, glass break) I couldn't trigger the actual event during testing so I can't say if it is working. But, if an event is shown with the correct icon in the playback list in the official app, then you should also be able to detect it with this function.

You could:

  1. every x seconds request the most recent events. The downside is that it introduces a load on the camera, and since the camera has limited resources (CPU, memory, etc.) the official app may become unresponsive, and it may cause other unknown issues
  2. when an event is detected with ONVIF, wait for 1s (or a smaller amount of time to make sure the event registers) and request the latest event from the camera to get the actual event type.

I've only tested method 1. When investigating I had some issues with ONVIF so I couldn't test method 2.

@rmtrane
Copy link

rmtrane commented Jun 7, 2023

Thank you for letting me know! I'm mainly interested in the sounds detection, so might try to get this to work.

(In case you're interested, I have had success in triggering the events resulting in notifications through the Tapo app by simply using youtube videos of baby crying, dog barking, etc.)

@JurajNyiri Any plans to implement something like this in the Home Assistant integration? I will probably try to do something ad-hoc, but would be really cool to have this in the integration 😊

@jterrace
Copy link

@basekson another way to get the xml dumps without having to use tshark/Wireshark is to use this script to connect to your camera:

https://github.com/openvideolibs/python-onvif-zeep-async/blob/async/examples/events.py

@basekson
Copy link

basekson commented Jan 18, 2025

@DarwinData Im using jterrace latest version i PR to core:
home-assistant/core@6571ebf#diff-a4e2b6b7404b1e39a6194c42cf51a5114cd1808c589647a72e7ffcdf6b9151a9

@jterrace

While troubleshooting ONVIF integration with my camera, I was asked to check the payloads being sent to my webhook for "Person Detected" events. Upon analyzing the logs, I discovered that the sequence of payloads being sent affects the behavior of the sensor.

Findings
The camera sends two types of payloads for the "Person Detected" event. These payloads are sent in sequence:

First Payload (Empty Detection - 6.xml): This payload indicates no detection, as IsPeople has Value="false".

Second Payload (Person Detected - 7.xml): This payload indicates detection, with IsPeople having Value="true".

However, the issue arises because the first payload (6.xml) is sent immediately before the "Person Detected" payload (7.xml). As a result, the sensor stays in the "Detected" state because it transitions from empty detection to detection without being reset.

Payloads
Here are the two payloads sent by the camera:

6.xml: Indicates no detection (Value="false").

xml
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" ...>
  <SOAP-ENV:Header>
    <wsa5:To SOAP-ENV:mustUnderstand="true">http://<anonymized-IP>/api/webhook/onviftapo_control</wsa5:To>
    <wsa5:Action SOAP-ENV:mustUnderstand="true">http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/Notify</wsa5:Action>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <wsnt:Notify xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2">
      <wsnt:NotificationMessage>
        <wsnt:Topic Dialect="http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet">
          tns1:RuleEngine/CellMotionDetector/People
        </wsnt:Topic>
        <wsnt:Message>
          <tt:Message PropertyOperation="Changed" UtcTime="2025-01-15T13:40:02Z">
            <tt:Data>
              <tt:SimpleItem Value="false" Name="IsPeople"/>
            </tt:Data>
          </tt:Message>
        </wsnt:Message>
      </wsnt:NotificationMessage>
    </wsnt:Notify>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

7.xml: Indicates detection (Value="true").

xml
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" ...>
  <SOAP-ENV:Header>
    <wsa5:To SOAP-ENV:mustUnderstand="true">http://<anonymized-IP>/api/webhook/onviftapo_control</wsa5:To>
    <wsa5:Action SOAP-ENV:mustUnderstand="true">http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/Notify</wsa5:Action>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <wsnt:Notify xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2">
      <wsnt:NotificationMessage>
        <wsnt:Topic Dialect="http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet">
          tns1:RuleEngine/CellMotionDetector/People
        </wsnt:Topic>
        <wsnt:Message>
          <tt:Message PropertyOperation="Changed" UtcTime="2025-01-15T13:40:00Z">
            <tt:Data>
              <tt:SimpleItem Value="true" Name="IsPeople"/>
            </tt:Data>
          </tt:Message>
        </wsnt:Message>
      </wsnt:NotificationMessage>
    </wsnt:Notify>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Conclusion

The order of these payloads causes the sensor to remain in the "Detected" state. This is because the empty detection (Value="false") is immediately followed by the detection (Value="true") without any intermediate reset or transition.

The event time in payloads are in correct order though, but this was the order in the post request load.

@GSzabados
Copy link
Contributor

GSzabados commented Jan 18, 2025

I would still consider that in Tapo world, all of these detections count as events. Like, "oh, I've seen a person, whatever...", so it puts a person detected event on the timeline and records with that tag. (unless the programmers have flicked a boolean wrongly.)

@jterrace
Copy link

@basekson thank you, that is very helpful data. And it looks pretty broken to me. It almost looks like the camera thinks "oh, I forgot to send you the event that person detection stopped last time, so let me send it now, right before this new event". Just to confirm, you are using webhook here not pullpoint? As another data point, I wonder if you could turn webhook off and test to see if you see any different behavior with pullpoint? See #304 (comment) above.

@GSzabados that's not how the onvif spec is defined and not how the other event types seems to work: they send a notification when an event is detected to "turn on" that type of detector and are supposed to send another when that detector has stopped. You can read more about it in section 9.4 of the onvif core spec: https://www.onvif.org/specs/core/ONVIF-Core-Specification.pdf - specifically, 9.4.2.1 has a good example:

The client is informed
by a corresponding “property created” notification indicating if the object appeared inside or outside the polygon.
Each time an object enters or leaves the polygon, a “property changed” notification is produced indicating that
the ObjectsInside property for this object has changed. When an object leaves the scene, the corresponding
ObjectsInside property is deleted and the client is informed via a “property deleted” notification.

@basekson
Copy link

Im kind of new to this kind of troubleshooting, how do I check pullpoint and how to disable webhooks? I can try if you guide me beacuse this was kind of fun :)

I used tshark to get the logs from my earlier comment

@jterrace
Copy link

@basekson thanks! Instructions at #304 (comment) for enabling/disabling webhook

@GSzabados
Copy link
Contributor

that's not how the onvif spec is defined and not how the other event types seems to work

@jterrace, you just caused me a serious deja vu feeling, as I was looking at some onvif specs. I am pretty sure that this discussion came up either here (in this repo) or another camera related topic.
Your basic assumption is that these cameras are ONVIF compliant as they supposed to be.
#312

Wouldn't be the first time if Tapo has misinterpreted things. So, can be broken. Even seriously broken. Or doing weird stuff.

And from the FAQ https://github.com/JurajNyiri/HomeAssistant-Tapo-Control#troubleshooting--faq

Certain camera firmwares have pullpoint broken, with only webhooks working. If you are not able to run webhooks because of above (https, or vlan setup), binary sensor will never show up.

Otherwise, I don't know how the line crossing should work, if not an event, by looking at that example.

@basekson
Copy link

@jterrace hmm, I did a complete reinstall again of everyting again and now all the requests are in the right order and binary_sensors is correct stage after a detections.

@CerebralBypass
Copy link

@DarwinData Did that work for you? I tried the custom_component way but it doesn't give me the person detection.

@DarwinData
Copy link

@DarwinData Did that work for you? I tried the custom_component way but it doesn't give me the person detection.

Nope, I tried various combinations of files copied from the dev branch but no luck. Disappointed but will patiently wait for next core release.

@jterrace
Copy link

Great news: tplink sent me a beta firmware to test on my C720:

We have pushed the trial firmware version 1.3.2 Build 250114 Rel.37772n to your C720, which is expected to be officially released in mid-February and will be prioritized for your testing. This firmware includes some ONVIF fixes, and pet detection is a known fix.

The fixes included in the C720 firmware will be applied to the official firmware for other models in the future.C520WS and C720 have completed testing and can provide beta firmware to use, while the latest firmware for other models has not yet been released.

I am receiving pet events now:

{ 'SubscriptionReference': { 'Address': { '_value_1': 'http://192.168.56.63:2020/event-0_2020', '_attr_1': None }, 'ReferenceParameters': None, 'Metadata': None, '_value_1': None, '_attr_1': None }, 'Topic': { '_value_1': 'tns1:RuleEngine/TPSmartEventDetector/TPSmartEvent', 'Dialect': 'http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet', '_attr_1': { } }, 'ProducerReference': { 'Address': { '_value_1': 'http://192.168.56.63:5656/event', '_attr_1': None }, 'ReferenceParameters': None, 'Metadata': None, '_value_1': None, '_attr_1': None }, 'Message': { '_value_1': { 'Source': { 'SimpleItem': [ { 'Name': 'VideoSourceConfigurationToken', 'Value': 'vsconf' }, { 'Name': 'VideoAnalyticsConfigurationToken', 'Value': 'VideoAnalyticsToken' }, { 'Name': 'Rule', 'Value': 'MyTPSmartEventDetectorRule' } ], 'ElementItem': [], 'Extension': None, '_attr_1': None }, 'Key': None, 'Data': { 'SimpleItem': [ { 'Name': 'IsPet', 'Value': 'true' } ], 'ElementItem': [], 'Extension': None, '_attr_1': None }, 'Extension': None, 'UtcTime': datetime.datetime(2025, 1, 22, 13, 24, 57, tzinfo=datetime.timezone.utc), 'PropertyOperation': 'Changed', '_attr_1': { } } } }

I will send a PR to ha core, hopefully tonight, to try to get it in before 2025.2 (not sure when the cutoff is).

@Mushoz
Copy link

Mushoz commented Jan 22, 2025

Awesome news! Really great to see Tp-link working on this with you. Thank you so very much for chasing them and getting them to actually fix stuff like this. I think I can speak for all of us when saying that we appreciate this a LOT :)

Did tp-link mention anything about baby cry detection by any chance?

@jterrace
Copy link

Yes, on baby crying they said:

I will also test whether the issues you mentioned regarding baby crying and vehicles have been resolved. Of course, you can also use your mobile phone/tablet to play a clip of a baby crying for testing.

But I explained to them that playing a video of a baby crying wouldn't work for me either, since neither the C720 or C325WB have baby crying detection 😆 . I don't have a C210 or similar camera that actually has the crying detection feature. I told them we could probably find someone else from this thread to beta test it if they need.

@GSzabados
Copy link
Contributor

@jterrace, I have a C100 and C200, which both should support the baby cry. How is it possible to get enrolled into the beta firmwares? (Besides that app on Google Play...)

@moritzvieli
Copy link

@jterrace I have a C210 to test, if you could provide me the beta firmware.

@GSzabados I think, you need to follow this process: #625

Please let me know, if there is an easier way for beta firmwares :)

@jterrace
Copy link

They don't have beta firmware yet for C100/C200/C210. The process is you give them the mac address of your camera and they add that camera to some allow list that makes your camera see a firmware update. If they say they have something ready, I'll update and ask if people want to test it.

@jterrace
Copy link

Does anyone have a C520WS that would be willing to use a beta firmware to see if baby crying events come in so we can get a sample? @GSzabados @CerebralBypass @DarwinData - send me an email at [email protected] if you can

@GSzabados
Copy link
Contributor

@jterrace, the C520WS does not support baby crying, as it is an outdoor camera.

Image

But the C100/C200 does support that. Being both indoor cameras. Below from the C100.

Image

@jterrace
Copy link

Oh interesting, not sure why the TP-Link engineer said this then:

We apologize for the misunderstanding; the C325WB and C720 do not have the baby crying feature. Currently, we only have the new firmware for the C520WS, which does have the baby crying feature.

I will ask for some clarification.

@GSzabados
Copy link
Contributor

I would expect that the outdoor cameras would not have baby cry feature, but only the indoor cameras.

@CerebralBypass
Copy link

Oh interesting, not sure why the TP-Link engineer said this then:

We apologize for the misunderstanding; the C325WB and C720 do not have the baby crying feature. Currently, we only have the new firmware for the C520WS, which does have the baby crying feature.

I will ask for some clarification.

Did you get a response yet? If not, I'm down to test that firmware for you.

@jterrace
Copy link

The response was that the indoor camera ONVIF is maintained by a different team and that he'd talk with the other team and get back to me. No news yet.

@jterrace
Copy link

Here's the update from TP-Link:

Currently, the changes made to the pet detection field are to accommodate the upcoming Tapo NVR. The baby crying field has not yet been fixed, and I will provide feedback on this feature.

All models will receive a formal firmware update to fix the pet detection field, but due to different models, the firmware update times may vary.

Sounds like we will get a firmware update for all cameras that fixes pet detection but that baby crying onvif is yet to be worked on. For folks who are looking for baby crying over onvif, I suggest starting a thread here: https://community.tp-link.com/en/smart-home/forum/777 and then linking it here for folks to upvote.

And while you're at it, upvote my top feature request 😆

@TheNexter
Copy link

Sorry, i am a bit loss about all those events detections with tapo.

I need to buy a surveillance camera for my living room to track if there is human inside (i can't use a sensor because of my cat 😅), is the person detection work in home assistant now ? Detection work without internet ? I am interest to buy a C222 that claim "person detection"

@bluecrystaldex
Copy link

I have two C210s and am VERY interested in getting baby crying alerts/notifications in HA.

@jterrace thanks for the update from TP-Link - I understand this issue has not been resolved and is not ready to test yet, but if (or when) it is ready, I'm happy to help test with beta firmware or beta versions of this integration if needed.

p.s., as you suggested, I opened a feature request thread on TP-Link's site here.

@arnabak
Copy link

arnabak commented Jan 29, 2025

Thank you so much for working on this!

I have a D130 and would find person notifications in HA incredibly useful. What do you think the chances are they'd come to that device with near-term firmware upgrades?

Like bluecrystaldex, I posted a feature request on the TP-Link forum.

@jterrace
Copy link

The D130 has ONVIF support. I'd expect it will work with person notifications once HA 2025.2 is released.

@arnabak
Copy link

arnabak commented Jan 29, 2025

Thank you!

Knowing that, I'm pretty sure I misunderstood the assignment (I'm going to remove my TP-Link feature request).

@BambamNZ
Copy link

BambamNZ commented Jan 31, 2025

Tapo C310 - I just discovered this thread as I struggled with My C310 for days if not weeks to get Person Detection to work...
Going over the troubleshooting over and over again....

As of today, I deleted the C310 from the integration, rebooted Camera and HA then readded the Cam to the Integration.
Walked passed the camera to get the initial detection and success

One thing I did differently, I did not leave the Motion Detection and Person Detection sensitivity default.
Before the initial detection I changed "Motion Detection" to "Low" and "Person Detection" to "High"

Image

Not sure if it was luck / persistence or something else happy it is working

Image

Image

Running on HA 2025.1.4 currently as of 5 days ago

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement New feature or request Help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests