From a45df7aac9299aa2233932033c92317b11895691 Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Tue, 16 Apr 2019 10:46:29 +0200 Subject: [PATCH] Axis - improved internal parameter handling (#23122) Will result in faster startup per entry due to less network data --- homeassistant/components/axis/__init__.py | 5 +- homeassistant/components/axis/config_flow.py | 6 +-- homeassistant/components/axis/device.py | 17 ++++--- homeassistant/components/axis/manifest.json | 8 +-- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/axis/test_config_flow.py | 52 +++++++------------- tests/components/axis/test_device.py | 12 +++-- 8 files changed, 40 insertions(+), 64 deletions(-) diff --git a/homeassistant/components/axis/__init__.py b/homeassistant/components/axis/__init__.py index 7d9cabd09fa..e9e8a158a3b 100644 --- a/homeassistant/components/axis/__init__.py +++ b/homeassistant/components/axis/__init__.py @@ -64,12 +64,9 @@ async def async_unload_entry(hass, config_entry): async def async_populate_options(hass, config_entry): """Populate default options for device.""" - from axis.vapix import VAPIX_IMAGE_FORMAT - device = await get_device(hass, config_entry.data[CONF_DEVICE]) - supported_formats = device.vapix.get_param(VAPIX_IMAGE_FORMAT) - + supported_formats = device.vapix.params.image_format camera = bool(supported_formats) options = { diff --git a/homeassistant/components/axis/config_flow.py b/homeassistant/components/axis/config_flow.py index 54d93f768d2..0c175de20c7 100644 --- a/homeassistant/components/axis/config_flow.py +++ b/homeassistant/components/axis/config_flow.py @@ -66,7 +66,6 @@ class AxisFlowHandler(config_entries.ConfigFlow): Manage device specific parameters. """ - from axis.vapix import VAPIX_MODEL_ID, VAPIX_SERIAL_NUMBER errors = {} if user_input is not None: @@ -79,13 +78,12 @@ class AxisFlowHandler(config_entries.ConfigFlow): } device = await get_device(self.hass, self.device_config) - self.serial_number = device.vapix.get_param( - VAPIX_SERIAL_NUMBER) + self.serial_number = device.vapix.params.system_serialnumber if self.serial_number in configured_devices(self.hass): raise AlreadyConfigured - self.model = device.vapix.get_param(VAPIX_MODEL_ID) + self.model = device.vapix.params.prodnbr return await self._create_entry() diff --git a/homeassistant/components/axis/device.py b/homeassistant/components/axis/device.py index 155d1c47608..48577799a13 100644 --- a/homeassistant/components/axis/device.py +++ b/homeassistant/components/axis/device.py @@ -67,13 +67,9 @@ class AxisNetworkDevice: async def async_setup(self): """Set up the device.""" - from axis.vapix import VAPIX_FW_VERSION, VAPIX_PROD_TYPE - - hass = self.hass - try: self.api = await get_device( - hass, self.config_entry.data[CONF_DEVICE]) + self.hass, self.config_entry.data[CONF_DEVICE]) except CannotConnect: raise ConfigEntryNotReady @@ -83,8 +79,8 @@ class AxisNetworkDevice: 'Unknown error connecting with Axis device on %s', self.host) return False - self.fw_version = self.api.vapix.get_param(VAPIX_FW_VERSION) - self.product_type = self.api.vapix.get_param(VAPIX_PROD_TYPE) + self.fw_version = self.api.vapix.params.firmware_version + self.product_type = self.api.vapix.params.prodtype if self.config_entry.options[CONF_CAMERA]: self.hass.async_create_task( @@ -188,9 +184,14 @@ async def get_device(hass, config): password=config[CONF_PASSWORD], port=config[CONF_PORT], web_proto='http') + device.vapix.initialize_params(preload_data=False) + try: with async_timeout.timeout(15): - await hass.async_add_executor_job(device.vapix.load_params) + await hass.async_add_executor_job( + device.vapix.params.update_brand) + await hass.async_add_executor_job( + device.vapix.params.update_properties) return device except axis.Unauthorized: diff --git a/homeassistant/components/axis/manifest.json b/homeassistant/components/axis/manifest.json index 0f2b39b9760..4d102590184 100644 --- a/homeassistant/components/axis/manifest.json +++ b/homeassistant/components/axis/manifest.json @@ -2,11 +2,7 @@ "domain": "axis", "name": "Axis", "documentation": "https://www.home-assistant.io/components/axis", - "requirements": [ - "axis==20" - ], + "requirements": ["axis==21"], "dependencies": [], - "codeowners": [ - "@kane610" - ] + "codeowners": ["@kane610"] } diff --git a/requirements_all.txt b/requirements_all.txt index 89054e68d62..92627b444f7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -192,7 +192,7 @@ av==6.1.2 # avion==0.10 # homeassistant.components.axis -axis==20 +axis==21 # homeassistant.components.baidu baidu-aip==1.6.6 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 30903911e4f..0b7da328ee1 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -61,7 +61,7 @@ apns2==0.3.0 av==6.1.2 # homeassistant.components.axis -axis==20 +axis==21 # homeassistant.components.zha bellows-homeassistant==0.7.2 diff --git a/tests/components/axis/test_config_flow.py b/tests/components/axis/test_config_flow.py index 0ce5757578d..1a83e9be8b5 100644 --- a/tests/components/axis/test_config_flow.py +++ b/tests/components/axis/test_config_flow.py @@ -6,8 +6,6 @@ from homeassistant.components.axis import config_flow from tests.common import mock_coro, MockConfigEntry -import axis as axis_lib - async def test_configured_devices(hass): """Test that configured devices works as expected.""" @@ -37,13 +35,9 @@ async def test_flow_works(hass): mock_device.port = port return mock_device - def mock_get_param(param): - """Fake get param method.""" - return param - mock_device.side_effect = mock_constructor - mock_device.vapix.load_params.return_value = Mock() - mock_device.vapix.get_param.side_effect = mock_get_param + mock_device.vapix.params.system_serialnumber = 'serialnumber' + mock_device.vapix.params.prodnbr = 'prodnbr' result = await hass.config_entries.flow.async_init( config_flow.DOMAIN, @@ -59,23 +53,22 @@ async def test_flow_works(hass): config_flow.CONF_HOST: '1.2.3.4', config_flow.CONF_USERNAME: 'user', config_flow.CONF_PASSWORD: 'pass', - config_flow.CONF_PORT: 81 + config_flow.CONF_PORT: 80 } ) assert result['type'] == 'create_entry' - assert result['title'] == '{} - {}'.format( - axis_lib.vapix.VAPIX_MODEL_ID, axis_lib.vapix.VAPIX_SERIAL_NUMBER) + assert result['title'] == '{} - {}'.format('prodnbr', 'serialnumber') assert result['data'] == { axis.CONF_DEVICE: { config_flow.CONF_HOST: '1.2.3.4', config_flow.CONF_USERNAME: 'user', config_flow.CONF_PASSWORD: 'pass', - config_flow.CONF_PORT: 81 + config_flow.CONF_PORT: 80 }, - config_flow.CONF_MAC: axis_lib.vapix.VAPIX_SERIAL_NUMBER, - config_flow.CONF_MODEL: axis_lib.vapix.VAPIX_MODEL_ID, - config_flow.CONF_NAME: 'Brand.ProdNbr 0' + config_flow.CONF_MAC: 'serialnumber', + config_flow.CONF_MODEL: 'prodnbr', + config_flow.CONF_NAME: 'prodnbr 0' } @@ -89,7 +82,7 @@ async def test_flow_fails_already_configured(hass): entry.add_to_hass(hass) mock_device = Mock() - mock_device.vapix.get_param.return_value = '1234' + mock_device.vapix.params.system_serialnumber = '1234' with patch('homeassistant.components.axis.config_flow.get_device', return_value=mock_coro(mock_device)): @@ -97,7 +90,7 @@ async def test_flow_fails_already_configured(hass): config_flow.CONF_HOST: '1.2.3.4', config_flow.CONF_USERNAME: 'user', config_flow.CONF_PASSWORD: 'pass', - config_flow.CONF_PORT: 81 + config_flow.CONF_PORT: 80 }) assert result['errors'] == {'base': 'already_configured'} @@ -114,7 +107,7 @@ async def test_flow_fails_faulty_credentials(hass): config_flow.CONF_HOST: '1.2.3.4', config_flow.CONF_USERNAME: 'user', config_flow.CONF_PASSWORD: 'pass', - config_flow.CONF_PORT: 81 + config_flow.CONF_PORT: 80 }) assert result['errors'] == {'base': 'faulty_credentials'} @@ -131,7 +124,7 @@ async def test_flow_fails_device_unavailable(hass): config_flow.CONF_HOST: '1.2.3.4', config_flow.CONF_USERNAME: 'user', config_flow.CONF_PASSWORD: 'pass', - config_flow.CONF_PORT: 81 + config_flow.CONF_PORT: 80 }) assert result['errors'] == {'base': 'device_unavailable'} @@ -207,13 +200,7 @@ async def test_discovery_flow_known_device(hass): mock_device.port = port return mock_device - def mock_get_param(param): - """Fake get param method.""" - return param - mock_device.side_effect = mock_constructor - mock_device.vapix.load_params.return_value = Mock() - mock_device.vapix.get_param.side_effect = mock_get_param result = await hass.config_entries.flow.async_init( config_flow.DOMAIN, @@ -303,13 +290,9 @@ async def test_import_flow_works(hass): mock_device.port = port return mock_device - def mock_get_param(param): - """Fake get param method.""" - return param - mock_device.side_effect = mock_constructor - mock_device.vapix.load_params.return_value = Mock() - mock_device.vapix.get_param.side_effect = mock_get_param + mock_device.vapix.params.system_serialnumber = 'serialnumber' + mock_device.vapix.params.prodnbr = 'prodnbr' result = await hass.config_entries.flow.async_init( config_flow.DOMAIN, @@ -324,8 +307,7 @@ async def test_import_flow_works(hass): ) assert result['type'] == 'create_entry' - assert result['title'] == '{} - {}'.format( - axis_lib.vapix.VAPIX_MODEL_ID, axis_lib.vapix.VAPIX_SERIAL_NUMBER) + assert result['title'] == '{} - {}'.format('prodnbr', 'serialnumber') assert result['data'] == { axis.CONF_DEVICE: { config_flow.CONF_HOST: '1.2.3.4', @@ -333,7 +315,7 @@ async def test_import_flow_works(hass): config_flow.CONF_PASSWORD: 'pass', config_flow.CONF_PORT: 80 }, - config_flow.CONF_MAC: axis_lib.vapix.VAPIX_SERIAL_NUMBER, - config_flow.CONF_MODEL: axis_lib.vapix.VAPIX_MODEL_ID, + config_flow.CONF_MAC: 'serialnumber', + config_flow.CONF_MODEL: 'prodnbr', config_flow.CONF_NAME: 'name' } diff --git a/tests/components/axis/test_device.py b/tests/components/axis/test_device.py index f6d17a3ef38..d95352abe9c 100644 --- a/tests/components/axis/test_device.py +++ b/tests/components/axis/test_device.py @@ -190,8 +190,10 @@ async def test_shutdown(): async def test_get_device(hass): """Successful call.""" - with patch('axis.vapix.Vapix.load_params', - return_value=mock_coro()): + with patch('axis.param_cgi.Params.update_brand', + return_value=mock_coro()), \ + patch('axis.param_cgi.Params.update_properties', + return_value=mock_coro()): assert await device.get_device(hass, DEVICE_DATA) @@ -199,7 +201,7 @@ async def test_get_device_fails(hass): """Device unauthorized yields authentication required error.""" import axis - with patch('axis.vapix.Vapix.load_params', + with patch('axis.param_cgi.Params.update_brand', side_effect=axis.Unauthorized), \ pytest.raises(errors.AuthenticationRequired): await device.get_device(hass, DEVICE_DATA) @@ -209,7 +211,7 @@ async def test_get_device_device_unavailable(hass): """Device unavailable yields cannot connect error.""" import axis - with patch('axis.vapix.Vapix.load_params', + with patch('axis.param_cgi.Params.update_brand', side_effect=axis.RequestError), \ pytest.raises(errors.CannotConnect): await device.get_device(hass, DEVICE_DATA) @@ -219,7 +221,7 @@ async def test_get_device_unknown_error(hass): """Device yield unknown error.""" import axis - with patch('axis.vapix.Vapix.load_params', + with patch('axis.param_cgi.Params.update_brand', side_effect=axis.AxisException), \ pytest.raises(errors.AuthenticationRequired): await device.get_device(hass, DEVICE_DATA)