diff --git a/homeassistant/components/netatmo/__init__.py b/homeassistant/components/netatmo/__init__.py index 776e63bef7d..b7d439b4a74 100644 --- a/homeassistant/components/netatmo/__init__.py +++ b/homeassistant/components/netatmo/__init__.py @@ -28,6 +28,7 @@ from . import api, config_flow from .const import ( AUTH, CONF_CLOUDHOOK_URL, + DATA_DEVICE_IDS, DATA_PERSONS, DOMAIN, OAUTH2_AUTHORIZE, @@ -65,6 +66,7 @@ async def async_setup(hass: HomeAssistant, config: dict): """Set up the Netatmo component.""" hass.data[DOMAIN] = {} hass.data[DOMAIN][DATA_PERSONS] = {} + hass.data[DOMAIN][DATA_DEVICE_IDS] = {} if DOMAIN not in config: return True @@ -104,7 +106,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): webhook_unregister(hass, entry.data[CONF_WEBHOOK_ID]) async def register_webhook(event): - # Wait for the could integration to be ready + # Wait for the cloud integration to be ready await asyncio.sleep(WAIT_FOR_CLOUD) if CONF_WEBHOOK_ID not in entry.data: @@ -112,6 +114,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): hass.config_entries.async_update_entry(entry, data=data) if hass.components.cloud.async_active_subscription(): + # Wait for cloud connection to be established + await asyncio.sleep(WAIT_FOR_CLOUD) + if CONF_CLOUDHOOK_URL not in entry.data: webhook_url = await hass.components.cloud.async_create_cloudhook( entry.data[CONF_WEBHOOK_ID] @@ -144,6 +149,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): """Unload a config entry.""" + if CONF_WEBHOOK_ID in entry.data: + await hass.async_add_executor_job( + hass.data[DOMAIN][entry.entry_id][AUTH].dropwebhook + ) + unload_ok = all( await asyncio.gather( *[ @@ -152,14 +162,10 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): ] ) ) + if unload_ok: hass.data[DOMAIN].pop(entry.entry_id) - if CONF_WEBHOOK_ID in entry.data: - await hass.async_add_executor_job( - hass.data[DOMAIN][entry.entry_id][AUTH].dropwebhook() - ) - return unload_ok diff --git a/homeassistant/components/netatmo/camera.py b/homeassistant/components/netatmo/camera.py index 616d2a620c5..30f209625f6 100644 --- a/homeassistant/components/netatmo/camera.py +++ b/homeassistant/components/netatmo/camera.py @@ -84,21 +84,11 @@ class NetatmoCamera(Camera): self._unique_id = f"{self._camera_id}-{self._camera_type}" self._verify_ssl = verify_ssl self._quality = quality - - # URLs self._vpnurl = None self._localurl = None - - # Monitoring status self._status = None - - # SD Card status self._sd_status = None - - # Power status self._alim_status = None - - # Is local self._is_local = None def camera_image(self): @@ -219,8 +209,6 @@ class NetatmoCamera(Camera): def update(self): """Update entity status.""" - - # Refresh camera data self._data.update() camera = self._data.camera_data.get_camera(cid=self._camera_id) diff --git a/homeassistant/components/netatmo/climate.py b/homeassistant/components/netatmo/climate.py index aa269cfeb49..1f1b7088b29 100644 --- a/homeassistant/components/netatmo/climate.py +++ b/homeassistant/components/netatmo/climate.py @@ -441,6 +441,11 @@ class ThermostatData: except TypeError: _LOGGER.error("ThermostatData::setup() got error") return False + except pyatmo.exceptions.NoDevice: + _LOGGER.debug( + "No climate devices for %s (%s)", self.home_name, self.home_id + ) + return False return True @Throttle(MIN_TIME_BETWEEN_UPDATES) diff --git a/homeassistant/components/netatmo/config_flow.py b/homeassistant/components/netatmo/config_flow.py index dce87fb7931..6d524ab9f29 100644 --- a/homeassistant/components/netatmo/config_flow.py +++ b/homeassistant/components/netatmo/config_flow.py @@ -33,6 +33,7 @@ class NetatmoFlowHandler( "read_station", "read_thermostat", "write_camera", + "write_presence", "write_thermostat", ] diff --git a/homeassistant/components/netatmo/const.py b/homeassistant/components/netatmo/const.py index 0a0c9575600..4e4ff308755 100644 --- a/homeassistant/components/netatmo/const.py +++ b/homeassistant/components/netatmo/const.py @@ -14,12 +14,12 @@ MODELS = { "NOC": "Smart Outdoor Camera", "NSD": "Smart Smoke Alarm", "NACamDoorTag": "Smart Door and Window Sensors", + "NHC": "Smart Indoor Air Quality Monitor", "NAMain": "Smart Home Weather station – indoor module", "NAModule1": "Smart Home Weather station – outdoor module", "NAModule4": "Smart Additional Indoor module", "NAModule3": "Smart Rain Gauge", "NAModule2": "Smart Anemometer", - "NHC": "Home Coach", } AUTH = "netatmo_auth" @@ -32,6 +32,7 @@ CONF_CLOUDHOOK_URL = "cloudhook_url" OAUTH2_AUTHORIZE = "https://api.netatmo.com/oauth2/authorize" OAUTH2_TOKEN = "https://api.netatmo.com/oauth2/token" +DATA_DEVICE_IDS = "netatmo_device_ids" DATA_PERSONS = "netatmo_persons" NETATMO_WEBHOOK_URL = None diff --git a/homeassistant/components/person/__init__.py b/homeassistant/components/person/__init__.py index 9cd3e882c48..006929c7345 100644 --- a/homeassistant/components/person/__init__.py +++ b/homeassistant/components/person/__init__.py @@ -77,7 +77,11 @@ PERSON_SCHEMA = vol.Schema( ) CONFIG_SCHEMA = vol.Schema( - {vol.Optional(DOMAIN): vol.All(cv.ensure_list, cv.remove_falsy, [PERSON_SCHEMA])}, + { + vol.Optional(DOMAIN, default=[]): vol.All( + cv.ensure_list, cv.remove_falsy, [PERSON_SCHEMA] + ) + }, extra=vol.ALLOW_EXTRA, ) diff --git a/homeassistant/config.py b/homeassistant/config.py index 27aff8ca36b..b1cd49b0852 100644 --- a/homeassistant/config.py +++ b/homeassistant/config.py @@ -571,7 +571,9 @@ def _identify_config_schema(module: ModuleType) -> Tuple[Optional[str], Optional schema = module.CONFIG_SCHEMA.schema[key] # type: ignore - if hasattr(key, "default"): + if hasattr(key, "default") and not isinstance( + key.default, vol.schema_builder.Undefined + ): default_value = schema(key.default()) if isinstance(default_value, dict): diff --git a/homeassistant/const.py b/homeassistant/const.py index 3d4e380439c..86ef567be6d 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 107 -PATCH_VERSION = "2" +PATCH_VERSION = "3" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 0) diff --git a/tests/components/netatmo/test_config_flow.py b/tests/components/netatmo/test_config_flow.py index c9a663991cb..29a1d4f53d5 100644 --- a/tests/components/netatmo/test_config_flow.py +++ b/tests/components/netatmo/test_config_flow.py @@ -65,6 +65,7 @@ async def test_full_flow(hass, aiohttp_client, aioclient_mock): "read_station", "read_thermostat", "write_camera", + "write_presence", "write_thermostat", ] )