diff --git a/.coveragerc b/.coveragerc index 73a79c2d87b..09d2f765d2a 100644 --- a/.coveragerc +++ b/.coveragerc @@ -346,6 +346,9 @@ omit = homeassistant/components/tuya.py homeassistant/components/*/tuya.py + homeassistant/components/spider.py + homeassistant/components/*/spider.py + homeassistant/components/alarm_control_panel/alarmdotcom.py homeassistant/components/alarm_control_panel/canary.py homeassistant/components/alarm_control_panel/concord232.py diff --git a/homeassistant/components/climate/spider.py b/homeassistant/components/climate/spider.py new file mode 100644 index 00000000000..9a8f7dd7fbd --- /dev/null +++ b/homeassistant/components/climate/spider.py @@ -0,0 +1,140 @@ +""" +Support for Spider thermostats. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/climate.spider/ +""" + +import logging + +from homeassistant.components.climate import ( + ATTR_TEMPERATURE, STATE_COOL, STATE_HEAT, STATE_IDLE, + SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE, ClimateDevice) +from homeassistant.components.spider import DOMAIN as SPIDER_DOMAIN +from homeassistant.const import TEMP_CELSIUS + +DEPENDENCIES = ['spider'] + +OPERATION_LIST = [ + STATE_HEAT, + STATE_COOL, +] + +HA_STATE_TO_SPIDER = { + STATE_COOL: 'Cool', + STATE_HEAT: 'Heat', + STATE_IDLE: 'Idle' +} + +SPIDER_STATE_TO_HA = {value: key for key, value in HA_STATE_TO_SPIDER.items()} + +_LOGGER = logging.getLogger(__name__) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the Spider thermostat.""" + if discovery_info is None: + return + + devices = [SpiderThermostat(hass.data[SPIDER_DOMAIN]['controller'], device) + for device in hass.data[SPIDER_DOMAIN]['thermostats']] + add_devices(devices, True) + + +class SpiderThermostat(ClimateDevice): + """Representation of a thermostat.""" + + def __init__(self, api, thermostat): + """Initialize the thermostat.""" + self.api = api + self.thermostat = thermostat + self.master = self.thermostat.has_operation_mode + + @property + def supported_features(self): + """Return the list of supported features.""" + supports = SUPPORT_TARGET_TEMPERATURE + + if self.thermostat.has_operation_mode: + supports = supports | SUPPORT_OPERATION_MODE + + return supports + + @property + def unique_id(self): + """Return the id of the thermostat, if any.""" + return self.thermostat.id + + @property + def name(self): + """Return the name of the thermostat, if any.""" + return self.thermostat.name + + @property + def temperature_unit(self): + """Return the unit of measurement.""" + return TEMP_CELSIUS + + @property + def current_temperature(self): + """Return the current temperature.""" + return self.thermostat.current_temperature + + @property + def target_temperature(self): + """Return the temperature we try to reach.""" + return self.thermostat.target_temperature + + @property + def target_temperature_step(self): + """Return the supported step of target temperature.""" + return self.thermostat.temperature_steps + + @property + def min_temp(self): + """Return the minimum temperature.""" + return self.thermostat.minimum_temperature + + @property + def max_temp(self): + """Return the maximum temperature.""" + return self.thermostat.maximum_temperature + + @property + def current_operation(self): + """Return current operation ie. heat, cool, idle.""" + return SPIDER_STATE_TO_HA[self.thermostat.operation_mode] + + @property + def operation_list(self): + """Return the list of available operation modes.""" + return OPERATION_LIST + + def set_temperature(self, **kwargs): + """Set new target temperature.""" + temperature = kwargs.get(ATTR_TEMPERATURE) + if temperature is None: + return + + self.thermostat.set_temperature(temperature) + + def set_operation_mode(self, operation_mode): + """Set new target operation mode.""" + self.thermostat.set_operation_mode( + HA_STATE_TO_SPIDER.get(operation_mode)) + + def update(self): + """Get the latest data.""" + try: + # Only let the master thermostat refresh + # and let the others use the cache + thermostats = self.api.get_thermostats( + force_refresh=self.master) + for thermostat in thermostats: + if thermostat.id == self.unique_id: + self.thermostat = thermostat + break + + except StopIteration: + _LOGGER.error("No data from the Spider API") + return diff --git a/homeassistant/components/spider.py b/homeassistant/components/spider.py new file mode 100644 index 00000000000..10dbd630b75 --- /dev/null +++ b/homeassistant/components/spider.py @@ -0,0 +1,56 @@ +""" +Support for Spider Smart devices. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/spider/ +""" +import logging + +import voluptuous as vol + +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.discovery import load_platform + +REQUIREMENTS = ['spiderpy==1.0.7'] + +_LOGGER = logging.getLogger(__name__) + +DOMAIN = 'spider' + +SPIDER_COMPONENTS = [ + 'climate' +] + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Required(CONF_PASSWORD): cv.string, + vol.Required(CONF_USERNAME): cv.string, + }) +}, extra=vol.ALLOW_EXTRA) + + +def setup(hass, config): + """Set up Spider Component.""" + from spiderpy.spiderapi import SpiderApi + from spiderpy.spiderapi import UnauthorizedException + + username = config[DOMAIN][CONF_USERNAME] + password = config[DOMAIN][CONF_PASSWORD] + + try: + api = SpiderApi(username, password) + + hass.data[DOMAIN] = { + 'controller': api, + 'thermostats': api.get_thermostats() + } + + for component in SPIDER_COMPONENTS: + load_platform(hass, component, DOMAIN, {}) + + _LOGGER.debug("Connection with Spider API succeeded") + return True + except UnauthorizedException: + _LOGGER.error("Can't connect to the Spider API") + return False diff --git a/requirements_all.txt b/requirements_all.txt index 8fb02383c27..2cd4d8d4a49 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1278,6 +1278,9 @@ somecomfort==0.5.2 # homeassistant.components.sensor.speedtest speedtest-cli==2.0.2 +# homeassistant.components.spider +spiderpy==1.0.7 + # homeassistant.components.sensor.spotcrime spotcrime==1.0.3