Skip to content

Conversation

digitaldan
Copy link
Contributor

@digitaldan digitaldan commented Sep 30, 2025

This binding integrates Ubiquiti UniFi Protect into openHAB. It connects to your Protect NVR/CloudKey/UNVR and provides live events and configurable settings for Cameras, Floodlights, and Sensors.

It uses the official Protect Integration API locally over HTTPS and WebSockets

Features

  • Supports multiple Protect devices (Cameras, Floodlights, Sensors)
  • Uses the official Protect Integration API locally to a UniFi Protect NVR/CloudKey/UNVR
  • Has granular triggers and channels for realtime motion events including AI object detection, audio, and line crossing events.
  • Uses websockets for realtime updates without polling
  • Supports WebRTC streaming for cameras with very low server CPU overhead
  • Supports 2-way audio for cameras that support it
  • Uses STUN for external access to cameras when outside your local network (e.g. when using the openHAB cloud service)
  • Provides general purpose image snapshot API endpoints for cameras

I know there is another protect binding in the marketplace, and i did first try and modify that, but after a day it became very obvious i would end up rewriting most of it completely to fit the official API. Also that binding has not been updated in almost a year.

I'm opening this PR up early to get some feedback from other protect users, will mark as WIP until ready for review.

Also See openhab/openhab-webui#3368 for updates to our video widget to support 2-way audio (can be merged independent of this)

Signed-off-by: Dan Cunningham <dan@digitaldan.com>
@digitaldan digitaldan requested a review from a team as a code owner September 30, 2025 15:18
@digitaldan
Copy link
Contributor Author

@digitaldan digitaldan marked this pull request as draft September 30, 2025 15:24
@lsiepel
Copy link
Contributor

lsiepel commented Sep 30, 2025

@digitaldan
Copy link
Contributor Author

@lsiepel if you read the bottom of my first i comment, i addressed this.

@lsiepel
Copy link
Contributor

lsiepel commented Sep 30, 2025

m opening this PR up early to get some feedback from other protect users, wil

Sorry, i somehow overlooked those lines. Did you try to contact @seaside1 ?
I have some unifi camera's, so i'will be able to test and comment on this PR. I have only started too much work lately and have little time in the next few weeks.

@digitaldan
Copy link
Contributor Author

I have not, he has not been on the forums since march, and in the end the binding would have needed a massive overhaul if submitted as a PR, regardless of the new API. Plus the binding has been untouched since Oct 2024, despite activity on the forums about issues. So i assumed it was mostly abandoned at this point.

After a weekend of trying to refactor the code, i ran out of steam and decided to start over starting with the published openapi.json as the basis for forming the DTO model, then the API client, and finally informing that shape of things and channels before writing the handlers. This lead to a different structure that is much more naturally suited to the official API.

@wborn wborn requested a review from Copilot October 1, 2025 06:32
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces the initial contribution of a UniFi Protect binding for openHAB. The binding provides integration with Ubiquiti UniFi Protect NVR systems using the official Protect Integration API for local communication via HTTPS and WebSockets.

  • Comprehensive binding implementation supporting cameras, floodlights, and sensors with real-time event processing
  • WebRTC streaming support with go2rtc integration for low-latency video and 2-way audio capabilities
  • STUN support for external access through NATs when using openHAB cloud services

Reviewed Changes

Copilot reviewed 125 out of 128 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
bundles/pom.xml Adds the new unifiprotect module and removes unnecessary whitespace
bundles/org.openhab.binding.unifiprotect/src/main/resources/OH-INF/thing/thing-types.xml Complete thing type definitions for NVR bridge and device types (cameras, lights, sensors) with channel configurations
bundles/org.openhab.binding.unifiprotect/src/main/resources/OH-INF/i18n/unifiprotect.properties Internationalization properties for labels and descriptions
bundles/org.openhab.binding.unifiprotect/src/main/resources/OH-INF/config/config.xml Binding configuration for binary downloads and STUN usage
bundles/org.openhab.binding.unifiprotect/src/main/resources/OH-INF/addon/addon.xml Addon metadata definition
bundles/org.openhab.binding.unifiprotect/src/main/java/org/openhab/binding/unifiprotect/internal/media/*.java Media service implementation for WebRTC streaming and go2rtc integration
bundles/org.openhab.binding.unifiprotect/src/main/java/org/openhab/binding/unifiprotect/internal/handler/*.java Thing handlers for NVR bridge and device types (cameras, lights, sensors)
bundles/org.openhab.binding.unifiprotect/src/main/java/org/openhab/binding/unifiprotect/internal/dto/*.java Complete data transfer object model for UniFi Protect API entities and events
Comments suppressed due to low confidence (1)

bundles/org.openhab.binding.unifiprotect/src/main/java/org/openhab/binding/unifiprotect/internal/media/NativeHelper.java:1

  • There is a spelling error: 'stupported' should be 'supported'.
/*

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@lolodomo lolodomo added the new binding If someone has started to work on a binding. For a new binding PR. label Oct 4, 2025
@openhab-bot
Copy link
Collaborator

This pull request has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/unifi-binding-beta-3-2-0-3-6-0/131156/195

@ErikDB87
Copy link
Contributor

I've tried to contact seaside months (a year?) ago, but no response. I'd gladly also join your test audience.

@ccutrer
Copy link
Contributor

ccutrer commented Oct 16, 2025

@digitaldan: I see you're updating snapshots before triggering channels when events come in. My first gut is to swap that (because I don't care about the snapshot when I'm taking actions like turning on lights) and sometimes taking a snapshot can take a non-trivial amount of time, but then I realized perhaps that's on purpose because another legitimate case is to send a notification with the snapshot when an event happens. What do you think the best course is to resolve these opposing goals? We could add a configuration to just never update snapshots automatically in response to events, then a user could choose, but that's still problematic if someone has both types of rules. Perhaps a 3-state option: no automatic snapshots, automatic snapshots before triggering channels, or automatic snapshots after triggering channels? Then if someone cares about both use cases, they can use the post-trigger update, and watch the snapshot channel itself (probably with additional state to only care shortly after an event was triggered).

@digitaldan
Copy link
Contributor Author

digitaldan commented Oct 16, 2025

but then I realized perhaps that's on purpose because another legitimate case is to send a notification with the snapshot when an event happens.

So thats exactly the reason, in rules i react to a item or trigger and send the image off. I was not aware of a significant delay grabbing images, but to be honest have not benchmarked that, so i can take a look. I'm ok adding an advanced option to swap the order if you thinks its a significant enough delay (more then a second i guess).

no automatic snapshots

I could have sworn i was checking if a channel was linked before taking a image snapshot, but i think i'm doing that on another binding i'm working on now that i look at it, i'm going to add that so if you don't link an item, we don't waste resources.

@digitaldan
Copy link
Contributor Author

Actually i am checking if a channel is linked before taking a snapshot 😅

 if (hasChannel(channelId) && isLinked(channelId)) {

@ccutrer
Copy link
Contributor

ccutrer commented Oct 16, 2025

I was not aware of a significant delay grabbing images, but to be honest have not benchmarked that, so i can take a look.

I haven't checked through the official API like this, but I've run into issues fetching snapshots completely with a rule that fetches the snapshot itself.

I could have sworn i was checking if a channel was linked before taking a image snapshot, but i think i'm doing that on another binding i'm working on now that i look at it, i'm going to add that so if you don't link an item, we don't waste resources.

yes, you are doing exactly that. but that doesn't help I still want the snapshot, but want both snapshot-less and snapshotting rules

@ccutrer
Copy link
Contributor

ccutrer commented Oct 16, 2025

2025-10-16 10:49:04.577 [TRACE] [t.internal.api.UniFiProtectApiClient] - WebSocket events message: {"item":{"id":"REDACTED","modelKey":"event","type":"ring","start":1760633342541,"device":"REDACTED"},"type":"add"}
2025-10-16 10:49:04.579 [TRACE] [t.internal.api.UniFiProtectApiClient] - New request GET /v1/cameras/REDACTED/snapshot?highQuality=true https://192.168.0.1/proxy/protect/integration/v1/cameras/REDACTED/snapshot?highQuality=true

BUT:

2025-10-16 10:49:04.965 [INFO ] [openhab.event.ChannelTriggeredEvent ] - unifiprotect:camera:udmpro:611d93d602515f038700da3f:ring triggered PRESSED
2025-10-16 10:49:04.970 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Doorbell_Ring_Snapshot' changed from NULL to raw type (image/jpeg): 271778 bytes
2025-10-16 10:49:04.970 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Doorbell_Doorbell_Ring' changed from NULL to OPEN

In other words it took nearly half a second to fetch the image. So not terrible. And perhaps my (wireless) doorbell is just behaving well today.

AFAICT, this is the only way to identify a doorbell

Signed-off-by: Cody Cutrer <cody@cutrer.us>
@digitaldan
Copy link
Contributor Author

Are you thinking a binding config or channel config (or something else)? We could add it something like

{channel="unifiprotect:camera:home:1234:smart-detect-zone-snapshot, sequence=before|after|never"}

but yes, i could see a wifi device delaying this, my doorbell also has notorious connectivity issues likely b/c of where you have to place it.

@ccutrer
Copy link
Contributor

ccutrer commented Oct 16, 2025

I was thinking thing level (not binding level), but I like the idea of channel level too. That way you could configure it differently depending on event type - you might be okay with a minor delay for object or audio detection, but want to send off a notification immediately for a doorbell button press.

Signed-off-by: Dan Cunningham <dan@digitaldan.com>
Copy link
Contributor

@lsiepel lsiepel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just two comments i noticed when looking at this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add semantic equipment tags to all things?

Please also add semantic tags to the channels (point+property) where possible.

add ring channels based on presence of lcdMessage in camera details
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
@seaside1
Copy link

I have been looking to add support for openHAB 5 for the UniFi Protect binding, however this looks promising and I can maybe help out to test and contribute here.

Signed-off-by: Dan Cunningham <dan@digitaldan.com>
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
@digitaldan digitaldan requested a review from Copilot October 21, 2025 16:14
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 126 out of 129 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

bundles/org.openhab.binding.unifiprotect/src/main/java/org/openhab/binding/unifiprotect/internal/media/NativeHelper.java:1

  • Corrected spelling of 'stupported' to 'supported'.
/*

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Signed-off-by: Dan Cunningham <dan@digitaldan.com>
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new binding If someone has started to work on a binding. For a new binding PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants