diff --git a/.coveragerc b/.coveragerc index 9fafe443dcf..b8016fa7624 100644 --- a/.coveragerc +++ b/.coveragerc @@ -16,6 +16,8 @@ omit = homeassistant/components/*/tellstick.py homeassistant/components/*/vera.py + + homeassistant/components/ecobee.py homeassistant/components/*/ecobee.py homeassistant/components/verisure.py diff --git a/homeassistant/components/ecobee.py b/homeassistant/components/ecobee.py new file mode 100644 index 00000000000..99db73b6a90 --- /dev/null +++ b/homeassistant/components/ecobee.py @@ -0,0 +1,127 @@ +""" +homeassistant.components.zwave +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Connects Home Assistant to the Ecobee API and maintains tokens. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/ecobee/ + +[ecobee] +api_key: asdflaksf +""" + +from homeassistant.loader import get_component +from homeassistant import bootstrap +from homeassistant.const import ( + EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, + EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE, ATTR_DISCOVERED, CONF_API_KEY) +from datetime import timedelta +import logging +import os + +DOMAIN = "ecobee" +DISCOVER_THERMOSTAT = "ecobee.thermostat" +DEPENDENCIES = [] +NETWORK = None + +REQUIREMENTS = [ + 'https://github.com/nkgilley/python-ecobee-api/archive/' + 'd35596b67c75451fa47001c493a15eebee195e93.zip#python-ecobee==0.0.1'] + +_LOGGER = logging.getLogger(__name__) + +ECOBEE_CONFIG_FILE = 'ecobee.conf' +_CONFIGURING = {} + +# Return cached results if last scan was less then this time ago +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180) + + +def request_configuration(network, hass): + """ Request configuration steps from the user. """ + configurator = get_component('configurator') + if 'ecobee' in _CONFIGURING: + configurator.notify_errors( + _CONFIGURING['ecobee'], "Failed to register, please try again.") + + return + + # pylint: disable=unused-argument + def ecobee_configuration_callback(callback_data): + """ Actions to do when our configuration callback is called. """ + network.request_tokens() + network.update() + setup_ecobee(hass, network) + + _CONFIGURING['ecobee'] = configurator.request_config( + hass, "Ecobee", ecobee_configuration_callback, + description=( + 'Please authorize this app at https://www.ecobee.com/consumer' + 'portal/index.html with pin code: ' + NETWORK.pin), + description_image="/static/images/config_ecobee_thermostat.png", + submit_caption="I have authorized the app." + ) + + +def setup_ecobee(hass, network): + """ Setup ecobee thermostat """ + # If ecobee has a PIN then it needs to be configured. + if network.pin is not None: + request_configuration(network, hass) + return + + if 'ecobee' in _CONFIGURING: + configurator = get_component('configurator') + configurator.request_done(_CONFIGURING.pop('ecobee')) + + +def setup(hass, config): + """ + Setup Ecobee. + Will automatically load thermostat and sensor components to support + devices discovered on the network. + """ + # pylint: disable=global-statement, import-error + global NETWORK + + if 'ecobee' in _CONFIGURING: + return + + from pyecobee import Ecobee, config_from_file + + # Create ecobee.conf if it doesn't exist + if not os.path.isfile(hass.config.path(ECOBEE_CONFIG_FILE)): + if config[DOMAIN].get(CONF_API_KEY) is None: + _LOGGER.error("No ecobee api_key found in config.") + return + jsonconfig = {"API_KEY": config[DOMAIN].get(CONF_API_KEY)} + config_from_file(hass.config.path(ECOBEE_CONFIG_FILE), jsonconfig) + + NETWORK = Ecobee(hass.config.path(ECOBEE_CONFIG_FILE)) + + setup_ecobee(hass, NETWORK) + + # Ensure component is loaded + bootstrap.setup_component(hass, 'thermostat', config) + + # Fire discovery event + hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { + ATTR_SERVICE: DISCOVER_THERMOSTAT, + ATTR_DISCOVERED: { + 'network': NETWORK, + } + }) + + def stop_ecobee(event): + """ Stop Ecobee. """ + + pass + + def start_ecobee(event): + """ Called when Home Assistant starts up. """ + + hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_ecobee) + + hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_ecobee) + + return True diff --git a/homeassistant/components/thermostat/ecobee.py b/homeassistant/components/thermostat/ecobee.py index 7258a3b65a1..5b377be4907 100644 --- a/homeassistant/components/thermostat/ecobee.py +++ b/homeassistant/components/thermostat/ecobee.py @@ -1,4 +1,3 @@ -#!/usr/local/bin/python3 """ homeassistant.components.thermostat.ecobee ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -24,19 +23,14 @@ thermostat: platform: ecobee api_key: asdfasdfasdfasdfasdfaasdfasdfasdfasdf """ -from homeassistant.loader import get_component from homeassistant.components.thermostat import (ThermostatDevice, STATE_COOL, STATE_IDLE, STATE_HEAT) -from homeassistant.const import ( - CONF_API_KEY, TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) +from homeassistant.const import (TEMP_FAHRENHEIT, STATE_ON, STATE_OFF) from homeassistant.util import Throttle from datetime import timedelta import logging -import os -REQUIREMENTS = [ - 'https://github.com/nkgilley/python-ecobee-api/archive/' - '790c20d820dbb727af2dbfb3ef0f79231e19a503.zip#python-ecobee==0.0.1'] +DEPENDENCIES = ['ecobee'] _LOGGER = logging.getLogger(__name__) @@ -47,70 +41,28 @@ _CONFIGURING = {} MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=180) -def setup_platform(hass, config, add_devices_callback, discovery_info=None): +def setup_platform(hass, config, add_devices, discovery_info=None): """ Setup Platform """ - # Only act if we are not already configuring this host - if 'ecobee' in _CONFIGURING: + _LOGGER.error("ecobee !!!!") + if discovery_info is None: return - - from pyecobee import config_from_file - - # Create ecobee.conf if it doesn't exist - if not os.path.isfile(hass.config.path(ECOBEE_CONFIG_FILE)): - jsonconfig = {"API_KEY": config[CONF_API_KEY]} - config_from_file(hass.config.path(ECOBEE_CONFIG_FILE), jsonconfig) - data = EcobeeData(hass.config.path(ECOBEE_CONFIG_FILE)) - setup_ecobee(hass, data, config, add_devices_callback) + data = EcobeeData(discovery_info[0]) + setup_ecobee(hass, data, add_devices) -def setup_ecobee(hass, data, config, add_devices_callback): +def setup_ecobee(hass, data, add_devices): """ Setup ecobee thermostat """ - # If ecobee has a PIN then it needs to be configured. - if data.ecobee.pin is not None: - request_configuration(data, hass, add_devices_callback) - return - if 'ecobee' in _CONFIGURING: - configurator = get_component('configurator') - configurator.request_done(_CONFIGURING.pop('ecobee')) - - add_devices_callback(Thermostat(data, index) - for index in range(len(data.ecobee.thermostats))) - - -def request_configuration(data, hass, add_devices_callback): - """ Request configuration steps from the user. """ - configurator = get_component('configurator') - if 'ecobee' in _CONFIGURING: - configurator.notify_errors( - _CONFIGURING['ecobee'], "Failed to register, please try again.") - - return - - # pylint: disable=unused-argument - def ecobee_configuration_callback(callback_data): - """ Actions to do when our configuration callback is called. """ - data.ecobee.request_tokens() - data.ecobee.update() - setup_ecobee(hass, data, None, add_devices_callback) - - _CONFIGURING['ecobee'] = configurator.request_config( - hass, "Ecobee", ecobee_configuration_callback, - description=( - 'Please authorize this app at https://www.ecobee.com/consumer' - 'portal/index.html with pin code: ' + data.ecobee.pin), - description_image="/static/images/config_ecobee_thermostat.png", - submit_caption="I have authorized the app." - ) + add_devices(Thermostat(data, index) + for index in range(len(data.ecobee.thermostats))) # pylint: disable=too-few-public-methods class EcobeeData(object): """ Gets the latest data and update the states. """ - def __init__(self, config_filename): - from pyecobee import Ecobee - self.ecobee = Ecobee(config_filename) + def __init__(self, network): + self.ecobee = network @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): diff --git a/requirements_all.txt b/requirements_all.txt index 3a930c145dd..b74226f4991 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -161,4 +161,4 @@ pushetta==1.0.15 orvibo==1.0.0 # Ecobee (*.ecobee) -https://github.com/nkgilley/python-ecobee-api/archive/730009b9593899d42e98c81a0544f91e65b2bc15.zip#python-ecobee==0.0.1 +https://github.com/nkgilley/python-ecobee-api/archive/d35596b67c75451fa47001c493a15eebee195e93.zip#python-ecobee==0.0.1