2019-02-13 20:21:14 +00:00
|
|
|
"""Support for Axis camera streaming."""
|
2017-05-12 15:51:54 +00:00
|
|
|
|
2019-04-05 17:14:54 +00:00
|
|
|
from homeassistant.components.camera import SUPPORT_STREAM
|
2019-03-17 03:44:05 +00:00
|
|
|
from homeassistant.components.mjpeg.camera import (
|
2019-07-31 19:25:30 +00:00
|
|
|
CONF_MJPEG_URL,
|
|
|
|
CONF_STILL_IMAGE_URL,
|
|
|
|
MjpegCamera,
|
|
|
|
filter_urllib3_logging,
|
|
|
|
)
|
2018-01-21 06:35:38 +00:00
|
|
|
from homeassistant.const import (
|
2019-07-31 19:25:30 +00:00
|
|
|
CONF_AUTHENTICATION,
|
|
|
|
CONF_NAME,
|
|
|
|
CONF_PASSWORD,
|
|
|
|
CONF_PORT,
|
|
|
|
CONF_USERNAME,
|
|
|
|
HTTP_DIGEST_AUTHENTICATION,
|
|
|
|
)
|
2019-03-24 15:16:50 +00:00
|
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
2017-05-12 15:51:54 +00:00
|
|
|
|
2019-05-20 05:45:31 +00:00
|
|
|
from .axis_base import AxisEntityBase
|
2020-06-01 16:45:38 +00:00
|
|
|
from .const import DEFAULT_STREAM_PROFILE, DOMAIN as AXIS_DOMAIN
|
2020-03-19 23:30:38 +00:00
|
|
|
|
2017-05-12 15:51:54 +00:00
|
|
|
|
2019-03-24 15:16:50 +00:00
|
|
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
|
|
|
"""Set up the Axis camera video stream."""
|
2019-01-03 18:56:36 +00:00
|
|
|
filter_urllib3_logging()
|
|
|
|
|
2020-01-04 07:58:18 +00:00
|
|
|
device = hass.data[AXIS_DOMAIN][config_entry.unique_id]
|
2019-03-24 15:16:50 +00:00
|
|
|
|
2020-05-15 21:56:09 +00:00
|
|
|
if not device.option_camera:
|
|
|
|
return
|
|
|
|
|
2020-06-01 16:45:38 +00:00
|
|
|
async_add_entities([AxisCamera(device)])
|
2017-06-24 07:14:57 +00:00
|
|
|
|
|
|
|
|
2019-05-20 05:45:31 +00:00
|
|
|
class AxisCamera(AxisEntityBase, MjpegCamera):
|
2018-01-21 06:35:38 +00:00
|
|
|
"""Representation of a Axis camera."""
|
2017-06-24 07:14:57 +00:00
|
|
|
|
2020-06-01 16:45:38 +00:00
|
|
|
def __init__(self, device):
|
2017-06-24 07:14:57 +00:00
|
|
|
"""Initialize Axis Communications camera component."""
|
2019-05-20 05:45:31 +00:00
|
|
|
AxisEntityBase.__init__(self, device)
|
2020-06-01 16:45:38 +00:00
|
|
|
|
|
|
|
config = {
|
|
|
|
CONF_NAME: device.config_entry.data[CONF_NAME],
|
|
|
|
CONF_USERNAME: device.config_entry.data[CONF_USERNAME],
|
|
|
|
CONF_PASSWORD: device.config_entry.data[CONF_PASSWORD],
|
|
|
|
CONF_MJPEG_URL: self.mjpeg_source,
|
|
|
|
CONF_STILL_IMAGE_URL: self.image_source,
|
|
|
|
CONF_AUTHENTICATION: HTTP_DIGEST_AUTHENTICATION,
|
|
|
|
}
|
2019-05-20 05:45:31 +00:00
|
|
|
MjpegCamera.__init__(self, config)
|
2019-03-24 15:16:50 +00:00
|
|
|
|
|
|
|
async def async_added_to_hass(self):
|
|
|
|
"""Subscribe camera events."""
|
2020-04-02 16:25:33 +00:00
|
|
|
self.async_on_remove(
|
2019-07-31 19:25:30 +00:00
|
|
|
async_dispatcher_connect(
|
2020-05-14 08:49:27 +00:00
|
|
|
self.hass, self.device.signal_new_address, self._new_address
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
|
|
|
)
|
2019-03-29 14:20:12 +00:00
|
|
|
|
2019-05-20 05:45:31 +00:00
|
|
|
await super().async_added_to_hass()
|
2019-04-15 22:06:45 +00:00
|
|
|
|
2019-04-05 17:14:54 +00:00
|
|
|
@property
|
|
|
|
def supported_features(self):
|
|
|
|
"""Return supported features."""
|
|
|
|
return SUPPORT_STREAM
|
|
|
|
|
2019-04-02 18:13:11 +00:00
|
|
|
def _new_address(self):
|
|
|
|
"""Set new device address for video stream."""
|
2020-06-01 16:45:38 +00:00
|
|
|
self._mjpeg_url = self.mjpeg_source
|
|
|
|
self._still_image_url = self.image_source
|
2019-03-27 17:25:01 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def unique_id(self):
|
|
|
|
"""Return a unique identifier for this device."""
|
2019-09-03 14:11:36 +00:00
|
|
|
return f"{self.device.serial}-camera"
|
2020-06-01 16:45:38 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def image_source(self):
|
|
|
|
"""Return still image URL for device."""
|
|
|
|
return f"http://{self.device.host}:{self.device.config_entry.data[CONF_PORT]}/axis-cgi/jpg/image.cgi"
|
|
|
|
|
|
|
|
@property
|
|
|
|
def mjpeg_source(self):
|
|
|
|
"""Return mjpeg URL for device."""
|
|
|
|
options = ""
|
|
|
|
if self.device.option_stream_profile != DEFAULT_STREAM_PROFILE:
|
|
|
|
options = f"?&streamprofile={self.device.option_stream_profile}"
|
|
|
|
|
|
|
|
return f"http://{self.device.host}:{self.device.config_entry.data[CONF_PORT]}/axis-cgi/mjpg/video.cgi{options}"
|
|
|
|
|
|
|
|
async def stream_source(self):
|
|
|
|
"""Return the stream source."""
|
|
|
|
options = ""
|
|
|
|
if self.device.option_stream_profile != DEFAULT_STREAM_PROFILE:
|
|
|
|
options = f"&streamprofile={self.device.option_stream_profile}"
|
|
|
|
|
|
|
|
return f"rtsp://{self.device.config_entry.data[CONF_USERNAME]}:{self.device.config_entry.data[CONF_PASSWORD]}@{self.device.host}/axis-media/media.amp?videocodec=h264{options}"
|