""" homeassistant.components.ecobee ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Ecobee Component This component adds support for Ecobee3 Wireless Thermostats. You will need to setup developer access to your thermostat, and create and API key on the ecobee website. The first time you run this component you will see a configuration component card in Home Assistant. This card will contain a PIN code that you will need to use to authorize access to your thermostat. You can do this at https://www.ecobee.com/consumerportal/index.html Click My Apps, Add application, Enter Pin and click Authorize. After authorizing the application click the button in the configuration card. Now your thermostat and sensors should shown in home-assistant. You can use the optional hold_temp parameter to set whether or not holds are set indefintely or until the next scheduled event. ecobee: api_key: asdfasdfasdfasdfasdfaasdfasdfasdfasdf hold_temp: True """ from datetime import timedelta import logging import os from homeassistant.loader import get_component from homeassistant import bootstrap from homeassistant.util import Throttle from homeassistant.const import ( EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE, ATTR_DISCOVERED, CONF_API_KEY) DOMAIN = "ecobee" DISCOVER_THERMOSTAT = "ecobee.thermostat" DISCOVER_SENSORS = "ecobee.sensor" NETWORK = None HOLD_TEMP = 'hold_temp' REQUIREMENTS = [ 'https://github.com/nkgilley/python-ecobee-api/archive/' '5645f843b64ac4f6e59dfb96233a07083c5e10c1.zip#python-ecobee==0.0.3'] _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, config): """ 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, config) _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, config): """ Setup ecobee thermostat """ # If ecobee has a PIN then it needs to be configured. if network.pin is not None: request_configuration(network, hass, config) return if 'ecobee' in _CONFIGURING: configurator = get_component('configurator') configurator.request_done(_CONFIGURING.pop('ecobee')) # Ensure component is loaded bootstrap.setup_component(hass, 'thermostat', config) bootstrap.setup_component(hass, 'sensor', config) hold_temp = config[DOMAIN].get(HOLD_TEMP, False) # Fire thermostat discovery event hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { ATTR_SERVICE: DISCOVER_THERMOSTAT, ATTR_DISCOVERED: {'hold_temp': hold_temp} }) # Fire sensor discovery event hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { ATTR_SERVICE: DISCOVER_SENSORS, ATTR_DISCOVERED: {} }) # pylint: disable=too-few-public-methods class EcobeeData(object): """ Gets the latest data and update the states. """ def __init__(self, config_file): from pyecobee import Ecobee self.ecobee = Ecobee(config_file) @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): """ Get the latest data from pyecobee. """ self.ecobee.update() _LOGGER.info("ecobee data updated successfully.") 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 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 = EcobeeData(hass.config.path(ECOBEE_CONFIG_FILE)) setup_ecobee(hass, NETWORK.ecobee, config) return True