Support Axis stream profile and configuring it through options flow (#36322)

* Support stream profile and configuring it through options flow

* Options flow test

* Allow configuration of not using a stream profile

* Shorten default stream profile string
This commit is contained in:
Robert Svensson authored and GitHub committed 2020-06-01 18:45:38 +02:00
1 parent 47706dac1a
commit cf6043fc2d
9 files changed
+220 -45

No files matched your search

+48 -2
View File
@@ -1,10 +1,17 @@
"""Axis camera platform tests."""
from homeassistant.components.axis.const import DOMAIN as AXIS_DOMAIN
from homeassistant.components import camera
from homeassistant.components.axis.const import (
CONF_CAMERA,
CONF_STREAM_PROFILE,
DOMAIN as AXIS_DOMAIN,
)
from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN
from homeassistant.setup import async_setup_component
from .test_device import NAME, setup_axis_integration
from .test_device import ENTRY_OPTIONS, NAME, setup_axis_integration
from tests.async_mock import patch
async def test_platform_manually_configured(hass):
@@ -28,3 +35,42 @@ async def test_camera(hass):
cam = hass.states.get(f"camera.{NAME}")
assert cam.state == "idle"
assert cam.name == NAME
camera_entity = camera._get_camera_from_entity_id(hass, f"camera.{NAME}")
assert camera_entity.image_source == "http://1.2.3.4:80/axis-cgi/jpg/image.cgi"
assert camera_entity.mjpeg_source == "http://1.2.3.4:80/axis-cgi/mjpg/video.cgi"
assert (
await camera_entity.stream_source()
== "rtsp://root:pass@1.2.3.4/axis-media/media.amp?videocodec=h264"
)
async def test_camera_with_stream_profile(hass):
"""Test that Axis camera entity is using the correct path with stream profike."""
with patch.dict(ENTRY_OPTIONS, {CONF_STREAM_PROFILE: "profile_1"}):
await setup_axis_integration(hass)
assert len(hass.states.async_entity_ids(CAMERA_DOMAIN)) == 1
cam = hass.states.get(f"camera.{NAME}")
assert cam.state == "idle"
assert cam.name == NAME
camera_entity = camera._get_camera_from_entity_id(hass, f"camera.{NAME}")
assert camera_entity.image_source == "http://1.2.3.4:80/axis-cgi/jpg/image.cgi"
assert (
camera_entity.mjpeg_source
== "http://1.2.3.4:80/axis-cgi/mjpg/video.cgi?&streamprofile=profile_1"
)
assert (
await camera_entity.stream_source()
== "rtsp://root:pass@1.2.3.4/axis-media/media.amp?videocodec=h264&streamprofile=profile_1"
)
async def test_camera_disabled(hass):
"""Test that Axis camera platform is loaded properly but does not create camera entity."""
with patch.dict(ENTRY_OPTIONS, {CONF_CAMERA: False}):
await setup_axis_integration(hass)
assert len(hass.states.async_entity_ids(CAMERA_DOMAIN)) == 0
+41 -5
View File
@@ -1,6 +1,14 @@
"""Test Axis config flow."""
from homeassistant import data_entry_flow
from homeassistant.components.axis import config_flow
from homeassistant.components.axis.const import CONF_MODEL, DOMAIN as AXIS_DOMAIN
from homeassistant.components.axis.const import (
CONF_CAMERA,
CONF_EVENTS,
CONF_MODEL,
CONF_STREAM_PROFILE,
DEFAULT_STREAM_PROFILE,
DOMAIN as AXIS_DOMAIN,
)
from homeassistant.const import (
CONF_HOST,
CONF_MAC,
@@ -268,8 +276,8 @@ async def test_zeroconf_flow_updated_configuration(hass):
assert device.config_entry.data == {
CONF_HOST: "1.2.3.4",
CONF_PORT: 80,
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
CONF_USERNAME: "root",
CONF_PASSWORD: "pass",
CONF_MAC: MAC,
CONF_MODEL: MODEL,
CONF_NAME: NAME,
@@ -291,8 +299,8 @@ async def test_zeroconf_flow_updated_configuration(hass):
assert device.config_entry.data == {
CONF_HOST: "2.3.4.5",
CONF_PORT: 8080,
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
CONF_USERNAME: "root",
CONF_PASSWORD: "pass",
CONF_MAC: MAC,
CONF_MODEL: MODEL,
CONF_NAME: NAME,
@@ -321,3 +329,31 @@ async def test_zeroconf_flow_ignore_link_local_address(hass):
assert result["type"] == "abort"
assert result["reason"] == "link_local_address"
async def test_option_flow(hass):
"""Test config flow options."""
device = await setup_axis_integration(hass)
assert device.option_stream_profile == DEFAULT_STREAM_PROFILE
result = await hass.config_entries.options.async_init(device.config_entry.entry_id)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "configure_stream"
assert set(result["data_schema"].schema[CONF_STREAM_PROFILE].container) == {
DEFAULT_STREAM_PROFILE,
"profile_1",
"profile_2",
}
result = await hass.config_entries.options.async_configure(
result["flow_id"], user_input={CONF_STREAM_PROFILE: "profile_1"},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] == {
CONF_CAMERA: True,
CONF_EVENTS: True,
CONF_STREAM_PROFILE: "profile_1",
}
assert device.option_stream_profile == "profile_1"
+12 -3
View File
@@ -52,8 +52,8 @@ ENTRY_OPTIONS = {CONF_CAMERA: True, CONF_EVENTS: True}
ENTRY_CONFIG = {
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
CONF_USERNAME: "root",
CONF_PASSWORD: "pass",
CONF_PORT: 80,
CONF_MAC: MAC,
CONF_MODEL: MODEL,
@@ -152,6 +152,15 @@ root.Properties.Image.Rotation=0,180
root.Properties.System.SerialNumber=00408C12345
"""
STREAM_PROFILES_RESPONSE = """root.StreamProfile.MaxGroups=26
root.StreamProfile.S0.Description=profile_1_description
root.StreamProfile.S0.Name=profile_1
root.StreamProfile.S0.Parameters=videocodec=h264
root.StreamProfile.S1.Description=profile_2_description
root.StreamProfile.S1.Name=profile_2
root.StreamProfile.S1.Parameters=videocodec=h265
"""
def vapix_session_request(session, url, **kwargs):
"""Return data based on url."""
@@ -170,7 +179,7 @@ def vapix_session_request(session, url, **kwargs):
if PROPERTIES_URL in url:
return PROPERTIES_RESPONSE
if STREAM_PROFILES_URL in url:
return ""
return STREAM_PROFILES_RESPONSE
async def setup_axis_integration(hass, config=ENTRY_CONFIG, options=ENTRY_OPTIONS):