diff --git a/homeassistant/components/airvisual/__init__.py b/homeassistant/components/airvisual/__init__.py index 73c39a450b85b..d0a3d46b56a49 100644 --- a/homeassistant/components/airvisual/__init__.py +++ b/homeassistant/components/airvisual/__init__.py @@ -31,6 +31,7 @@ CONF_COUNTRY, CONF_GEOGRAPHIES, CONF_INTEGRATION_TYPE, + CONF_TREND_MEASUREMENTS, DATA_CLIENT, DOMAIN, INTEGRATION_TYPE_GEOGRAPHY, @@ -46,7 +47,7 @@ DEFAULT_ATTRIBUTION = "Data provided by AirVisual" DEFAULT_GEOGRAPHY_SCAN_INTERVAL = timedelta(minutes=10) DEFAULT_NODE_PRO_SCAN_INTERVAL = timedelta(minutes=1) -DEFAULT_OPTIONS = {CONF_SHOW_ON_MAP: True} +DEFAULT_TREND_MEASUREMENTS = 100 GEOGRAPHY_COORDINATES_SCHEMA = vol.Schema( { @@ -148,6 +149,9 @@ def _standardize_node_pro_config_entry(hass, config_entry): """Ensure that Node/Pro config entries have appropriate properties.""" entry_updates = {} + if not config_entry.options: + # If the config entry doesn't already have any options set, set defaults: + entry_updates["options"] = {CONF_TREND_MEASUREMENTS: DEFAULT_TREND_MEASUREMENTS} if CONF_INTEGRATION_TYPE not in config_entry.data: # If the config entry data doesn't contain the integration type, add it: entry_updates["data"] = { @@ -172,15 +176,13 @@ async def async_setup_entry(hass, config_entry): Client(websession, api_key=config_entry.data[CONF_API_KEY]), config_entry, ) - - # Only geography-based entries have options: - config_entry.add_update_listener(async_update_options) else: _standardize_node_pro_config_entry(hass, config_entry) airvisual = AirVisualNodeProData(hass, Client(websession), config_entry) - await airvisual.async_update() + config_entry.add_update_listener(async_update_options) + await airvisual.async_update() hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = airvisual for component in PLATFORMS: @@ -362,6 +364,7 @@ def __init__(self, hass, client, config_entry): self.data = {} self.integration_type = INTEGRATION_TYPE_NODE_PRO self.ip_address = config_entry.data[CONF_IP_ADDRESS] + self.options = config_entry.options self.scan_interval = DEFAULT_NODE_PRO_SCAN_INTERVAL self.topic_update = TOPIC_UPDATE.format(config_entry.data[CONF_IP_ADDRESS]) @@ -369,7 +372,10 @@ async def async_update(self): """Get new data from the Node/Pro.""" try: self.data = await self._client.node.from_samba( - self.ip_address, self._password, include_history=False + self.ip_address, + self._password, + include_history=False, + measurements_to_use=self.options[CONF_TREND_MEASUREMENTS], ) except NodeProError as err: LOGGER.error("Error while retrieving Node/Pro data: %s", err) @@ -378,3 +384,8 @@ async def async_update(self): LOGGER.debug("Received new Node/Pro data") async_dispatcher_send(self._hass, self.topic_update) + + @callback + def async_update_options(self, options): + """Update the data manager's options.""" + self.options = options diff --git a/homeassistant/components/airvisual/config_flow.py b/homeassistant/components/airvisual/config_flow.py index 22a8c77602787..58b6963e1a468 100644 --- a/homeassistant/components/airvisual/config_flow.py +++ b/homeassistant/components/airvisual/config_flow.py @@ -21,6 +21,7 @@ from .const import ( # pylint: disable=unused-import CONF_GEOGRAPHIES, CONF_INTEGRATION_TYPE, + CONF_TREND_MEASUREMENTS, DOMAIN, INTEGRATION_TYPE_GEOGRAPHY, INTEGRATION_TYPE_NODE_PRO, @@ -179,20 +180,31 @@ class AirVisualOptionsFlowHandler(config_entries.OptionsFlow): def __init__(self, config_entry): """Initialize.""" self.config_entry = config_entry + self.geography_options_schema = vol.Schema( + { + vol.Required( + CONF_SHOW_ON_MAP, + default=self.config_entry.options.get(CONF_SHOW_ON_MAP), + ): bool + } + ) + self.node_pro_options_schema = vol.Schema( + { + vol.Required( + CONF_TREND_MEASUREMENTS, + default=self.config_entry.options.get(CONF_TREND_MEASUREMENTS), + ): int + } + ) async def async_step_init(self, user_input=None): """Manage the options.""" if user_input is not None: return self.async_create_entry(title="", data=user_input) - return self.async_show_form( - step_id="init", - data_schema=vol.Schema( - { - vol.Required( - CONF_SHOW_ON_MAP, - default=self.config_entry.options.get(CONF_SHOW_ON_MAP), - ): bool - } - ), - ) + if self.config_entry.data[CONF_INTEGRATION_TYPE] == INTEGRATION_TYPE_GEOGRAPHY: + schema = self.geography_options_schema + else: + schema = self.node_pro_options_schema + + return self.async_show_form(step_id="init", data_schema=schema) diff --git a/homeassistant/components/airvisual/const.py b/homeassistant/components/airvisual/const.py index 0e0e62a9b0c58..59b77d55607c3 100644 --- a/homeassistant/components/airvisual/const.py +++ b/homeassistant/components/airvisual/const.py @@ -11,6 +11,7 @@ CONF_COUNTRY = "country" CONF_GEOGRAPHIES = "geographies" CONF_INTEGRATION_TYPE = "integration_type" +CONF_TREND_MEASUREMENTS = "trend_measurements" DATA_CLIENT = "client" diff --git a/homeassistant/components/airvisual/strings.json b/homeassistant/components/airvisual/strings.json index 8b9978b611fda..188361afed728 100644 --- a/homeassistant/components/airvisual/strings.json +++ b/homeassistant/components/airvisual/strings.json @@ -42,7 +42,8 @@ "init": { "title": "Configure AirVisual", "data": { - "show_on_map": "Show monitored geography on the map" + "show_on_map": "Show monitored geography on the map", + "trend_measurements": "Measurements to use for trends (-1 to use all)" } } } diff --git a/homeassistant/components/airvisual/translations/en.json b/homeassistant/components/airvisual/translations/en.json index 842eaaaa1de1d..39228c71d1372 100644 --- a/homeassistant/components/airvisual/translations/en.json +++ b/homeassistant/components/airvisual/translations/en.json @@ -28,10 +28,7 @@ }, "user": { "data": { - "api_key": "API Key", "cloud_api": "Geographical Location", - "latitude": "Latitude", - "longitude": "Longitude", "node_pro": "AirVisual Node Pro", "type": "Integration Type" }, @@ -44,9 +41,9 @@ "step": { "init": { "data": { - "show_on_map": "Show monitored geography on the map" + "show_on_map": "Show monitored geography on the map", + "trend_measurements": "Measurements to use for trends (-1 to use all)" }, - "description": "Set various options for the AirVisual integration.", "title": "Configure AirVisual" } } diff --git a/tests/components/airvisual/test_config_flow.py b/tests/components/airvisual/test_config_flow.py index 9127e6b278076..aa31afe93e7cf 100644 --- a/tests/components/airvisual/test_config_flow.py +++ b/tests/components/airvisual/test_config_flow.py @@ -6,6 +6,7 @@ from homeassistant.components.airvisual import ( CONF_GEOGRAPHIES, CONF_INTEGRATION_TYPE, + CONF_TREND_MEASUREMENTS, DOMAIN, INTEGRATION_TYPE_GEOGRAPHY, INTEGRATION_TYPE_NODE_PRO, @@ -137,18 +138,19 @@ async def test_migration(hass): } -async def test_options_flow(hass): - """Test config flow options.""" - geography_conf = { +async def test_options_flow_geography(hass): + """Test config flow options for a geography-based config entry.""" + conf = { CONF_API_KEY: "abcde12345", CONF_LATITUDE: 51.528308, CONF_LONGITUDE: -0.3817765, + CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY, } config_entry = MockConfigEntry( domain=DOMAIN, unique_id="51.528308, -0.3817765", - data=geography_conf, + data=conf, options={CONF_SHOW_ON_MAP: True}, ) config_entry.add_to_hass(hass) @@ -169,6 +171,38 @@ async def test_options_flow(hass): assert config_entry.options == {CONF_SHOW_ON_MAP: False} +async def test_options_flow_node_pro(hass): + """Test config flow options for a Node/Pro-based config entry.""" + conf = { + CONF_IP_ADDRESS: "192.168.1.100", + CONF_PASSWORD: "my_password", + CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_NODE_PRO, + } + + config_entry = MockConfigEntry( + domain=DOMAIN, + unique_id="51.528308, -0.3817765", + data=conf, + options={CONF_TREND_MEASUREMENTS: -1}, + ) + config_entry.add_to_hass(hass) + + with patch( + "homeassistant.components.airvisual.async_setup_entry", return_value=True + ): + result = await hass.config_entries.options.async_init(config_entry.entry_id) + + assert result["type"] == data_entry_flow.RESULT_TYPE_FORM + assert result["step_id"] == "init" + + result = await hass.config_entries.options.async_configure( + result["flow_id"], user_input={CONF_TREND_MEASUREMENTS: 10} + ) + + assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + assert config_entry.options == {CONF_TREND_MEASUREMENTS: 10} + + async def test_step_geography(hass): """Test the geograph (cloud API) step.""" conf = {