Describe the bug
I have a stacked UNVR setup. The API camera.get_rtsps_streams() fails with uiprotect.exceptions.BadRequest when called against a camera that is hosted on the secondary UNVR.
To Reproduce
Set up a stacked UNVR environment.
Ensure cameras are on both devices.
Run this code.
import asyncio
from uiprotect import ProtectApiClient
host = "<IPADDRESS>" # Primary stacked UNVR
port = 443 # SSL
user = "<USER>" # User
pwd = "<PASSWORD>" # Password
key = "<API Key>" # API Key
async def do_it():
protect = ProtectApiClient(host, port, user, pwd, api_key=key, verify_ssl=False)
await protect.update()
host1 = None
host2 = None
interested = []
# First time through, print al the cameras out and where they are hosted
for camera in protect.bootstrap.cameras.values():
if host1 is None:
host1 = camera.connection_host
interested.append(camera.id)
elif host2 is None:
if camera.connection_host is not host1:
host2 = camera.connection_host
interested.append(camera.id)
print(f"{camera.name} : {camera.id} [{camera.host} on {camera.connection_host}]")
print("*** Now we have a couple of cameras to be interested in, lets get the RTSPS streams ...")
for camera in protect.bootstrap.cameras.values():
if camera.id in interested:
print(f"{camera.name} : {camera.id} [{camera.host} on {camera.connection_host}]")
for stm in await camera.get_rtsps_streams():
print(f" {stm}")
if __name__ == "__main__":
asyncio.run(do_it())
This will print out all the cameras and which host they are on. It will also pick the first camera on each host and then attempt to get the RTSPS streams. It will work fine on the first camera (which in my case is the same host as the main UI), but will fail on the second host with an exception.
In my case, the redacted output is:
Lane : a3f9c7e2b1d48a0c9f12de34 [192.168.103.44 on 192.168.23.221]
Workshop Cam : b7d1e4c9a02f88de671c53ab [192.168.77.206 on 192.168.23.221]
Back Patio : 9c4a12de88f0b7e1d653aa90 [192.168.189.139 on 192.168.23.221]
Front Doorbell : e1d0c6b487a9f2038c45de91 [192.168.131.9 on 192.168.23.221]
Drive & Gate : 7f91b2e4d8c03a5e619ad044 [192.168.149.24 on 192.168.23.221]
Garage Wide : d204fbe198a73c5e6a90d211 [192.168.134.108 on 192.168.23.221]
Nola Cam : 81c7f2e04db93a56eaa19c88 [192.168.168.112 on 192.168.23.221]
Hedgehog Cam : 5e3f9a1c0db842e7a661c9d2 [192.168.210.85 on 192.168.23.221]
Study Cam : f9c2d3b1a48e77c05d10e9aa [192.168.147.185 on 192.168.23.221]
Front Porch : 0a9d5c8e71f3b2e44d6a19cf [192.168.122.161 on 192.168.23.221]
Outside Gates : c71e3a20d9bf458aa6e1209d [192.168.195.32 on 192.168.23.221]
Hall Cam : 2b8f09d41c5ea773a90de621 [192.168.27.7 on 192.168.23.221]
Gate Doorbell : a0e98b6c42f7d3a11e5c90db [192.168.131.15 on 192.168.23.221]
By Family Room : 6a4d90b2ce1f3885e7a921dd [192.168.88.167 on 192.168.23.221]
Front Drive : 8d1b2e6f0c4a9e735aa19f02 [192.168.16.102 on 192.168.15.239]
Sentry : 3e9c02b71fa8d45a6c11e8b0 [192.168.153.103 on 192.168.15.239]
Bootroom : f1b93e27a0d845c69e4a110b [192.168.181.83 on 192.168.15.239]
Verandah : 4c7a0de218b9f35e61d02aac [192.168.122.75 on 192.168.15.239]
Garage Bays : 90e6bfa21d4837c5a119de02 [192.168.2.125 on 192.168.15.239]
Apple Tree : 1e8c6b5d9a2037f4eaa120bc [192.168.61.110 on 192.168.15.239]
Side Bit : a4c7e92b1f6d03859e11a0d9 [192.168.61.4 on 192.168.15.239]
Pool : 6b0d8a5e29c471f31aa9e204 [192.168.184.205 on 192.168.15.239]
*** Now we have a couple of cameras to be interested in, lets get the RTSPS streams …
Lane : a3f9c7e2b1d48a0c9f12de34 [192.168.103.44 on 192.168.23.221]
(‘high’, ‘rtsps://192.168.23.221:7441/Fa92cE1bD0e4A7c9?enableSrtp’)
(‘medium’, None)
(‘low’, ‘rtsps://192.168.23.221:7441/9dC0Abe27F14cE8a?enableSrtp’)
(‘package’, None)
Front Drive : 8d1b2e6f0c4a9e735aa19f02 [192.168.16.102 on 192.168.15.239]
Traceback (most recent call last):
File "/media/psf/Home/Documents/esphome/protect.py", line 39, in <module>
asyncio.run(do_it())
File "/usr/lib/python3.12/asyncio/runners.py", line 194, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/media/psf/Home/Documents/esphome/protect.py", line 35, in do_it
for stm in await camera.get_rtsps_streams():
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/media/psf/Home/Documents/esphome/esphome-venv/lib/python3.12/site-packages/uiprotect/data/devices.py", line 2182, in get_rtsps_streams
return await self._api.get_camera_rtsps_streams(self.id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/media/psf/Home/Documents/esphome/esphome-venv/lib/python3.12/site-packages/uiprotect/api.py", line 2118, in get_camera_rtsps_streams
response = await self.api_request_raw(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/media/psf/Home/Documents/esphome/esphome-venv/lib/python3.12/site-packages/uiprotect/api.py", line 571, in api_request_raw
await self._raise_for_status(response, raise_exception)
File "/media/psf/Home/Documents/esphome/esphome-venv/lib/python3.12/site-packages/uiprotect/api.py", line 610, in _raise_for_status
raise BadRequest(msg % (url, status, reason))
uiprotect.exceptions.BadRequest: Request failed: https://192.168.23.221/proxy/protect/integration/v1/cameras/8d1b2e6f0c4a9e735aa19f02/rtsps-stream - Status: 404 - Reason: Entity 'camera' not found
Additional context
I am trying to get my stacked UNVR cameras working in Home Assistant. I raised an issue there (home-assistant/core#154433) and some work was done on it but it wasn't quite fixed so I thought I'd try going a bit lower with the protect api, but I can't quite get there yet, I suspect it is related.
Version
7.33.2
Platform
macOS 15.6.1
Code of Conduct
No Duplicate
Describe the bug
I have a stacked UNVR setup. The API
camera.get_rtsps_streams()fails withuiprotect.exceptions.BadRequestwhen called against a camera that is hosted on the secondary UNVR.To Reproduce
Set up a stacked UNVR environment.
Ensure cameras are on both devices.
Run this code.
This will print out all the cameras and which host they are on. It will also pick the first camera on each host and then attempt to get the RTSPS streams. It will work fine on the first camera (which in my case is the same host as the main UI), but will fail on the second host with an exception.
In my case, the redacted output is:
Additional context
I am trying to get my stacked UNVR cameras working in Home Assistant. I raised an issue there (home-assistant/core#154433) and some work was done on it but it wasn't quite fixed so I thought I'd try going a bit lower with the protect api, but I can't quite get there yet, I suspect it is related.
Version
7.33.2
Platform
macOS 15.6.1
Code of Conduct
No Duplicate