From df598544d6f5a72e7c951872cc5930d01d60ea62 Mon Sep 17 00:00:00 2001 From: msvinth Date: Sun, 17 Feb 2019 11:45:58 +0100 Subject: [PATCH] Make Netatmo able to discover both Weather station and Health Coach (#20274) * Resolve conflicts and review comments * Corretly handle HomeCoach in manual setup * Fix code reivew comments * Move import back int methods * Formatting fix * Lint fix --- homeassistant/components/netatmo/sensor.py | 94 +++++++++++++++++----- 1 file changed, 72 insertions(+), 22 deletions(-) diff --git a/homeassistant/components/netatmo/sensor.py b/homeassistant/components/netatmo/sensor.py index 78a118528b9..3f04f22ac76 100644 --- a/homeassistant/components/netatmo/sensor.py +++ b/homeassistant/components/netatmo/sensor.py @@ -47,6 +47,7 @@ SENSOR_TYPES = { 'rf_status_lvl': ['Radio_lvl', '', 'mdi:signal', None], 'wifi_status': ['Wifi', '', 'mdi:wifi', None], 'wifi_status_lvl': ['Wifi_lvl', 'dBm', 'mdi:wifi', None], + 'health_idx': ['Health', '', 'mdi:cloud', None], } MODULE_SCHEMA = vol.Schema({ @@ -67,23 +68,55 @@ MODULE_TYPE_INDOOR = 'NAModule4' def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the available Netatmo weather sensors.""" netatmo = hass.components.netatmo - data = NetAtmoData(netatmo.NETATMO_AUTH, config.get(CONF_STATION, None)) dev = [] + if CONF_MODULES in config: + manual_config(netatmo, config, dev) + else: + auto_config(netatmo, config, dev) + + if dev: + add_entities(dev, True) + + +def manual_config(netatmo, config, dev): + """Handle manual configuration.""" import pyatmo - try: - if CONF_MODULES in config: + + all_classes = all_product_classes() + not_handled = {} + for data_class in all_classes: + data = NetAtmoData(netatmo.NETATMO_AUTH, data_class, + config.get(CONF_STATION)) + try: # Iterate each module for module_name, monitored_conditions in \ config[CONF_MODULES].items(): # Test if module exists if module_name not in data.get_module_names(): - _LOGGER.error('Module name: "%s" not found', module_name) - continue - # Only create sensors for monitored properties - for variable in monitored_conditions: - dev.append(NetAtmoSensor(data, module_name, variable)) - else: + not_handled[module_name] = \ + not_handled[module_name]+1 \ + if module_name in not_handled else 1 + else: + # Only create sensors for monitored properties + for variable in monitored_conditions: + dev.append(NetAtmoSensor(data, module_name, variable)) + except pyatmo.NoDevice: + continue + + for module_name, count in not_handled.items(): + if count == len(all_classes): + _LOGGER.error('Module name: "%s" not found', module_name) + + +def auto_config(netatmo, config, dev): + """Handle auto configuration.""" + import pyatmo + + for data_class in all_product_classes(): + data = NetAtmoData(netatmo.NETATMO_AUTH, data_class, + config.get(CONF_STATION)) + try: for module_name in data.get_module_names(): for variable in \ data.station_data.monitoredConditions(module_name): @@ -92,10 +125,15 @@ def setup_platform(hass, config, add_entities, discovery_info=None): else: _LOGGER.warning("Ignoring unknown var %s for mod %s", variable, module_name) - except pyatmo.NoDevice: - return None + except pyatmo.NoDevice: + continue - add_entities(dev, True) + +def all_product_classes(): + """Provide all handled Netatmo product classes.""" + import pyatmo + + return [pyatmo.WeatherStationData, pyatmo.HomeCoachData] class NetAtmoSensor(Entity): @@ -299,6 +337,17 @@ class NetAtmoSensor(Entity): self._state = "High" elif data['wifi_status'] <= 55: self._state = "Full" + elif self.type == 'health_idx': + if data['health_idx'] == 0: + self._state = "Healthy" + elif data['health_idx'] == 1: + self._state = "Fine" + elif data['health_idx'] == 2: + self._state = "Fair" + elif data['health_idx'] == 3: + self._state = "Poor" + elif data['health_idx'] == 4: + self._state = "Unhealthy" except KeyError: _LOGGER.error("No %s data found for %s", self.type, self.module_name) @@ -309,9 +358,10 @@ class NetAtmoSensor(Entity): class NetAtmoData: """Get the latest data from NetAtmo.""" - def __init__(self, auth, station): + def __init__(self, auth, data_class, station): """Initialize the data object.""" self.auth = auth + self.data_class = data_class self.data = None self.station_data = None self.station = station @@ -321,6 +371,8 @@ class NetAtmoData: def get_module_names(self): """Return all module available on the API as a list.""" self.update() + if not self.data: + return [] return self.data.keys() def _detect_platform_type(self): @@ -328,14 +380,12 @@ class NetAtmoData: The return can be a WeatherStationData or a HomeCoachData. """ - import pyatmo - for data_class in [pyatmo.WeatherStationData, pyatmo.HomeCoachData]: - try: - station_data = data_class(self.auth) - _LOGGER.debug("%s detected!", str(data_class.__name__)) - return station_data - except TypeError: - continue + try: + station_data = self.data_class(self.auth) + _LOGGER.debug("%s detected!", str(self.data_class.__name__)) + return station_data + except TypeError: + return def update(self): """Call the Netatmo API to update the data. @@ -366,7 +416,7 @@ class NetAtmoData: newinterval = self.data[module]['When'] break except TypeError: - _LOGGER.error("No modules found!") + _LOGGER.debug("No %s modules found", self.data_class.__name__) if newinterval: # Try and estimate when fresh data will be available