Skip to content

Commit

Permalink
Fix duplicate ONVIF sensors (#92629)
Browse files Browse the repository at this point in the history
Some cameras do not configure the video source correctly
when using webhooks but work fine with PullPoint which
results in duplicate sensors
  • Loading branch information
bdraco authored and balloob committed May 5, 2023
1 parent fe57901 commit ddebfb3
Showing 1 changed file with 23 additions and 10 deletions.
33 changes: 23 additions & 10 deletions homeassistant/components/onvif/parsers.py
Expand Up @@ -15,6 +15,19 @@
str, Callable[[str, Any], Coroutine[Any, Any, Event | None]]
] = Registry()

VIDEO_SOURCE_MAPPING = {
"vsconf": "VideoSourceToken",
}


def _normalize_video_source(source: str) -> str:
"""Normalize video source.
Some cameras do not set the VideoSourceToken correctly so we get duplicate
sensors, so we need to normalize it to the correct value.
"""
return VIDEO_SOURCE_MAPPING.get(source, source)


def local_datetime_or_none(value: str) -> datetime.datetime | None:
"""Convert strings to datetimes, if invalid, return None."""
Expand Down Expand Up @@ -188,7 +201,7 @@ async def async_parse_field_detector(uid: str, msg) -> Event | None:
rule = ""
for source in msg.Message._value_1.Source.SimpleItem:
if source.Name == "VideoSourceConfigurationToken":
video_source = source.Value
video_source = _normalize_video_source(source.Value)
if source.Name == "VideoAnalyticsConfigurationToken":
video_analytics = source.Value
if source.Name == "Rule":
Expand Down Expand Up @@ -220,7 +233,7 @@ async def async_parse_cell_motion_detector(uid: str, msg) -> Event | None:
rule = ""
for source in msg.Message._value_1.Source.SimpleItem:
if source.Name == "VideoSourceConfigurationToken":
video_source = source.Value
video_source = _normalize_video_source(source.Value)
if source.Name == "VideoAnalyticsConfigurationToken":
video_analytics = source.Value
if source.Name == "Rule":
Expand Down Expand Up @@ -251,7 +264,7 @@ async def async_parse_motion_region_detector(uid: str, msg) -> Event | None:
rule = ""
for source in msg.Message._value_1.Source.SimpleItem:
if source.Name == "VideoSourceConfigurationToken":
video_source = source.Value
video_source = _normalize_video_source(source.Value)
if source.Name == "VideoAnalyticsConfigurationToken":
video_analytics = source.Value
if source.Name == "Rule":
Expand Down Expand Up @@ -282,7 +295,7 @@ async def async_parse_tamper_detector(uid: str, msg) -> Event | None:
rule = ""
for source in msg.Message._value_1.Source.SimpleItem:
if source.Name == "VideoSourceConfigurationToken":
video_source = source.Value
video_source = _normalize_video_source(source.Value)
if source.Name == "VideoAnalyticsConfigurationToken":
video_analytics = source.Value
if source.Name == "Rule":
Expand Down Expand Up @@ -312,7 +325,7 @@ async def async_parse_dog_cat_detector(uid: str, msg) -> Event | None:
video_source = ""
for source in msg.Message._value_1.Source.SimpleItem:
if source.Name == "Source":
video_source = source.Value
video_source = _normalize_video_source(source.Value)

return Event(
f"{uid}_{msg.Topic._value_1}_{video_source}",
Expand All @@ -337,7 +350,7 @@ async def async_parse_vehicle_detector(uid: str, msg) -> Event | None:
video_source = ""
for source in msg.Message._value_1.Source.SimpleItem:
if source.Name == "Source":
video_source = source.Value
video_source = _normalize_video_source(source.Value)

return Event(
f"{uid}_{msg.Topic._value_1}_{video_source}",
Expand All @@ -362,7 +375,7 @@ async def async_parse_person_detector(uid: str, msg) -> Event | None:
video_source = ""
for source in msg.Message._value_1.Source.SimpleItem:
if source.Name == "Source":
video_source = source.Value
video_source = _normalize_video_source(source.Value)

return Event(
f"{uid}_{msg.Topic._value_1}_{video_source}",
Expand All @@ -387,7 +400,7 @@ async def async_parse_face_detector(uid: str, msg) -> Event | None:
video_source = ""
for source in msg.Message._value_1.Source.SimpleItem:
if source.Name == "Source":
video_source = source.Value
video_source = _normalize_video_source(source.Value)

return Event(
f"{uid}_{msg.Topic._value_1}_{video_source}",
Expand All @@ -412,7 +425,7 @@ async def async_parse_visitor_detector(uid: str, msg) -> Event | None:
video_source = ""
for source in msg.Message._value_1.Source.SimpleItem:
if source.Name == "Source":
video_source = source.Value
video_source = _normalize_video_source(source.Value)

return Event(
f"{uid}_{msg.Topic._value_1}_{video_source}",
Expand Down Expand Up @@ -683,7 +696,7 @@ async def async_parse_count_aggregation_counter(uid: str, msg) -> Event | None:
rule = ""
for source in msg.Message._value_1.Source.SimpleItem:
if source.Name == "VideoSourceConfigurationToken":
video_source = source.Value
video_source = _normalize_video_source(source.Value)
if source.Name == "VideoAnalyticsConfigurationToken":
video_analytics = source.Value
if source.Name == "Rule":
Expand Down

0 comments on commit ddebfb3

Please sign in to comment.