Repository navigation
Conversation
ONVIF motion did not work on any of the three cameras I tested it against, each for a different reason. All three are fixed here and verified live. Transport, two separate causes of a 400 on every PullMessages: - Axis returns the same subscription URL for every subscription and identifies them by a SubscriptionId in ReferenceParameters. Those were discarded, so the camera could not tell which subscription was being polled. They are now echoed back as SOAP headers, as WS-Addressing requires. - Reolink rejects a subscription-manager request that carries no wsa:To and wsa:Action. Both are now sent, with the right action URI per operation. Sending both satisfies all three brands, so this is one path rather than per-brand handling. Renew and Unsubscribe carry them too: renewal happens about 50s into a session, so getting it wrong looks like motion working for a minute and then stopping. Parsing: - SimpleItem attributes were matched with a single pattern requiring Name before Value. Tapo sends Value first, which is equally valid XML, so every one of its motion events was silently dropped. Attributes are now read independently of order. A Tapo went from 0 of 116 events parsed to 116 of 116. Choosing the event: - Only four hardcoded motion topics were recognised, and only IsMotion or State as the value. A camera's own analytics are usually more accurate and far less noisy than a pixel-change alarm, so onvif_topic selects a topic by substring: an AXIS Object Analytics scenario, or one of the per-class detectors a Reolink exposes. "active" joins the default item names, which is what the Axis application topics report under, so those need no other config. onvif_items overrides the names for anything unusual. Defaults are unchanged: no topic means the same four motion topics as before, and ParseMotionEvents is kept as a wrapper over ParseEvents. Tests use payloads captured from the cameras themselves, including Tapo's attribute order and a real AOA message.
A camera often exposes a dedicated person detector alongside plain motion, and a doorbell wants both: someone walking up, or anything else moving. onvif_topic now accepts a list and triggers on any one of them. A single topic can still be written as a plain string, so existing config is unaffected.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I tried
motion: onvifagainst three cameras and it worked on none ofthem, each failing for a different reason. This fixes all three. Every
finding here comes from probing the actual hardware, and the whole lot is
now running on my cameras.
Independent of AlexxIT#2130's HKSV changes: different files, no overlap beyond
the config struct and the README.
Transport: 400 on every PullMessages, two separate causes
Axis returns the same subscription URL for every subscription and
identifies them by a
SubscriptionIdinsideReferenceParameters. OnlyAddresswas kept, so the camera could not tell which subscription wasbeing polled. Those parameters are now echoed back as SOAP headers, which
is what WS-Addressing requires. Confirmed on the camera: identical
request, 400 without the header, 200 with it.
Reolink rejects a subscription-manager request carrying no
wsa:Toand
wsa:Action. Both are now sent, with the correct action URI peroperation. Same test: 400 without, 200 with.
Sending both satisfies all three brands, so it is one code path rather
than per-brand handling. Renew and Unsubscribe carry them too. Renewal
fires about 50s into a session, so getting that wrong looks like motion
working for a minute and then stopping.
Parsing: valid events silently dropped
SimpleItemattributes were matched with one pattern requiringNamebefore
Value. Tapo sendsValuefirst, which is equally valid XML, soevery one of its motion events was discarded with no error at any log
level. Attributes are now read independently of order. A Tapo C200 went
from 0 of 116 events parsed to 116 of 116.
Choosing which event
Only four hardcoded motion topics were recognised, and only
IsMotionorStateas the value. A camera's own analytics are usually more accurateand much less noisy: one tested Axis emitted 137 events in 75 seconds, all
but 3 of them PTZ and hardware status.
onvif_topicselects by substring, and accepts a list so several cantrigger:
activejoins the default item names, which is what Axis applicationtopics report under, so those need nothing else.
onvif_itemsoverridesthe names for anything unusual.
Defaults are unchanged: no topic means the same four motion topics as
before, a single topic can still be written as a plain string, and
ParseMotionEventsis kept as a wrapper over the newParseEvents.Verified
Running on 7 cameras across 3 brands. Each trigger type confirmed firing
in production with hold times behaving correctly (30s floor, extending
while activity continues):
Sensor/PIRMyRuleDetector/PeopleDetectTests use payloads captured from the cameras themselves, including Tapo's
attribute order and a real AOA message.
Two things worth documenting that cost me time
GetEventPropertiesunder-reports. A Reolink advertises 5 topics whileemitting 8, hiding every AI detector, and still sets
FixedTopicSettotrue. Subscribing with no filter for a minute is the only reliable wayto enumerate them. Noted in the README.
The ONVIF port is usually not 80 and is not discoverable from an RTSP
URL: Tapo uses 2020 with 80 closed, Reolink 8000. Since auto-discovery
only works when a stream source is itself an
onvif://URL,onvif_urlis effectively required. Also noted.
Not addressed
pkg/onvif/client.gohardcodeshttp://, so an HTTPS-only camera stillcannot be used. And there is a pre-existing data race on
motionActivein
onvif_motion.gobetween the poll loop and the hold-timer goroutine.Both left alone to keep this focused; happy to take either in a follow-up.