I just recently migrated from Unifi Video NVR to Unifi Protect NVR. I run Unifi Protect on a Unifi Cloud Key Gen2+ and I must say I really love the system. It is all local, so no cloud dependency and no sharing of my recordings with external parties.
Even though I can get the Camera feed in to Home Assistant using the Generic Camera component, and also some other stuff by installing MQTT on the Cloud Key, I would rather just have a Component that does all that, and without having to fiddle around outside Unifi Protect and Home Assistant.
So I decided to see if I could write my own Custom Component supporting the Unfi Protect platform. The problem I ran into immediately was that there is no official API released by Ubiquiti, but by searching the web I found a couple of people who had found some API commands that worked. So with this as a starting point and using Google Inspector I managed to pull enough together to write this and get support for what I wanted.
The component is supporting the following:
camera - It will automatically add a Camera entity of all Cameras found in your Unifi Protect NVR, and this supports all the basic Camera functions in HA.
binary_sensor - For each camera in Unifi Protect a binary sensor is created that shows if motion occurs on that camera. Note: This only works if the camera is armed.
sensor - Again, for all cameras a sensor is created that shows the current Recording State
Installation and Configuration
Please go to the Github Repository for installation and configuration instructions.
I am a “learn as you go” programmer, so please excuse me if the code is not optimal Python, but I have now had it running for a few days on 2 different HA installations and without receiving any errors, so it seems to me that it works as expected.
So I really look forward to hear from other people testing this.
If I understand your question correctly, that should work. I can cast a view that displays the stream from from the cameras defined here to my Google Nest Hub. Is that what you are asking for?
I have the CC running for two days now and works really nice. Thanks for creating!
Maybe as an addition to the installation instructions you could mention a warning to remove pre-existing manual camera configurations with the same name. I took me a while to figure out why the CC wasn’t creating the sensors.
Hi Michael,
Glad you like it. Let me know what kind of additional functionality you would like to see and I will see if I can dig up the API calls to deliver it.
HACS is done as a Custom Integration, but as the Component seems to work for several people, I will now submit it as an official HACS Integration.
Hi Sean,
Yes you can see a live stream. If you did as instructed in the README file and activated the RTSP stream for each Camera, you just click on the image and a Window will pop up. The first time it might take a little while, but click the box in the top right corner Preload Stream and it should go faster the next time.
Getting it working slowly… Ran into an issue where I had a reset camera with no “last motion”. Generated an error when loading…
homeassistant | 2019-12-31 17:26:36 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up platform unifiprotect
homeassistant | Traceback (most recent call last):
homeassistant | File “/usr/src/homeassistant/homeassistant/helpers/entity_platform.py”, line 150, in _async_setup_platform
homeassistant | await asyncio.wait_for(asyncio.shield(task), SLOW_SETUP_MAX_WAIT)
homeassistant | File “/usr/local/lib/python3.7/asyncio/tasks.py”, line 442, in wait_for
homeassistant | return fut.result()
homeassistant | File “/config/custom_components/unifiprotect/sensor.py”, line 38, in async_setup_platform
homeassistant | for camera in cameradata.cameras:
homeassistant | File “/config/custom_components/unifiprotect/protectnvr.py”, line 43, in cameras
homeassistant | self._api_camera_list = self._get_camera_list()
homeassistant | File “/config/custom_components/unifiprotect/protectnvr.py”, line 116, in _get_camera_list
homeassistant | lastmotion = datetime.datetime.fromtimestamp(int(camera[‘lastMotion’])/1000).strftime(‘%Y-%m-%d %H:%M:%S’)
homeassistant | TypeError: int() argument must be a string, a bytes-like object or a number, not ‘NoneType’
I have posted a new release to Github and the HACS store, with the following content:
Added Integration to the Default HACS store. So it can now be installed directly from there. Search for unifiprotect
binary_sensor_:
Changed default SCAN_INTERVAL to 3 seconds to optimize Motion Detection
camera:
Added new service camera.unifiprotect_save_thumbnail. When calling this services the Thumbnail of the last recorded motion will be saved to disk, and could then be used in an automation, to send to a phone via the notify platform. Requires entity_id and filename as attributes.
The thumbnail image is the same image you see when you open the activity page in the Unifi Protect App.
sensor:
Added new attribute camera_type to the sensor. Showing what type of Unfi Camera is attached to this sensor
Core Module
changed size of the thumbnail image when being created.
Many thanks @briis for working on this. I’m pretty sure many people are greatful for this, myself included.
Apolgies for the possibly newbie question, I have lot to learn in HASS itself, yet alone when it comes to custom components. I’m facing with the following error message:
Sat Jan 04 2020 16:29:08 GMT+0100 (Central European Standard Time)
Error while setting up platform unifiprotect
Traceback (most recent call last):
File "/config/custom_components/unifiprotect/camera.py", line 27, in async_setup_platform
cameras = nvrobject.cameras
File "/config/custom_components/unifiprotect/protectnvr.py", line 43, in cameras
self._api_camera_list = self._get_camera_list()
File "/config/custom_components/unifiprotect/protectnvr.py", line 127, in _get_camera_list
upsince = datetime.datetime.fromtimestamp(int(camera['upSince'])/1000).strftime('%Y-%m-%d %H:%M:%S')
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 150, in _async_setup_platform
await asyncio.wait_for(asyncio.shield(task), SLOW_SETUP_MAX_WAIT)
File "/usr/local/lib/python3.7/asyncio/tasks.py", line 442, in wait_for
return fut.result()
File "/config/custom_components/unifiprotect/camera.py", line 33, in async_setup_platform
except nvr.NotAuthorized:
NameError: name 'nvr' is not defined
I’m using the latest version you published recently. Installed it with HACS. Created a local user in Protect and verified that it works fine. Added the needful to the configration.yaml.
Worth noting that I have one camera offline. Could it that one cause the uptime to be NoneType? If so, maybe this is an edge case which the component could handle gracefully in a future release?
Alternatively, if you think I’m doing something wrong please let me know
Don’t apologise, there are no bad questions
You might be right. I need to do some error handling when reading that field, so that it does not crash when a camera is offline. I will make a fix available shortly.