PR #390 adds GET /control/azimuth. It covers the two moving cases (hardware read-back on Linovision, dead reckoning from commanded moves on Reolink PTZ), but the stationary case, where the azimuth is a constant already present in credentials.json, has no path through the code.
Priority: low/medium. No production caller (with livestreaming access) consumes /control/azimuth yet, and the PTZ paths delivered in #390 are unaffected.
Static Reolink ("type": "static")
current_azimuth is initialised to None in pyro_camera_api/camera/adapters/reolink.py:62 and only ever written by _sync_azimuth_from_pose, reached solely via operation == "ToPos" (reolink.py:137-138). A static camera never receives a ToPos, since static_loop only captures (pyro_camera_api/camera/patrol.py:119). The value therefore stays None for the process lifetime and /control/azimuth answers azimuth_deg: null.
- The constructor guard in
reolink.py:66 is explicitly if self.cam_type == "ptz" and .... It validates the poses/azimuths alignment for PTZ and does nothing for static. That is the natural place for the missing branch: for a static camera with a configured azimuth, seed current_azimuth directly from cam_azimuths[0], no poses involved.
- The background sync cannot help either:
_cameras_needing_azimuths skips any camera with not cam.cam_poses (pyro_camera_api/camera/pose_azimuths.py:71), and static cameras have none.
Non-PTZ adapters (rtsp / url / rest)
_require_ptz (pyro_camera_api/api/routes_control.py:527, used at routes_control.py:866) returns 400 for anything that is not a PTZMixin. Their azimuth is in RAW_CONFIG and is already reported by /cameras/camera_infos, so the data exists, it is just unreachable through this endpoint. A client that wants to know where a camera is pointing has to special-case the adapter type instead of asking one endpoint.
Proposed fix
- Seed the azimuth from config for static cameras, in a constructor branch next to
reolink.py:66.
- In the route, fall back to
RAW_CONFIG[camera_ip]["azimuths"][0] when the adapter has no tracked or hardware value, and drop the hard PTZ requirement for this read-only lookup.
- Return
"source": "config" ? for these, so callers can tell a fixed value from a tracked or measured one.
PR #390 adds
GET /control/azimuth. It covers the two moving cases (hardware read-back on Linovision, dead reckoning from commanded moves on Reolink PTZ), but the stationary case, where the azimuth is a constant already present incredentials.json, has no path through the code.Priority: low/medium. No production caller (with livestreaming access) consumes
/control/azimuthyet, and the PTZ paths delivered in #390 are unaffected.Static Reolink (
"type": "static")current_azimuthis initialised toNoneinpyro_camera_api/camera/adapters/reolink.py:62and only ever written by_sync_azimuth_from_pose, reached solely viaoperation == "ToPos"(reolink.py:137-138). A static camera never receives aToPos, sincestatic_looponly captures (pyro_camera_api/camera/patrol.py:119). The value therefore staysNonefor the process lifetime and/control/azimuthanswersazimuth_deg: null.reolink.py:66is explicitlyif self.cam_type == "ptz" and .... It validates the poses/azimuths alignment for PTZ and does nothing for static. That is the natural place for the missing branch: for a static camera with a configured azimuth, seedcurrent_azimuthdirectly fromcam_azimuths[0], no poses involved._cameras_needing_azimuthsskips any camera withnot cam.cam_poses(pyro_camera_api/camera/pose_azimuths.py:71), and static cameras have none.Non-PTZ adapters (rtsp / url / rest)
_require_ptz(pyro_camera_api/api/routes_control.py:527, used atroutes_control.py:866) returns 400 for anything that is not aPTZMixin. Their azimuth is inRAW_CONFIGand is already reported by/cameras/camera_infos, so the data exists, it is just unreachable through this endpoint. A client that wants to know where a camera is pointing has to special-case the adapter type instead of asking one endpoint.Proposed fix
reolink.py:66.RAW_CONFIG[camera_ip]["azimuths"][0]when the adapter has no tracked or hardware value, and drop the hard PTZ requirement for this read-only lookup."source": "config"? for these, so callers can tell a fixed value from a tracked or measured one.