diff --git a/homeassistant/components/environment_canada/__init__.py b/homeassistant/components/environment_canada/__init__.py index b47d280b34e..fa2643054df 100644 --- a/homeassistant/components/environment_canada/__init__.py +++ b/homeassistant/components/environment_canada/__init__.py @@ -5,7 +5,7 @@ import xml.etree.ElementTree as et from env_canada import ECAirQuality, ECRadar, ECWeather, ec_exc -from homeassistant.config_entries import ConfigEntry +from homeassistant.config_entries import ConfigEntry, ConfigEntryNotReady from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -28,6 +28,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b lang = config_entry.data.get(CONF_LANGUAGE, "English") coordinators = {} + errors = 0 weather_data = ECWeather( station_id=station, @@ -37,19 +38,34 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b coordinators["weather_coordinator"] = ECDataUpdateCoordinator( hass, weather_data, "weather", DEFAULT_WEATHER_UPDATE_INTERVAL ) - await coordinators["weather_coordinator"].async_config_entry_first_refresh() + try: + await coordinators["weather_coordinator"].async_config_entry_first_refresh() + except ConfigEntryNotReady: + errors = errors + 1 + _LOGGER.warning("Unable to retrieve Environment Canada weather") radar_data = ECRadar(coordinates=(lat, lon)) coordinators["radar_coordinator"] = ECDataUpdateCoordinator( hass, radar_data, "radar", DEFAULT_RADAR_UPDATE_INTERVAL ) - await coordinators["radar_coordinator"].async_config_entry_first_refresh() + try: + await coordinators["radar_coordinator"].async_config_entry_first_refresh() + except ConfigEntryNotReady: + errors = errors + 1 + _LOGGER.warning("Unable to retrieve Environment Canada radar") aqhi_data = ECAirQuality(coordinates=(lat, lon)) coordinators["aqhi_coordinator"] = ECDataUpdateCoordinator( hass, aqhi_data, "AQHI", DEFAULT_WEATHER_UPDATE_INTERVAL ) - await coordinators["aqhi_coordinator"].async_config_entry_first_refresh() + try: + await coordinators["aqhi_coordinator"].async_config_entry_first_refresh() + except ConfigEntryNotReady: + errors = errors + 1 + _LOGGER.warning("Unable to retrieve Environment Canada AQHI") + + if errors == 3: + raise ConfigEntryNotReady hass.data.setdefault(DOMAIN, {}) hass.data[DOMAIN][config_entry.entry_id] = coordinators @@ -79,6 +95,7 @@ class ECDataUpdateCoordinator(DataUpdateCoordinator): hass, _LOGGER, name=f"{DOMAIN} {name}", update_interval=update_interval ) self.ec_data = ec_data + self.last_update_success = False async def _async_update_data(self): """Fetch data from EC.""" diff --git a/homeassistant/components/environment_canada/camera.py b/homeassistant/components/environment_canada/camera.py index c389e178cbd..e09ae99e006 100644 --- a/homeassistant/components/environment_canada/camera.py +++ b/homeassistant/components/environment_canada/camera.py @@ -42,6 +42,8 @@ class ECCamera(CoordinatorEntity, Camera): self, width: int | None = None, height: int | None = None ) -> bytes | None: """Return bytes of camera image.""" + if not hasattr(self.radar_object, "timestamp"): + return None self.observation_time = self.radar_object.timestamp return self.radar_object.image diff --git a/homeassistant/components/environment_canada/sensor.py b/homeassistant/components/environment_canada/sensor.py index ea93a203372..4cfe6bbbfb2 100644 --- a/homeassistant/components/environment_canada/sensor.py +++ b/homeassistant/components/environment_canada/sensor.py @@ -223,35 +223,35 @@ ALERT_TYPES: tuple[ECSensorEntityDescription, ...] = ( key="advisories", name="Advisory", icon="mdi:bell-alert", - value_fn=lambda data: data.alerts.get("advisories", {}).get("value", []), + value_fn=lambda data: data.alerts.get("advisories", {}).get("value"), transform=len, ), ECSensorEntityDescription( key="endings", name="Endings", icon="mdi:alert-circle-check", - value_fn=lambda data: data.alerts.get("endings", {}).get("value", []), + value_fn=lambda data: data.alerts.get("endings", {}).get("value"), transform=len, ), ECSensorEntityDescription( key="statements", name="Statements", icon="mdi:bell-alert", - value_fn=lambda data: data.alerts.get("statements", {}).get("value", []), + value_fn=lambda data: data.alerts.get("statements", {}).get("value"), transform=len, ), ECSensorEntityDescription( key="warnings", name="Warnings", icon="mdi:alert-octagon", - value_fn=lambda data: data.alerts.get("warnings", {}).get("value", []), + value_fn=lambda data: data.alerts.get("warnings", {}).get("value"), transform=len, ), ECSensorEntityDescription( key="watches", name="Watches", icon="mdi:alert", - value_fn=lambda data: data.alerts.get("watches", {}).get("value", []), + value_fn=lambda data: data.alerts.get("watches", {}).get("value"), transform=len, ), ) @@ -283,13 +283,13 @@ class ECBaseSensor(CoordinatorEntity, SensorEntity): self._ec_data = coordinator.ec_data self._attr_attribution = self._ec_data.metadata["attribution"] self._attr_name = f"{coordinator.config_entry.title} {description.name}" - self._attr_unique_id = f"{self._ec_data.metadata['location']}-{description.key}" + self._attr_unique_id = f"{coordinator.config_entry.title}-{description.key}" @property def native_value(self): """Return the native value of the sensor.""" value = self.entity_description.value_fn(self._ec_data) - if self.entity_description.transform: + if value is not None and self.entity_description.transform: value = self.entity_description.transform(value) return value @@ -313,6 +313,8 @@ class ECAlertSensor(ECBaseSensor): def extra_state_attributes(self): """Return the extra state attributes.""" value = self.entity_description.value_fn(self._ec_data) + if not value: + return None extra_state_attrs = { ATTR_LOCATION: self._ec_data.metadata.get("location"),