From 98eaecf61dfd4a18a2b76401d56228666647981f Mon Sep 17 00:00:00 2001 From: Mark Coombes Date: Fri, 4 Oct 2019 02:31:45 -0400 Subject: [PATCH] Add device registry support to ecobee integration (#27109) * Add manufacturer const * Add device_info to binary sensor * Add device info to climate * Add device info to sensor * Add device info to weather * Add constant for device info * Fix log messages * Use guard clauses --- .../components/ecobee/binary_sensor.py | 40 ++++++++++++++++++- homeassistant/components/ecobee/climate.py | 25 +++++++++++- homeassistant/components/ecobee/const.py | 14 +++++++ homeassistant/components/ecobee/sensor.py | 40 ++++++++++++++++++- homeassistant/components/ecobee/weather.py | 26 +++++++++++- 5 files changed, 141 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/ecobee/binary_sensor.py b/homeassistant/components/ecobee/binary_sensor.py index 68d8a88df47..97ba94aaa70 100644 --- a/homeassistant/components/ecobee/binary_sensor.py +++ b/homeassistant/components/ecobee/binary_sensor.py @@ -4,7 +4,7 @@ from homeassistant.components.binary_sensor import ( DEVICE_CLASS_OCCUPANCY, ) -from .const import DOMAIN +from .const import DOMAIN, ECOBEE_MODEL_TO_NAME, MANUFACTURER, _LOGGER async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): @@ -52,6 +52,44 @@ class EcobeeBinarySensor(BinarySensorDevice): return f"{sensor['code']}-{self.device_class}" return f"{sensor['id']}-{self.device_class}" + @property + def device_info(self): + """Return device information for this sensor.""" + identifier = None + model = None + for sensor in self.data.ecobee.get_remote_sensors(self.index): + if sensor["name"] != self.sensor_name: + continue + if "code" in sensor: + identifier = sensor["code"] + model = "ecobee Room Sensor" + else: + thermostat = self.data.ecobee.get_thermostat(self.index) + identifier = thermostat["identifier"] + try: + model = ( + f"{ECOBEE_MODEL_TO_NAME[thermostat['modelNumber']]} Thermostat" + ) + except KeyError: + _LOGGER.error( + "Model number for ecobee thermostat %s not recognized. " + "Please visit this link and provide the following information: " + "https://github.com/home-assistant/home-assistant/issues/27172 " + "Unrecognized model number: %s", + thermostat["name"], + thermostat["modelNumber"], + ) + break + + if identifier is not None and model is not None: + return { + "identifiers": {(DOMAIN, identifier)}, + "name": self.sensor_name, + "manufacturer": MANUFACTURER, + "model": model, + } + return None + @property def is_on(self): """Return the status of the sensor.""" diff --git a/homeassistant/components/ecobee/climate.py b/homeassistant/components/ecobee/climate.py index f930282ba7b..491fd8d686a 100644 --- a/homeassistant/components/ecobee/climate.py +++ b/homeassistant/components/ecobee/climate.py @@ -36,7 +36,7 @@ from homeassistant.const import ( from homeassistant.util.temperature import convert import homeassistant.helpers.config_validation as cv -from .const import DOMAIN, _LOGGER +from .const import DOMAIN, ECOBEE_MODEL_TO_NAME, MANUFACTURER, _LOGGER from .util import ecobee_date, ecobee_time ATTR_COOL_TEMP = "cool_temp" @@ -310,6 +310,29 @@ class Thermostat(ClimateDevice): """Return a unique identifier for this ecobee thermostat.""" return self.thermostat["identifier"] + @property + def device_info(self): + """Return device information for this ecobee thermostat.""" + try: + model = f"{ECOBEE_MODEL_TO_NAME[self.thermostat['modelNumber']]} Thermostat" + except KeyError: + _LOGGER.error( + "Model number for ecobee thermostat %s not recognized. " + "Please visit this link and provide the following information: " + "https://github.com/home-assistant/home-assistant/issues/27172 " + "Unrecognized model number: %s", + self.name, + self.thermostat["modelNumber"], + ) + return None + + return { + "identifiers": {(DOMAIN, self.thermostat["identifier"])}, + "name": self.name, + "manufacturer": MANUFACTURER, + "model": model, + } + @property def temperature_unit(self): """Return the unit of measurement.""" diff --git a/homeassistant/components/ecobee/const.py b/homeassistant/components/ecobee/const.py index c3a23099b8a..411f5ddeeeb 100644 --- a/homeassistant/components/ecobee/const.py +++ b/homeassistant/components/ecobee/const.py @@ -9,4 +9,18 @@ DATA_ECOBEE_CONFIG = "ecobee_config" CONF_INDEX = "index" CONF_REFRESH_TOKEN = "refresh_token" +ECOBEE_MODEL_TO_NAME = { + "idtSmart": "ecobee Smart", + "idtEms": "ecobee Smart EMS", + "siSmart": "ecobee Si Smart", + "siEms": "ecobee Si EMS", + "athenaSmart": "ecobee3 Smart", + "athenaEms": "ecobee3 EMS", + "corSmart": "Carrier/Bryant Cor", + "nikeSmart": "ecobee3 lite Smart", + "nikeEms": "ecobee3 lite EMS", +} + ECOBEE_PLATFORMS = ["binary_sensor", "climate", "sensor", "weather"] + +MANUFACTURER = "ecobee" diff --git a/homeassistant/components/ecobee/sensor.py b/homeassistant/components/ecobee/sensor.py index 8cf9af0e3b4..27a8ae3ef07 100644 --- a/homeassistant/components/ecobee/sensor.py +++ b/homeassistant/components/ecobee/sensor.py @@ -8,7 +8,7 @@ from homeassistant.const import ( ) from homeassistant.helpers.entity import Entity -from .const import DOMAIN +from .const import DOMAIN, ECOBEE_MODEL_TO_NAME, MANUFACTURER, _LOGGER SENSOR_TYPES = { "temperature": ["Temperature", TEMP_FAHRENHEIT], @@ -63,6 +63,44 @@ class EcobeeSensor(Entity): return f"{sensor['code']}-{self.device_class}" return f"{sensor['id']}-{self.device_class}" + @property + def device_info(self): + """Return device information for this sensor.""" + identifier = None + model = None + for sensor in self.data.ecobee.get_remote_sensors(self.index): + if sensor["name"] != self.sensor_name: + continue + if "code" in sensor: + identifier = sensor["code"] + model = "ecobee Room Sensor" + else: + thermostat = self.data.ecobee.get_thermostat(self.index) + identifier = thermostat["identifier"] + try: + model = ( + f"{ECOBEE_MODEL_TO_NAME[thermostat['modelNumber']]} Thermostat" + ) + except KeyError: + _LOGGER.error( + "Model number for ecobee thermostat %s not recognized. " + "Please visit this link and provide the following information: " + "https://github.com/home-assistant/home-assistant/issues/27172 " + "Unrecognized model number: %s", + thermostat["name"], + thermostat["modelNumber"], + ) + break + + if identifier is not None and model is not None: + return { + "identifiers": {(DOMAIN, identifier)}, + "name": self.sensor_name, + "manufacturer": MANUFACTURER, + "model": model, + } + return None + @property def device_class(self): """Return the device class of the sensor.""" diff --git a/homeassistant/components/ecobee/weather.py b/homeassistant/components/ecobee/weather.py index 6175405638e..53e9842aae7 100644 --- a/homeassistant/components/ecobee/weather.py +++ b/homeassistant/components/ecobee/weather.py @@ -13,7 +13,7 @@ from homeassistant.components.weather import ( ) from homeassistant.const import TEMP_FAHRENHEIT -from .const import DOMAIN +from .const import DOMAIN, ECOBEE_MODEL_TO_NAME, MANUFACTURER, _LOGGER ATTR_FORECAST_TEMP_HIGH = "temphigh" ATTR_FORECAST_PRESSURE = "pressure" @@ -66,6 +66,30 @@ class EcobeeWeather(WeatherEntity): """Return a unique identifier for the weather platform.""" return self.data.ecobee.get_thermostat(self._index)["identifier"] + @property + def device_info(self): + """Return device information for the ecobee weather platform.""" + thermostat = self.data.ecobee.get_thermostat(self._index) + try: + model = f"{ECOBEE_MODEL_TO_NAME[thermostat['modelNumber']]} Thermostat" + except KeyError: + _LOGGER.error( + "Model number for ecobee thermostat %s not recognized. " + "Please visit this link and provide the following information: " + "https://github.com/home-assistant/home-assistant/issues/27172 " + "Unrecognized model number: %s", + thermostat["name"], + thermostat["modelNumber"], + ) + return None + + return { + "identifiers": {(DOMAIN, thermostat["identifier"])}, + "name": self.name, + "manufacturer": MANUFACTURER, + "model": model, + } + @property def condition(self): """Return the current condition."""