From 1552319e944d165f59ddd287a4da065883e80822 Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Sun, 23 Jul 2023 17:56:58 +0200 Subject: [PATCH] Add Axis camera sources to diagnostics (#97063) --- homeassistant/components/axis/camera.py | 43 ++++++++++++++------ homeassistant/components/axis/device.py | 2 + homeassistant/components/axis/diagnostics.py | 2 +- tests/components/axis/test_diagnostics.py | 5 +++ 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/axis/camera.py b/homeassistant/components/axis/camera.py index c593c4fa419..53e2c3c9fe5 100644 --- a/homeassistant/components/axis/camera.py +++ b/homeassistant/components/axis/camera.py @@ -35,10 +35,16 @@ class AxisCamera(AxisEntity, MjpegCamera): _attr_supported_features = CameraEntityFeature.STREAM + _still_image_url: str + _mjpeg_url: str + _stream_source: str + def __init__(self, device: AxisNetworkDevice) -> None: """Initialize Axis Communications camera component.""" AxisEntity.__init__(self, device) + self._generate_sources() + MjpegCamera.__init__( self, username=device.username, @@ -46,41 +52,52 @@ class AxisCamera(AxisEntity, MjpegCamera): mjpeg_url=self.mjpeg_source, still_image_url=self.image_source, authentication=HTTP_DIGEST_AUTHENTICATION, + unique_id=f"{device.unique_id}-camera", ) - self._attr_unique_id = f"{device.unique_id}-camera" - async def async_added_to_hass(self) -> None: """Subscribe camera events.""" self.async_on_remove( async_dispatcher_connect( - self.hass, self.device.signal_new_address, self._new_address + self.hass, self.device.signal_new_address, self._generate_sources ) ) await super().async_added_to_hass() - def _new_address(self) -> None: - """Set new device address for video stream.""" - self._mjpeg_url = self.mjpeg_source - self._still_image_url = self.image_source + def _generate_sources(self) -> None: + """Generate sources. + + Additionally used when device change IP address. + """ + image_options = self.generate_options(skip_stream_profile=True) + self._still_image_url = f"http://{self.device.host}:{self.device.port}/axis-cgi/jpg/image.cgi{image_options}" + + mjpeg_options = self.generate_options() + self._mjpeg_url = f"http://{self.device.host}:{self.device.port}/axis-cgi/mjpg/video.cgi{mjpeg_options}" + + stream_options = self.generate_options(add_video_codec_h264=True) + self._stream_source = f"rtsp://{self.device.username}:{self.device.password}@{self.device.host}/axis-media/media.amp{stream_options}" + + self.device.additional_diagnostics["camera_sources"] = { + "Image": self._still_image_url, + "MJPEG": self._mjpeg_url, + "Stream": f"rtsp://user:pass@{self.device.host}/axis-media/media.amp{stream_options}", + } @property def image_source(self) -> str: """Return still image URL for device.""" - options = self.generate_options(skip_stream_profile=True) - return f"http://{self.device.host}:{self.device.port}/axis-cgi/jpg/image.cgi{options}" + return self._still_image_url @property def mjpeg_source(self) -> str: """Return mjpeg URL for device.""" - options = self.generate_options() - return f"http://{self.device.host}:{self.device.port}/axis-cgi/mjpg/video.cgi{options}" + return self._mjpeg_url async def stream_source(self) -> str: """Return the stream source.""" - options = self.generate_options(add_video_codec_h264=True) - return f"rtsp://{self.device.username}:{self.device.password}@{self.device.host}/axis-media/media.amp{options}" + return self._stream_source def generate_options( self, skip_stream_profile: bool = False, add_video_codec_h264: bool = False diff --git a/homeassistant/components/axis/device.py b/homeassistant/components/axis/device.py index f53e69fba9f..8f3c8b9a8b6 100644 --- a/homeassistant/components/axis/device.py +++ b/homeassistant/components/axis/device.py @@ -62,6 +62,8 @@ class AxisNetworkDevice: self.fw_version = api.vapix.firmware_version self.product_type = api.vapix.product_type + self.additional_diagnostics: dict[str, Any] = {} + @property def host(self): """Return the host address of this device.""" diff --git a/homeassistant/components/axis/diagnostics.py b/homeassistant/components/axis/diagnostics.py index 277f24513de..20dfedd717b 100644 --- a/homeassistant/components/axis/diagnostics.py +++ b/homeassistant/components/axis/diagnostics.py @@ -21,7 +21,7 @@ async def async_get_config_entry_diagnostics( ) -> dict[str, Any]: """Return diagnostics for a config entry.""" device: AxisNetworkDevice = hass.data[AXIS_DOMAIN][config_entry.entry_id] - diag: dict[str, Any] = {} + diag: dict[str, Any] = device.additional_diagnostics.copy() diag["config"] = async_redact_data(config_entry.as_dict(), REDACT_CONFIG) diff --git a/tests/components/axis/test_diagnostics.py b/tests/components/axis/test_diagnostics.py index df5d071ddbe..a76aa40ebc8 100644 --- a/tests/components/axis/test_diagnostics.py +++ b/tests/components/axis/test_diagnostics.py @@ -38,6 +38,11 @@ async def test_entry_diagnostics( "unique_id": REDACTED, "disabled_by": None, }, + "camera_sources": { + "Image": "http://1.2.3.4:80/axis-cgi/jpg/image.cgi", + "MJPEG": "http://1.2.3.4:80/axis-cgi/mjpg/video.cgi", + "Stream": "rtsp://user:pass@1.2.3.4/axis-media/media.amp?videocodec=h264", + }, "api_discovery": [ { "id": "api-discovery",