Unifi Protect: Improve integration to manipulate notification settings

Problem:
Unifi Protect (native) doesn’t allow much by the way of rules for notifications. You have a choice between location OR schedule, but not both. I can enable/disable smart detections, but that’s not desired – I want to disable the notification but not the detection.

Desired Feature:
If the maintainers/contributors of the Unifi Protect integration could extend it to allow manipulation of notification settings via HA entities, we can do this all in node-RED or HA automations.

See my example below (that doesn’t work :sob:):

It is not really possible to control the UniFi Protect notification settings from Home Assistant. Notification settings in Protect are on a per-user level. You cannot configure notifications for other users, and you cannot log into Protect as multiple users in Home Assistant.

I have no real plans of implementing the notification APIs in pyunifiprotect, since they have no real usefulness in Home Assistant. Especially since Home Assistant’s notification system is 100x better then Protect’s. However, if you want to implement them, contributions are welcome.

Hi! I believe you replied to me in Discord as well. So cool of you to engage, thank you.

I was able to do this via API w/Node Red. And I did it for both myself and my wife (separate urls/API keys/tokens/cookies in the headers) so it’s also possible for separate users. And unfortunately I disagree with you about HA notif being better than protect’s as I mentioned in discord too. HA’s is far robust but why would i want to click a notification to see a static frame in HA when I can get an interactive notification that takes me to an exact moment in a scrubbable timeline in Protect? Maybe we have different use cases.

I do think my node-red setup is brittle and will break dependent on cookie expiration. In the meantime I hope this helps anyone else if you’re not thinking of considering it right now. Just because you don’t think it’s useful doesn’t mean I have to agree. :grin: But thanks overall for making such an amazing integration!

For other folks in the meantime, I can write this up if anyone plans to use it.

3 Likes

I’d be interested in how you set this up. I agree that the Protect notifications with deep links are more useful, and the native schedule/location settings don’t give me as much control as I want.

Can you please do a write up on how yo did this, I wanna do this to.

I will soon. Just have been very busy, sorry.

Please share it :slight_smile:

Hi. No amount of posting is going to solve my blocking problem.

Sharing how to do it is easy. The problem is that when i screen record you can see my cookies, tokens, private keys, etc. which then means a lot more effort editing the videos to redact that information.

If you know a way I can easily blur out or mask my private info in videos please let me know and I can do it. I would love to help but the video editing part is way too time consuming using the techniques i know.

I think a lot of people, including myself, are interested in how you did this.

I was able to do this via API

This isn’t much to go on. If you don’t have the time to do a video, just add a new reply that at least tells us if you used a Python library for talking to Ubiquiti cameras, or just a library like requests for making web requests. Did you create a custom service? A custom integration? What was the endpoint you hit to enable/disable notifications? What was the method (POST?), and what was in the body? What headers did you use to authenticate with.

Thanks

I did some digging. To change notifications on Unifi Protect using just the REST API, this is what you would do:

Login

POST {NVR_IP}/login with JSON body:

{
   "username":"YOUR_USERNAME",
   "password":"YOUR_PASSWORD",
   "token":"",
   "rememberMe":false
}

The response will give you 2 important headers:

  • set-cookie header with a TOKEN cookie that future requests will need to provide
    • Note: This token appears to be good for 2 hours
  • x-csrf-token header that you’ll need to remember and use for all future non-GET requests

Get Info

GET {NVR_IP}/proxy/protect/api/bootstrap

As long as your request has the TOKEN cookie, you should get a response with info about all your cameras, users, NVR, etc.

Change Notifications

PATCH {NVR_IP}/proxy/protect/api/users/{USER_ID}/notifications

Where {USER_ID} is the ID of the user whose notification settings you want to change.
You can get this info from the bootstrap endpoint above. Look under the users key for the id field of each user.

Body:

{
   "state":"on",
   "detectionNotifications":{
      "cameras":[
         {
            "inheritFromParent":true,       # True if you want to use Global Notification Settings on this camera. False if you don't
            "camera":"...",                 # The Camera ID
            "trigger":{
               "when":"always",
               "location":"away",
               "sendAnyway":false,
               "schedules":[
                  
               ]
            },
            "motion":[
               
            ],
            "alarmSmoke":[
               
            ],
            "alarmCmonx":[
               
            ],
            "alarmBabyCry":[
               
            ],
            "person":[
               "push",    # For push notifications
               "email"    # For email notifications
            ],
            "vehicle":[
               
            ],
            "animal":[
               
            ]
         }
      ]
   }
}

Any of the categories can have either a “push”, or “email” notification. Not sure if others are supported. In the above config, I have no notifications if the camera detects a vehicle for example, but both push and email notifications if it detects a person.

All that’s left is to make a home-assistant service that uses something like the Python requests library to do this automatically, and that should work.

I’ll look into that sometime.

1 Like

As previously stated, it is not possible to add this as a service or entity to Home Assistant. Each induvial user can only edit their own notification settings. You will get a 403 unauthorized if you try to edit another user’s.

Since each config entry require 1 user, you would have to add the same Protect instance for each user. Additionally, Protect notifications only work if you have Remote Access enabled and you are using an Ubiquiti Cloud Account, which requires MFA to be enabled and not something you can easily automate locally in HA since Protect does not provide any other auth mechanism, such as API tokens or oauth.

It is also very dangerous to use Ubiquiti Cloud Accounts on HA, which is why both myself (for the UniFi Protect integration) and Robban (for the UniFi Network integration) have not implemented MFA support and explicitly state in the docs you must use a local account.

Hi Talz, you’re awesome. Thanks for taking over. My HA is down during a remodel and I can’t demo the solution for people.

One important thing to note is the token expires every two weeks. So here is what I did

  1. Get the JSON payload for each full configuration of notifications that you want for a given scenario
  2. Set those up as states in node red
  3. Switch between those states as API requests based on your node red scenarios
  4. Set up a 403 forbidden error notification function in node red that lets you know if you’re token has expired so that you couldn’t go back in and update it to whatever the new one is

I get all this information through chrome inspector looking at the payload sent whenever I change a setting on the notifications page

1 Like

Thanks @jkmaxwell.
I actually don’t use Node Red, but hopefully that helps someone.

I put together a quick demo script in Python to change notification settings here. Mine just change from Global Settings (which have notifications enabled) to non-global-settings which disable notifications for a camera, but it’s easy enough to set whatever settings you want per camera with my script.

@AngellusMortis I really appreciate your work on the UniFi Protect integration - it has been extremely useful, and easy to use. When you say “it is not possible to add this as a service or entity to Home Assistant”, if you’re talking about building it into the Unifi Protect integration as the post is asking for, and you don’t see a way to do this cleanly, that’s unfortunate, but I understand. This is more of a workaround that can be used by individuals outside of the Unifi Protect integration.

This does not deal with MFA at all, so if someone has that as a requirement, maybe they can build off of this.

It is also very dangerous to use Ubiquiti Cloud Accounts on HA,

Why is that? Is it because other integrations can gain access to the credentials, send them home, and the developer of the integration can remotely login and watch your cameras, and control them? If so, I’m currently planning on using AppDaemon to run my Python scripts, so I don’t think my NVR username/password would really be exposed to any other integrations - only to appdaemon itself.

HA does not have any kind of access controls. Anyone and everyone has full access to every file on disk for HA. There is also no protection for credentials, so they are all stored in plain text. That means if you use a UI Cloud Account on HA, everyone and everything that has access to HA has access to your account (and potentially ownership of all of your remote connected consoles if you are using the owner account).

@AngellusMortis - if I understand you correctly, and elaborating on what I previously mentioned, the fear is that a rogue integration will have code that traverses the filesystem, will find the file that stores the username/password for Unifi Protect, and send that information home. Since that file contains the cleartext password for a cloud account, the attacker is free to login to your Unifi system remotely, and will have as much control over it as the username gives him. If that sounds right, that’s definitely serious, and something for people to keep in mind.

In my case, HA runs in a docker container. It only has access to the filesystem that’s inside that docker container. Python scripts are run by AppDaemon, which is a completely separate docker container. Unless I’m mistaken, integrations running on HA have no access to the filesystem of a completely separate docker container, where the password to the Unifi Protect portal is.

In order for an integration to gain access to the password on my system, it would need to break out of the docker container, gain access to the AppDaemon docker container, find the credentials file, and read the username/password from there. That’s not to say that this is impossible, or even unheard of, but it’s definitely non-trivial. Am I wrong @AngellusMortis?