Custom Component: Unifi Protect

Just sent you a PM.

Release 0.5.1

Two fixes are implemented in this release:

  1. Basic data for Cameras were pulled at the same interval as the Events for Motion and Doorbell. This caused an unnecessary load on the CPU. Now the base Camera data is only pulled every 60 seconds, to minimize that load.

  2. A user reported that when having more than 20 Cameras attached, the Binary Sensors stayed in an unavailable state. This was caused by the fact that a poll interval of 2 seconds for the events, was not enough to go through all cameras, so the state was never reported back to Home Assistant. With this release there is now an option on the Integration Widget to change the Scan Interval to a value between 2 and 30 seconds. You ONLY have to make this adjustment if you experience that the sensors stay unavailable - so typically if you have many Cameras attached. Default is still 2 seconds.

  3. The same user mentioned above, is running Unifi Protect on the new NVR4 device, and the Integration seems to work fine on this new platform. I have not heard from anyone else on this, but at least one user has success with that.

  4. Bumped pyunifiprotect to v0.16 which fixes the problem mentioned in point 1 above. Thank you to @bdraco for the fix.

Just upgrade and restart Home Assistant.

1 Like

Works fine now!

Thanks!

1 Like

Updated to the 0.5.1.and it seems none of my sensors, cameras are showing in lovelace anymore

Found this error:

2020-06-19 11:38:03 ERROR (MainThread) [homeassistant.config_entries] Error setting up entry Cloud Key Gen2 Plus for unifiprotect
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 217, in async_setup
    hass, self
  File "/config/custom_components/unifiprotect/__init__.py", line 90, in async_setup_entry
    nvr_info = await protectserver.server_information()
  File "/usr/local/lib/python3.7/site-packages/pyunifiprotect/unifi_protect_server.py", line 104, in server_information
    return await self._get_server_info()
  File "/usr/local/lib/python3.7/site-packages/pyunifiprotect/unifi_protect_server.py", line 211, in _get_server_info
    bootstrap_uri, headers=self.headers, verify_ssl=self._verify_ssl,
  File "/usr/local/lib/python3.7/site-packages/aiohttp/client.py", line 1012, in __aenter__
    self._resp = await self._coro
  File "/usr/local/lib/python3.7/site-packages/aiohttp/client.py", line 504, in _request
    await resp.start(conn)
  File "/usr/local/lib/python3.7/site-packages/aiohttp/client_reqrep.py", line 847, in start
    message, payload = await self._protocol.read()  # type: ignore  # noqa
  File "/usr/local/lib/python3.7/site-packages/aiohttp/streams.py", line 591, in read
    await self._waiter
aiohttp.client_exceptions.ServerDisconnectedError: None

Thoughts on troubleshooting steps??

Edit: yet another HA restart seems to have resolved…

1 Like

Looks like a transient error from the protect server. aiohttp throws ServerDisconnectedError when the http connection is dropped on a persistent connection which can happen at any time.

pyunifiprotect needs to trap aiohttp.client_exceptions.ServerDisconnectedError and throw NVRError or __init__.py needs to catch aiohttp.client_exceptions.ServerDisconnectedError in the same block as NvrError so ConfigEntryNotReady is thrown instead.

1 Like

Thanks @bdraco,
I decided to implement this in the __init__.py so that the ConfigEntryNotReady is thrown when a ServerDisconnectedError error is detected.
It will part of the next release.

1 Like

The install seemed to go fine, but I’m stuck on the configuration:

To add Unifi Protect to your Home Assistant installation, go to the Integrations page inside the configuration panel and add a CloudKey+ or UDMP by providing the Host IP, Port Number, Username and Password.

If the Unifi Protect Server is found on the network it will be added to your installation. After that, you can add more Unifi Protect Servers, should have more than one installed.

I have a CloudKey Gen2+, but I don’t see any option within Configuration → Integrations for CloudKey or UDMP. What am I doing wrong?

Thanks!!

The integration is named “Unifi Protect”

Within Configuration -> Integration, I press ‘+’, but don’t see “Unifi Protect” anywhere.

Have you installed the component as accustom comoontent in some manner (e.g. via HACs)?

Yes, I installed via HACS. I don’t see any errors in the logs.

It should then be visible (perhaps after a restart of HA?).

Hi,
Normally when this happens, it is a Browser caching issue. Try and Force a Refresh of your browser when on the Integrations Page, and then hit the +Key again.

@briis Thank you. That did the trick! Thanks for writing this integration. Can’t wait to start integrating it now!!

1 Like

Hi and thanks for great integration. I do have an issue when running “Check configuration”.
Platform error light.unifiprotect - No module named custom_components.unifiprotect.light
No idea what that means.

That is correct - This integration does not implement a light entity. Try and search your yaml files for light.unifiprotect You might have put this in there by error? And anyhow, Unifiprotect does not use the yaml files, so there should be no references to it here.

Had my first decent play with this just now (Single G3 micro camera before I throw money at the bullets!). Top work @briis - It’s perfect! - also big thanks to @TazUk for sharing his automations, which has got me to a nice place. (Shame iOS notifications can’t link to a lovelace view!)

One potential idea… could the binary_sensor.motion_xxxxxx entity include which motion zone caused the last trigger? or does the API you’re hitting not provide this?

1 Like

Happy that it helps you. I got a similar request yesterday and as I said here, I don’t know if it is possible to read the motion zone when an event occurs, but I will look in to it.

EDIT:
Did some testing, and unfortunately the API does not tell us what Motion Zone has been triggered. Below is the raw JSOn data that is send when a motion starts and ends. I have defined zones on this particular camera, and I moved through them, but unfortunately, at this point in time, Unifi Protect does not deliver that information back to us.

Start Motion Event:

 {
  "type": "motion",
  "start": 1594098988964,
  "end": null,
  "camera": "5e2368d3031b6703e70004e4",
  "score": 0,
  "id": "5f04053000339103e70026db",
  "metadata": {
   "objectType": null,
   "objectCoords": null,
   "objectConfidence": null
  },
  "modelKey": "event",
  "partition": null,
  "thumbnail": "e-5f04053000339103e70026db",
  "heatmap": "e-5f04053000339103e70026db"
 }

End Motion Event:

{
  "type": "motion",
  "start": 1594098988964,
  "end": 1594098994194,
  "camera": "5e2368d3031b6703e70004e4",
  "score": 56,
  "id": "5f04053000339103e70026db",
  "metadata": {
   "objectType": null,
   "objectCoords": null,
   "objectConfidence": null
  },
  "modelKey": "event",
  "partition": null,
  "thumbnail": "e-5f04053000339103e70026db",
  "heatmap": "e-5f04053000339103e70026db"
 }

Thank you for doing the research! From the looks of the json maybe UniFi will give us the partition (assuming this is what they meant) or possibly we could figure it out from the object coordinates one day.

Yes, hopefully some of the empty data above will someday be published with data. The metadata also looks exiting, as this seems to be made some kind of AI, with detection of objects and people, and here it seems that they have planned to put coordinates for maybe a bounding box or something, but that might be translated to a zone.
I will keep my eyes on this.