Unifiptotect G4 PTZ

The Unifi G4 PTZ supports position presets in the latest firmware.
It it very helpful if HA was able to set position points of the PTZ camera.

G4 PTZ support 11 positions 0…9 and a home Position.

If you get motion triggers from the alarm, it great if you can move the camera position to one of the presets that matches the zone.
This way you can use the PTZ camera with different detections methods.
And its usable to move the camera to positions with other triggers or time schedules.

Thanks for the info.

I don’t know if they have the option in the API to call a service for the presets.
I was more thinking of a services call to go to a preset, 10 individual Buttons is not manageable I agree.

So there is a Unifi Protect API, GitHub - hjdhjd/unifi-protect: A nearly complete implementation of the UniFi Protect API.. I haven’t played with it all yet, it’s all been reverse engineered through trial and error. Just looking at the documentation I’m not certain if we’d be able to control the presets through there. You can get events and such pretty easily, and take snapshots. The presets are currently called in the Unifi WebUI by hitting the number keys 0-9, or R for home. I guess the thing to do would be to try and snoop the conversation in the browser and see maybe what it is sending to the controller to do command these. I’d like to see this so we could implement a simple patrol route. You know, the basic PTZ feature this $1800 camera lacks out of the box for the last 3 years. lol

Yeah, I just picked up a G5 PTZ. I didn’t expect full PTZ control of it via HA, but was surprised there is not an action to PTZ to various presets.

+1, in particular it would be great to have a “star patrol” ability since it doesn’t seem possible from the Protect app.

Hi,
I have started to work on adding some functionality to PTZ camera through the integrations but progress is slow.
i have added an action to goto a preset


which is working well and i have an automation that triggers it.

I’m working to see how to add this visibility on the device menu as well. i did hit some snags with how to bring the preset names to the home assistant device UI.
Did anyone else try to do the same and want to collaborate?

Also, I have never submitted a pr to the homeassistant core repo so i dont know how fast i will be able to share it back to the community.

Any more info on how you managed to pull this off? I’d love to be able to have a motion detector move the camera to a different position.

I have added a service to the unifiprotect integration. found here:

Then I can use it in automation that trigger on a movement.
I will look into adding more functionality like a select option from the camera device page.

unfortunately it didnt pass review because the suggestion was to create a select entity. the select entity setup code is somewhat not build to handle this and it will take me time to do this from a select option.

Well that’s a huge bummer. Anything I can do to help?

so i have created a select entities. but i’m not sure that will be approved since the get_ptz_presets, get_ptz_home, and get_ptz_currrent are all async that need to be called from within the loop. so i had to use nest_asyncio and i’m not sure that the homeassistant review will approve it.
more so, i have hard time to add tests on this code since the dataclass is frozen and i can’t patch the function to mock the return. here is the code if someone can look at it and tell me a maybe a better way to do this:

Thanks so much for you hard work on this! I’m not very familiar with any of those modules and how they work, so I doubt I will be much help. I’m wondering if there is some way you can use an await and yield instead of needing a nested loop? I guess it’s called an async generator?

import asyncio

async def get_data(n):
    for i in range(n):
        await asyncio.sleep(1)  # Simulating some asynchronous operation
        yield i

async def main():
    async for data in get_data(5):
        print(data)

asyncio.run(main())

So after putting some time in I realized that it would take me much more time to make this work as a select entity.
instead I currently use pyscript which allow a pretty easy way to run python scripts.

I have created a script that looks like:

from uiprotect import ProtectApiClient


def unifi_client():
    return ProtectApiClient("YOUR_IP_HERE", 443, "USER", "PASSWORD", verify_ssl=False)

@service
def move_ptz(slot=-1, camera_name=None):
    log.info(f"moving camera {camera_name} to slot {slot}")
    c = unifi_client()
    c.update()
    cameras = c.get_cameras()
    for camera in cameras:
        if camera.name == camera_name:
            break
    camera.goto_ptz_slot(slot=slot)

then calling this from different automations.
it works well.

Wow, that’s awesome! Thank you so much, I’ll give this a shot!